[Bf-blender-cvs] [8b8fbffeea2] master: Fix software cursor being used with absolute events in Wayland

Campbell Barton noreply at git.blender.org
Thu Jun 9 02:11:41 CEST 2022


Commit: 8b8fbffeea21a7f063ee60ab95113e0f14e38555
Author: Campbell Barton
Date:   Thu Jun 9 10:02:15 2022 +1000
Branches: master
https://developer.blender.org/rB8b8fbffeea21a7f063ee60ab95113e0f14e38555

Fix software cursor being used with absolute events in Wayland

The software cursor was being enabled with absolute events,
causing a problem with absolute tablet events.

This caused both cursors to be visible at once when using a tablet
(with D15152 applied).

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

M	intern/ghost/GHOST_C-api.h
M	intern/ghost/GHOST_IWindow.h
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_Window.cpp
M	intern/ghost/intern/GHOST_Window.h
M	source/blender/windowmanager/intern/wm_draw.c

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

diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 57714083656..ad19efadba5 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -402,9 +402,10 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
                                               int32_t x,
                                               int32_t y);
 
-GHOST_TSuccess GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle,
-                                        GHOST_TAxisFlag *r_wrap_axis,
-                                        int r_bounds[4]);
+void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle,
+                              GHOST_TGrabCursorMode *r_mode,
+                              GHOST_TAxisFlag *r_wrap_axis,
+                              int r_bounds[4]);
 
 /**
  * Grabs the cursor for a modal operation, to keep receiving
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 681ad9c5b07..7927190de04 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -256,7 +256,9 @@ class GHOST_IWindow {
 
   virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) = 0;
 
-  virtual GHOST_TSuccess getCursorGrabState(GHOST_TAxisFlag &axis_flag, GHOST_Rect &bounds) = 0;
+  virtual void getCursorGrabState(GHOST_TGrabCursorMode &mode,
+                                  GHOST_TAxisFlag &axis_flag,
+                                  GHOST_Rect &bounds) = 0;
 
   /**
    * Test if the standard cursor shape is supported by current platform.
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index f4c978a88d4..8dd31a88ad3 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -376,21 +376,18 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
       mode, wrap_axis, bounds ? &bounds_rect : nullptr, mouse_ungrab_xy ? mouse_xy : nullptr);
 }
 
-GHOST_TSuccess GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle,
-                                        GHOST_TAxisFlag *r_axis_flag,
-                                        int r_bounds[4])
+void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle,
+                              GHOST_TGrabCursorMode *r_mode,
+                              GHOST_TAxisFlag *r_axis_flag,
+                              int r_bounds[4])
 {
   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
   GHOST_Rect bounds_rect;
-  if (!window->getCursorGrabState(*r_axis_flag, bounds_rect)) {
-    return GHOST_kFailure;
-  }
-
+  window->getCursorGrabState(*r_mode, *r_axis_flag, bounds_rect);
   r_bounds[0] = bounds_rect.m_l;
   r_bounds[1] = bounds_rect.m_t;
   r_bounds[2] = bounds_rect.m_r;
   r_bounds[3] = bounds_rect.m_b;
-  return GHOST_kSuccess;
 }
 
 GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index 12963abf128..de7c5422d3f 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -162,12 +162,11 @@ GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds)
   return (bounds.m_l == -1 && bounds.m_r == -1) ? GHOST_kFailure : GHOST_kSuccess;
 }
 
-GHOST_TSuccess GHOST_Window::getCursorGrabState(GHOST_TAxisFlag &wrap_axis, GHOST_Rect &bounds)
+void GHOST_Window::getCursorGrabState(GHOST_TGrabCursorMode &mode,
+                                      GHOST_TAxisFlag &wrap_axis,
+                                      GHOST_Rect &bounds)
 {
-  if (m_cursorGrab == GHOST_kGrabDisable) {
-    return GHOST_kFailure;
-  }
-
+  mode = m_cursorGrab;
   if (m_cursorGrab == GHOST_kGrabWrap) {
     bounds = m_cursorGrabBounds;
     wrap_axis = m_cursorGrabAxis;
@@ -179,7 +178,6 @@ GHOST_TSuccess GHOST_Window::getCursorGrabState(GHOST_TAxisFlag &wrap_axis, GHOS
     bounds.m_b = -1;
     wrap_axis = GHOST_kGrabAxisNone;
   }
-  return GHOST_kSuccess;
 }
 
 GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index b0042a33a00..adbc29eb84e 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -152,7 +152,9 @@ class GHOST_Window : public GHOST_IWindow {
    */
   GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds);
 
-  GHOST_TSuccess getCursorGrabState(GHOST_TAxisFlag &axis_flag, GHOST_Rect &bounds);
+  void getCursorGrabState(GHOST_TGrabCursorMode &mode,
+                          GHOST_TAxisFlag &axis_flag,
+                          GHOST_Rect &bounds);
 
   /**
    * Sets the progress bar value displayed in the window/application icon
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 810cc9001fe..c2a63c9db7a 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -137,6 +137,13 @@ static struct {
     .winid = -1,
 };
 
+/** Reuse the result from #GHOST_GetCursorGrabState. */
+struct GrabState {
+  GHOST_TGrabCursorMode mode;
+  GHOST_TAxisFlag wrap_axis;
+  int bounds[4];
+};
+
 static bool wm_software_cursor_needed(void)
 {
   if (UNLIKELY(g_software_cursor.enabled == -1)) {
@@ -145,10 +152,19 @@ static bool wm_software_cursor_needed(void)
   return g_software_cursor.enabled;
 }
 
-static bool wm_software_cursor_needed_for_window(const wmWindow *win)
+static bool wm_software_cursor_needed_for_window(const wmWindow *win, struct GrabState *grab_state)
 {
   BLI_assert(wm_software_cursor_needed());
-  return (win->grabcursor == GHOST_kGrabWrap) && GHOST_GetCursorVisibility(win->ghostwin);
+  if (GHOST_GetCursorVisibility(win->ghostwin)) {
+    /* NOTE: The value in `win->grabcursor` can't be used as it
+     * doesn't always match GHOST's value in the case of tablet events. */
+    GHOST_GetCursorGrabState(
+        win->ghostwin, &grab_state->mode, &grab_state->wrap_axis, grab_state->bounds);
+    if (grab_state->mode == GHOST_kGrabWrap) {
+      return true;
+    }
+  }
+  return false;
 }
 
 static bool wm_software_cursor_motion_test(const wmWindow *win)
@@ -173,28 +189,24 @@ static void wm_software_cursor_motion_clear(void)
   g_software_cursor.xy[1] = -1;
 }
 
-static void wm_software_cursor_draw(wmWindow *win)
+static void wm_software_cursor_draw(wmWindow *win, const struct GrabState *grab_state)
 {
   int x = win->eventstate->xy[0];
   int y = win->eventstate->xy[1];
 
-  int bounds[4];
-  GHOST_TAxisFlag wrap_axis = 0;
-  if (GHOST_GetCursorGrabState(win->ghostwin, &wrap_axis, bounds) != GHOST_kFailure) {
-    if (wrap_axis & GHOST_kAxisX) {
-      const int min = bounds[0];
-      const int max = bounds[2];
-      if (min != max) {
-        x = mod_i(x - min, max - min) + min;
-      }
+  if (grab_state->wrap_axis & GHOST_kAxisX) {
+    const int min = grab_state->bounds[0];
+    const int max = grab_state->bounds[2];
+    if (min != max) {
+      x = mod_i(x - min, max - min) + min;
     }
-    if (wrap_axis & GHOST_kGrabAxisY) {
-      const int height = WM_window_pixels_y(win);
-      const int min = height - bounds[1];
-      const int max = height - bounds[3];
-      if (min != max) {
-        y = mod_i(y - max, min - max) + max;
-      }
+  }
+  if (grab_state->wrap_axis & GHOST_kGrabAxisY) {
+    const int height = WM_window_pixels_y(win);
+    const int min = height - grab_state->bounds[1];
+    const int max = height - grab_state->bounds[3];
+    if (min != max) {
+      y = mod_i(y - max, min - max) + max;
     }
   }
 
@@ -979,8 +991,9 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
   }
 
   if (wm_software_cursor_needed()) {
-    if (wm_software_cursor_needed_for_window(win)) {
-      wm_software_cursor_draw(win);
+    struct GrabState grab_state;
+    if (wm_software_cursor_needed_for_window(win, &grab_state)) {
+      wm_software_cursor_draw(win, &grab_state);
       wm_software_cursor_motion_update(win);
     }
     else {
@@ -1139,7 +1152,9 @@ static bool wm_draw_update_test_window(Main *bmain, bContext *C, wmWindow *win)
   }
 
   if (wm_software_cursor_needed()) {
-    if (wm_software_cursor_needed_for_window(win) && wm_software_cursor_motion_test(win)) {
+    struct GrabState grab_state;
+    if (wm_software_cursor_needed_for_window(win, &grab_state) &&
+        wm_software_cursor_motion_test(win)) {
       return true;
     }
   }



More information about the Bf-blender-cvs mailing list