CtrlCore: FullRefreshCleanup (to avoid any stuck fullrefresh flags)

This commit is contained in:
Mirek Fidler 2024-10-23 16:21:44 +02:00
parent 9218a5d287
commit 678289f77f
6 changed files with 72 additions and 61 deletions

View file

@ -209,6 +209,7 @@ void Ctrl::StateH(int reason)
if((*statehook()[i])(this, reason))
return;
StateDeep(reason);
FullRefreshCleanup();
}
bool Ctrl::Accept()
@ -1042,4 +1043,4 @@ ViewDraw::ViewDraw(Ctrl *ctrl, const Rect& r)
#endif
}
}

View file

@ -41,7 +41,7 @@
#define GUIPLATFORM_INCLUDE "Gtk.h"
#endif
#endif
#endif
#define GUI_APP_MAIN_HOOK
@ -266,7 +266,7 @@ enum {
DND_MOVE = 2,
DND_ALL = 3,
DND_EXACTIMAGE = 0x80000000,
};
@ -496,11 +496,11 @@ private:
MultiFrame multi;
Rect16_ view;
};
void SetView(const Rect& r) { view.left = r.left; view.right = r.right; view.top = r.top; view.bottom = r.bottom; }
Rect GetView() const { return Rect16(view.left, view.top, view.right, view.bottom); }
};
struct Scroll : Moveable<Scroll> {
Rect rect;
int dx;
@ -565,7 +565,9 @@ private:
bool layout_id_literal:1; // info_ptr points to layout char * literal, no heap involved
bool multi_frame:1; // there is more than single frame, they are stored in heap
bool top:1;
bool megarect:1; // support for large virtual screen area - SetRect > 16000
bool megarect:1; // support for large virtual screen area - SetRect.TopLeft > 16000
static bool was_fullrefresh; // indicates that some widgets might have fullrefresh true
static Ptr<Ctrl> eventCtrl;
static Ptr<Ctrl> mouseCtrl;
@ -595,7 +597,7 @@ private:
static Ptr<Ctrl> repeatTopCtrl;
static Point repeatMousePos;
static PenInfo pen;
static bool is_pen_event;
@ -688,6 +690,7 @@ private:
void PaintCaret(SystemDraw& w);
void CtrlPaint(SystemDraw& w, const Rect& clip);
void RemoveFullRefresh();
static void FullRefreshCleanup();
bool PaintOpaqueAreas(SystemDraw& w, const Rect& r, const Rect& clip, bool nochild = false);
void GatherTransparentAreas(Vector<Rect>& area, SystemDraw& w, Rect r, const Rect& clip);
void ExcludeDHCtrls(SystemDraw& w, const Rect& r, const Rect& clip);
@ -744,11 +747,11 @@ private:
void SysEndLoop();
String Name0() const;
Top *GetTop() { return top ? utop : NULL; }
const Top *GetTop() const { return top ? utop : NULL; }
void DeleteTop();
void SetTop(Top *t) { utop = t; top = true; }
void SetParent(Ctrl *parent);
@ -756,10 +759,10 @@ private:
const Frame& GetFrame0(int i) const { ASSERT(i < GetFrameCount()); return multi_frame ? frame.frames[i] : frame; }
void FreeFrames() { if(multi_frame) MemoryFree(frame.frames); }
Frame AllocFrames(int alloc);
Rect OffsetMegaRect(Rect r) const;
void MegaRect(Rect& r);
PackedData& Attrs();
@ -773,7 +776,7 @@ private:
static bool IsNoLayoutZoom;
static void Csizeinit();
static void (*skin)();
static void (*cancel_preedit)();
friend void InitRichTextZoom();
@ -808,9 +811,9 @@ private:
#endif
static void InstallPanicBox();
bool IsDHCtrl() const;
struct EventLevelDo {
EventLevelDo() { EventLevel++; };
~EventLevelDo() { EventLevel--; };
@ -825,7 +828,7 @@ protected:
Ctrl& Unicode() { unicode = true; return *this; }
Rect StdGetWorkArea() const;
enum {
ATTR_LAYOUT_ID,
ATTR_TIP,
@ -836,35 +839,35 @@ protected:
ATTR_MEGARECT_Y,
ATTR_LAST
};
void SetTextAttr(int ii, const char *s);
void SetTextAttr(int ii, const String& s);
String GetTextAttr(int ii) const;
void SetColorAttr(int ii, Color c);
Color GetColorAttr(int ii) const;
void SetFontAttr(int ii, Font fnt);
Font GetFontAttr(int ii) const;
void SetIntAttr(int ii, int val);
int GetIntAttr(int ii, int def = Null) const;
void SetInt64Attr(int ii, int64 val);
int64 GetInt64Attr(int ii, int64 def = Null) const;
void SetVoidPtrAttr(int ii, const void *ptr);
void *GetVoidPtrAttr(int ii) const;
template <class T>
void DeleteAttr(int ii) { void *p = GetVoidPtrAttr(ii); if(p) { delete (T *)p; SetVoidPtrAttr(ii, nullptr); }; }
template <class T>
T& CreateAttr(int ii) { DeleteAttr<T>(ii); T *q = new T; SetVoidPtrAttr(ii, q); return *q; }
template <class T>
T GetAttr(int ii) const { void *p = GetVoidPtrAttr(ii); return p ? *(T *)p : T(); }
public:
enum StateReason {
FOCUS = 10,
@ -944,7 +947,7 @@ public:
static void InstallStateHook(StateHook hook);
static void DeinstallStateHook(StateHook hook);
static int RegisterSystemHotKey(dword key, Function<void ()> cb);
static void UnregisterSystemHotKey(int id);
@ -996,9 +999,9 @@ public:
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
virtual void HorzMouseWheel(Point p, int zdelta, dword keyflags);
virtual void MouseLeave();
virtual void Pen(Point p, const PenInfo& pen, dword keyflags);
virtual Point GetPreedit();
virtual Font GetPreeditFont();
@ -1145,7 +1148,7 @@ public:
void RefreshLayout() { SyncLayout(1); }
void RefreshLayoutDeep() { SyncLayout(2); }
void RefreshParentLayout();
void UpdateLayout() { SyncLayout(); }
void UpdateParentLayout();
@ -1191,7 +1194,7 @@ public:
void RefreshFrame(const Rect& r);
void RefreshFrame(int x, int y, int cx, int cy);
void RefreshFrame();
static bool IsPainting() { return painting; }
void ScrollView(const Rect& r, int dx, int dy);
@ -1247,7 +1250,7 @@ public:
void CancelModeDeep();
static void CancelPreedit();
void CancelMyPreedit() { if(HasFocus()) CancelPreedit(); }
static Ctrl *GetFocusCtrl() { return FocusCtrl(); }
@ -1329,7 +1332,7 @@ public:
bool ExistsTimeCallback(int id = 0) const;
void PostCallback(Function<void ()> cb, int id = 0);
void KillPostCallback(Function<void ()> cb, int id);
enum { TIMEID_COUNT = 1 };
static Ctrl *GetActiveCtrl();
@ -1363,7 +1366,7 @@ public:
static PasteClip& Selection();
void SetSelectionSource(const char *fmts);
static void RegisterDropFormats(const char *fmts); // MacOS requires drop formats to be registered
int DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
@ -1376,9 +1379,9 @@ public:
bool IsDragAndDropSource() { return this == GetDragAndDropSource(); }
bool IsDragAndDropTarget() { return this == GetDragAndDropTarget(); }
static Size StdSampleSize() { return Size(DPI(126), DPI(106)); }
static PenInfo GetPenInfo() { return pen; }
public:
static void SetSkin(void (*skin)());
@ -1391,10 +1394,10 @@ public:
static Size LayoutZoom(Size sz);
static void NoLayoutZoom();
static void GetZoomRatio(Size& m, Size& d);
static void SetUHDEnabled(bool set = true);
static bool IsUHDEnabled();
static void SetDarkThemeEnabled(bool set = true);
static bool IsDarkThemeEnabled();
@ -1430,7 +1433,7 @@ public:
virtual void Dump(Stream& s) const;
static bool LogMessages;
void SetTitle(const char *s);
#endif
@ -1446,7 +1449,7 @@ public:
static bool IsShutdownThreads() { return Thread::IsShutdownThreads(); }
static void ShutdownThreads();
static int64 GetEventId() { return eventid; }
Ctrl();
@ -1457,16 +1460,16 @@ private: // support for for(Ctrl& q : *this)
protected:
friend class Ctrl;
const Ctrl *q;
public:
void operator++() { q = q->GetNext(); }
bool operator!=(CtrlConstIterator& b) const { return q != b.q; }
const Ctrl& operator*() const { return *q; }
};
class CtrlIterator : public CtrlConstIterator { // support for(Ctrl *q : *this)
friend class Ctrl;
public:
Ctrl& operator*() { return *const_cast<Ctrl *>(q); }
};
@ -1869,4 +1872,4 @@ public:
}
#endif
#endif

View file

@ -8,6 +8,8 @@ namespace Upp {
bool Ctrl::globalbackpaint;
bool Ctrl::globalbackbuffer;
bool Ctrl::was_fullrefresh;
static void sCheckGuiLock()
{
ASSERT_(ThreadHasGuiLock(), "Using GUI in non-main thread without GuiLock");
@ -52,8 +54,11 @@ void Ctrl::Refresh() {
GuiLock __; // Beware: Even if we have ThreadHasGuiLock ASSERT, we still can be the main thread!
if(fullrefresh || !IsVisible() || !IsOpen()) return;
LLOG("Refresh " << Name() << " full:" << fullrefresh);
Rect r = Rect(GetSize()).Inflated(OverPaint());
if(r.IsEmpty())
return;
if(!GuiPlatformSetFullRefreshSpecial())
fullrefresh = true; // Needs to be set ahead because of possible MT ICall that can cause repaint during Refresh0
was_fullrefresh = fullrefresh = true; // Needs to be set ahead because of possible MT ICall that can cause repaint during Refresh0
Refresh0(Rect(GetSize()).Inflated(OverPaint()));
}
@ -561,6 +566,16 @@ void Ctrl::RemoveFullRefresh()
q->RemoveFullRefresh();
}
void Ctrl::FullRefreshCleanup()
{ // remove any potentially stuck fullrefresh
GuiLock __;
if(was_fullrefresh) {
for(Ctrl *q : GetTopCtrls())
q->RemoveFullRefresh();
was_fullrefresh = false;
}
}
Ctrl *Ctrl::GetTopRect(Rect& r, bool inframe, bool clip)
{
GuiLock __;
@ -636,13 +651,13 @@ void Ctrl::DrawCtrl(Draw& w, int x, int y)
{
GuiLock __;
w.Offset(x, y);
SystemDraw *ws = dynamic_cast<SystemDraw *>(&w);
if(ws)
UpdateArea(*ws, GetRect().GetSize());
// CtrlPaint(w, GetSize()); _DBG_
w.End();
}
@ -687,4 +702,4 @@ void Ctrl::GlobalBackBuffer(bool b)
globalbackbuffer = b;
}
}
}

View file

@ -155,6 +155,7 @@ void Ctrl::SyncLayout(int force)
if(destroying)
return;
LLOG("SyncLayout " << Name() << " size: " << GetSize());
fullrefresh = false;
bool refresh = false;
Rect oview = GetView();
Rect view = GetRect().Size();
@ -473,4 +474,4 @@ Rect Ctrl::StdGetWorkArea() const
return GetPrimaryWorkArea();
}
}
}

View file

@ -112,7 +112,7 @@ void Ctrl::TimerProc(dword time)
for(;;) {
TimeEvent *todo = NULL;
int maxtm = -1;
for(Link<> *le = list->GetNext(); le != list; le = le->GetNext()) {
TimeEvent *e = (TimeEvent *)le;
int tm = (int)(time - e->time);
@ -154,6 +154,7 @@ void Ctrl::TimerProc(dword time)
}
LLOG("----");
sTimerLock.Leave();
FullRefreshCleanup();
}
void Ctrl::InitTimer()
@ -198,4 +199,4 @@ dword GetTimeClick()
return sTClick;
}
}
}

View file

@ -2361,24 +2361,14 @@ system. Ctrl must be open.&]
event in input queue.&]
[s3;%- &]
[s4;%- &]
[s5;:Ctrl`:`:ProcessEvent`(bool`*`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* ProcessEven
t]([@(0.0.255) bool]_`*[*@3 quit]_`=_NULL)&]
[s2;b17;a17; Processes single event from input queue. When there
is no pending event, returns immediately. (Processing event involves
usually involves dispatching it via virtual methods to proper
Ctrls).&]
[s7;i1120;a17; [%-*C@3 quit]-|Assigned true when WM`_QUIT message is
intercepted (Win32 specific).&]
[s7;i1120;a17; [*/ Return value]-|True indicates that event was processed,
false that queue was empty.&]
[s3;%- &]
[s4;%- &]
[s5;:Ctrl`:`:ProcessEvents`(bool`*`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* ProcessEve
nts]([@(0.0.255) bool]_`*[*@3 quit]_`=_NULL)&]
[s2;b17;a17; Processes all events from input queue. When there is
no pending event, returns immediately. (Processing event involves
usually involves dispatching it via virtual methods to proper
Ctrls).&]
Ctrls). Additionally, after all input events are processed, all
pending timer events are processed and all Refreshed areas of
windows are repainted.&]
[s7;i1120;a17; [%-*C@3 quit]-|Assigned true when WM`_QUIT message is
intercepted (Win32 specific).&]
[s7;i1120;a17; [*/ Return value]-|True indicates that one or more events