Compare commits

...

6 Commits

Author SHA1 Message Date
Mason Remaley
753029b3ad
Merge 9ae058b208 into 9352d8fe93 2026-01-14 22:27:17 -03:00
Camilla Löwy
9352d8fe93 X11: Cleanup 2026-01-14 18:26:50 +01:00
Camilla Löwy
a228a8b447 X11: Fix window made non-floating by being hidden
The previous implementation was based on the incorrect assumption that
the _NET_WM_STATE_ABOVE state is always retained on unmapped windows.
According to EWMH the WM should remove the _NET_WM_STATE property when
a window is unmapped.

This commit moves the adding of _NET_WM_STATE_ABOVE to before mapping
the window during glfwShowWindow.  The logic for removing
_NET_WM_STATE_ABOVE from hidden windows is retained, as EWMH still
allows WMs to leave the window property on unmapped window.

Fixes #2276
2026-01-12 21:26:42 +01:00
Mason Remaley
9ae058b208 Slightly adjusts button mappings for compatibility with SDL game controller database 2024-07-05 22:11:59 -07:00
Mason Remaley
6836e650bc Remaps indices of buttons below the previous minimum
This prevents us from missing their inputs, while also maintaining
backwards compatibility with previous indices
2024-07-05 21:56:00 -07:00
Mason Remaley
5e1ec2444f Fixes an out of bounds joystick array access
Testing with an Xbox Series X controller. The extra button they
added directly under the Xbox button emits 0xA7 for me, which is
lower than BTN_MISC. As a result, when pressed, handleKeyEvent
was indexing an array with a negative index.

This commit adds a bounds check preventing the negative index, and
adds a second bounds check to a similar function preemptively.

It's possible that the better fix for this is to extend the range of
the buttons array so that this button can be mapped, but that may
need some disucssion first.
2024-07-05 20:17:02 -07:00
4 changed files with 68 additions and 33 deletions

View File

@ -153,6 +153,7 @@ information on what to include when reporting a bug.
- [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale - [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale
less than 1 (#2754) less than 1 (#2754)
- [X11] Bugfix: Clamp width and height to >= 1 to prevent BadValue error and app exit - [X11] Bugfix: Clamp width and height to >= 1 to prevent BadValue error and app exit
- [X11] Bugfix: Floating windows silently became non-floating when hidden (#2276)
- [Linux] Bugfix: The header for `ioctl` was only implicitly included (#2778) - [Linux] Bugfix: The header for `ioctl` was only implicitly included (#2778)
- [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`

View File

@ -51,7 +51,7 @@
static void handleKeyEvent(_GLFWjoystick* js, int code, int value) static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
{ {
_glfwInputJoystickButton(js, _glfwInputJoystickButton(js,
js->linjs.keyMap[code - BTN_MISC], js->linjs.keyMap[code],
value ? GLFW_PRESS : GLFW_RELEASE); value ? GLFW_PRESS : GLFW_RELEASE);
} }
@ -191,12 +191,28 @@ static GLFWbool openJoystickDevice(const char* path)
int axisCount = 0, buttonCount = 0, hatCount = 0; int axisCount = 0, buttonCount = 0, hatCount = 0;
for (int code = BTN_MISC; code < KEY_CNT; code++) // This loop should stop at KEY_CNT instead of KEY_MAX. However, we are
// terminating the loop one iteration early to maintain compatibility with
// the SDL gamepad mappings.
for (int code = BTN_JOYSTICK; code < KEY_MAX; code++)
{ {
if (!isBitSet(code, keyBits)) if (!isBitSet(code, keyBits))
continue; continue;
linjs.keyMap[code - BTN_MISC] = buttonCount; linjs.keyMap[code] = buttonCount;
buttonCount++;
}
// Originally, this range was not mapped, but some controllers now output
// these values. Appending them to the end of the list maintains both
// backwards compatibility with older versions of GLFW, and with the SDL
// gamepad mappings.
for (int code = 0; code < BTN_JOYSTICK; code++)
{
if (!isBitSet(code, keyBits))
continue;
linjs.keyMap[code] = buttonCount;
buttonCount++; buttonCount++;
} }

View File

@ -37,7 +37,7 @@ typedef struct _GLFWjoystickLinux
{ {
int fd; int fd;
char path[PATH_MAX]; char path[PATH_MAX];
int keyMap[KEY_CNT - BTN_MISC]; int keyMap[KEY_CNT];
int absMap[ABS_CNT]; int absMap[ABS_CNT];
struct input_absinfo absInfo[ABS_CNT]; struct input_absinfo absInfo[ABS_CNT];
int hats[4][2]; int hats[4][2];

View File

@ -2438,6 +2438,38 @@ void _glfwShowWindowX11(_GLFWwindow* window)
if (_glfwWindowVisibleX11(window)) if (_glfwWindowVisibleX11(window))
return; return;
if (window->floating && _glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE)
{
Atom* states = NULL;
const unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
XA_ATOM, (unsigned char**) &states);
// NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append)
unsigned long i;
for (i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
break;
}
if (i == count)
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
if (states)
XFree(states);
}
XMapWindow(_glfw.x11.display, window->x11.handle); XMapWindow(_glfw.x11.display, window->x11.handle);
waitForVisibilityNotify(window); waitForVisibilityNotify(window);
} }
@ -2667,6 +2699,10 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
} }
else else
{ {
// NOTE: _NET_WM_STATE_ABOVE is added when the window is shown
if (enabled)
return;
Atom* states = NULL; Atom* states = NULL;
const unsigned long count = const unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle, _glfwGetWindowPropertyX11(window->x11.handle,
@ -2677,8 +2713,6 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
// NOTE: We don't check for failure as this property may not exist yet // NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append) // and that's fine (and we'll create it implicitly with append)
if (enabled)
{
unsigned long i; unsigned long i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -2687,28 +2721,12 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
break; break;
} }
if (i == count) if (i < count)
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
}
else if (states)
{
for (unsigned long i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
{ {
states[i] = states[count - 1]; states[i] = states[count - 1];
XChangeProperty(_glfw.x11.display, window->x11.handle, XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32, _glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) states, count - 1); PropModeReplace, (unsigned char*) states, count - 1);
break;
}
}
} }
if (states) if (states)