Compare commits

...

8 Commits

Author SHA1 Message Date
iacore
42997d45ea
Merge 0c181dcf74 into acb92944d4 2025-08-19 18:50:56 +08:00
Doug Binks
acb92944d4 Revert readme for "Wayland: Keyboard leave event handler now processes key repeats" 2025-08-19 11:30:52 +02:00
Camilla Löwy
7ef6efeb66 Wayland: Fix cursor position after a modal
If a modal surface like the window menu was active, clicking on the GLFW
window content area to close it would correctly emit the cursor enter
event but would not propagate the cursor position from the event.
2025-08-18 20:58:12 +02:00
Camilla Löwy
3cf9f6726d Wayland: Fix fallback decoration cursor updating
When a click through to the fallback decorations caused the end of
a modal like the window menu, the cursor shape would not be updated
until the next time the cursor moved.

This commit adds an update of the cursor for the pointer enter event for
fallback decoration surfaces, in addition to the updates at pointer
motion events.
2025-08-18 18:06:46 +02:00
Camilla Löwy
bfa1c424e5 Wayland: Fix fallback decoration menu placement
The fallback decorations would place the menu at the wrong position, by
not translating the last decoration surface position into toplevel
surface coordinates.

This also limits the menu to the caption area of the top decoration
surface, similar to how other toolkits work.
2025-08-18 18:06:46 +02:00
Locria Cyber
0c181dcf74
Fix to Pass tests 2023-06-14 18:57:57 +00:00
Locria Cyber
337a4589a9
Add guard for linux joystick 2023-06-13 15:22:22 +00:00
Locria Cyber
1e9380584a
Match gamepad by USB vendor+product on Linux 2023-06-12 22:45:57 +00:00
5 changed files with 101 additions and 15 deletions

View File

@ -134,11 +134,15 @@ information on what to include when reporting a bug.
- [Wayland] Bugfix: Ignore key repeat events when no window has keyboard focus (#2727) - [Wayland] Bugfix: Ignore key repeat events when no window has keyboard focus (#2727)
- [Wayland] Bugfix: Reset key repeat timer when window destroyed (#2741,#2727) - [Wayland] Bugfix: Reset key repeat timer when window destroyed (#2741,#2727)
- [Wayland] Bugfix: Memory would leak if reading a data offer failed midway - [Wayland] Bugfix: Memory would leak if reading a data offer failed midway
- [Wayland] Bugfix: Keyboard leave event handler now processes key repeats (#2736)
- [Wayland] Bugfix: Retrieved cursor position would be incorrect when hovering over - [Wayland] Bugfix: Retrieved cursor position would be incorrect when hovering over
fallback decorations fallback decorations
- [Wayland] Bugfix: Fallback decorations would report scroll events - [Wayland] Bugfix: Fallback decorations would report scroll events
- [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568) - [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568)
- [Wayland] Bugfix: Fallback decorations would show menu at wrong position
- [Wayland] Bugfix: The cursor was not updated when clicking through from
a modal to a fallback decoration
- [Wayland] Bugfix: The cursor position was not updated when clicking through
from a modal to the content area
- [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)
- [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

@ -65,21 +65,68 @@ static GLFWbool initJoysticks(void)
return _glfw.joysticksInitialized = GLFW_TRUE; return _glfw.joysticksInitialized = GLFW_TRUE;
} }
// Finds a mapping based on joystick GUID #if defined(GLFW_BUILD_LINUX_JOYSTICK)
//
static _GLFWmapping* findMapping(const char* guid)
{
int i;
for (i = 0; i < _glfw.mappingCount; i++) uint16_t parseHexDigit(char c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
assert(GLFW_FALSE);
}
struct vendor_product
{
uint16_t vendor;
uint16_t product;
};
static struct vendor_product parseGUID(const char* guid)
{
struct vendor_product result;
result.vendor = parseHexDigit(guid[8]) | (parseHexDigit(guid[9]) << 8);
result.product = parseHexDigit(guid[16]) | (parseHexDigit(guid[17]) << 8);
return result;
}
static _GLFWmapping* findMappingUSBVendorProduct(const char* guid)
{
struct vendor_product this;
this = parseGUID(guid);
for (int i = 0; i < _glfw.mappingCount; i++)
{ {
if (strcmp(_glfw.mappings[i].guid, guid) == 0) struct vendor_product that = parseGUID(_glfw.mappings[i].guid);
if (memcmp(&this, &that, sizeof(struct vendor_product)) == 0)
return _glfw.mappings + i; return _glfw.mappings + i;
} }
return NULL; return NULL;
} }
#endif
// Finds a mapping based on joystick GUID
//
static _GLFWmapping* findMapping(const char* guid)
{
// exact match
for (int i = 0; i < _glfw.mappingCount; i++)
{
if (strncmp(_glfw.mappings[i].guid, guid, 32) == 0)
return _glfw.mappings + i;
}
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
// only match vendor id, product id
return findMappingUSBVendorProduct(guid);
#else
return NULL;
#endif
}
// Checks whether a gamepad mapping element is present in the hardware // Checks whether a gamepad mapping element is present in the hardware
// //
static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e, static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,

View File

@ -76,6 +76,7 @@ typedef struct _GLFWmonitor _GLFWmonitor;
typedef struct _GLFWcursor _GLFWcursor; typedef struct _GLFWcursor _GLFWcursor;
typedef struct _GLFWmapelement _GLFWmapelement; typedef struct _GLFWmapelement _GLFWmapelement;
typedef struct _GLFWmapping _GLFWmapping; typedef struct _GLFWmapping _GLFWmapping;
typedef struct _GLFWusbinfo _GLFWusbinfo;
typedef struct _GLFWjoystick _GLFWjoystick; typedef struct _GLFWjoystick _GLFWjoystick;
typedef struct _GLFWtls _GLFWtls; typedef struct _GLFWtls _GLFWtls;
typedef struct _GLFWmutex _GLFWmutex; typedef struct _GLFWmutex _GLFWmutex;
@ -640,6 +641,16 @@ struct _GLFWmapping
_GLFWmapelement axes[6]; _GLFWmapelement axes[6];
}; };
// USB vendor, product, version
//
struct _GLFWusbinfo
{
uint16_t bustype;
uint16_t vendor;
uint16_t product;
uint16_t version;
};
// Joystick structure // Joystick structure
// //
struct _GLFWjoystick struct _GLFWjoystick
@ -655,6 +666,7 @@ struct _GLFWjoystick
char name[128]; char name[128];
void* userPointer; void* userPointer;
char guid[33]; char guid[33];
_GLFWusbinfo usbInfo;
_GLFWmapping* mapping; _GLFWmapping* mapping;
// This is defined in platform.h // This is defined in platform.h

View File

@ -170,6 +170,12 @@ static GLFWbool openJoystickDevice(const char* path)
char guid[33] = ""; char guid[33] = "";
_GLFWusbinfo usbinfo;
usbinfo.bustype = id.bustype;
usbinfo.vendor = id.vendor;
usbinfo.product = id.product;
usbinfo.version = id.version;
// Generate a joystick GUID that matches the SDL 2.0.5+ one // Generate a joystick GUID that matches the SDL 2.0.5+ one
if (id.vendor && id.product && id.version) if (id.vendor && id.product && id.version)
{ {
@ -229,6 +235,7 @@ static GLFWbool openJoystickDevice(const char* path)
close(linjs.fd); close(linjs.fd);
return GLFW_FALSE; return GLFW_FALSE;
} }
js->usbInfo = usbinfo;
strncpy(linjs.path, path, sizeof(linjs.path) - 1); strncpy(linjs.path, path, sizeof(linjs.path) - 1);
memcpy(&js->linjs, &linjs, sizeof(linjs)); memcpy(&js->linjs, &linjs, sizeof(linjs));

View File

@ -405,13 +405,19 @@ static void handleFallbackDecorationButton(_GLFWwindow* window,
} }
else if (button == BTN_RIGHT) else if (button == BTN_RIGHT)
{ {
if (window->wl.xdg.toplevel) if (!window->wl.xdg.toplevel)
{ return;
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
_glfw.wl.seat, serial, if (window->wl.fallback.focus != window->wl.fallback.top.surface)
window->wl.cursorPosX, return;
window->wl.cursorPosY);
} if (ypos < GLFW_BORDER_SIZE)
return;
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
_glfw.wl.seat, serial,
xpos,
ypos - GLFW_CAPTION_HEIGHT - GLFW_BORDER_SIZE);
} }
} }
@ -1532,11 +1538,21 @@ static void pointerHandleEnter(void* userData,
window->wl.hovered = GLFW_TRUE; window->wl.hovered = GLFW_TRUE;
_glfwSetCursorWayland(window, window->wl.currentCursor); _glfwSetCursorWayland(window, window->wl.currentCursor);
_glfwInputCursorEnter(window, GLFW_TRUE); _glfwInputCursorEnter(window, GLFW_TRUE);
if (window->cursorMode != GLFW_CURSOR_DISABLED)
{
window->wl.cursorPosX = wl_fixed_to_double(sx);
window->wl.cursorPosY = wl_fixed_to_double(sy);
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
}
} }
else else
{ {
if (window->wl.fallback.decorations) if (window->wl.fallback.decorations)
{
window->wl.fallback.focus = surface; window->wl.fallback.focus = surface;
updateFallbackDecorationCursor(window, sx, sy);
}
} }
} }