[Bf-blender-cvs] [443690604f4] master: Fix cursor display size with tablet input in GHOST/Wayland

Campbell Barton noreply at git.blender.org
Sat Jul 9 14:48:13 CEST 2022


Commit: 443690604f4ed5bdcf05cca40c8d6f1f88a1c29a
Author: Campbell Barton
Date:   Sat Jul 9 22:27:34 2022 +1000
Branches: master
https://developer.blender.org/rB443690604f4ed5bdcf05cca40c8d6f1f88a1c29a

Fix cursor display size with tablet input in GHOST/Wayland

The scale for tablet cursor surfaces was never set, making them display
larger. Now the outputs scale is set for mouse & tablet cursors.

===================================================================

M	intern/ghost/intern/GHOST_SystemWayland.cpp
M	intern/ghost/intern/GHOST_SystemWayland.h

===================================================================

diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 4b390615435..876f77732c2 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -146,10 +146,7 @@ struct cursor_t {
   size_t custom_data_size = 0;
   int size = 0;
   std::string theme_name;
-  /** Outputs on which the cursor is visible. */
-  std::unordered_set<const output_t *> outputs;
 
-  int theme_scale = 1;
   int custom_scale = 1;
 };
 
@@ -231,6 +228,11 @@ struct input_state_pointer_t {
    */
   wl_fixed_t xy[2] = {0, 0};
 
+  /** Outputs on which the cursor is visible. */
+  std::unordered_set<const output_t *> outputs;
+
+  int theme_scale = 1;
+
   /** The serial of the last used pointer or tablet. */
   uint32_t serial = 0;
 
@@ -396,6 +398,19 @@ static input_state_pointer_t *input_state_pointer_active(input_t *input)
   return nullptr;
 }
 
+static input_state_pointer_t *input_state_pointer_from_cursor_surface(input_t *input,
+                                                                      const wl_surface *wl_surface)
+{
+  if (ghost_wl_surface_own_cursor_pointer(wl_surface)) {
+    return &input->pointer;
+  }
+  if (ghost_wl_surface_own_cursor_tablet(wl_surface)) {
+    return &input->tablet;
+  }
+  GHOST_ASSERT(0, "Surface found without pointer/tablet tag");
+  return nullptr;
+}
+
 static void display_destroy(display_t *d)
 {
   if (d->data_device_manager) {
@@ -1358,19 +1373,22 @@ static const struct wl_buffer_listener cursor_buffer_listener = {
 static CLG_LogRef LOG_WL_CURSOR_SURFACE = {"ghost.wl.handle.cursor_surface"};
 #define LOG (&LOG_WL_CURSOR_SURFACE)
 
-static bool update_cursor_scale(cursor_t &cursor, wl_shm *shm)
+static bool update_cursor_scale(cursor_t &cursor,
+                                wl_shm *shm,
+                                input_state_pointer_t *input_state,
+                                wl_surface *cursor_surface)
 {
   int scale = 0;
-  for (const output_t *output : cursor.outputs) {
+  for (const output_t *output : input_state->outputs) {
     if (output->scale > scale) {
       scale = output->scale;
     }
   }
 
-  if (scale > 0 && cursor.theme_scale != scale) {
-    cursor.theme_scale = scale;
+  if (scale > 0 && input_state->theme_scale != scale) {
+    input_state->theme_scale = scale;
     if (!cursor.is_custom) {
-      wl_surface_set_buffer_scale(cursor.wl_surface, scale);
+      wl_surface_set_buffer_scale(cursor_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);
@@ -1380,7 +1398,7 @@ static bool update_cursor_scale(cursor_t &cursor, wl_shm *shm)
 }
 
 static void cursor_surface_handle_enter(void *data,
-                                        struct wl_surface * /*wl_surface*/,
+                                        struct wl_surface *wl_surface,
                                         struct wl_output *output)
 {
   if (!ghost_wl_output_own(output)) {
@@ -1390,13 +1408,14 @@ static void cursor_surface_handle_enter(void *data,
   CLOG_INFO(LOG, 2, "handle_enter");
 
   input_t *input = static_cast<input_t *>(data);
+  input_state_pointer_t *input_state = input_state_pointer_from_cursor_surface(input, wl_surface);
   const output_t *reg_output = ghost_wl_output_user_data(output);
-  input->cursor.outputs.insert(reg_output);
-  update_cursor_scale(input->cursor, input->system->shm());
+  input_state->outputs.insert(reg_output);
+  update_cursor_scale(input->cursor, input->system->shm(), input_state, wl_surface);
 }
 
 static void cursor_surface_handle_leave(void *data,
-                                        struct wl_surface * /*wl_surface*/,
+                                        struct wl_surface *wl_surface,
                                         struct wl_output *output)
 {
   if (!(output && ghost_wl_output_own(output))) {
@@ -1406,9 +1425,10 @@ static void cursor_surface_handle_leave(void *data,
   CLOG_INFO(LOG, 2, "handle_leave");
 
   input_t *input = static_cast<input_t *>(data);
+  input_state_pointer_t *input_state = input_state_pointer_from_cursor_surface(input, wl_surface);
   const output_t *reg_output = ghost_wl_output_user_data(output);
-  input->cursor.outputs.erase(reg_output);
-  update_cursor_scale(input->cursor, input->system->shm());
+  input_state->outputs.erase(reg_output);
+  update_cursor_scale(input->cursor, input->system->shm(), input_state, wl_surface);
 }
 
 static const struct wl_surface_listener cursor_surface_listener = {
@@ -1952,6 +1972,8 @@ static void tablet_seat_handle_tool_added(void *data,
 
   /* Every tool has it's own cursor surface. */
   tool_input->cursor_surface = wl_compositor_create_surface(input->system->compositor());
+  ghost_wl_surface_tag_cursor_tablet(tool_input->cursor_surface);
+
   wl_surface_add_listener(tool_input->cursor_surface, &cursor_surface_listener, (void *)input);
 
   zwp_tablet_tool_v2_add_listener(id, &tablet_tool_listner, tool_input);
@@ -2360,7 +2382,9 @@ static void seat_handle_capabilities(void *data,
       input->cursor.size = default_cursor_size;
     }
     wl_pointer_add_listener(input->wl_pointer, &pointer_listener, data);
+
     wl_surface_add_listener(input->cursor.wl_surface, &cursor_surface_listener, data);
+    ghost_wl_surface_tag_cursor_pointer(input->cursor.wl_surface);
   }
 
   if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
@@ -3211,19 +3235,30 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
 static void cursor_buffer_show(const input_t *input)
 {
   const cursor_t *c = &input->cursor;
-  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) {
-    tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
-        zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
-    zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
-                                  input->tablet.serial,
-                                  tool_input->cursor_surface,
-                                  hotspot_x,
-                                  hotspot_y);
+
+  if (input->wl_pointer) {
+    const int scale = c->is_custom ? c->custom_scale : input->pointer.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;
+    if (input->wl_pointer) {
+      wl_pointer_set_cursor(
+          input->wl_pointer, input->pointer.serial, c->wl_surface, hotspot_x, hotspot_y);
+    }
+  }
+
+  if (!input->tablet_tools.empty()) {
+    const int scale = c->is_custom ? c->custom_scale : input->tablet.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;
+    for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
+      tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
+          zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
+      zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
+                                    input->tablet.serial,
+                                    tool_input->cursor_surface,
+                                    hotspot_x,
+                                    hotspot_y);
+    }
   }
 }
 
@@ -3241,52 +3276,58 @@ static void cursor_buffer_hide(const input_t *input)
   }
 }
 
+static void cursor_buffer_set_surface_impl(const input_t *input,
+                                           wl_buffer *buffer,
+                                           struct wl_surface *wl_surface,
+                                           const int scale)
+{
+  const wl_cursor_image *wl_image = &input->cursor.wl_image;
+  const int32_t image_size_x = int32_t(wl_image->width);
+  const int32_t image_size_y = int32_t(wl_image->height);
+  GHOST_ASSERT((image_size_x % scale) == 0 && (image_size_y % scale) == 0,
+               "The size must be a multiple of the scale!");
+
+  wl_surface_set_buffer_scale(wl_surface, scale);
+  wl_surface_attach(wl_surface, buffer, 0, 0);
+  wl_surface_damage(wl_surface, 0, 0, image_size_x, image_size_y);
+  wl_surface_commit(wl_surface);
+}
+
 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 wl_cursor_image *wl_image = &input->cursor.wl_image;
   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);
-
   /* 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 % scale) == 0 && (image_size_y % scale) == 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, 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);
-
-  wl_pointer_set_cursor(input->wl_pointer,
-                        input->pointer.serial,
-                        visible ? c->wl_surface : nullptr,
-                        hotspot_x,
-                        hotspot_y);
+  if (input->wl_pointer) {
+    const int scale = c->is_custom ? c->custom_scale : input->pointer.theme_scale;
+    const int32_t hotspot_x = int32_t(wl_image->hotspot_x) / scale;
+    const int32_t hotspot_y = int32_t(wl_image->hotspot_y) / scale;
+    cursor_buffer_set_surface_impl(input, buffer, c->wl_surface, scale);
+    wl_pointer_set_cursor(input->wl_pointer,
+                          input->poi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list