From 767a46da33114d353ed600b669efb361f1d6a3ac Mon Sep 17 00:00:00 2001 From: Rick Calixte <10281587+rcalixte@users.noreply.github.com> Date: Sat, 2 Dec 2023 21:39:48 -0500 Subject: [PATCH] Fix segfault during Alt-Tab when window focus mode is either 'Sloppy' or 'Mouse' (gdb backtrace attached) (gdb) bt #\0 meta_wayland_surface_get_relative_coordinates (surface=0x0, abs_x=719, abs_y=405, sx=0x7ffe15cea768, sy=0x7ffe15cea76c) at ../src/wayland/meta-wayland-surface.c:1569 #\1 0x00007fba6070ec62 in meta_wayland_pointer_get_relative_coordinates (pointer=pointer@entry=0x564387be1670, surface=surface@entry=0x0, sx=sx@entry=0x7ffe15cea7a8, sy=sy@entry=0x7ffe15cea7ac) at ../src/wayland/meta-wayland-pointer.c:1061 #\2 0x00007fba6070ef13 in meta_wayland_pointer_send_enter (surface=0x0, serial=38, pointer_resource=0x56438b2179e0, pointer=0x564387be1670) at ../src/wayland/meta-wayland-pointer.c:850 #\3 meta_wayland_pointer_broadcast_enter (surface=0x0, serial=38, pointer=0x564387be1670) at ../src/wayland/meta-wayland-pointer.c:875 #\4 meta_wayland_pointer_set_focus (pointer=0x564387be1670, surface=) at ../src/wayland/meta-wayland-pointer.c:967 #\5 0x00007fba6070f573 in repick_for_event (pointer=0x564387be1670, for_event=) at ../src/wayland/meta-wayland-pointer.c:640 #\6 0x00007fba6070f6df in meta_wayland_pointer_repick (pointer=) at ../src/wayland/meta-wayland-pointer.c:1048 #\7 0x00007fba60712799 in meta_wayland_seat_repick (seat=) at ../src/wayland/meta-wayland-seat.c:441 #\8 0x00007fba606b09a0 in meta_display_sync_wayland_input_focus (display=) at ../src/core/display.c:1457 #\9 0x00007fba606942a0 in meta_end_modal_for_plugin (compositor=0x564387f6fe10, plugin=0x564387beeae0, timestamp=140036) at ../src/compositor/compositor.c:495 #\10 0x00007fba6069bef8 in meta_plugin_end_modal (plugin=, timestamp=) at ../src/compositor/meta-plugin.c:187 #\11 0x00007fba60e719eb in cinnamon_global_end_modal (global=0x564387fef940, timestamp=140036) at ../src/cinnamon-global.c:1000 Soft rebase from Mutter 40.10: * Adding clutter_stage_get_device_coords() * Adding PointerDeviceEntry struct * Updating _ClutterStagePrivate struct * Cherry-pick for repick_for_event() * Cherry-pick and adding null-pointer check for meta_wayland_pointer_set_focus() * Cherry-pick for meta_wayland_pointer_get_relative_coordinates() * Add null checks for meta_wayland_surface_get_relative_coordinates() Fix meson.build warning: * path() -> full_path() --- clutter/clutter/clutter-mutter.h | 5 +++++ clutter/clutter/clutter-stage.c | 36 ++++++++++++++++++++++++++++++ meson.build | 2 +- src/wayland/meta-wayland-pointer.c | 15 ++++++++----- src/wayland/meta-wayland-surface.c | 13 ++++++----- 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h index d61746d5f..489e93f93 100644 --- a/clutter/clutter/clutter-mutter.h +++ b/clutter/clutter/clutter-mutter.h @@ -78,6 +78,11 @@ void clutter_stage_update_resource_scales (ClutterStage *stage); CLUTTER_EXPORT gboolean clutter_actor_has_damage (ClutterActor *actor); +CLUTTER_EXPORT +void clutter_stage_get_device_coords (ClutterStage *stage, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords); #undef __CLUTTER_H_INSIDE__ #endif /* __CLUTTER_MUTTER_H__ */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index fa20b8e28..11e63bb66 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -99,6 +99,15 @@ typedef struct _PickClipRecord graphene_point_t vertex[4]; } PickClipRecord; +typedef struct _PointerDeviceEntry +{ + ClutterStage *stage; + ClutterInputDevice *device; + ClutterEventSequence *sequence; + graphene_point_t coords; + ClutterActor *current_actor; +} PointerDeviceEntry; + struct _ClutterStagePrivate { /* the stage implementation */ @@ -147,6 +156,9 @@ struct _ClutterStagePrivate gboolean needs_update; + GHashTable *pointer_devices; + GHashTable *touch_sequences; + guint redraw_pending : 1; guint is_cursor_visible : 1; guint throttle_motion_events : 1; @@ -4796,3 +4808,27 @@ _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage, *view_scale = scale; return TRUE; } + +/** + * clutter_stage_get_device_coords: (skip): + */ +void +clutter_stage_get_device_coords (ClutterStage *stage, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords) +{ + ClutterStagePrivate *priv = stage->priv; + PointerDeviceEntry *entry = NULL; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + g_return_if_fail (device != NULL); + + if (sequence != NULL) + entry = g_hash_table_lookup (priv->touch_sequences, sequence); + else + entry = g_hash_table_lookup (priv->pointer_devices, device); + + if (entry && coords) + *coords = entry->coords; +} diff --git a/meson.build b/meson.build index d3cb8b4c8..81495d741 100644 --- a/meson.build +++ b/meson.build @@ -383,7 +383,7 @@ have_xwayland_initfd = false if have_wayland xwayland_path = get_option('xwayland_path') if xwayland_path == '' - xwayland_path = find_program('Xwayland').path() + xwayland_path = find_program('Xwayland').full_path() endif cdata.set_quoted('XWAYLAND_PATH', xwayland_path) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index d30085202..6187515bd 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -618,10 +618,10 @@ repick_for_event (MetaWaylandPointer *pointer, ClutterActor *actor; MetaWaylandSurface *surface; - if (for_event) - actor = clutter_event_get_source (for_event); + if (clutter_event_type (for_event) == CLUTTER_LEAVE) + actor = clutter_event_get_related (for_event); else - actor = clutter_input_device_get_pointer_actor (pointer->device); + actor = clutter_event_get_source (for_event); if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) { @@ -938,6 +938,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, if (surface != NULL) { + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); struct wl_client *client = wl_resource_get_client (surface->resource); graphene_point_t pos; MetaWindow *focus_window; @@ -949,7 +950,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, G_CALLBACK (focus_surface_destroyed), pointer); - clutter_input_device_get_coords (pointer->device, NULL, &pos); + clutter_stage_get_device_coords (stage, pointer->device, NULL, &pos); focus_window = meta_wayland_surface_get_window (pointer->focus_surface); if (focus_window) @@ -960,7 +961,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, pointer->focus_client = meta_wayland_pointer_get_pointer_client (pointer, client); - if (pointer->focus_client) + if (pointer->focus_client && pointer->focus_surface) { pointer->focus_serial = meta_wayland_input_device_next_serial (input_device); @@ -1054,10 +1055,12 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, wl_fixed_t *sx, wl_fixed_t *sy) { + MetaBackend *backend = meta_get_backend (); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); float xf = 0.0f, yf = 0.0f; graphene_point_t pos; - clutter_input_device_get_coords (pointer->device, NULL, &pos); + clutter_stage_get_device_coords (stage, pointer->device, NULL, &pos); meta_wayland_surface_get_relative_coordinates (surface, pos.x, pos.y, &xf, &yf); *sx = wl_fixed_from_double (xf); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index aecaac4ce..befac4f84 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1566,12 +1566,15 @@ meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, float *sx, float *sy) { - MetaWaylandSurfaceRoleClass *surface_role_class = - META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role); + if (surface != NULL && surface->role) + { + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role); - surface_role_class->get_relative_coordinates (surface->role, - abs_x, abs_y, - sx, sy); + surface_role_class->get_relative_coordinates (surface->role, + abs_x, abs_y, + sx, sy); + } } void