mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
CtrlCore: New MT rules implemented in X11 and GTK
git-svn-id: svn://ultimatepp.org/upp/trunk@6170 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
a5cc4e2902
commit
8f9bfcc8e3
9 changed files with 59 additions and 64 deletions
|
|
@ -138,4 +138,4 @@ somewhere or what ever..)&]
|
|||
again, and when time has come, pushes it to 2 other streams..(so
|
||||
a little `'data latency`' is expected..if you want to make the
|
||||
data be available at once, call Flush() after your operations..&]
|
||||
[s0; ]
|
||||
[s0; ]]
|
||||
|
|
@ -9,7 +9,7 @@ NAMESPACE_UPP
|
|||
void Ctrl::Create(Ctrl *owner, bool popup)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
ASSERT_(IsMainThread(), "Only the main thread can open a window");
|
||||
LLOG("Create " << Name() << " " << GetRect());
|
||||
ASSERT(!IsChild() && !IsOpen());
|
||||
LLOG("Ungrab1");
|
||||
|
|
@ -117,12 +117,7 @@ void Ctrl::GuiPlatformRemove()
|
|||
i++;
|
||||
}
|
||||
|
||||
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
|
||||
{
|
||||
Call(callback2(this, &Ctrl::PopUp0, owner, activate));
|
||||
}
|
||||
|
||||
void Ctrl::PopUp0(Ctrl *owner, bool activate)
|
||||
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool, bool)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("POPUP " << Name() << ", " << GetRect() << ", activate " << activate);
|
||||
|
|
|
|||
|
|
@ -581,10 +581,10 @@ void WakeUpGuiThread()
|
|||
g_main_context_wakeup(g_main_context_default());
|
||||
}
|
||||
|
||||
void Ctrl::EventLoop0(Ctrl *ctrl)
|
||||
void Ctrl::EventLoop(Ctrl *ctrl)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
ASSERT_(IsMainThread(), "Event loop can only run in the main thread");
|
||||
ASSERT(LoopLevel == 0 || ctrl);
|
||||
LoopLevel++;
|
||||
LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN);
|
||||
|
|
@ -614,9 +614,10 @@ gboolean sOnce(GtkWidget *)
|
|||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::GuiSleep0(int ms)
|
||||
void Ctrl::GuiSleep(int ms)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT_(IsMainThread(), "Only the main thread can perform GuiSleep");
|
||||
if(ms < 20) // Periodic timer is each 20ms, so that is the longest possible wait
|
||||
g_timeout_add(ms, (GSourceFunc) sOnce, NULL); // otherwise setup shorter timer
|
||||
FetchEvents(TRUE);
|
||||
|
|
|
|||
|
|
@ -36,17 +36,17 @@ void TopWindow::SyncSizeHints()
|
|||
GdkWindowHints(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE));
|
||||
}
|
||||
|
||||
void TopWindow::SyncTitle0()
|
||||
void TopWindow::SyncTitle()
|
||||
{
|
||||
GuiLock __;
|
||||
if(top)
|
||||
gtk_window_set_title(gtk(), FromUnicode(title, CHARSET_UTF8));
|
||||
}
|
||||
|
||||
void TopWindow::SyncCaption0()
|
||||
void TopWindow::SyncCaption()
|
||||
{
|
||||
GuiLock __;
|
||||
SyncTitle0();
|
||||
SyncTitle();
|
||||
if(top) {
|
||||
if(gdk_icon.Set(icon))
|
||||
gtk_window_set_icon(gtk(), gdk_icon);
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ Rect Ctrl::GetWndScreenRect() const
|
|||
return Null;
|
||||
}
|
||||
|
||||
void Ctrl::WndShow0(bool b)
|
||||
void Ctrl::WndShow(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndShow " << Name() << ", " << b);
|
||||
|
|
@ -301,7 +301,7 @@ int Ctrl::GetKbdSpeed()
|
|||
return 1000 / 32;
|
||||
}
|
||||
|
||||
void Ctrl::SetWndForeground0()
|
||||
void Ctrl::SetWndForeground()
|
||||
{
|
||||
GuiLock __;
|
||||
if(top)
|
||||
|
|
@ -343,18 +343,19 @@ void Ctrl::FocusSync()
|
|||
}
|
||||
}
|
||||
|
||||
void Ctrl::SetWndFocus(bool *b)
|
||||
bool Ctrl::SetWndFocus()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetWndFocus0 " << Upp::Name(this) << ", top: " << top);
|
||||
if(top) {
|
||||
LLOG("SetWndFocus0 DO gdk: " << gdk());
|
||||
SetWndForeground0();
|
||||
SetWndForeground();
|
||||
int t0 = msecs();
|
||||
while(!gtk_window_is_active(gtk()) && msecs() - t0 < 500) // Wait up to 500ms for window to become active - not ideal, but only possibility
|
||||
FetchEvents(true);
|
||||
FocusSync();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Ctrl::WndInvalidateRect(const Rect& r)
|
||||
|
|
@ -365,7 +366,7 @@ void Ctrl::WndInvalidateRect(const Rect& r)
|
|||
// gtk_widget_queue_draw_area(top->window, r.left, r.top, r.GetWidth(), r.GetHeight());
|
||||
}
|
||||
|
||||
void Ctrl::WndScrollView0(const Rect& r, int dx, int dy)
|
||||
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("ScrollView " << rect);
|
||||
|
|
@ -391,7 +392,7 @@ bool Ctrl::SweepConfigure(bool wait)
|
|||
return r;
|
||||
}
|
||||
|
||||
void Ctrl::WndSetPos0(const Rect& rect)
|
||||
void Ctrl::WndSetPos(const Rect& rect)
|
||||
{
|
||||
LLOG("WndSetPos0 " << rect);
|
||||
GuiLock __;
|
||||
|
|
@ -413,11 +414,11 @@ void Ctrl::WndSetPos0(const Rect& rect)
|
|||
LLOG("-- WndSetPos0 " << rect << " " << msecs() - t0);
|
||||
}
|
||||
|
||||
void Ctrl::WndEnable(bool *b)
|
||||
void Ctrl::WndEnable(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
if(top) {
|
||||
gtk_widget_set_sensitive(top->window, *b);
|
||||
gtk_widget_set_sensitive(top->window, b);
|
||||
StateH(ENABLE);
|
||||
}
|
||||
}
|
||||
|
|
@ -426,7 +427,7 @@ void Ctrl::WndUpdate(const Rect& r)
|
|||
{
|
||||
GuiLock __;
|
||||
LLOG("WndUpdate0r " << r);
|
||||
WndUpdate0(); // Not found a way how to update only part of window
|
||||
WndUpdate(); // Not found a way how to update only part of window
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate()
|
||||
|
|
|
|||
|
|
@ -843,7 +843,7 @@ void Ctrl::EventLoop(Ctrl *ctrl)
|
|||
void Ctrl::GuiSleep(int ms)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
ASSERT_(IsMainThread(), "Only the main thread can perform GuiSleep");
|
||||
ELOG("GuiSleep");
|
||||
int level = LeaveGuiMutexAll();
|
||||
#if !defined(flagDLL) && !defined(PLATFORM_WINCE)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void TopWindow::DefSyncTitle()
|
|||
}
|
||||
}
|
||||
|
||||
void TopWindow::SyncTitle0()
|
||||
void TopWindow::SyncTitle()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SyncTitle: " << title);
|
||||
|
|
@ -129,7 +129,7 @@ void WmState(Window w, bool set, Atom a1, Atom a2 = 0)
|
|||
XSendEvent(Xdisplay, Xroot, false, SubstructureNotifyMask | SubstructureRedirectMask, &e);
|
||||
}
|
||||
|
||||
void TopWindow::SyncState0()
|
||||
void TopWindow::SyncState()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SyncState");
|
||||
|
|
@ -160,11 +160,11 @@ typedef struct {
|
|||
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
|
||||
#define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS
|
||||
|
||||
void TopWindow::SyncCaption0()
|
||||
void TopWindow::SyncCaption()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SyncCaption0");
|
||||
SyncTitle0();
|
||||
SyncTitle();
|
||||
if(IsOpen() && GetWindow()) {
|
||||
unsigned long wina[6];
|
||||
memset(wina, 0, sizeof(wina));
|
||||
|
|
@ -256,11 +256,6 @@ void TopWindow::CenterRect(Ctrl *owner)
|
|||
}
|
||||
|
||||
void TopWindow::Open(Ctrl *owner)
|
||||
{
|
||||
Open0(owner);
|
||||
}
|
||||
|
||||
void TopWindow::Open0(Ctrl *owner)
|
||||
{
|
||||
LLOG("TopWindow::Open");
|
||||
GuiLock __;
|
||||
|
|
@ -281,7 +276,7 @@ void TopWindow::Open0(Ctrl *owner)
|
|||
title2.Clear();
|
||||
if(!weplace) {
|
||||
LLOG("SyncCaption");
|
||||
SyncCaption0();
|
||||
SyncCaption();
|
||||
}
|
||||
LLOG("SyncSizeHints");
|
||||
size_hints->flags = 0;
|
||||
|
|
@ -382,7 +377,7 @@ void TopWindow::Open0(Ctrl *owner)
|
|||
XChangeProperty(Xdisplay, win, XAtom("XdndAware"), XA_ATOM, 32,
|
||||
0, (byte *)&version, 1);
|
||||
|
||||
SyncState0();
|
||||
SyncState();
|
||||
FixIcons();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ void Ctrl::DoPaint(const Vector<Rect>& invalid)
|
|||
}
|
||||
}
|
||||
|
||||
void Ctrl::WndScrollView0(const Rect& r, int dx, int dy)
|
||||
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
|
||||
{
|
||||
GuiLock __;
|
||||
if(r.IsEmpty() || !GetWindow()) return;
|
||||
|
|
@ -383,11 +383,11 @@ void WakeUpGuiThread()
|
|||
IGNORE_RESULT(write(WakePipe[1], "\1", 1));
|
||||
}
|
||||
|
||||
void Ctrl::GuiSleep0(int ms)
|
||||
void Ctrl::GuiSleep(int ms)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG(GetTickCount() << " GUISLEEP " << ms);
|
||||
ASSERT(IsMainThread());
|
||||
ASSERT_(IsMainThread(), "Only main thread can perform GuiSleep");
|
||||
timeval timeout;
|
||||
timeout.tv_sec = ms / 1000;
|
||||
timeout.tv_usec = ms % 1000 * 1000;
|
||||
|
|
@ -417,7 +417,7 @@ void Ctrl::SysEndLoop()
|
|||
{
|
||||
}
|
||||
|
||||
void Ctrl::EventLoop0(Ctrl *ctrl)
|
||||
void Ctrl::EventLoop(Ctrl *ctrl)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT_(IsMainThread(), "Event loop can only run in the main thread");
|
||||
|
|
@ -434,7 +434,7 @@ void Ctrl::EventLoop0(Ctrl *ctrl)
|
|||
|
||||
while(loopno > EndSessionLoopNo && (ctrl ? ctrl->InLoop() && ctrl->IsOpen() : GetTopCtrls().GetCount())) {
|
||||
XEvent event;
|
||||
GuiSleep0(granularity);
|
||||
GuiSleep(granularity);
|
||||
SyncMousePos();
|
||||
while(IsWaitingEvent()) {
|
||||
LTIMING("XNextEvent");
|
||||
|
|
@ -466,7 +466,7 @@ void Ctrl::SyncExpose()
|
|||
void Ctrl::Create(Ctrl *owner, bool redirect, bool savebits)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread(), "Only main thread can create windows");
|
||||
ASSERT_(IsMainThread(), "Only main thread can create windows");
|
||||
LLOG("Create " << Name() << " " << GetRect());
|
||||
ASSERT(!IsChild() && !IsOpen());
|
||||
LLOG("Ungrab1");
|
||||
|
|
@ -682,7 +682,7 @@ Ctrl *Ctrl::GetOwner()
|
|||
return q >= 0 ? Xwindow()[q].owner : NULL;
|
||||
}
|
||||
|
||||
void Ctrl::WndShow0(bool b)
|
||||
void Ctrl::WndShow(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndShow " << b);
|
||||
|
|
@ -700,7 +700,7 @@ void Ctrl::WndShow0(bool b)
|
|||
}
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate0()
|
||||
void Ctrl::WndUpdate()
|
||||
{
|
||||
GuiLock __;
|
||||
LTIMING("WndUpdate");
|
||||
|
|
@ -718,7 +718,7 @@ void Ctrl::WndUpdate0()
|
|||
}
|
||||
}
|
||||
|
||||
void Ctrl::WndUpdate0r(const Rect& r)
|
||||
void Ctrl::WndUpdate(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
LTIMING("WndUpdate Rect");
|
||||
|
|
@ -734,7 +734,7 @@ void Ctrl::WndUpdate0r(const Rect& r)
|
|||
xw.invalid = Subtract(xw.invalid, r, dummy);
|
||||
}
|
||||
|
||||
void Ctrl::WndSetPos0(const Rect& r)
|
||||
void Ctrl::WndSetPos(const Rect& r)
|
||||
{
|
||||
GuiLock __;
|
||||
if(!top) return;
|
||||
|
|
@ -882,11 +882,10 @@ void Ctrl::KillFocus(Window window)
|
|||
w.ctrl->KillFocusWnd();
|
||||
}
|
||||
|
||||
void Ctrl::SetWndFocus0(bool *b)
|
||||
bool Ctrl::SetWndFocus()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetWndFocus " << Name());
|
||||
*b = false;
|
||||
if(top && top->window != focusWindow && IsEnabled() && IsVisible()) {
|
||||
LLOG("Setting focus... ");
|
||||
LTIMING("XSetInfputFocus");
|
||||
|
|
@ -897,8 +896,9 @@ void Ctrl::SetWndFocus0(bool *b)
|
|||
focusWindow = top->window;
|
||||
SetFocusWnd();
|
||||
}
|
||||
*b = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Ctrl::HasWndFocus() const
|
||||
|
|
@ -1010,7 +1010,7 @@ void Ctrl::WndInvalidateRect(const Rect& r)
|
|||
Invalidate(Xwindow().Get(top->window), r);
|
||||
}
|
||||
|
||||
void Ctrl::SetWndForeground0()
|
||||
void Ctrl::SetWndForeground()
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetWndForeground " << Name());
|
||||
|
|
@ -1037,20 +1037,16 @@ bool Ctrl::IsWndForeground() const
|
|||
return ~focusCtrlWnd == (q ? q : GetTopCtrl());
|
||||
}
|
||||
|
||||
void Ctrl::WndEnable0(bool *b)
|
||||
void Ctrl::WndEnable(bool b)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("WndEnable");
|
||||
if(!top) {
|
||||
*b = false;
|
||||
return;
|
||||
}
|
||||
if(!*b) {
|
||||
if(!top) return;
|
||||
if(!b) {
|
||||
ReleaseCapture();
|
||||
if(HasWndFocus())
|
||||
XSetInputFocus(Xdisplay, None, RevertToPointerRoot, CurrentTime);
|
||||
}
|
||||
*b = true;
|
||||
}
|
||||
|
||||
// 01/12/2007 - mdelfede
|
||||
|
|
|
|||
|
|
@ -2298,7 +2298,8 @@ view or frame coordinates.&]
|
|||
HWND_[*@3 hwnd], [@(0.0.255) bool]_[*@3 savebits]_`=_[@(0.0.255) true],
|
||||
[@(0.0.255) bool]_[*@3 activate]_`=_[@(0.0.255) true], [@(0.0.255) bool]_[*@3 dropshadow]_`=
|
||||
_[@(0.0.255) false], [@(0.0.255) bool]_[*@3 topmost]_`=_[@(0.0.255) false])&]
|
||||
[s2;b17;a17; Opens top`-level Ctrl as pop`-up window.&]
|
||||
[s2;b17;a17; Opens top`-level Ctrl as pop`-up window. [*/ This method
|
||||
can only be invoked in the main thread.]&]
|
||||
[s6; [2 Win32 specific.]&]
|
||||
[s7;i1120;a17; [%-*C@3 hwnd]-|Win32 handle of owner window.&]
|
||||
[s7;i1120;a17; [%-*C@3 savebits]-|Indicates that system should try to
|
||||
|
|
@ -2313,7 +2314,8 @@ preserve background bits.&]
|
|||
trl]_`*[*@3 owner]_`=_NULL, [@(0.0.255) bool]_[*@3 savebits]_`=_[@(0.0.255) true],
|
||||
[@(0.0.255) bool]_[*@3 activate]_`=_[@(0.0.255) true], [@(0.0.255) bool]_[*@3 dropshadow]_`=
|
||||
_[@(0.0.255) false], [@(0.0.255) bool]_[*@3 topmost]_`=_[@(0.0.255) false])&]
|
||||
[s2;b17;a17; Opens top`-level Ctrl as pop`-up window.&]
|
||||
[s2;b17;a17; Opens top`-level Ctrl as pop`-up window. [*/ This method
|
||||
can only be invoked in the main thread.]&]
|
||||
[s7;i1120;a17; [%-*C@3 owner]-|Owner.&]
|
||||
[s7;i1120;a17; [%-*C@3 savebits]-|Indicates that system should try to
|
||||
preserve background bits.&]
|
||||
|
|
@ -2362,15 +2364,16 @@ were processed, false that queue was empty.&]
|
|||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:IsPopUp`(`)const:%- [@(0.0.255) bool]_[* IsPopUp]()_[@(0.0.255) const]&]
|
||||
[s7;i1120;a17; [*/ Return value]-|True if Ctrl is pop`-up window.&]
|
||||
[s3;%- &]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:EventLoop`(`:`:Ctrl`*`):%- [@(0.0.255) static] [@(0.0.255) void]_[* EventLoop](
|
||||
[_^`:`:Ctrl^ Ctrl]_`*[*@3 loopctrl]_`=_NULL)&]
|
||||
[s5;:Ctrl`:`:EventLoop`(Ctrl`*`):%- [@(0.0.255) static] [@(0.0.255) void]_[* EventLoop]([_^`:`:Ctrl^ C
|
||||
trl]_`*[*@3 loopctrl]_`=_NULL)&]
|
||||
[s2;b17;a17; Executes event`-loop. If [*@3 loopctrl ]is not NULL, it
|
||||
must be opened top`-level Ctrl and loop is executed until EndLoop
|
||||
method for [*@3 loopctrl ]is invoked. If [*@3 loopctrl] is NULL,
|
||||
loop is executed as long as any top`-level Ctrl exists or application
|
||||
is terminated by OS specific `"shutdown`" event.&]
|
||||
is terminated by OS specific `"shutdown`" event. [*/ This method
|
||||
can only be invoked in the main thread.]&]
|
||||
[s7;i1120;a17; [%-*C@3 loopctrl]-|Looping Ctrl.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
|
|
@ -2612,7 +2615,7 @@ does is platform specific).&]
|
|||
nt]_[*@3 ms])&]
|
||||
[s2;b17;a17; Sleeps (while allowing other applications or threads
|
||||
to run) for at least [*@3 ms] milliseconds or until new input event
|
||||
is available.&]
|
||||
is available. [*/ This method can only be invoked in the main thread.]&]
|
||||
[s7;i1120;a17; [%-*@3 ms]-|Time to sleep.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
|
|
@ -2622,7 +2625,11 @@ allback]_[*@3 cb])&]
|
|||
for GUI). It works by posting callback into timer queue (with
|
||||
zero delay), then waits its completion using Semaphore. Main
|
||||
GUI thread has to run timer queue management for callback to
|
||||
be executed (by running event`-loop (TopWindow`::Run) or ProcessEvents).&]
|
||||
be executed (by running event`-loop (TopWindow`::Run) or ProcessEvents).
|
||||
Warning: Call unlocks GuiLock so that the main thread can run
|
||||
on GUI, this is possible source of race`-conditions. Be prepared
|
||||
that some other code can run on GUI between call to Call and
|
||||
cb being executed!&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:IsShutdownThreads`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsShutdownTh
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue