Compare commits

...

9 Commits

Author SHA1 Message Date
Marco Lizza
3ec07e6e90
Merge cdcd9c194a into 7ef6efeb66 2025-08-19 11:14:11 +08: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
Marco Lizza
cdcd9c194a Fixing dlsym cast warning. 2024-02-29 01:57:41 +01:00
Marco Lizza
596cabbe58 Tweaking GLFW_ANY_POSITION to int32_t max value to avoid signed/unsigned warnings. 2024-02-29 01:51:48 +01:00
Marco Lizza
a02b287b1d Fixing signed/unsigned mismatch warnings. 2024-02-29 01:50:49 +01:00
Marco Lizza
7c2e8c7c5a Using designated initializers to avoid warnings. 2024-02-29 01:50:21 +01:00
Marco Lizza
58f2aab759 Fixing constant pointers. 2024-02-29 01:49:48 +01:00
19 changed files with 82 additions and 54 deletions

View File

@ -139,6 +139,11 @@ information on what to include when reporting a bug.
fallback decorations
- [Wayland] Bugfix: Fallback decorations would report scroll events
- [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)
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`

View File

@ -1180,7 +1180,7 @@ extern "C" {
#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
#define GLFW_ANY_POSITION 0x80000000
#define GLFW_ANY_POSITION 0x7FFFFFFF
/*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes.

View File

@ -272,7 +272,7 @@ EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void);
EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions);
void _glfwGetRequiredInstanceExtensionsCocoa(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -1922,7 +1922,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window)
return window->ns.layer;
}
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions)
void _glfwGetRequiredInstanceExtensionsCocoa(const char** extensions)
{
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
{

View File

@ -1289,7 +1289,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
const size_t length = strcspn(c, "\r\n");
if (length < sizeof(line))
{
_GLFWmapping mapping = {{0}};
_GLFWmapping mapping = { .name = {0} };
memcpy(line, c, length);
line[length] = '\0';

View File

@ -756,7 +756,7 @@ struct _GLFWplatform
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*);
// vulkan
void (*getRequiredInstanceExtensions)(char**);
void (*getRequiredInstanceExtensions)(const char**);
GLFWbool (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
};
@ -863,7 +863,7 @@ struct _GLFWlibrary
struct {
GLFWbool available;
void* handle;
char* extensions[2];
const char* extensions[2];
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
GLFWbool KHR_surface;
GLFWbool KHR_win32_surface;

View File

@ -274,7 +274,7 @@ EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void);
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsNull(char** extensions);
void _glfwGetRequiredInstanceExtensionsNull(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -701,7 +701,7 @@ int _glfwGetKeyScancodeNull(int key)
return _glfw.null.scancodes[key];
}
void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
void _glfwGetRequiredInstanceExtensionsNull(const char** extensions)
{
if (!_glfw.vk.KHR_surface || !_glfw.vk.EXT_headless_surface)
return;

View File

@ -44,10 +44,17 @@ void _glfwPlatformFreeModule(void* module)
dlclose(module);
}
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return dlsym(module, name);
return (GLFWproc)dlsym(module, name);
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif // GLFW_BUILD_POSIX_MODULE

View File

@ -150,7 +150,7 @@ GLFWbool _glfwInitVulkan(int mode)
_glfw.vk.available = GLFW_TRUE;
_glfw.platform.getRequiredInstanceExtensions(_glfw.vk.extensions);
_glfw.platform.getRequiredInstanceExtensions((const char **)_glfw.vk.extensions);
return GLFW_TRUE;
}

View File

@ -540,7 +540,7 @@ EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWin32(char** extensions);
void _glfwGetRequiredInstanceExtensionsWin32(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWin32(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -2501,7 +2501,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window)
return window->win32.handle;
}
void _glfwGetRequiredInstanceExtensionsWin32(char** extensions)
void _glfwGetRequiredInstanceExtensionsWin32(const char** extensions)
{
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface)
return;

View File

@ -243,7 +243,7 @@ void libdecorHandleError(struct libdecor* context,
static const struct libdecor_interface libdecorInterface =
{
libdecorHandleError
.error = libdecorHandleError
};
static void libdecorReadyCallback(void* userData,

View File

@ -674,7 +674,7 @@ EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWayland(char** extensions);
void _glfwGetRequiredInstanceExtensionsWayland(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -405,13 +405,19 @@ static void handleFallbackDecorationButton(_GLFWwindow* window,
}
else if (button == BTN_RIGHT)
{
if (window->wl.xdg.toplevel)
{
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
_glfw.wl.seat, serial,
window->wl.cursorPosX,
window->wl.cursorPosY);
}
if (!window->wl.xdg.toplevel)
return;
if (window->wl.fallback.focus != window->wl.fallback.top.surface)
return;
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);
}
}
@ -614,8 +620,8 @@ static void surfaceHandleLeave(void* userData,
static const struct wl_surface_listener surfaceListener =
{
surfaceHandleEnter,
surfaceHandleLeave
.enter = surfaceHandleEnter,
.leave = surfaceHandleLeave
};
static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
@ -756,8 +762,8 @@ static void xdgToplevelHandleClose(void* userData,
static const struct xdg_toplevel_listener xdgToplevelListener =
{
xdgToplevelHandleConfigure,
xdgToplevelHandleClose
.configure = xdgToplevelHandleConfigure,
.close = xdgToplevelHandleClose
};
static void xdgSurfaceHandleConfigure(void* userData,
@ -931,10 +937,10 @@ void libdecorFrameHandleDismissPopup(struct libdecor_frame* frame,
static const struct libdecor_frame_interface libdecorFrameInterface =
{
libdecorFrameHandleConfigure,
libdecorFrameHandleClose,
libdecorFrameHandleCommit,
libdecorFrameHandleDismissPopup
.configure = libdecorFrameHandleConfigure,
.close = libdecorFrameHandleClose,
.commit = libdecorFrameHandleCommit,
.dismiss_popup = libdecorFrameHandleDismissPopup
};
static GLFWbool createLibdecorFrame(_GLFWwindow* window)
@ -1284,7 +1290,7 @@ static GLFWbool flushDisplay(void)
if (errno != EAGAIN)
return GLFW_FALSE;
struct pollfd fd = { wl_display_get_fd(_glfw.wl.display), POLLOUT };
struct pollfd fd = { .fd = wl_display_get_fd(_glfw.wl.display), POLLOUT };
while (poll(&fd, 1, -1) == -1)
{
@ -1532,11 +1538,21 @@ static void pointerHandleEnter(void* userData,
window->wl.hovered = GLFW_TRUE;
_glfwSetCursorWayland(window, window->wl.currentCursor);
_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
{
if (window->wl.fallback.decorations)
{
window->wl.fallback.focus = surface;
updateFallbackDecorationCursor(window, sx, sy);
}
}
}
@ -1648,11 +1664,11 @@ static void pointerHandleAxis(void* userData,
static const struct wl_pointer_listener pointerListener =
{
pointerHandleEnter,
pointerHandleLeave,
pointerHandleMotion,
pointerHandleButton,
pointerHandleAxis,
.enter = pointerHandleEnter,
.leave = pointerHandleLeave,
.motion = pointerHandleMotion,
.button = pointerHandleButton,
.axis = pointerHandleAxis,
};
static void keyboardHandleKeymap(void* userData,
@ -1961,7 +1977,7 @@ static void dataOfferHandleOffer(void* userData,
static const struct wl_data_offer_listener dataOfferListener =
{
dataOfferHandleOffer
.offer = dataOfferHandleOffer
};
static void dataDeviceHandleDataOffer(void* userData,
@ -1980,7 +1996,7 @@ static void dataDeviceHandleDataOffer(void* userData,
_glfw.wl.offers = offers;
_glfw.wl.offerCount++;
_glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { offer };
_glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { .offer = offer };
wl_data_offer_add_listener(offer, &dataOfferListener, NULL);
}
@ -3169,9 +3185,9 @@ static void dataSourceHandleCancelled(void* userData,
static const struct wl_data_source_listener dataSourceListener =
{
dataSourceHandleTarget,
dataSourceHandleSend,
dataSourceHandleCancelled,
.target = dataSourceHandleTarget,
.send = dataSourceHandleSend,
.cancelled = dataSourceHandleCancelled,
};
void _glfwSetClipboardStringWayland(const char* string)
@ -3245,7 +3261,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window)
return window->wl.egl.window;
}
void _glfwGetRequiredInstanceExtensionsWayland(char** extensions)
void _glfwGetRequiredInstanceExtensionsWayland(const char** extensions)
{
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
return;

View File

@ -231,7 +231,7 @@ static void createKeyTables(void)
const struct
{
int key;
char* name;
const char* name;
} keymap[] =
{
{ GLFW_KEY_GRAVE_ACCENT, "TLDE" },
@ -366,7 +366,7 @@ static void createKeyTables(void)
// keyboard layout. Because function keys aren't mapped correctly
// when using traditional KeySym translations, they are mapped
// here instead.
for (int i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++)
for (size_t i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++)
{
if (strncmp(desc->names->keys[scancode].name,
keymap[i].name,
@ -390,7 +390,7 @@ static void createKeyTables(void)
continue;
}
for (int j = 0; j < sizeof(keymap) / sizeof(keymap[0]); j++)
for (size_t j = 0; j < sizeof(keymap) / sizeof(keymap[0]); j++)
{
if (strncmp(desc->names->key_aliases[i].alias,
keymap[j].name,

View File

@ -180,8 +180,8 @@ void _glfwPollMonitorsX11(void)
{
if (screens[j].x_org == ci->x &&
screens[j].y_org == ci->y &&
screens[j].width == ci->width &&
screens[j].height == ci->height)
screens[j].width == (int)ci->width &&
screens[j].height == (int)ci->height)
{
monitor->x11.index = j;
break;
@ -573,7 +573,7 @@ void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != (int)ramp->size)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp size must match current ramp size");

View File

@ -959,7 +959,7 @@ EGLenum _glfwGetEGLPlatformX11(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayX11(void);
EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsX11(char** extensions);
void _glfwGetRequiredInstanceExtensionsX11(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportX11(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceX11(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -62,7 +62,7 @@
//
static GLFWbool waitForX11Event(double* timeout)
{
struct pollfd fd = { ConnectionNumber(_glfw.x11.display), POLLIN };
struct pollfd fd = { .fd = ConnectionNumber(_glfw.x11.display), .events = POLLIN };
while (!XPending(_glfw.x11.display))
{
@ -97,7 +97,7 @@ static GLFWbool waitForAnyEvent(double* timeout)
if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout))
return GLFW_FALSE;
for (int i = 1; i < sizeof(fds) / sizeof(fds[0]); i++)
for (size_t i = 1; i < sizeof(fds) / sizeof(fds[0]); i++)
{
if (fds[i].revents & POLLIN)
return GLFW_TRUE;
@ -235,10 +235,10 @@ static int translateState(int state)
// Translates an X11 key code to a GLFW key token
//
static int translateKey(int scancode)
static int translateKey(unsigned int scancode)
{
// Use the pre-filled LUT (see createKeyTables() in x11_init.c)
if (scancode < 0 || scancode > 255)
if (scancode > 255)
return GLFW_KEY_UNKNOWN;
return _glfw.x11.keycodes[scancode];
@ -1145,7 +1145,7 @@ static void releaseMonitor(_GLFWwindow* window)
//
static void processEvent(XEvent *event)
{
int keycode = 0;
unsigned int keycode = 0;
Bool filtered = False;
// HACK: Save scancode as some IMs clear the field in XFilterEvent
@ -3133,7 +3133,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window)
return (EGLNativeWindowType) window->x11.handle;
}
void _glfwGetRequiredInstanceExtensionsX11(char** extensions)
void _glfwGetRequiredInstanceExtensionsX11(const char** extensions)
{
if (!_glfw.vk.KHR_surface)
return;