diff --git a/client/displayservers/X11/x11.c b/client/displayservers/X11/x11.c index f26a0969..de155554 100644 --- a/client/displayservers/X11/x11.c +++ b/client/displayservers/X11/x11.c @@ -967,13 +967,19 @@ static void x11Startup(void) static void x11Shutdown(void) { - if (x11.jitRender) + if (x11.frameEvent) x11SignalFrame(LG_DS_WAIT_FRAME_INTERRUPTED); + + if (x11.eventThread) + { + lgJoinThread(x11.eventThread, NULL); + x11.eventThread = NULL; + } } static void x11Free(void) { - lgJoinThread(x11.eventThread, NULL); + x11Shutdown(); if (x11.jitRender) { diff --git a/client/include/interface/displayserver.h b/client/include/interface/displayserver.h index 90b06dbb..0d313014 100644 --- a/client/include/interface/displayserver.h +++ b/client/include/interface/displayserver.h @@ -149,10 +149,10 @@ struct LG_DisplayServerOps /* called after window creation, renderer, and input providers are ready */ void (*startup)(void); - /* called just before final window destruction, before final free */ + /* stop all callbacks before application subsystems are destroyed */ void (*shutdown)(void); - /* final free */ + /* final resource destruction after shutdown */ void (*free)(void); /* diff --git a/client/src/main.c b/client/src/main.c index e24184c5..01009adb 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -3483,6 +3483,11 @@ static void lg_shutdown(void) lgJoinThread(t_render, NULL); } + // Stop external input callbacks before tearing down shared client state + evdev_stop(); + if (g_state.ds && g_state.dsInitialized) + g_state.ds->shutdown(); + fallbackStop(); if (t_cursorRepaint) @@ -3498,9 +3503,6 @@ static void lg_shutdown(void) } LG_LOCK_FREE(l_cursorRepaint.lock); - // An evdev batch may call input handlers; join before input teardown - evdev_stop(); - if (g_state.transport.ops) { lgInput_dropTransport(); @@ -3534,9 +3536,6 @@ static void lg_shutdown(void) e_startup = NULL; } - if (g_state.ds) - g_state.ds->shutdown(); - lgClipboard_free(); app_releaseAllKeybinds();