[Bf-blender-cvs] [827fa817673] master: Fix cursor coordinates being quantized to the window scale in Wayland

Campbell Barton noreply at git.blender.org
Tue Jun 14 08:59:43 CEST 2022


Commit: 827fa8176737f822b7f8d2354b05e59976c7101a
Author: Campbell Barton
Date:   Tue Jun 14 15:54:17 2022 +1000
Branches: master
https://developer.blender.org/rB827fa8176737f822b7f8d2354b05e59976c7101a

Fix cursor coordinates being quantized to the window scale in Wayland

- Apply the scale before converting cursor coordinates to int.
- Store sub-pixel cursor coordinates internally since
  this is what Wayland uses.
- Use `wl_fixed_t xy[2]` for storing coordinates as it simplifies
  assigning/passing x/y coordinates to an argument / variable.
- Also fix drag-and-drop coordinates which ignored scale.

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

M	intern/ghost/intern/GHOST_SystemWayland.cpp

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

diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index dceff4ef2b4..9e683ceb437 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -107,7 +107,8 @@ struct data_offer_t {
   struct wl_data_offer *id;
   std::atomic<bool> in_use;
   struct {
-    int x, y;
+    /** Compatible with #input_t.xy coordinates. */
+    wl_fixed_t xy[2];
   } dnd;
 };
 
@@ -137,7 +138,23 @@ struct input_t {
 
   uint32_t pointer_serial;
   uint32_t tablet_serial;
-  int x, y;
+
+  /** Use to check if the last cursor input was tablet or pointer. */
+  uint32_t cursor_serial;
+
+  /**
+   * High precision mouse coordinates (pointer or tablet).
+   *
+   * The following example converts these values to screen coordinates.
+   * \code{.cc}
+   * const wl_fixed_t scale = win->scale();
+   * const int event_xy[2] = {
+   *   wl_fixed_to_int(scale * input->xy[0]),
+   *   wl_fixed_to_int(scale * input->xy[1]),
+   * };
+   * \endocde
+   */
+  wl_fixed_t xy[2];
   GHOST_Buttons buttons;
   struct cursor_t cursor;
 
@@ -544,18 +561,19 @@ static void relative_pointer_relative_motion(
     wl_fixed_t /*dy_unaccel*/)
 {
   input_t *input = static_cast<input_t *>(data);
-
-  input->x += wl_fixed_to_int(dx);
-  input->y += wl_fixed_to_int(dy);
-
-  GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
-      wl_surface_get_user_data(input->focus_pointer));
+  GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(get_window(input->focus_pointer));
+  if (win == nullptr) {
+    return;
+  }
+  const wl_fixed_t scale = win->scale();
+  input->xy[0] += dx / scale;
+  input->xy[1] += dy / scale;
 
   input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                  GHOST_kEventCursorMove,
                                                  win,
-                                                 input->x,
-                                                 input->y,
+                                                 wl_fixed_to_int(scale * input->xy[0]),
+                                                 wl_fixed_to_int(scale * input->xy[1]),
                                                  GHOST_TABLET_DATA_NONE));
 }
 
@@ -573,16 +591,20 @@ static void dnd_events(const input_t *const input, const GHOST_TEventType event)
 {
   /* NOTE: `input->data_offer_dnd_mutex` must already be locked. */
   const uint64_t time = input->system->getMilliSeconds();
-  GHOST_IWindow *const window = static_cast<GHOST_WindowWayland *>(
+  GHOST_WindowWayland *const win = static_cast<GHOST_WindowWayland *>(
       wl_surface_get_user_data(input->focus_dnd));
+  if (!win) {
+    return;
+  }
+  const wl_fixed_t scale = win->scale();
+  const int event_xy[2] = {
+      wl_fixed_to_int(scale * input->data_offer_dnd->dnd.xy[0]),
+      wl_fixed_to_int(scale * input->data_offer_dnd->dnd.xy[1]),
+  };
+
   for (const std::string &type : mime_preference_order) {
-    input->system->pushEvent(new GHOST_EventDragnDrop(time,
-                                                      event,
-                                                      mime_dnd.at(type),
-                                                      window,
-                                                      input->data_offer_dnd->dnd.x,
-                                                      input->data_offer_dnd->dnd.y,
-                                                      nullptr));
+    input->system->pushEvent(new GHOST_EventDragnDrop(
+        time, event, mime_dnd.at(type), win, event_xy[0], event_xy[1], nullptr));
   }
 }
 
@@ -759,8 +781,8 @@ static void data_device_enter(void *data,
   data_offer_t *data_offer = input->data_offer_dnd;
 
   data_offer->in_use.store(true);
-  data_offer->dnd.x = wl_fixed_to_int(x);
-  data_offer->dnd.y = wl_fixed_to_int(y);
+  data_offer->dnd.xy[0] = x;
+  data_offer->dnd.xy[1] = y;
 
   wl_data_offer_set_actions(id,
                             WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
@@ -799,8 +821,9 @@ static void data_device_motion(void *data,
   input_t *input = static_cast<input_t *>(data);
   std::lock_guard lock{input->data_offer_dnd_mutex};
 
-  input->data_offer_dnd->dnd.x = wl_fixed_to_int(x);
-  input->data_offer_dnd->dnd.y = wl_fixed_to_int(y);
+  input->data_offer_dnd->dnd.xy[0] = x;
+  input->data_offer_dnd->dnd.xy[1] = y;
+
   dnd_events(input, GHOST_kEventDraggingUpdated);
 }
 
@@ -820,8 +843,7 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
                       data_offer_t *data_offer,
                       wl_surface *surface,
                       const std::string mime_receive) {
-    const int x = data_offer->dnd.x;
-    const int y = data_offer->dnd.y;
+    const wl_fixed_t *xy = data_offer->dnd.xy;
 
     const std::string data = read_pipe(data_offer, mime_receive, nullptr);
 
@@ -863,12 +885,14 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
         flist->strings[i] = static_cast<uint8_t *>(malloc((uris[i].size() + 1) * sizeof(uint8_t)));
         memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1);
       }
+
+      const wl_fixed_t scale = win->scale();
       system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
                                                  GHOST_kEventDraggingDropDone,
                                                  GHOST_kDragnDropTypeFilenames,
                                                  win,
-                                                 x,
-                                                 y,
+                                                 wl_fixed_to_int(scale * xy[0]),
+                                                 wl_fixed_to_int(scale * xy[1]),
                                                  flist));
     }
     else if (mime_receive == mime_text_plain || mime_receive == mime_text_utf8) {
@@ -1052,17 +1076,19 @@ static void pointer_enter(void *data,
 
   input_t *input = static_cast<input_t *>(data);
   input->pointer_serial = serial;
-  input->x = win->scale() * wl_fixed_to_int(surface_x);
-  input->y = win->scale() * wl_fixed_to_int(surface_y);
+  input->cursor_serial = serial;
+  input->xy[0] = surface_x;
+  input->xy[1] = surface_y;
   input->focus_pointer = surface;
 
   win->setCursorShape(win->getCursorShape());
 
+  const wl_fixed_t scale = win->scale();
   input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                  GHOST_kEventCursorMove,
                                                  static_cast<GHOST_WindowWayland *>(win),
-                                                 input->x,
-                                                 input->y,
+                                                 wl_fixed_to_int(scale * input->xy[0]),
+                                                 wl_fixed_to_int(scale * input->xy[1]),
                                                  GHOST_TABLET_DATA_NONE));
 }
 
@@ -1095,14 +1121,15 @@ static void pointer_motion(void *data,
     return;
   }
 
-  input->x = win->scale() * wl_fixed_to_int(surface_x);
-  input->y = win->scale() * wl_fixed_to_int(surface_y);
+  input->xy[0] = surface_x;
+  input->xy[1] = surface_y;
 
+  const wl_fixed_t scale = win->scale();
   input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                  GHOST_kEventCursorMove,
                                                  win,
-                                                 input->x,
-                                                 input->y,
+                                                 wl_fixed_to_int(scale * input->xy[0]),
+                                                 wl_fixed_to_int(scale * input->xy[1]),
                                                  GHOST_TABLET_DATA_NONE));
 }
 
@@ -1253,6 +1280,8 @@ static void tablet_tool_proximity_in(void *data,
 
   input->focus_tablet = surface;
   input->tablet_serial = serial;
+  input->cursor_serial = serial;
+
   input->data_source_serial = serial;
 
   /* Update #GHOST_TabletData. */
@@ -1333,14 +1362,15 @@ static void tablet_tool_motion(void *data,
     return;
   }
 
-  input->x = win->scale() * wl_fixed_to_int(x);
-  input->y = win->scale() * wl_fixed_to_int(y);
+  input->xy[0] = x;
+  input->xy[1] = y;
 
+  const wl_fixed_t scale = win->scale();
   input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                  GHOST_kEventCursorMove,
                                                  win,
-                                                 input->x,
-                                                 input->y,
+                                                 wl_fixed_to_int(scale * input->xy[0]),
+                                                 wl_fixed_to_int(scale * input->xy[1]),
                                                  tool_input->data));
 }
 
@@ -2116,13 +2146,26 @@ uint8_t GHOST_SystemWayland::getNumDisplays() const
 
 GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) const
 {
-  if (d->inputs.empty() ||
-      (d->inputs[0]->focus_pointer == nullptr && d->inputs[0]->focus_tablet == nullptr)) {
+  if (d->inputs.empty()) {
+    return GHOST_kFailure;
+  }
+
+  input_t *input = d->inputs[0];
+  struct wl_surface *surface = nullptr;
+  if (input->pointer_serial == input->cursor_serial) {
+    surface = input->focus_pointer;
+  }
+  else if (input->tablet_serial == input->cursor_serial) {
+    surface = input->focus_tablet;
+  }
+  if (!surface) {
     return GHOST_kFailure;
   }
 
-  x = d->inputs[0]->x;
-  y = d->inputs[0]->y;
+  GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface));
+  const wl_fixed_t scale = win->scale();
+  x = wl_fixed_to_int(scale * input->xy[0]);
+  y = wl_fixed_to_int(scale * input->xy[1]);
   return GHOST_kSuccess;
 }
 
@@ -2556,30 +2599,36 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
       if (mode_current == GHOST_kGrabWr

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list