diff options
author | Campbell Barton <campbell@blender.org> | 2022-06-30 15:53:24 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-06-30 16:46:57 +0300 |
commit | 1cf64434ed1aa2a3be65c73c61e030745a597858 (patch) | |
tree | 590608470c26c59fb41e0e969697a7d895b6bdc7 | |
parent | 6bd2c6789b244a03bccdb254502567691c42b944 (diff) |
Fix accessing cursor position for GHOST/Wayland
GHOST_GetCursorPosition wasn't working properly under Wayland because
the last focused window didn't necessarily match the window used to call
wm_cursor_position_get(..).
Now the window passed into wm_cursor_position_get is passed to GHOST
so that window is used to access cursor coordinates.
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 92 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.h | 8 |
2 files changed, 74 insertions, 26 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index af629e83b19..cec06ed6a50 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -2649,58 +2649,100 @@ uint8_t GHOST_SystemWayland::getNumDisplays() const return d ? uint8_t(d->outputs.size()) : 0; } -GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) const +static GHOST_TSuccess getCursorPositionClientRelative_impl( + const input_state_pointer_t *input_state, + const GHOST_WindowWayland *win, + int32_t &x, + int32_t &y) { - if (d->inputs.empty()) { + const wl_fixed_t scale = win->scale(); + x = wl_fixed_to_int(scale * input_state->xy[0]); + y = wl_fixed_to_int(scale * input_state->xy[1]); + return GHOST_kSuccess; +} + +static GHOST_TSuccess setCursorPositionClientRelative_impl(input_t *input, + GHOST_WindowWayland *win, + const int32_t x, + const int32_t y) +{ + /* NOTE: WAYLAND doesn't support warping the cursor. + * However when grab is enabled, we already simulate a cursor location + * so that can be set to a new location. */ + if (!input->relative_pointer) { return GHOST_kFailure; } + const wl_fixed_t scale = win->scale(); + const wl_fixed_t xy_next[2] = { + wl_fixed_from_int(x) / scale, + wl_fixed_from_int(y) / scale, + }; + /* As the cursor was "warped" generate an event at the new location. */ + relative_pointer_handle_relative_motion_impl(input, win, xy_next); + + return GHOST_kSuccess; +} + +GHOST_TSuccess GHOST_SystemWayland::getCursorPositionClientRelative(const GHOST_IWindow *window, + int32_t &x, + int32_t &y) const +{ + if (d->inputs.empty()) { + return GHOST_kFailure; + } input_t *input = d->inputs[0]; input_state_pointer_t *input_state = input_state_pointer_active(input); - if (!input_state || !input_state->wl_surface) { return GHOST_kFailure; } + const GHOST_WindowWayland *win = static_cast<const GHOST_WindowWayland *>(window); + return getCursorPositionClientRelative_impl(input_state, win, x, y); +} - GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>( - wl_surface_get_user_data(input_state->wl_surface)); - if (!win) { +GHOST_TSuccess GHOST_SystemWayland::setCursorPositionClientRelative(GHOST_IWindow *window, + const int32_t x, + const int32_t y) +{ + if (d->inputs.empty()) { return GHOST_kFailure; } + input_t *input = d->inputs[0]; + GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(window); + return setCursorPositionClientRelative_impl(input, win, x, y); +} - const wl_fixed_t scale = win->scale(); - x = wl_fixed_to_int(scale * input_state->xy[0]); - y = wl_fixed_to_int(scale * input_state->xy[1]); - return GHOST_kSuccess; +GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) const +{ + if (d->inputs.empty()) { + return GHOST_kFailure; + } + input_t *input = d->inputs[0]; + input_state_pointer_t *input_state = input_state_pointer_active(input); + if (!input_state || !input_state->wl_surface) { + return GHOST_kFailure; + } + GHOST_WindowWayland *win = window_from_surface(input->pointer.wl_surface); + if (!win) { + return GHOST_kFailure; + } + return getCursorPositionClientRelative_impl(input_state, win, x, y); } GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(const int32_t x, const int32_t y) { - /* NOTE: WAYLAND doesn't support warping the cursor. - * However when grab is enabled, we already simulate a cursor location - * so that can be set to a new location. */ if (d->inputs.empty()) { return GHOST_kFailure; } input_t *input = d->inputs[0]; - if (!input->relative_pointer) { + if (!input->pointer.wl_surface) { return GHOST_kFailure; } - GHOST_WindowWayland *win = window_from_surface(input->pointer.wl_surface); if (!win) { return GHOST_kFailure; } - const wl_fixed_t scale = win->scale(); - const wl_fixed_t xy_next[2] = { - wl_fixed_from_int(x) / scale, - wl_fixed_from_int(y) / scale, - }; - - /* As the cursor was "warped" generate an event at the new location. */ - relative_pointer_handle_relative_motion_impl(input, win, xy_next); - - return GHOST_kSuccess; + return setCursorPositionClientRelative_impl(input, win, x, y); } void GHOST_SystemWayland::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index 972d16257eb..7f7bd021bda 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -79,8 +79,14 @@ class GHOST_SystemWayland : public GHOST_System { uint8_t getNumDisplays() const override; - GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const override; + GHOST_TSuccess getCursorPositionClientRelative(const GHOST_IWindow *window, + int32_t &x, + int32_t &y) const override; + GHOST_TSuccess setCursorPositionClientRelative(GHOST_IWindow *window, + int32_t x, + int32_t y) override; + GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const override; GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) override; void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const override; |