diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-07 16:34:22 +0000 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-30 14:26:49 +0000 |
commit | 2f02b9294d68d1fc2632464e790665cd0525dd3f (patch) | |
tree | 61e894774a02adbdc04749f9dd5ca11316236c50 | |
parent | 05d2da4169ec7951d8ee18917b5aa34e8ccc3519 (diff) |
Make window creation and destruction be synchronous
At the moment, because Windows windows must be created and destroyed by the
thread that we want to process events with, XCWM_EVENT_WINDOW_CREATE just posts
a message to another thread to create the window, we can then receive and try to
process additional events (usually damage) on that window before the window
creation has completed.
Likewise XCWM_EVENT_WINDOW_DELETE just posts a message to another thread to
delete the window, then releases the xcwm_window_t. If a different WM_* message
is recieved for that window before the WM_DELETE is processed, the xcw_window_t
pointer stored in the WIN_XCWM_PROP property will be invalid.
Block the processing of additional X events until window creation or destruction
completes.
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/wndproc.c | 2 |
2 files changed, 18 insertions, 4 deletions
@@ -22,6 +22,7 @@ #include <stdio.h> #include <getopt.h> #include <xcwm/xcwm.h> +#include <semaphore.h> #include "debug.h" #include "global.h" @@ -33,6 +34,8 @@ xcwm_context_t *context; DWORD msgPumpThread; +static sem_t semaphore; + static void eventHandler(const xcwm_event_t *event) { @@ -51,6 +54,7 @@ eventHandler(const xcwm_event_t *event) message pump in to create the window... */ PostThreadMessage(msgPumpThread, WM_XCWM_CREATE, 0, (LPARAM)window); + sem_wait(&semaphore); break; case XCWM_EVENT_WINDOW_DESTROY: @@ -58,6 +62,7 @@ eventHandler(const xcwm_event_t *event) Only the owner thread is allowed to destroy a window */ PostThreadMessage(msgPumpThread, WM_XCWM_DESTROY, 0, (LPARAM)window); + sem_wait(&semaphore); break; case XCWM_EVENT_WINDOW_NAME: @@ -139,6 +144,9 @@ int main(int argc, char **argv) PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); msgPumpThread = GetCurrentThreadId(); + // initialize semaphore used for synchronization + sem_init(&semaphore, 0, 0); + // Get access to DwmEnableBlurBehindWindow, if available, so we can take advantage of it // on Vista and later, but still run on earlier versions of Windows HMODULE hDwmApiLib = LoadLibraryEx("dwmapi.dll", NULL, 0); @@ -161,9 +169,15 @@ int main(int argc, char **argv) while (GetMessage(&msg, NULL, 0, 0) > 0) { if (msg.message == WM_XCWM_CREATE) - winCreateWindowsWindow((xcwm_window_t *)msg.lParam); + { + winCreateWindowsWindow((xcwm_window_t *)msg.lParam); + sem_post(&semaphore); + } else if (msg.message == WM_XCWM_DESTROY) - winDestroyWindowsWindow((xcwm_window_t *)msg.lParam); + { + winDestroyWindowsWindow((xcwm_window_t *)msg.lParam); + sem_post(&semaphore); + } else DispatchMessage(&msg); } @@ -177,4 +191,6 @@ int main(int argc, char **argv) xcwm_context_close(context); FreeLibrary(hDwmApiLib); + + sem_destroy(&semaphore); } diff --git a/src/wndproc.c b/src/wndproc.c index f50fde0..dbc0c07 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -836,8 +836,6 @@ winTopLevelWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CLOSE: xcwm_window_request_close(window); - // XXX: RACE!!! window will become invalid when we get XCB_DESTROY_NOTIFY back from server - // but this wndproc may continue to touch it until we get WM_DESTROY.. return 0; case WM_DESTROY: |