From 678289f77f045265ef9459b4358d1fb0dcafc406 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Wed, 23 Oct 2024 16:21:44 +0200 Subject: [PATCH] CtrlCore: FullRefreshCleanup (to avoid any stuck fullrefresh flags) --- uppsrc/CtrlCore/Ctrl.cpp | 3 +- uppsrc/CtrlCore/CtrlCore.h | 83 +++++++++++++------------- uppsrc/CtrlCore/CtrlDraw.cpp | 23 +++++-- uppsrc/CtrlCore/CtrlPos.cpp | 3 +- uppsrc/CtrlCore/CtrlTimer.cpp | 5 +- uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp | 16 +---- 6 files changed, 72 insertions(+), 61 deletions(-) diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index f33c87dc8..9261b6ebb 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -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 -} +} \ No newline at end of file diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 02424abda..0457a036a 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -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 { 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 eventCtrl; static Ptr mouseCtrl; @@ -595,7 +597,7 @@ private: static Ptr 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& 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 void DeleteAttr(int ii) { void *p = GetVoidPtrAttr(ii); if(p) { delete (T *)p; SetVoidPtrAttr(ii, nullptr); }; } template T& CreateAttr(int ii) { DeleteAttr(ii); T *q = new T; SetVoidPtrAttr(ii, q); return *q; } - + template 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 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 cb, int id = 0); void KillPostCallback(Function 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(q); } }; @@ -1869,4 +1872,4 @@ public: } -#endif +#endif \ No newline at end of file diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index 8cf72bce4..7dab14eb5 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -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(&w); if(ws) UpdateArea(*ws, GetRect().GetSize()); // CtrlPaint(w, GetSize()); _DBG_ - + w.End(); } @@ -687,4 +702,4 @@ void Ctrl::GlobalBackBuffer(bool b) globalbackbuffer = b; } -} +} \ No newline at end of file diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index 2b8ab6019..945d52a93 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -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(); } -} +} \ No newline at end of file diff --git a/uppsrc/CtrlCore/CtrlTimer.cpp b/uppsrc/CtrlCore/CtrlTimer.cpp index 50bd570e4..113aa510b 100644 --- a/uppsrc/CtrlCore/CtrlTimer.cpp +++ b/uppsrc/CtrlCore/CtrlTimer.cpp @@ -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; } -} +} \ No newline at end of file diff --git a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp index dc1461339..93cb9adad 100644 --- a/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp +++ b/uppsrc/CtrlCore/src.tpp/Ctrl_en-us.tpp @@ -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