mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
CtrlCore: FullRefreshCleanup (to avoid any stuck fullrefresh flags)
This commit is contained in:
parent
9218a5d287
commit
678289f77f
6 changed files with 72 additions and 61 deletions
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue