Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-06-20 04:38:47 +0300
committerCampbell Barton <campbell@blender.org>2022-06-20 05:12:05 +0300
commita76c1ddecc5c0026f35fde21db53cb8eea26c4ac (patch)
tree9fcff3ceffede79b47ba76c5667110de035c0e3b
parent6e8217d35e0ba920abf423f3e442c33c36ed1bef (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.
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp33
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);