Compare commits

..

1 Commits

Author SHA1 Message Date
Jens Weggemann
28e1de64c7
Merge 24c2b3cf01 into 9352d8fe93 2026-01-21 19:57:22 +01:00
6 changed files with 71 additions and 102 deletions

View File

@ -4520,8 +4520,7 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
* GLFW will pass those events on to the application callbacks before * GLFW will pass those events on to the application callbacks before
* returning. * returning.
* *
* Event processing is not required to receive joystick input. Joystick state * Event processing is not required for joystick input to work.
* is polled when a joystick input or gamepad input function is called.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -4566,8 +4565,7 @@ GLFWAPI void glfwPollEvents(void);
* GLFW will pass those events on to the application callbacks before * GLFW will pass those events on to the application callbacks before
* returning. * returning.
* *
* Event processing is not required to receive joystick input. Joystick state * Event processing is not required for joystick input to work.
* is polled when a joystick input or gamepad input function is called.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -4614,8 +4612,7 @@ GLFWAPI void glfwWaitEvents(void);
* GLFW will pass those events on to the application callbacks before * GLFW will pass those events on to the application callbacks before
* returning. * returning.
* *
* Event processing is not required to receive joystick input. Joystick state * Event processing is not required for joystick input to work.
* is polled when a joystick input or gamepad input function is called.
* *
* @param[in] timeout The maximum amount of time, in seconds, to wait. * @param[in] timeout The maximum amount of time, in seconds, to wait.
* *

View File

@ -834,7 +834,7 @@ int _glfwInitWayland(void)
createKeyTables(); createKeyTables();
_glfw.wl.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); _glfw.wl.xkb.context = xkb_context_new(0);
if (!_glfw.wl.xkb.context) if (!_glfw.wl.xkb.context)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,

View File

@ -360,6 +360,7 @@ typedef struct _GLFWwindowWayland
GLFWbool maximized; GLFWbool maximized;
GLFWbool activated; GLFWbool activated;
GLFWbool fullscreen; GLFWbool fullscreen;
GLFWbool hovered;
GLFWbool transparent; GLFWbool transparent;
GLFWbool scaleFramebuffer; GLFWbool scaleFramebuffer;
struct wl_surface* surface; struct wl_surface* surface;
@ -388,6 +389,7 @@ typedef struct _GLFWwindowWayland
struct libdecor_frame* frame; struct libdecor_frame* frame;
} libdecor; } libdecor;
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY; double cursorPosX, cursorPosY;
char* appId; char* appId;
@ -414,6 +416,7 @@ typedef struct _GLFWwindowWayland
GLFWbool decorations; GLFWbool decorations;
struct wl_buffer* buffer; struct wl_buffer* buffer;
_GLFWfallbackEdgeWayland top, left, right, bottom; _GLFWfallbackEdgeWayland top, left, right, bottom;
struct wl_surface* focus;
wl_fixed_t pointerX, pointerY; wl_fixed_t pointerX, pointerY;
const char* cursorName; const char* cursorName;
} fallback; } fallback;
@ -454,7 +457,6 @@ typedef struct _GLFWlibraryWayland
const char* tag; const char* tag;
struct wl_surface* pointerSurface;
struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorTheme;
struct wl_cursor_theme* cursorThemeHiDPI; struct wl_cursor_theme* cursorThemeHiDPI;
struct wl_surface* cursorSurface; struct wl_surface* cursorSurface;
@ -513,6 +515,7 @@ typedef struct _GLFWlibraryWayland
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym; PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
} xkb; } xkb;
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus; _GLFWwindow* keyboardFocus;
struct { struct {

View File

@ -253,9 +253,6 @@ static void createFallbackDecorations(_GLFWwindow* window)
static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge) static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge)
{ {
if (edge->surface == _glfw.wl.pointerSurface)
_glfw.wl.pointerSurface = NULL;
if (edge->subsurface) if (edge->subsurface)
wl_subsurface_destroy(edge->subsurface); wl_subsurface_destroy(edge->subsurface);
if (edge->surface) if (edge->surface)
@ -291,26 +288,26 @@ static void updateFallbackDecorationCursor(_GLFWwindow* window,
if (window->resizable) if (window->resizable)
{ {
if (_glfw.wl.pointerSurface == window->wl.fallback.top.surface) if (window->wl.fallback.focus == window->wl.fallback.top.surface)
{ {
if (ypos < GLFW_BORDER_SIZE) if (ypos < GLFW_BORDER_SIZE)
cursorName = "n-resize"; cursorName = "n-resize";
} }
else if (_glfw.wl.pointerSurface == window->wl.fallback.left.surface) else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
{ {
if (ypos < GLFW_BORDER_SIZE) if (ypos < GLFW_BORDER_SIZE)
cursorName = "nw-resize"; cursorName = "nw-resize";
else else
cursorName = "w-resize"; cursorName = "w-resize";
} }
else if (_glfw.wl.pointerSurface == window->wl.fallback.right.surface) else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
{ {
if (ypos < GLFW_BORDER_SIZE) if (ypos < GLFW_BORDER_SIZE)
cursorName = "ne-resize"; cursorName = "ne-resize";
else else
cursorName = "e-resize"; cursorName = "e-resize";
} }
else if (_glfw.wl.pointerSurface == window->wl.fallback.bottom.surface) else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
{ {
if (xpos < GLFW_BORDER_SIZE) if (xpos < GLFW_BORDER_SIZE)
cursorName = "sw-resize"; cursorName = "sw-resize";
@ -363,12 +360,8 @@ static void updateFallbackDecorationCursor(_GLFWwindow* window,
static void handleFallbackDecorationButton(_GLFWwindow* window, static void handleFallbackDecorationButton(_GLFWwindow* window,
uint32_t serial, uint32_t serial,
uint32_t button, uint32_t button)
uint32_t state)
{ {
if (state != WL_POINTER_BUTTON_STATE_PRESSED)
return;
const double xpos = wl_fixed_to_double(window->wl.fallback.pointerX); const double xpos = wl_fixed_to_double(window->wl.fallback.pointerX);
const double ypos = wl_fixed_to_double(window->wl.fallback.pointerY); const double ypos = wl_fixed_to_double(window->wl.fallback.pointerY);
@ -376,28 +369,28 @@ static void handleFallbackDecorationButton(_GLFWwindow* window,
{ {
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE; uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
if (_glfw.wl.pointerSurface == window->wl.fallback.top.surface) if (window->wl.fallback.focus == window->wl.fallback.top.surface)
{ {
if (ypos < GLFW_BORDER_SIZE) if (ypos < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP; edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
else else
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
} }
else if (_glfw.wl.pointerSurface == window->wl.fallback.left.surface) else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
{ {
if (ypos < GLFW_BORDER_SIZE) if (ypos < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
else else
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
} }
else if (_glfw.wl.pointerSurface == window->wl.fallback.right.surface) else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
{ {
if (ypos < GLFW_BORDER_SIZE) if (ypos < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
else else
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
} }
else if (_glfw.wl.pointerSurface == window->wl.fallback.bottom.surface) else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
{ {
if (xpos < GLFW_BORDER_SIZE) if (xpos < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
@ -415,7 +408,7 @@ static void handleFallbackDecorationButton(_GLFWwindow* window,
if (!window->wl.xdg.toplevel) if (!window->wl.xdg.toplevel)
return; return;
if (_glfw.wl.pointerSurface != window->wl.fallback.top.surface) if (window->wl.fallback.focus != window->wl.fallback.top.surface)
return; return;
if (ypos < GLFW_BORDER_SIZE) if (ypos < GLFW_BORDER_SIZE)
@ -1274,16 +1267,14 @@ static void setCursorImage(_GLFWwindow* window,
wl_surface_commit(surface); wl_surface_commit(surface);
} }
static void incrementCursorImage(void) static void incrementCursorImage(_GLFWwindow* window)
{ {
if (!_glfw.wl.pointerSurface) _GLFWcursor* cursor;
if (!window || !window->wl.hovered)
return; return;
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface); cursor = window->wl.currentCursor;
if (window->wl.surface != _glfw.wl.pointerSurface)
return;
_GLFWcursor* cursor = window->cursor;
if (cursor && cursor->wl.cursor) if (cursor && cursor->wl.cursor)
{ {
cursor->wl.currentImage += 1; cursor->wl.currentImage += 1;
@ -1445,7 +1436,7 @@ static void handleEvents(double* timeout)
uint64_t repeats; uint64_t repeats;
if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8) if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)
incrementCursorImage(); incrementCursorImage(_glfw.wl.pointerFocus);
} }
if (fds[LIBDECOR_FD].revents & POLLIN) if (fds[LIBDECOR_FD].revents & POLLIN)
@ -1536,14 +1527,16 @@ static void pointerHandleEnter(void* userData,
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
return; return;
_GLFWwindow* window = wl_surface_get_user_data(surface);
_glfw.wl.serial = serial; _glfw.wl.serial = serial;
_glfw.wl.pointerEnterSerial = serial; _glfw.wl.pointerEnterSerial = serial;
_glfw.wl.pointerSurface = surface; _glfw.wl.pointerFocus = window;
_GLFWwindow* window = wl_surface_get_user_data(surface); if (surface == window->wl.surface)
if (window->wl.surface == surface)
{ {
_glfwSetCursorWayland(window, window->cursor); window->wl.hovered = GLFW_TRUE;
_glfwSetCursorWayland(window, window->wl.currentCursor);
_glfwInputCursorEnter(window, GLFW_TRUE); _glfwInputCursorEnter(window, GLFW_TRUE);
if (window->cursorMode != GLFW_CURSOR_DISABLED) if (window->cursorMode != GLFW_CURSOR_DISABLED)
@ -1556,7 +1549,10 @@ static void pointerHandleEnter(void* userData,
else else
{ {
if (window->wl.fallback.decorations) if (window->wl.fallback.decorations)
{
window->wl.fallback.focus = surface;
updateFallbackDecorationCursor(window, sx, sy); updateFallbackDecorationCursor(window, sx, sy);
}
} }
} }
@ -1571,16 +1567,25 @@ static void pointerHandleLeave(void* userData,
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag) if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
return; return;
_glfw.wl.serial = serial; _GLFWwindow* window = _glfw.wl.pointerFocus;
_glfw.wl.pointerSurface = NULL; if (!window)
return;
_GLFWwindow* window = wl_surface_get_user_data(surface); _glfw.wl.serial = serial;
if (window->wl.surface == surface) _glfw.wl.pointerFocus = NULL;
if (window->wl.hovered)
{
window->wl.hovered = GLFW_FALSE;
_glfwInputCursorEnter(window, GLFW_FALSE); _glfwInputCursorEnter(window, GLFW_FALSE);
}
else else
{ {
if (window->wl.fallback.decorations) if (window->wl.fallback.decorations)
{
window->wl.fallback.focus = NULL;
window->wl.fallback.cursorName = NULL; window->wl.fallback.cursorName = NULL;
}
} }
} }
@ -1590,15 +1595,14 @@ static void pointerHandleMotion(void* userData,
wl_fixed_t sx, wl_fixed_t sx,
wl_fixed_t sy) wl_fixed_t sy)
{ {
if (!_glfw.wl.pointerSurface) _GLFWwindow* window = _glfw.wl.pointerFocus;
if (!window)
return; return;
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface);
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
return; return;
if (window->wl.surface == _glfw.wl.pointerSurface) if (window->wl.hovered)
{ {
window->wl.cursorPosX = wl_fixed_to_double(sx); window->wl.cursorPosX = wl_fixed_to_double(sx);
window->wl.cursorPosY = wl_fixed_to_double(sy); window->wl.cursorPosY = wl_fixed_to_double(sy);
@ -1618,12 +1622,11 @@ static void pointerHandleButton(void* userData,
uint32_t button, uint32_t button,
uint32_t state) uint32_t state)
{ {
if (!_glfw.wl.pointerSurface) _GLFWwindow* window = _glfw.wl.pointerFocus;
if (!window)
return; return;
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface); if (window->wl.hovered)
if (window->wl.surface == _glfw.wl.pointerSurface)
{ {
_glfw.wl.serial = serial; _glfw.wl.serial = serial;
@ -1635,7 +1638,7 @@ static void pointerHandleButton(void* userData,
else else
{ {
if (window->wl.fallback.decorations) if (window->wl.fallback.decorations)
handleFallbackDecorationButton(window, serial, button, state); handleFallbackDecorationButton(window, serial, button);
} }
} }
@ -1645,12 +1648,11 @@ static void pointerHandleAxis(void* userData,
uint32_t axis, uint32_t axis,
wl_fixed_t value) wl_fixed_t value)
{ {
if (!_glfw.wl.pointerSurface) _GLFWwindow* window = _glfw.wl.pointerFocus;
if (!window)
return; return;
_GLFWwindow* window = wl_surface_get_user_data(_glfw.wl.pointerSurface); if (window->wl.hovered)
if (window->wl.surface == _glfw.wl.pointerSurface)
{ {
// NOTE: 10 units of motion per mouse wheel step seems to be a common ratio // NOTE: 10 units of motion per mouse wheel step seems to be a common ratio
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
@ -1699,7 +1701,7 @@ static void keyboardHandleKeymap(void* userData,
keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context, keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context,
mapStr, mapStr,
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_FORMAT_TEXT_V1,
XKB_KEYMAP_COMPILE_NO_FLAGS); 0);
munmap(mapStr, size); munmap(mapStr, size);
close(fd); close(fd);
@ -1930,11 +1932,7 @@ static void seatHandleCapabilities(void* userData,
} }
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer) else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
{ {
if (wl_pointer_get_version(_glfw.wl.pointer) >= WL_POINTER_RELEASE_SINCE_VERSION) wl_pointer_destroy(_glfw.wl.pointer);
wl_pointer_release(_glfw.wl.pointer);
else
wl_pointer_destroy(_glfw.wl.pointer);
_glfw.wl.pointer = NULL; _glfw.wl.pointer = NULL;
} }
@ -1945,11 +1943,7 @@ static void seatHandleCapabilities(void* userData,
} }
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard) else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
{ {
if (wl_keyboard_get_version(_glfw.wl.keyboard) >= WL_KEYBOARD_RELEASE_SINCE_VERSION) wl_keyboard_destroy(_glfw.wl.keyboard);
wl_keyboard_release(_glfw.wl.keyboard);
else
wl_keyboard_destroy(_glfw.wl.keyboard);
_glfw.wl.keyboard = NULL; _glfw.wl.keyboard = NULL;
} }
} }
@ -2229,8 +2223,8 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
void _glfwDestroyWindowWayland(_GLFWwindow* window) void _glfwDestroyWindowWayland(_GLFWwindow* window)
{ {
if (window->wl.surface == _glfw.wl.pointerSurface) if (window == _glfw.wl.pointerFocus)
_glfw.wl.pointerSurface = NULL; _glfw.wl.pointerFocus = NULL;
if (window == _glfw.wl.keyboardFocus) if (window == _glfw.wl.keyboardFocus)
{ {
@ -2606,7 +2600,7 @@ GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window)
GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window) GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window)
{ {
return window->wl.surface == _glfw.wl.pointerSurface; return window->wl.hovered;
} }
GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window) GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window)
@ -2736,7 +2730,7 @@ void _glfwSetCursorPosWayland(_GLFWwindow* window, double x, double y)
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode) void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
{ {
_glfwSetCursorWayland(window, window->cursor); _glfwSetCursorWayland(window, window->wl.currentCursor);
} }
const char* _glfwGetScancodeNameWayland(int scancode) const char* _glfwGetScancodeNameWayland(int scancode)
@ -3070,7 +3064,11 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor)
if (!_glfw.wl.pointer) if (!_glfw.wl.pointer)
return; return;
if (window->wl.surface != _glfw.wl.pointerSurface) window->wl.currentCursor = cursor;
// If we're not in the correct window just save the cursor
// the next time the pointer enters the window the cursor will change
if (!window->wl.hovered)
return; return;
// Update pointer lock to match cursor mode // Update pointer lock to match cursor mode

View File

@ -3344,6 +3344,8 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
GLFWAPI void glfwSetX11SelectionString(const char* string) GLFWAPI void glfwSetX11SelectionString(const char* string)
{ {
assert(string != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (_glfw.platform.platformID != GLFW_PLATFORM_X11) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -3352,8 +3354,6 @@ GLFWAPI void glfwSetX11SelectionString(const char* string)
return; return;
} }
assert(string != NULL);
_glfw_free(_glfw.x11.primarySelectionString); _glfw_free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = _glfw_strdup(string); _glfw.x11.primarySelectionString = _glfw_strdup(string);

View File

@ -36,14 +36,6 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
static bool needs_update;
static void window_close_callback(GLFWwindow* window)
{
needs_update = true;
}
static void error_callback(int error, const char* description) static void error_callback(int error, const char* description)
{ {
@ -53,15 +45,7 @@ static void error_callback(int error, const char* description)
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GLFW_TRUE); glfwSetWindowShouldClose(window, GLFW_TRUE);
needs_update = true;
}
}
static void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
needs_update = true;
} }
static float nrand(void) static float nrand(void)
@ -88,11 +72,8 @@ int main(void)
} }
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glfwSwapInterval(0);
gladLoadGL(glfwGetProcAddress); gladLoadGL(glfwGetProcAddress);
glfwSetWindowCloseCallback(window, window_close_callback);
glfwSetKeyCallback(window, key_callback); glfwSetKeyCallback(window, key_callback);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
@ -106,18 +87,8 @@ int main(void)
glClearColor(r / l, g / l, b / l, 1.f); glClearColor(r / l, g / l, b / l, 1.f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window); glfwSwapBuffers(window);
needs_update = false;
const double start = glfwGetTime(); glfwWaitEventsTimeout(1.0);
while (!needs_update)
{
const double elapsed = glfwGetTime() - start;
if (elapsed >= 1.0)
needs_update = true;
else
glfwWaitEventsTimeout(1.0 - elapsed);
}
} }
glfwDestroyWindow(window); glfwDestroyWindow(window);