From cc7b6f9e4968a361c1cc646dc29b42bf68ca6672 Mon Sep 17 00:00:00 2001 From: Rudolf-Walter Kiss-Szakacs Date: Fri, 2 Dec 2022 07:22:31 +0200 Subject: [PATCH] Add SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS. (cherry picked from commit 232ed540dbf3924543ab1a084a43f2e70f4b31a9) --- include/SDL3/SDL_hints.h | 22 ++++++++++++++++++++++ src/video/windows/SDL_windowsevents.c | 6 ++++-- src/video/windows/SDL_windowsvideo.c | 20 ++++++++++---------- src/video/windows/SDL_windowsvideo.h | 1 + 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 2f6e7aa1b..5532b5d9f 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -1941,6 +1941,28 @@ extern "C" { */ #define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" +/** + * \brief Controls whether menus can be opened with their keyboard shortcut (Alt+mnemonic). + * + * If the mnemonics are enabled, then menus can be opened by pressing the Alt + * key and the corresponding mnemonic (for example, Alt+F opens the File menu). + * However, in case an invalid mnemonic is pressed, Windows makes an audible + * beep to convey that nothing happened. This is true even if the window has + * no menu at all! + * + * Because most SDL applications don't have menus, and some want to use the Alt + * key for other purposes, SDL disables mnemonics (and the beeping) by default. + * + * Note: This also affects keyboard events: with mnemonics enabled, when a + * menu is opened from the keyboard, you will not receive a KEYUP event for + * the mnemonic key, and *might* not receive one for Alt. + * + * This variable can be set to the following values: + * "0" - Alt+mnemonic does nothing, no beeping. (default) + * "1" - Alt+mnemonic opens menus, invalid mnemonics produce a beep. + */ +#define SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS "SDL_WINDOWS_ENABLE_MENU_MNEMONICS" + /** * \brief A variable controlling whether the windows message loop is processed by SDL * diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 5269036ff..6914989bb 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1357,8 +1357,10 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_SYSCOMMAND: { - if ((wParam & 0xFFF0) == SC_KEYMENU) { - return 0; + if (!g_WindowsEnableMenuMnemonics) { + if ((wParam & 0xFFF0) == SC_KEYMENU) { + return 0; + } } #if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER) diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index f81b0c658..9cdf8d3bd 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -24,6 +24,7 @@ #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" +#include "../../SDL_hints_c.h" #include "SDL_windowsvideo.h" #include "SDL_windowsframebuffer.h" @@ -38,24 +39,22 @@ static void WIN_VideoQuit(_THIS); /* Hints */ SDL_bool g_WindowsEnableMessageLoop = SDL_TRUE; +SDL_bool g_WindowsEnableMenuMnemonics = SDL_FALSE; SDL_bool g_WindowFrameUsableWhileCursorHidden = SDL_TRUE; static void SDLCALL UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue) { - if (newValue && *newValue == '0') { - g_WindowsEnableMessageLoop = SDL_FALSE; - } else { - g_WindowsEnableMessageLoop = SDL_TRUE; - } + g_WindowsEnableMessageLoop = SDL_GetStringBoolean(newValue, SDL_TRUE); +} + +static void SDLCALL UpdateWindowsEnableMenuMnemonics(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + g_WindowsEnableMenuMnemonics = SDL_GetStringBoolean(newValue, SDL_FALSE); } static void SDLCALL UpdateWindowFrameUsableWhileCursorHidden(void *userdata, const char *name, const char *oldValue, const char *newValue) { - if (newValue && *newValue == '0') { - g_WindowFrameUsableWhileCursorHidden = SDL_FALSE; - } else { - g_WindowFrameUsableWhileCursorHidden = SDL_TRUE; - } + g_WindowFrameUsableWhileCursorHidden = SDL_GetStringBoolean(newValue, SDL_TRUE); } #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) @@ -450,6 +449,7 @@ int WIN_VideoInit(_THIS) #endif SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL); + SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL); SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL); #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index e94b198b8..fe88e770d 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -460,6 +460,7 @@ typedef struct SDL_VideoData } SDL_VideoData; extern SDL_bool g_WindowsEnableMessageLoop; +extern SDL_bool g_WindowsEnableMenuMnemonics; extern SDL_bool g_WindowFrameUsableWhileCursorHidden; typedef struct IDirect3D9 IDirect3D9;