diff options
author | Campbell Barton <campbell@blender.org> | 2022-06-20 04:38:47 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-06-20 05:12:05 +0300 |
commit | a76c1ddecc5c0026f35fde21db53cb8eea26c4ac (patch) | |
tree | 9fcff3ceffede79b47ba76c5667110de035c0e3b /intern | |
parent | 6e8217d35e0ba920abf423f3e442c33c36ed1bef (diff) |
Fix setting the custom cursor for Hi-DPI displays in Wayland
Changing the cursor would intermittently close Blender's window
(without crashing).
This happened because the size of a cursor must be the a multiple of the
scale, for themed cursor this is always true but with custom cursors
it's not.
Separate theme scale from custom cursor scale to avoid this bug.
In the future we can support Hi-DPI custom cursors, for now they're
scale is always set to 1.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 6a4d1827a80..37648c853e3 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -113,7 +113,9 @@ struct cursor_t { std::string theme_name; /** Outputs on which the cursor is visible. */ std::unordered_set<const output_t *> outputs; - int scale = 1; + + int theme_scale = 1; + int custom_scale = 1; }; /** @@ -1091,9 +1093,11 @@ static bool update_cursor_scale(cursor_t &cursor, wl_shm *shm) } } - if (scale > 0 && cursor.scale != scale) { - cursor.scale = scale; - wl_surface_set_buffer_scale(cursor.wl_surface, scale); + if (scale > 0 && cursor.theme_scale != scale) { + cursor.theme_scale = scale; + if (!cursor.is_custom) { + wl_surface_set_buffer_scale(cursor.wl_surface, scale); + } wl_cursor_theme_destroy(cursor.wl_theme); cursor.wl_theme = wl_cursor_theme_load(cursor.theme_name.c_str(), scale * cursor.size, shm); return true; @@ -2550,8 +2554,9 @@ void GHOST_SystemWayland::setSelection(const std::string &selection) static void cursor_buffer_show(const input_t *input) { const cursor_t *c = &input->cursor; - const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / c->scale; - const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / c->scale; + const int scale = c->is_custom ? c->custom_scale : c->theme_scale; + const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale; + const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale; wl_pointer_set_cursor( input->wl_pointer, input->pointer_serial, c->wl_surface, hotspot_x, hotspot_y); for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) { @@ -2582,15 +2587,22 @@ static void cursor_buffer_hide(const input_t *input) static void cursor_buffer_set(const input_t *input, wl_buffer *buffer) { const cursor_t *c = &input->cursor; + const int scale = c->is_custom ? c->custom_scale : c->theme_scale; + const bool visible = (c->visible && c->is_hardware); const int32_t image_size_x = int32_t(c->wl_image.width); const int32_t image_size_y = int32_t(c->wl_image.height); - const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / c->scale; - const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / c->scale; + /* This is a requirement of WAYLAND, when this isn't the case, + * it causes Blender's window to close intermittently. */ + GHOST_ASSERT((image_size_x % size) == 0 && (image_size_y % size) == 0, + "The size must be a multiple of the scale!"); + + const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale; + const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale; - wl_surface_set_buffer_scale(c->wl_surface, c->scale); + wl_surface_set_buffer_scale(c->wl_surface, scale); wl_surface_attach(c->wl_surface, buffer, 0, 0); wl_surface_damage(c->wl_surface, 0, 0, image_size_x, image_size_y); wl_surface_commit(c->wl_surface); @@ -2608,7 +2620,7 @@ static void cursor_buffer_set(const input_t *input, wl_buffer *buffer) /* FIXME: for some reason cursor scale is applied twice (when the scale isn't 1x), * this happens both in gnome-shell & KDE. Setting the surface scale here doesn't help. */ - wl_surface_set_buffer_scale(tool_input->cursor_surface, c->scale); + wl_surface_set_buffer_scale(tool_input->cursor_surface, scale); wl_surface_attach(tool_input->cursor_surface, buffer, 0, 0); wl_surface_damage(tool_input->cursor_surface, 0, 0, image_size_x, image_size_y); wl_surface_commit(tool_input->cursor_surface); @@ -2823,6 +2835,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap, cursor->visible = true; cursor->is_custom = true; + cursor->custom_scale = 1; /* TODO: support Hi-DPI custom cursors. */ cursor->wl_buffer = buffer; cursor->wl_image.width = uint32_t(sizex); cursor->wl_image.height = uint32_t(sizey); |