[Bf-blender-cvs] [da00d62c491] master: Fix crash with window decorations (libdecor) in Wayland

Campbell Barton noreply at git.blender.org
Fri Jul 1 14:51:52 CEST 2022


Commit: da00d62c4913a71e116f74f874d7a17cfee9c14e
Author: Campbell Barton
Date:   Fri Jul 1 22:45:10 2022 +1000
Branches: master
https://developer.blender.org/rBda00d62c4913a71e116f74f874d7a17cfee9c14e

Fix crash with window decorations (libdecor) in Wayland

Surfaces from window decorations were passed into GHOST's listeners
since libdecor & GHOST share a connection.

This error introduced by recent changes that assumed surfaces passed to
GHOST's handler functions were owned by GHOST.

Tag GHOST surfaces & outputs to ensure GHOST only attempts to access
data it created.

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

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 6a419fc718d..c360423c256 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -786,7 +786,7 @@ static void relative_pointer_handle_relative_motion(
 {
   input_t *input = static_cast<input_t *>(data);
   if (wl_surface *focus_surface = input->pointer.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     const wl_fixed_t scale = win->scale();
     const wl_fixed_t xy_next[2] = {
         input->pointer.xy[0] + (dx / scale),
@@ -810,7 +810,7 @@ static void dnd_events(const input_t *const input, const GHOST_TEventType event)
 {
   /* NOTE: `input->data_offer_dnd_mutex` must already be locked. */
   if (wl_surface *focus_surface = input->focus_dnd) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(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]),
@@ -992,6 +992,10 @@ static void data_device_handle_enter(void *data,
                                      const wl_fixed_t y,
                                      struct wl_data_offer *id)
 {
+  if (!ghost_wl_surface_own(surface)) {
+    return;
+  }
+
   input_t *input = static_cast<input_t *>(data);
   std::lock_guard lock{input->data_offer_dnd_mutex};
 
@@ -1077,9 +1081,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_find(surface);
-      GHOST_ASSERT(win != nullptr, "Unable to find window for drop event from surface");
-
+      GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface);
       std::vector<std::string> uris;
 
       size_t pos = 0;
@@ -1238,12 +1240,13 @@ static void cursor_surface_handle_enter(void *data,
                                         struct wl_surface * /*wl_surface*/,
                                         struct wl_output *output)
 {
-  input_t *input = static_cast<input_t *>(data);
-  for (const output_t *reg_output : input->system->outputs()) {
-    if (reg_output->wl_output == output) {
-      input->cursor.outputs.insert(reg_output);
-    }
+  if (!ghost_wl_output_own(output)) {
+    return;
   }
+
+  input_t *input = static_cast<input_t *>(data);
+  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());
 }
 
@@ -1251,12 +1254,13 @@ static void cursor_surface_handle_leave(void *data,
                                         struct wl_surface * /*wl_surface*/,
                                         struct wl_output *output)
 {
-  input_t *input = static_cast<input_t *>(data);
-  for (const output_t *reg_output : input->system->outputs()) {
-    if (reg_output->wl_output == output) {
-      input->cursor.outputs.erase(reg_output);
-    }
+  if (!(output && ghost_wl_output_own(output))) {
+    return;
   }
+
+  input_t *input = static_cast<input_t *>(data);
+  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());
 }
 
@@ -1278,7 +1282,11 @@ static void pointer_handle_enter(void *data,
                                  const wl_fixed_t surface_x,
                                  const wl_fixed_t surface_y)
 {
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface);
+  if (!ghost_wl_surface_own(surface)) {
+    return;
+  }
+
+  GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface);
 
   win->activate();
 
@@ -1307,8 +1315,8 @@ 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;
-  if (surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface);
+  if (surface && ghost_wl_surface_own(surface)) {
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface);
     win->deactivate();
   }
 }
@@ -1324,7 +1332,7 @@ static void pointer_handle_motion(void *data,
   input->pointer.xy[1] = surface_y;
 
   if (wl_surface *focus_surface = input->pointer.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     const wl_fixed_t scale = win->scale();
     input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                    GHOST_kEventCursorMove,
@@ -1383,7 +1391,7 @@ static void pointer_handle_button(void *data,
   input->pointer.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
 
   if (wl_surface *focus_surface = input->pointer.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     input->system->pushEvent(new GHOST_EventButton(
         input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
   }
@@ -1402,7 +1410,7 @@ static void pointer_handle_axis(void *data,
   }
 
   if (wl_surface *focus_surface = input->pointer.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     input->system->pushEvent(new GHOST_EventWheel(
         input->system->getMilliSeconds(), win, std::signbit(value) ? +1 : -1));
   }
@@ -1474,6 +1482,10 @@ static void tablet_tool_handle_proximity_in(void *data,
                                             struct zwp_tablet_v2 * /*tablet*/,
                                             struct wl_surface *surface)
 {
+  if (!ghost_wl_surface_own(surface)) {
+    return;
+  }
+
   tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data);
   tool_input->proximity = true;
 
@@ -1492,7 +1504,7 @@ static void tablet_tool_handle_proximity_in(void *data,
   /* In case pressure isn't supported. */
   td.Pressure = 1.0f;
 
-  GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->tablet.wl_surface);
+  GHOST_WindowWayland *win = ghost_wl_surface_user_data(input->tablet.wl_surface);
 
   win->activate();
 
@@ -1520,7 +1532,7 @@ static void tablet_tool_handle_down(void *data,
   input->tablet.buttons.set(ebutton, true);
 
   if (wl_surface *focus_surface = input->tablet.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     input->system->pushEvent(new GHOST_EventButton(
         input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
   }
@@ -1536,7 +1548,7 @@ static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_
   input->tablet.buttons.set(ebutton, false);
 
   if (wl_surface *focus_surface = input->tablet.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     input->system->pushEvent(new GHOST_EventButton(
         input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
   }
@@ -1608,7 +1620,7 @@ 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;
   if (wl_surface *focus_surface = input->tablet.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     input->system->pushEvent(new GHOST_EventWheel(input->system->getMilliSeconds(), win, clicks));
   }
 }
@@ -1648,7 +1660,7 @@ static void tablet_tool_handle_button(void *data,
   input->tablet.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
 
   if (wl_surface *focus_surface = input->tablet.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     input->system->pushEvent(new GHOST_EventButton(
         input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data));
   }
@@ -1661,7 +1673,7 @@ static void tablet_tool_handle_frame(void *data,
   input_t *input = tool_input->input;
 
   if (wl_surface *focus_surface = input->tablet.wl_surface) {
-    GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface);
+    GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface);
     const wl_fixed_t scale = win->scale();
     input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
                                                    GHOST_kEventCursorMove,
@@ -1813,6 +1825,10 @@ static void keyboard_handle_enter(void *data,
                                   struct wl_surface *surface,
                                   struct wl_array * /*keys*/)
 {
+  if (!ghost_wl_surface_own(surface)) {
+    return;
+  }
+
   input_t *input = static_cast<input_t *>(data);
   input->keyboard.serial = serial;
   input->keyboard.wl_surface = surface;
@@ -1827,8 +1843,12 @@ static void keyboard_handle_enter(void *data,
 static void keyboard_handle_leave(void *data,
                                   struct wl_keyboard * /*wl_keyboard*/,
                                   const uint32_t /*serial*/,
-                                  struct wl_surface * /*surface*/)
+                                  struct wl_surface *surface)
 {
+  if (!(surface && ghost_wl_surface_own(surface))) {
+    return;
+  }
+
   input_t *input = static_cast<input_t *>(dat

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list