[Bf-blender-cvs] [0e88c2fc593] master: GHOST/Wayland: split pointer/tablet state into separate structs

Campbell Barton noreply at git.blender.org
Mon Jun 27 07:58:21 CEST 2022


Commit: 0e88c2fc59373974d0d259b651f6ddfe45fd0005
Author: Campbell Barton
Date:   Mon Jun 27 15:09:00 2022 +1000
Branches: master
https://developer.blender.org/rB0e88c2fc59373974d0d259b651f6ddfe45fd0005

GHOST/Wayland: split pointer/tablet state into separate structs

For Wayland the mouse & tablet are separate devices with their
own location, button-pressed state and focused window.
Split internal state storage so they're separate.

Also track mouse button press/release state without needing focused
windows.

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

M	intern/ghost/intern/GHOST_SystemWayland.cpp

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

diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 66d0902c0ca..d4bd2c75886 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -174,6 +174,51 @@ struct input_grab_state_t {
   bool use_confine = false;
 };
 
+/**
+ * State of the pointing device (tablet or mouse).
+ */
+struct input_state_pointer_t {
+  /**
+   * High precision coordinates.
+   *
+   * Mapping to pixels requires the window scale.
+   * 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_state->xy[0]),
+   *   wl_fixed_to_int(scale * input_state->xy[1]),
+   * };
+   * \endcode
+   */
+  wl_fixed_t xy[2] = {0, 0};
+
+  /** The serial of the last used pointer or tablet. */
+  uint32_t serial = 0;
+
+  /**
+   * The surface last used with this pointing device
+   * (events with this pointing device will be sent here).
+   */
+  struct wl_surface *wl_surface = nullptr;
+
+  GHOST_Buttons buttons = GHOST_Buttons();
+};
+
+/**
+ * State of the keyboard.
+ */
+struct input_state_keyboard_t {
+  /** The serial of the last used pointer or tablet. */
+  uint32_t serial = 0;
+
+  /**
+   * The surface last used with this pointing device
+   * (events with this pointing device will be sent here).
+   */
+  struct wl_surface *wl_surface = nullptr;
+};
+
 struct input_t {
   GHOST_SystemWayland *system = nullptr;
 
@@ -186,31 +231,20 @@ struct input_t {
   /** All currently active tablet tools (needed for changing the cursor). */
   std::unordered_set<zwp_tablet_tool_v2 *> tablet_tools;
 
-  uint32_t pointer_serial = 0;
-  uint32_t tablet_serial = 0;
-
   /** Use to check if the last cursor input was tablet or pointer. */
-  uint32_t cursor_serial = 0;
+  uint32_t cursor_source_serial = 0;
 
-  /**
-   * 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]),
-   * };
-   * \endcode
-   */
-  wl_fixed_t xy[2] = {0, 0};
+  input_state_pointer_t pointer;
+
+  /** Mostly this can be interchanged with `pointer` however it can't be locked/confined. */
+  input_state_pointer_t tablet;
+
+  input_state_keyboard_t keyboard;
 
 #ifdef USE_GNOME_CONFINE_HACK
-  bool xy_software_confine = false;
+  bool use_pointer_software_confine = false;
 #endif
 
-  GHOST_Buttons buttons = GHOST_Buttons();
   struct cursor_t cursor;
 
   struct zwp_relative_pointer_v1 *relative_pointer = nullptr;
@@ -219,6 +253,7 @@ struct input_t {
 
   struct xkb_context *xkb_context = nullptr;
   struct xkb_state *xkb_state = nullptr;
+
   struct {
     /** Key repetition in character per second. */
     int32_t rate = 0;
@@ -228,9 +263,6 @@ struct input_t {
     GHOST_ITimerTask *timer = nullptr;
   } key_repeat;
 
-  struct wl_surface *focus_tablet = nullptr;
-  struct wl_surface *focus_pointer = nullptr;
-  struct wl_surface *focus_keyboard = nullptr;
   struct wl_surface *focus_dnd = nullptr;
 
   struct wl_data_device *data_device = nullptr;
@@ -304,6 +336,17 @@ static void ghost_wayland_log_handler(const char *msg, va_list arg)
   }
 }
 
+static input_state_pointer_t *input_state_pointer_active(input_t *input)
+{
+  if (input->pointer.serial == input->cursor_source_serial) {
+    return &input->pointer;
+  }
+  if (input->tablet.serial == input->cursor_source_serial) {
+    return &input->tablet;
+  }
+  return nullptr;
+}
+
 static void display_destroy(display_t *d)
 {
   if (d->data_device_manager) {
@@ -641,11 +684,11 @@ static void relative_pointer_handle_relative_motion_impl(input_t *input,
 {
   const wl_fixed_t scale = win->scale();
 
-  input->xy[0] = xy[0];
-  input->xy[1] = xy[1];
+  input->pointer.xy[0] = xy[0];
+  input->pointer.xy[1] = xy[1];
 
 #ifdef USE_GNOME_CONFINE_HACK
-  if (input->xy_software_confine) {
+  if (input->use_pointer_software_confine) {
     GHOST_Rect bounds;
     win->getClientBounds(bounds);
     /* Needed or the cursor is considered outside the window and doesn't restore the location. */
@@ -656,14 +699,14 @@ static void relative_pointer_handle_relative_motion_impl(input_t *input,
     bounds.m_t = wl_fixed_from_int(bounds.m_t) / scale;
     bounds.m_r = wl_fixed_from_int(bounds.m_r) / scale;
     bounds.m_b = wl_fixed_from_int(bounds.m_b) / scale;
-    bounds.clampPoint(input->xy[0], input->xy[1]);
+    bounds.clampPoint(input->pointer.xy[0], input->pointer.xy[1]);
   }
 #endif
   input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                  GHOST_kEventCursorMove,
                                                  win,
-                                                 wl_fixed_to_int(scale * input->xy[0]),
-                                                 wl_fixed_to_int(scale * input->xy[1]),
+                                                 wl_fixed_to_int(scale * input->pointer.xy[0]),
+                                                 wl_fixed_to_int(scale * input->pointer.xy[1]),
                                                  GHOST_TABLET_DATA_NONE));
 }
 
@@ -678,14 +721,14 @@ static void relative_pointer_handle_relative_motion(
     const wl_fixed_t /*dy_unaccel*/)
 {
   input_t *input = static_cast<input_t *>(data);
-  GHOST_WindowWayland *win = window_from_surface(input->focus_pointer);
+  GHOST_WindowWayland *win = window_from_surface(input->pointer.wl_surface);
   if (!win) {
     return;
   }
   const wl_fixed_t scale = win->scale();
   const wl_fixed_t xy_next[2] = {
-      input->xy[0] + dx / scale,
-      input->xy[1] + dy / scale,
+      input->pointer.xy[0] + (dx / scale),
+      input->pointer.xy[1] + (dy / scale),
   };
   relative_pointer_handle_relative_motion_impl(input, win, xy_next);
 }
@@ -1195,11 +1238,11 @@ static void pointer_handle_enter(void *data,
   win->activate();
 
   input_t *input = static_cast<input_t *>(data);
-  input->pointer_serial = serial;
-  input->cursor_serial = serial;
-  input->xy[0] = surface_x;
-  input->xy[1] = surface_y;
-  input->focus_pointer = surface;
+  input->cursor_source_serial = serial;
+  input->pointer.serial = serial;
+  input->pointer.xy[0] = surface_x;
+  input->pointer.xy[1] = surface_y;
+  input->pointer.wl_surface = surface;
 
   win->setCursorShape(win->getCursorShape());
 
@@ -1207,8 +1250,8 @@ static void pointer_handle_enter(void *data,
   input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                  GHOST_kEventCursorMove,
                                                  static_cast<GHOST_WindowWayland *>(win),
-                                                 wl_fixed_to_int(scale * input->xy[0]),
-                                                 wl_fixed_to_int(scale * input->xy[1]),
+                                                 wl_fixed_to_int(scale * input->pointer.xy[0]),
+                                                 wl_fixed_to_int(scale * input->pointer.xy[1]),
                                                  GHOST_TABLET_DATA_NONE));
 }
 
@@ -1217,8 +1260,8 @@ static void pointer_handle_leave(void *data,
                                  const uint32_t /*serial*/,
                                  struct wl_surface *surface)
 {
-  /* First clear the `focus_pointer`, since the window won't exist when closing the window. */
-  static_cast<input_t *>(data)->focus_pointer = nullptr;
+  /* First clear the `pointer.wl_surface`, since the window won't exist when closing the window. */
+  static_cast<input_t *>(data)->pointer.wl_surface = nullptr;
 
   GHOST_IWindow *win = window_from_surface(surface);
   if (!win) {
@@ -1234,20 +1277,19 @@ static void pointer_handle_motion(void *data,
                                   const wl_fixed_t surface_y)
 {
   input_t *input = static_cast<input_t *>(data);
-  GHOST_WindowWayland *win = window_from_surface(input->focus_pointer);
+  input->pointer.xy[0] = surface_x;
+  input->pointer.xy[1] = surface_y;
+
+  GHOST_WindowWayland *win = window_from_surface(input->pointer.wl_surface);
   if (!win) {
     return;
   }
-
-  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,
-                                                 wl_fixed_to_int(scale * input->xy[0]),
-                                                 wl_fixed_to_int(scale * input->xy[1]),
+                                                 wl_fixed_to_int(scale * input->pointer.xy[0]),
+                                                 wl_fixed_to_int(scale * input->pointer.xy[1]),
                                                  GHOST_TABLET_DATA_NONE));
 }
 
@@ -1259,10 +1301,6 @@ static void pointer_handle_button(void *data,
                                   const uint32_t state)
 {
   input_t *input = static_cast<input_t *>(data);
-  GHOST_IWindow *win = window_from_surface(input->focus_pointer);
-  if (!win) {
-    return;
-  }
 
   GHOST_TEventType etype = GHOST_kEventUnknown;
   switch (state) {
@@ -1300,7 +1338,13 @@ static void pointer_handle_button(void *data,
   }
 
   input->data_source_serial = serial;
-  input->buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
+  input->pointer.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
+
+  GHOST_IWindow *win = window_from_surface(input->pointer.wl_surface);
+  if (!win) {
+    return;
+  }
+
   input->system->pushEvent(new GHOST_EventButton(
       input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
 }
@@ -1312,15 +1356,15 @@ static void pointer_handle_axis(void *data,
                                 const wl_fixed_t value)
 {
   input_t *input = static_cast<input_t *>(data);
-  GHOS

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list