[gtk/gtk-3-24: 1/2] Wayland: ignore touch/tablet events on destroyed surfaces
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 1/2] Wayland: ignore touch/tablet events on destroyed surfaces
- Date: Sun, 10 Jan 2021 13:18:17 +0000 (UTC)
commit 19a740e277d3beb4ae05f30389c0792286d3e096
Author: wisp3rwind <wisp3rwind posteo eu>
Date: Wed Nov 11 10:12:26 2020 +0100
Wayland: ignore touch/tablet events on destroyed surfaces
When destroying a wl_surface (e.g. when a window or menu is closed), the
surface may continue to exist in the compositor slightly longer than on
the client side. In that case, the surface can still receive input
events, which need to be ignored gracefully.
In particular, this prevents segfaulting on wl_surface_get_user_data()
in that situation.
Reported in
https://gitlab.gnome.org/GNOME/gtk/-/issues/3296
The same issue for pointers/keyboards was reported in
https://bugzilla.gnome.org/show_bug.cgi?id=693338
and fixed with in
bfd7137ffbcbd8caa531d7a47d799fefb6605a5a
3625f17857328ae7e7aa43340f29efa56575a7b0
a8fc099a725543649fe3aab76943c14bdcd860fc
gdk/wayland/gdkdevice-wayland.c | 81 +++++++++++++++++++++++++++++++++--------
1 file changed, 66 insertions(+), 15 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 7d81eaff3b..f887973bce 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -2460,6 +2460,9 @@ touch_handle_down (void *data,
_gdk_wayland_display_update_serial (display, serial);
+ if (!wl_surface)
+ return;
+
touch = gdk_wayland_seat_add_touch (seat, id, wl_surface);
touch->x = wl_fixed_to_double (x);
touch->y = wl_fixed_to_double (y);
@@ -2495,6 +2498,9 @@ touch_handle_up (void *data,
_gdk_wayland_display_update_serial (display, serial);
touch = gdk_wayland_seat_get_touch (seat, id);
+ if (!touch)
+ return;
+
event = _create_touch_event (seat, touch, GDK_TOUCH_END, time);
GDK_NOTE (EVENTS,
@@ -2521,6 +2527,9 @@ touch_handle_motion (void *data,
GdkEvent *event;
touch = gdk_wayland_seat_get_touch (seat, id);
+ if (!touch)
+ return;
+
touch->x = wl_fixed_to_double (x);
touch->y = wl_fixed_to_double (y);
@@ -3634,19 +3643,21 @@ tablet_tool_handle_proximity_in (void *data,
struct zwp_tablet_tool_v2 *wp_tablet_tool,
uint32_t serial,
struct zwp_tablet_v2 *wp_tablet,
- struct wl_surface *surface)
+ struct wl_surface *wl_surface)
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = zwp_tablet_v2_get_user_data (wp_tablet);
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
- GdkWindow *window = wl_surface_get_user_data (surface);
+ GdkWindow *window;
GdkEvent *event;
- if (!surface)
- return;
+ if (!wl_surface)
+ return;
+
+ window = wl_surface_get_user_data (wl_surface);
if (!GDK_IS_WINDOW (window))
- return;
+ return;
tool->current_tablet = tablet;
tablet->current_tool = tool;
@@ -3685,6 +3696,9 @@ tablet_tool_handle_proximity_out (void *data,
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
#endif
+ if (!tablet)
+ return;
+
GDK_NOTE (EVENTS,
g_message ("proximity out, seat %p, tool %d", seat,
gdk_device_tool_get_tool_type (tool->tool)));
@@ -3741,7 +3755,7 @@ tablet_tool_handle_down (void *data,
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
- if (!tablet->pointer_info.focus)
+ if (!tablet || !tablet->pointer_info.focus)
return;
_gdk_wayland_display_update_serial (display_wayland, serial);
@@ -3758,7 +3772,7 @@ tablet_tool_handle_up (void *data,
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
- if (!tablet->pointer_info.focus)
+ if (!tablet || !tablet->pointer_info.focus)
return;
tablet_create_button_event_frame (tablet, GDK_BUTTON_RELEASE, GDK_BUTTON_PRIMARY);
@@ -3777,6 +3791,9 @@ tablet_tool_handle_motion (void *data,
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
GdkEvent *event;
+ if (!tablet)
+ return;
+
tablet->pointer_info.surface_x = wl_fixed_to_double (sx);
tablet->pointer_info.surface_y = wl_fixed_to_double (sy);
@@ -3809,7 +3826,12 @@ tablet_tool_handle_pressure (void *data,
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
- gint axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
+ gint axis_index;
+
+ if (!tablet)
+ return;
+
+ axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
_gdk_device_translate_axis (tablet->current_device, axis_index,
pressure, &tablet->axes[axis_index]);
@@ -3826,7 +3848,12 @@ tablet_tool_handle_distance (void *data,
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
- gint axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
+ gint axis_index;
+
+ if (!tablet)
+ return;
+
+ axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
_gdk_device_translate_axis (tablet->current_device, axis_index,
distance, &tablet->axes[axis_index]);
@@ -3844,8 +3871,14 @@ tablet_tool_handle_tilt (void *data,
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
- gint xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
- gint ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
+ gint xtilt_axis_index;
+ gint ytilt_axis_index;
+
+ if (!tablet)
+ return;
+
+ xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
+ ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
_gdk_device_translate_axis (tablet->current_device, xtilt_axis_index,
wl_fixed_to_double (xtilt),
@@ -3872,7 +3905,7 @@ tablet_tool_handle_button (void *data,
GdkEventType evtype;
guint n_button;
- if (!tablet->pointer_info.focus)
+ if (!tablet || !tablet->pointer_info.focus)
return;
tablet->pointer_info.press_serial = serial;
@@ -3903,7 +3936,12 @@ tablet_tool_handle_rotation (void *data,
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
- gint axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
+ gint axis_index;
+
+ if (!tablet)
+ return;
+
+ axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
_gdk_device_translate_axis (tablet->current_device, axis_index,
wl_fixed_to_double (degrees),
@@ -3922,7 +3960,12 @@ tablet_tool_handle_slider (void *data,
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
- gint axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
+ gint axis_index;
+
+ if (!tablet)
+ return;
+
+ axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
_gdk_device_translate_axis (tablet->current_device, axis_index,
position, &tablet->axes[axis_index]);
@@ -3940,9 +3983,12 @@ tablet_tool_handle_wheel (void *data,
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
- GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
+ GdkWaylandSeat *seat;
GdkEvent *event;
+ if (!tablet)
+ return;
+
GDK_NOTE (EVENTS,
g_message ("tablet tool %d wheel %d/%d",
gdk_device_tool_get_tool_type (tool->tool), degrees, clicks));
@@ -3950,6 +3996,8 @@ tablet_tool_handle_wheel (void *data,
if (clicks == 0)
return;
+ seat = GDK_WAYLAND_SEAT (tablet->seat);
+
/* Send smooth event */
event = create_scroll_event (seat, &tablet->pointer_info,
tablet->master, tablet->current_device, FALSE);
@@ -3975,6 +4023,9 @@ tablet_tool_handle_frame (void *data,
GdkWaylandTabletData *tablet = tool->current_tablet;
GdkEvent *frame_event;
+ if (!tablet)
+ return;
+
GDK_NOTE (EVENTS,
g_message ("tablet frame, time %d", time));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]