[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