Implement the modifier levels on Win32 by expanding the table.

This commit is contained in:
Yukari Hafner 2026-06-17 15:36:21 +02:00
parent 43e85ed627
commit 7b6e62829d
No known key found for this signature in database
GPG key ID: A65ADD33A582C0E2
4 changed files with 53 additions and 20 deletions

View file

@ -712,9 +712,9 @@ const char* _glfwGetScancodeNameNull(int scancode, int modifiers)
int level = 0;
if (modifiers & GLFW_MOD_SHIFT)
level |= 0b01;
level |= 1;
if ((modifiers & GLFW_MOD_CONTROL) && (modifiers & GLFW_MOD_ALT))
level |= 0b10;
level |= 2;
return keyNames[scancode][level];
}

View file

@ -488,7 +488,7 @@ void _glfwInputErrorWin32(int error, const char* description)
//
void _glfwUpdateKeyNamesWin32(void)
{
int key;
int key, level;
BYTE state[256] = {0};
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
@ -518,26 +518,35 @@ void _glfwUpdateKeyNamesWin32(void)
else
vk = MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK);
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
if (length == -1)
for (level = 0; level < 8; ++level)
{
// This is a dead key, so we need a second simulated key press
// to make it output its own character (usually a diacritic)
int mods = _GLFWmodelevels[level];
state[(int) VK_SHIFT] = (mods & GLFW_MOD_SHIFT)? 0xff : 0x00;
state[(int) VK_CONTROL] = (mods & GLFW_MOD_CONTROL)? 0xff : 0x00;
state[(int) VK_MENU] = (mods & GLFW_MOD_ALT)? 0xff : 0x00;
state[(int) VK_CAPITAL] = (mods & GLFW_MOD_CAPS_LOCK)? 0xff : 0x00;
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
if (length == -1)
{
// This is a dead key, so we need a second simulated key press
// to make it output its own character (usually a diacritic)
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
}
if (length < 1)
continue;
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
_glfw.win32.keynames[key][level],
sizeof(_glfw.win32.keynames[key][level]),
NULL, NULL);
}
if (length < 1)
continue;
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
_glfw.win32.keynames[key],
sizeof(_glfw.win32.keynames[key]),
NULL, NULL);
}
}

View file

@ -377,6 +377,17 @@ typedef struct _GLFWwindowWin32
WCHAR highSurrogate;
} _GLFWwindowWin32;
const static int _GLFWmodelevels[] = {
0,
GLFW_MOD_SHIFT,
GLFW_MOD_CAPS_LOCK,
GLFW_MOD_SHIFT | GLFW_MOD_CAPS_LOCK,
GLFW_MOD_CONTROL | GLFW_MOD_ALT,
GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SHIFT,
GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_CAPS_LOCK,
GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SHIFT | GLFW_MOD_CAPS_LOCK
};
// Win32-specific global data
//
typedef struct _GLFWlibraryWin32
@ -390,7 +401,7 @@ typedef struct _GLFWlibraryWin32
char* clipboardString;
short int keycodes[512];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
char keynames[GLFW_KEY_LAST + 1][8][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active

View file

@ -2267,7 +2267,20 @@ const char* _glfwGetScancodeNameWin32(int scancode, int modifiers)
if (key == GLFW_KEY_UNKNOWN)
return NULL;
return _glfw.win32.keynames[key];
// Determine corresponding modifier level
int level = 0;
if (modifiers)
{
for (level = 0; level < 8; ++level)
{
if ((_GLFWmodelevels[level] & modifiers) == modifiers)
break;
}
if (level == 8)
level = 0;
}
return _glfw.win32.keynames[key][level];
}
int _glfwGetKeyScancodeWin32(int key)