Added uiQueueMain() (basically g_idle_add()) and implemented it on all platforms except Haiku. A test to come. After this we can start rewriting the Go package ui at long last.
This commit is contained in:
parent
d12974eef1
commit
f77955aefb
|
@ -105,8 +105,18 @@ void uiMain(void)
|
|||
[realNSApp() run];
|
||||
}
|
||||
|
||||
// TODO make this delayed
|
||||
void uiQuit(void)
|
||||
{
|
||||
canQuit = YES;
|
||||
[realNSApp() terminate:realNSApp()];
|
||||
}
|
||||
|
||||
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch for this
|
||||
// TODO will dispatch_get_main_queue() break after _CFRunLoopSetCurrent()?
|
||||
void uiQueueMain(void (*f)(void *data), void *data)
|
||||
{
|
||||
// dispatch_get_main_queue() is a serial queue so it will not execute multiple uiQueueMain() functions concurrently
|
||||
// the signature of f matches dispatch_function_t
|
||||
dispatch_async_f(dispatch_get_main_queue(), data, f);
|
||||
}
|
||||
|
|
|
@ -44,3 +44,8 @@ void uiQuit(void)
|
|||
// TODO see window.cpp for why that alone won't work
|
||||
app->Quit();
|
||||
}
|
||||
|
||||
void uiQueueMain(void (*f)(void *data), void *data)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
3
ui.h
3
ui.h
|
@ -29,6 +29,9 @@ _UI_EXTERN void uiFreeInitError(const char *err);
|
|||
_UI_EXTERN void uiMain(void);
|
||||
_UI_EXTERN void uiQuit(void);
|
||||
|
||||
// TODO write a test for this after adding multiline entries
|
||||
_UI_EXTERN void uiQueueMain(void (*f)(void *data), void *data);
|
||||
|
||||
_UI_EXTERN void uiOnShouldQuit(int (*f)(void *data), void *data);
|
||||
|
||||
_UI_EXTERN void uiFreeText(char *text);
|
||||
|
|
25
unix/main.c
25
unix/main.c
|
@ -48,3 +48,28 @@ void uiQuit(void)
|
|||
{
|
||||
gdk_threads_add_idle(quit, NULL);
|
||||
}
|
||||
|
||||
struct queued {
|
||||
void (*f)(void *);
|
||||
void *data;
|
||||
};
|
||||
|
||||
static gboolean doqueued(gpointer data)
|
||||
{
|
||||
struct queued *q = (struct queued *) data;
|
||||
|
||||
(*(q->f))(q->data);
|
||||
uiFree(q);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// TODO document that the effect of calling this function after uiQuit() is called (either directly or via a nonzero return to uiShouldQuit()) is undefined
|
||||
void uiQueueMain(void (*f)(void *data), void *data)
|
||||
{
|
||||
struct queued *q;
|
||||
|
||||
q = uiNew(struct queued);
|
||||
q->f = f;
|
||||
q->data = data;
|
||||
gdk_threads_add_idle(doqueued, q);
|
||||
}
|
||||
|
|
|
@ -41,3 +41,10 @@ void uiQuit(void)
|
|||
{
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
|
||||
void uiQueueMain(void (*f)(void *data), void *data)
|
||||
{
|
||||
if (PostMessageW(utilWindow, msgQueued, (WPARAM) f, (LPARAM) data) == 0)
|
||||
// TODO make sure this is safe to call across threads
|
||||
logLastError("error queueing function to run on main thread in uiQueueMain()");
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ enum {
|
|||
msgNOTIFY,
|
||||
msgHSCROLL,
|
||||
msgConsoleEndSession,
|
||||
msgQueued,
|
||||
};
|
||||
|
||||
// init.c
|
||||
|
|
|
@ -18,6 +18,7 @@ HWND utilWindow;
|
|||
|
||||
static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
void (*qf)(void *);
|
||||
LRESULT lResult;
|
||||
|
||||
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
||||
|
@ -41,6 +42,10 @@ static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
|
|||
case WM_WININICHANGE:
|
||||
issueWM_WININICHANGE(wParam, lParam);
|
||||
return 0;
|
||||
case msgQueued:
|
||||
qf = (void (*)(void *)) wParam;
|
||||
(*qf)((void *) lParam);
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue