[Bf-blender-cvs] [650a15fb9b9] master: Fix accessing windows from surfaces in Wayland

Campbell Barton noreply at git.blender.org
Fri Jul 1 07:25:32 CEST 2022


Commit: 650a15fb9b9cd32506454759a0c834d7535b8ee9
Author: Campbell Barton
Date:   Fri Jul 1 15:09:59 2022 +1000
Branches: master
https://developer.blender.org/rB650a15fb9b9cd32506454759a0c834d7535b8ee9

Fix accessing windows from surfaces in Wayland

This is a follow up to [0], where it was assumed flushing the output
would run the appropriate leave handlers & clear the keyboard & pointer
surfaces. While that's mostly true it's not guaranteed.

Resolve this by clearing the pointers when closing windows and add NULL
checks before accessing the windows.

Tested with Gnome, KDE & River compositors.

[0]: 58ccd8338e53423e223085094af2d35c76285c30

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

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

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

diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 6562387358d..fb34a72235c 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -783,13 +783,15 @@ static void relative_pointer_handle_relative_motion(
     const wl_fixed_t /*dy_unaccel*/)
 {
   input_t *input = static_cast<input_t *>(data);
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->pointer.wl_surface);
-  const wl_fixed_t scale = win->scale();
-  const wl_fixed_t xy_next[2] = {
-      input->pointer.xy[0] + (dx / scale),
-      input->pointer.xy[1] + (dy / scale),
-  };
-  relative_pointer_handle_relative_motion_impl(input, win, xy_next);
+  if (wl_surface *focus_surface = input->pointer.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    const wl_fixed_t scale = win->scale();
+    const wl_fixed_t xy_next[2] = {
+        input->pointer.xy[0] + (dx / scale),
+        input->pointer.xy[1] + (dy / scale),
+    };
+    relative_pointer_handle_relative_motion_impl(input, win, xy_next);
+  }
 }
 
 static const zwp_relative_pointer_v1_listener relative_pointer_listener = {
@@ -805,17 +807,19 @@ static const zwp_relative_pointer_v1_listener relative_pointer_listener = {
 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_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->focus_dnd);
-  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]),
-  };
+  if (wl_surface *focus_surface = input->focus_dnd) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    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), win, event_xy[0], event_xy[1], nullptr));
+    const uint64_t time = input->system->getMilliSeconds();
+    for (const std::string &type : mime_preference_order) {
+      input->system->pushEvent(new GHOST_EventDragnDrop(
+          time, event, mime_dnd.at(type), win, event_xy[0], event_xy[1], nullptr));
+    }
   }
 }
 
@@ -1071,7 +1075,7 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
       static constexpr const char *file_proto = "file://";
       static constexpr const char *crlf = "\r\n";
 
-      GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface);
+      GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_find(surface);
       GHOST_ASSERT(win != nullptr, "Unable to find window for drop event from surface");
 
       std::vector<std::string> uris;
@@ -1301,12 +1305,10 @@ static void pointer_handle_leave(void *data,
 {
   /* 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;
-  /* Use `from_surface_find_mut` because this callback runs when the window is has been closed. */
-  if (!surface) {
-    return;
+  if (surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface);
+    win->deactivate();
   }
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface);
-  win->deactivate();
 }
 
 static void pointer_handle_motion(void *data,
@@ -1319,14 +1321,16 @@ static void pointer_handle_motion(void *data,
   input->pointer.xy[0] = surface_x;
   input->pointer.xy[1] = surface_y;
 
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->pointer.wl_surface);
-  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->pointer.xy[0]),
-                                                 wl_fixed_to_int(scale * input->pointer.xy[1]),
-                                                 GHOST_TABLET_DATA_NONE));
+  if (wl_surface *focus_surface = input->pointer.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    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->pointer.xy[0]),
+                                                   wl_fixed_to_int(scale * input->pointer.xy[1]),
+                                                   GHOST_TABLET_DATA_NONE));
+  }
 }
 
 static void pointer_handle_button(void *data,
@@ -1376,9 +1380,11 @@ static void pointer_handle_button(void *data,
   input->data_source_serial = serial;
   input->pointer.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
 
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->pointer.wl_surface);
-  input->system->pushEvent(new GHOST_EventButton(
-      input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
+  if (wl_surface *focus_surface = input->pointer.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    input->system->pushEvent(new GHOST_EventButton(
+        input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
+  }
 }
 
 static void pointer_handle_axis(void *data,
@@ -1393,9 +1399,11 @@ static void pointer_handle_axis(void *data,
     return;
   }
 
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->pointer.wl_surface);
-  input->system->pushEvent(
-      new GHOST_EventWheel(input->system->getMilliSeconds(), win, std::signbit(value) ? +1 : -1));
+  if (wl_surface *focus_surface = input->pointer.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    input->system->pushEvent(new GHOST_EventWheel(
+        input->system->getMilliSeconds(), win, std::signbit(value) ? +1 : -1));
+  }
 }
 
 static const struct wl_pointer_listener pointer_listener = {
@@ -1509,9 +1517,11 @@ static void tablet_tool_handle_down(void *data,
   input->data_source_serial = serial;
   input->tablet.buttons.set(ebutton, true);
 
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->tablet.wl_surface);
-  input->system->pushEvent(new GHOST_EventButton(
-      input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
+  if (wl_surface *focus_surface = input->tablet.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    input->system->pushEvent(new GHOST_EventButton(
+        input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
+  }
 }
 
 static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/)
@@ -1523,9 +1533,11 @@ static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_
 
   input->tablet.buttons.set(ebutton, false);
 
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->tablet.wl_surface);
-  input->system->pushEvent(new GHOST_EventButton(
-      input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
+  if (wl_surface *focus_surface = input->tablet.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    input->system->pushEvent(new GHOST_EventButton(
+        input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
+  }
 }
 
 static void tablet_tool_handle_motion(void *data,
@@ -1593,8 +1605,10 @@ static void tablet_tool_handle_wheel(void *data,
 
   tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
   input_t *input = tool_input->input;
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->tablet.wl_surface);
-  input->system->pushEvent(new GHOST_EventWheel(input->system->getMilliSeconds(), win, clicks));
+  if (wl_surface *focus_surface = input->tablet.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    input->system->pushEvent(new GHOST_EventWheel(input->system->getMilliSeconds(), win, clicks));
+  }
 }
 static void tablet_tool_handle_button(void *data,
                                       struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
@@ -1631,9 +1645,11 @@ static void tablet_tool_handle_button(void *data,
   input->data_source_serial = serial;
   input->tablet.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
 
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->tablet.wl_surface);
-  input->system->pushEvent(new GHOST_EventButton(
-      input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
+  if (wl_surface *focus_surface = input->tablet.wl_surface) {
+    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    input->system->pushEvent(new GHOST_EventButton(
+        input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
+  }
 }
 static void tablet_tool_handle_frame(void *data,
                                      struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/,
@@ -1642,10 +1658,8 @@ static void tablet_tool_handle_frame(void *data,
   tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
   input_t *input = tool_input->input;
 
-  /* Use "find", unlike most other handlers because the window
-   * may have been closed before this

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list