diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index a2a27c457..049df1e50 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() diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 02424abda..b39158288 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -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; @@ -647,6 +649,8 @@ private: Image DispatchMouseEvent(int e, Point p, int zd = 0); void LogMouseEvent(const char *f, const Ctrl *ctrl, int event, Point p, int zdelta, dword keyflags); + static bool ProcessEvent(bool *quit = NULL); + struct CallBox; static void PerformCall(CallBox *cbox); @@ -688,6 +692,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); @@ -1343,7 +1348,6 @@ public: void SetAlpha(byte alpha); static bool IsWaitingEvent(); - static bool ProcessEvent(bool *quit = NULL); static bool ProcessEvents(bool *quit = NULL); static int GetEventLevel() { return EventLevel; } diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index c92f6b2a3..45480f6b1 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"); @@ -17,7 +19,7 @@ void Ctrl::RefreshFrame(const Rect& r) { LTIMING("RefreshFrame"); sCheckGuiLock(); GuiLock __; // Beware: Even if we have ThreadHasGuiLock ASSERT, we still can be the main thread! - DLOG("RefreshFrame " << Name() << ' ' << r); + DLOG("RefreshFrame " << Name() << ' ' << r << " version 1"); if(!IsOpen() || !IsVisible() || r.IsEmpty()) return; DLOG("RefreshRect A"); if(GuiPlatformRefreshFrameSpecial(r)) @@ -50,7 +52,6 @@ void Ctrl::Refresh(const Rect& area) { Refresh0(area); } -#if 0 // CHANGE TO 1 TO TEST THE FIX void Ctrl::Refresh() { sCheckGuiLock(); GuiLock __; // Beware: Even if we have ThreadHasGuiLock ASSERT, we still can be the main thread! @@ -60,20 +61,9 @@ void Ctrl::Refresh() { 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(r); } -#else -void Ctrl::Refresh() { - sCheckGuiLock(); - GuiLock __; // Beware: Even if we have ThreadHasGuiLock ASSERT, we still can be the main thread! - DLOG("Refresh " << Name() << " full:" << fullrefresh << " rect: " << GetRect()); - if(fullrefresh || !IsVisible() || !IsOpen()) return; - if(!GuiPlatformSetFullRefreshSpecial()) - fullrefresh = true; // Needs to be set ahead because of possible MT ICall that can cause repaint during Refresh0 - Refresh0(Rect(GetSize()).Inflated(OverPaint())); -} -#endif void Ctrl::Refresh(int x, int y, int cx, int cy) { Refresh(RectC(x, y, cx, cy)); @@ -579,6 +569,17 @@ void Ctrl::RemoveFullRefresh() q->RemoveFullRefresh(); } +void Ctrl::FullRefreshCleanup() +{ // remove any potentially stuck fullrefresh + GuiLock __; + if(was_fullrefresh) { + DTIMESTOP("FullRefreshCleanup"); + for(Ctrl *q : GetTopCtrls()) + q->RemoveFullRefresh(); + was_fullrefresh = false; + } +} + Ctrl *Ctrl::GetTopRect(Rect& r, bool inframe, bool clip) { GuiLock __; diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index 32aa40b2f..15c1a2c09 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -155,7 +155,7 @@ void Ctrl::SyncLayout(int force) if(destroying) return; LLOG("SyncLayout " << Name() << " size: " << GetSize()); -// fullrefresh = false; // UNCOMMENT TO TEST THE FIX + fullrefresh = false; bool refresh = false; Rect oview = GetView(); Rect view = GetRect().Size(); diff --git a/uppsrc/CtrlCore/CtrlTimer.cpp b/uppsrc/CtrlCore/CtrlTimer.cpp index 50bd570e4..c7d25891f 100644 --- a/uppsrc/CtrlCore/CtrlTimer.cpp +++ b/uppsrc/CtrlCore/CtrlTimer.cpp @@ -154,6 +154,7 @@ void Ctrl::TimerProc(dword time) } LLOG("----"); sTimerLock.Leave(); + FullRefreshCleanup(); } void Ctrl::InitTimer() 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