Compare commits

...

3 Commits

Author SHA1 Message Date
Grzesiek11
fbddd92269
Merge 7235dddefd into 162896e5b9 2025-11-17 09:02:31 +08:00
Doug Binks
162896e5b9
Wayland: free modules at end of terminate function
- Fixes #2744
2025-11-14 16:35:47 +00:00
Grzesiek11
7235dddefd
Fix extended scancode of 0 not being processed correctly
On Windows, keyboard events with an extended 0 Windows scancode are now
processed by mapping the virtual-key code to a Windows scancode using
the Win32 MapVirtualKey function.

Some keyboard scancodes (in particular, ones used for some non-typical
keys) are not mapped to corresponding Windows scancodes, and are instead
mapped to an extended 0 Windows scancode, with the distinction being
only in the virtual-key code.

This causes GLFW to report a 256 GLFW scancode (0x00 | 0x100, 0x100
being the extended bit bitmask) for any of those keys, which causes API
consumers to be unable to distinguish between them.

There exists, however, a Win32 function MapVirtualKey that maps those
virtual key-codes to proper Windows scancodes. GLFW even appears to use
this workaround, but after further inspection, it checks whether the
Windows scancode is 0 (0x00), and not extended 0 (0x100).

This change makes GLFW check for the extended 0 keycode instead, which
seems to work correctly. I'm not sure if checking for the non-extended 0
Windows scancode was intentional, as I never seem to have encountered
one during testing with multiple keyboards. Thus, the handling of the
non-extended 0 Windows scancode was removed, but it can be brought back
if necessary.
2025-04-04 02:55:49 +02:00
4 changed files with 38 additions and 26 deletions

View File

@ -144,6 +144,8 @@ information on what to include when reporting a bug.
a modal to a fallback decoration a modal to a fallback decoration
- [Wayland] Bugfix: The cursor position was not updated when clicking through - [Wayland] Bugfix: The cursor position was not updated when clicking through
from a modal to the content area from a modal to the content area
- [Wayland] Bugfix: free modules at end of terminate function to resolve
potential segmentation fault (#2744)
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631) - [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
- [X11] Bugfix: Occasional crash when an idle display awakes (#2766) - [X11] Bugfix: Occasional crash when an idle display awakes (#2766)
- [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale - [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale
@ -152,6 +154,7 @@ information on what to include when reporting a bug.
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to - [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
- [Win32] Bugfix: Extended scancode of 0 was not being processed correctly
`GLFW_NATIVE_CONTEXT_API` (#2518) `GLFW_NATIVE_CONTEXT_API` (#2518)

View File

@ -555,7 +555,8 @@ void _glfwTerminateEGL(void)
_glfw.egl.display = EGL_NO_DISPLAY; _glfw.egl.display = EGL_NO_DISPLAY;
} }
if (_glfw.egl.handle) // Free modules only after all wayland termination functions are called
if (_glfw.egl.handle && _glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
{ {
_glfwPlatformFreeModule(_glfw.egl.handle); _glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL; _glfw.egl.handle = NULL;

View File

@ -711,11 +711,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
const int mods = getKeyMods(); const int mods = getKeyMods();
scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff)); scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff));
if (!scancode) if (scancode == 0x100)
{ {
// NOTE: Some synthetic key messages have a scancode of zero // NOTE: Some synthetic key messages have a scancode of extended zero
// HACK: Map the virtual key back to a usable scancode // HACK: Map the virtual key back to a usable scancode
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC); scancode = KF_EXTENDED | MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
} }
// HACK: Alt+PrtSc has a different scancode than just PrtSc // HACK: Alt+PrtSc has a different scancode than just PrtSc

View File

@ -907,18 +907,6 @@ void _glfwTerminateWayland(void)
libdecor_unref(_glfw.wl.libdecor.context); libdecor_unref(_glfw.wl.libdecor.context);
} }
if (_glfw.wl.libdecor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
_glfw.wl.libdecor.handle = NULL;
}
if (_glfw.wl.egl.handle)
{
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
_glfw.wl.egl.handle = NULL;
}
if (_glfw.wl.xkb.composeState) if (_glfw.wl.xkb.composeState)
xkb_compose_state_unref(_glfw.wl.xkb.composeState); xkb_compose_state_unref(_glfw.wl.xkb.composeState);
if (_glfw.wl.xkb.keymap) if (_glfw.wl.xkb.keymap)
@ -927,21 +915,11 @@ void _glfwTerminateWayland(void)
xkb_state_unref(_glfw.wl.xkb.state); xkb_state_unref(_glfw.wl.xkb.state);
if (_glfw.wl.xkb.context) if (_glfw.wl.xkb.context)
xkb_context_unref(_glfw.wl.xkb.context); xkb_context_unref(_glfw.wl.xkb.context);
if (_glfw.wl.xkb.handle)
{
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
_glfw.wl.xkb.handle = NULL;
}
if (_glfw.wl.cursorTheme) if (_glfw.wl.cursorTheme)
wl_cursor_theme_destroy(_glfw.wl.cursorTheme); wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
if (_glfw.wl.cursorThemeHiDPI) if (_glfw.wl.cursorThemeHiDPI)
wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI); wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
if (_glfw.wl.cursor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
_glfw.wl.cursor.handle = NULL;
}
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
wl_data_offer_destroy(_glfw.wl.offers[i].offer); wl_data_offer_destroy(_glfw.wl.offers[i].offer);
@ -1001,6 +979,36 @@ void _glfwTerminateWayland(void)
if (_glfw.wl.cursorTimerfd >= 0) if (_glfw.wl.cursorTimerfd >= 0)
close(_glfw.wl.cursorTimerfd); close(_glfw.wl.cursorTimerfd);
// Free modules only after all wayland termination functions are called
if (_glfw.egl.handle)
{
_glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL;
}
if (_glfw.wl.libdecor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
_glfw.wl.libdecor.handle = NULL;
}
if (_glfw.wl.egl.handle)
{
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
_glfw.wl.egl.handle = NULL;
}
if (_glfw.wl.xkb.handle)
{
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
_glfw.wl.xkb.handle = NULL;
}
if (_glfw.wl.cursor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
_glfw.wl.cursor.handle = NULL;
}
_glfw_free(_glfw.wl.clipboardString); _glfw_free(_glfw.wl.clipboardString);
} }