diff --git a/engine/client/menu.c b/engine/client/menu.c index 190444796..486c3589b 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -1577,6 +1577,18 @@ void M_Init (void) } #endif +void M_Window_ClosePrompt(void) +{ //someone clicked our window's 'close' button or system menu or alt+f4 or etc. we blocked it for now, but don't just ignore it... + COM_AssertMainThread("M_Window_ClosePrompt"); + Key_Dest_Remove(kdm_console); + if (Cmd_Exists("menu_quit") || Cmd_AliasExist("menu_quit", RESTRICT_LOCAL)) + Cmd_ExecuteString("menu_quit prompt", RESTRICT_LOCAL); //our builtin menus use this form + else if (Cmd_Exists("m_quit") || Cmd_AliasExist("m_quit", RESTRICT_LOCAL)) + Cmd_ExecuteString("m_quit", RESTRICT_LOCAL); //some menuqc mods use a different name for the command to avoid conflicts. + else + Cmd_ExecuteString("quit", RESTRICT_LOCAL); //fall back to the engine's version +} + // Generic function to choose which game menu to draw int M_GameType (void) diff --git a/engine/client/menu.h b/engine/client/menu.h index 806a32213..361ec9471 100644 --- a/engine/client/menu.h +++ b/engine/client/menu.h @@ -150,6 +150,7 @@ void M_Menu_Mods_f (void); //used at startup if the current gamedirs look dodgy. void M_Menu_Installer (void); //given an embedded manifest, this displays an install menu for said game. mpic_t *M_CachePic (char *path); void M_Menu_Quit_f (void); +void M_Window_ClosePrompt (void); //called when the window was requested to be closed. displays whatever quit menu is appropriate. void menufixme(void); //REMOVE REMOVE REMOVE typedef struct emenu_s emenu_t; diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index 68a3e825a..22707837c 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -3193,14 +3193,8 @@ static void GetEvent(void) char *protname = x11.pXGetAtomName(vid_dpy, event.xclient.data.l[0]); if (!strcmp(protname, "WM_DELETE_WINDOW")) { - Key_Dest_Remove(kdm_console); - if (Cmd_Exists("menu_quit") || Cmd_AliasExist("menu_quit", RESTRICT_LOCAL)) - Cmd_ExecuteString("menu_quit prompt", RESTRICT_LOCAL); - else if (Cmd_Exists("m_quit") || Cmd_AliasExist("m_quit", RESTRICT_LOCAL)) - Cmd_ExecuteString("m_quit", RESTRICT_LOCAL); - else - Cmd_ExecuteString("quit", RESTRICT_LOCAL); - x11.pXSetInputFocus(vid_dpy, vid_window, RevertToParent, CurrentTime); + x11.pXSetInputFocus(vid_dpy, vid_window, RevertToParent, CurrentTime); //make it easier to pick an option. FIXME: bring to top is a separate thing. + M_Window_ClosePrompt(); } else if (!strcmp(protname, "_NET_WM_PING")) { diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index d9d56f9d2..32627ab0e 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -2854,7 +2854,7 @@ void MainThreadWndProc(void *ctx, void *data, size_t msg, size_t ex) Z_Free(data); break; case WM_CLOSE: - Cbuf_AddText("\nquit\n", RESTRICT_LOCAL); + M_Window_ClosePrompt(); break; case WM_SIZE: case WM_MOVE: @@ -3110,6 +3110,14 @@ static LONG WINAPI GLMainWndProc ( case WM_CLOSE: if (!vid_initializing) { +#if 1 + #ifdef WTHREAD + COM_AddWork(WG_MAIN, MainThreadWndProc, NULL, NULL, uMsg, 0); + #else + M_Window_ClosePrompt(); + #endif + SetFocus(hWnd); +#else if (wantquit) { //urr, this would be the second time that they've told us to quit. @@ -3133,6 +3141,7 @@ static LONG WINAPI GLMainWndProc ( #endif wantquit = true; } +#endif } break; diff --git a/engine/gl/gl_vidwayland.c b/engine/gl/gl_vidwayland.c index 4b410c0b6..f0827bb07 100644 --- a/engine/gl/gl_vidwayland.c +++ b/engine/gl/gl_vidwayland.c @@ -598,13 +598,8 @@ void xdg_toplevel_handle_configure(void *data, struct xdg_toplevel *xdg_toplevel } void xdg_toplevel_handle_close(void *data, struct xdg_toplevel *xdg_toplevel) { - Key_Dest_Remove(kdm_console); - if (Cmd_Exists("menu_quit") || Cmd_AliasExist("menu_quit", RESTRICT_LOCAL)) - Cmd_ExecuteString("menu_quit prompt", RESTRICT_LOCAL); - else if (Cmd_Exists("m_quit") || Cmd_AliasExist("m_quit", RESTRICT_LOCAL)) - Cmd_ExecuteString("m_quit", RESTRICT_LOCAL); - else - Cmd_ExecuteString("quit", RESTRICT_LOCAL); + //fixme: steal focus, bring to top, or just hope the compositor is doing that for us when the user right-clicked the task bar of our minimised app or whatever. + M_Window_ClosePrompt(); } static struct xdg_toplevel_listener { void (*configure)(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states);