Submitted By: Xi Ruoyao Date: 2022-03-22 Initial Package Version: 42.0 Upstream Status: Partly merged Origin: See below Description: Consolidated patch of various fixes for mutter that couldn't go into 42.O. See https://gitlab.gnome.org/GNOME/mutter/-/issues/2175 diff --color -Naur mutter-42.0/clutter/clutter/cally/cally-stage.c mutter-42.0-patched/clutter/clutter/cally/cally-stage.c --- mutter-42.0/clutter/clutter/cally/cally-stage.c 2022-03-13 07:30:36.245525000 +0800 +++ mutter-42.0-patched/clutter/clutter/cally/cally-stage.c 2022-03-22 15:30:21.494145864 +0800 @@ -39,6 +39,8 @@ #include "cally-stage.h" #include "cally-actor-private.h" +#include "../clutter-stage-private.h" + /* AtkObject.h */ static void cally_stage_real_initialize (AtkObject *obj, gpointer data); @@ -191,6 +193,9 @@ stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (obj)); + if (clutter_stage_is_activated (stage)) + cally_stage_activate_cb (stage, CALLY_STAGE (obj)); + g_signal_connect (stage, "activate", G_CALLBACK (cally_stage_activate_cb), obj); g_signal_connect (stage, "deactivate", G_CALLBACK (cally_stage_deactivate_cb), obj); g_signal_connect (stage, "notify::key-focus", diff --color -Naur mutter-42.0/clutter/clutter/clutter-actor.c mutter-42.0-patched/clutter/clutter/clutter-actor.c --- mutter-42.0/clutter/clutter/clutter-actor.c 2022-03-13 07:30:36.249525000 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-actor.c 2022-03-22 15:32:35.377543018 +0800 @@ -1264,6 +1264,10 @@ if (CLUTTER_ACTOR_IS_MAPPED (self) == mapped) return; + g_return_if_fail (!CLUTTER_ACTOR_IN_MAP_UNMAP (self)); + + CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_MAP_UNMAP); + if (mapped) { CLUTTER_ACTOR_GET_CLASS (self)->map (self); @@ -1274,6 +1278,8 @@ CLUTTER_ACTOR_GET_CLASS (self)->unmap (self); g_assert (!CLUTTER_ACTOR_IS_MAPPED (self)); } + + CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_MAP_UNMAP); } /* this function updates the mapped and realized states according to @@ -1695,6 +1701,13 @@ */ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAPPED]); + if (priv->has_pointer) + { + ClutterActor *stage = _clutter_actor_get_stage_internal (self); + + clutter_stage_pointer_actor_unreactive (CLUTTER_STAGE (stage), self); + } + /* relinquish keyboard focus if we were unmapped while owning it */ if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) maybe_unset_key_focus (self); @@ -12434,8 +12447,12 @@ clutter_actor_set_reactive (ClutterActor *actor, gboolean reactive) { + ClutterActorPrivate *priv; + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + priv = actor->priv; + if (reactive == CLUTTER_ACTOR_IS_REACTIVE (actor)) return; @@ -12445,6 +12462,13 @@ CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REACTIVE); g_object_notify_by_pspec (G_OBJECT (actor), obj_props[PROP_REACTIVE]); + + if (!CLUTTER_ACTOR_IS_REACTIVE (actor) && priv->has_pointer) + { + ClutterActor *stage = _clutter_actor_get_stage_internal (actor); + + clutter_stage_pointer_actor_unreactive (CLUTTER_STAGE (stage), actor); + } } /** diff --color -Naur mutter-42.0/clutter/clutter/clutter-event.c mutter-42.0-patched/clutter/clutter/clutter-event.c --- mutter-42.0/clutter/clutter/clutter-event.c 2022-03-13 07:30:36.265525300 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-event.c 2022-03-22 15:30:26.902562665 +0800 @@ -1772,7 +1772,8 @@ } gboolean -_clutter_event_process_filters (ClutterEvent *event) +_clutter_event_process_filters (ClutterEvent *event, + ClutterActor *event_actor) { ClutterMainContext *context = _clutter_context_get_default (); GList *l, *next; @@ -1789,7 +1790,7 @@ if (event_filter->stage && event_filter->stage != event->any.stage) continue; - if (event_filter->func (event, event_filter->user_data) == CLUTTER_EVENT_STOP) + if (event_filter->func (event, event_actor, event_filter->user_data) == CLUTTER_EVENT_STOP) return CLUTTER_EVENT_STOP; } diff --color -Naur mutter-42.0/clutter/clutter/clutter-event.h mutter-42.0-patched/clutter/clutter/clutter-event.h --- mutter-42.0/clutter/clutter/clutter-event.h 2022-03-13 07:30:36.265525300 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-event.h 2022-03-22 15:30:26.902562665 +0800 @@ -615,6 +615,7 @@ /** * ClutterEventFilterFunc: * @event: the event that is going to be emitted + * @event_actor: the current device actor of the events device * @user_data: the data pointer passed to clutter_event_add_filter() * * A function pointer type used by event filters that are added with @@ -628,6 +629,7 @@ * Since: 1.18 */ typedef gboolean (* ClutterEventFilterFunc) (const ClutterEvent *event, + ClutterActor *event_actor, gpointer user_data); CLUTTER_EXPORT diff --color -Naur mutter-42.0/clutter/clutter/clutter-event-private.h mutter-42.0-patched/clutter/clutter/clutter-event-private.h --- mutter-42.0/clutter/clutter/clutter-event-private.h 2022-03-13 07:30:36.261525400 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-event-private.h 2022-03-22 15:30:26.902562665 +0800 @@ -14,7 +14,8 @@ void _clutter_process_event (ClutterEvent *event); CLUTTER_EXPORT -gboolean _clutter_event_process_filters (ClutterEvent *event); +gboolean _clutter_event_process_filters (ClutterEvent *event, + ClutterActor *event_actor); /* clears the event queue inside the main context */ void _clutter_clear_events_queue (void); diff --color -Naur mutter-42.0/clutter/clutter/clutter-input-pointer-a11y.c mutter-42.0-patched/clutter/clutter/clutter-input-pointer-a11y.c --- mutter-42.0/clutter/clutter/clutter-input-pointer-a11y.c 2022-03-13 07:30:36.269525500 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-input-pointer-a11y.c 2022-03-22 15:30:18.889956635 +0800 @@ -25,11 +25,13 @@ #include "clutter-build-config.h" +#include "clutter-backend-private.h" #include "clutter-enum-types.h" #include "clutter-input-device.h" #include "clutter-input-device-private.h" #include "clutter-input-pointer-a11y-private.h" #include "clutter-main.h" +#include "clutter-private.h" #include "clutter-virtual-input-device.h" static gboolean @@ -726,3 +728,39 @@ return (is_secondary_click_enabled (device) || is_dwell_click_enabled (device)); } + +void +_clutter_input_pointer_a11y_maybe_handle_event (ClutterEvent *event) +{ + + ClutterInputDevice *device = clutter_event_get_device (event); + ClutterMainContext *clutter_context; + ClutterBackend *backend; + + if (!_clutter_is_input_pointer_a11y_enabled (device)) + return; + + if ((event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC) != 0) + return; + + clutter_context = _clutter_context_get_default (); + backend = clutter_context->backend; + + if (!clutter_backend_is_display_server (backend)) + return; + + if (event->type == CLUTTER_MOTION) + { + float x, y; + + clutter_event_get_coords (event, &x, &y); + _clutter_input_pointer_a11y_on_motion_event (device, x, y); + } + else if (event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_BUTTON_RELEASE) + { + _clutter_input_pointer_a11y_on_button_event (device, + event->button.button, + event->type == CLUTTER_BUTTON_PRESS); + } +} diff --color -Naur mutter-42.0/clutter/clutter/clutter-input-pointer-a11y-private.h mutter-42.0-patched/clutter/clutter/clutter-input-pointer-a11y-private.h --- mutter-42.0/clutter/clutter/clutter-input-pointer-a11y-private.h 2022-03-13 07:30:36.269525500 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-input-pointer-a11y-private.h 2022-03-22 15:30:18.888956564 +0800 @@ -42,6 +42,9 @@ CLUTTER_EXPORT gboolean _clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device); +CLUTTER_EXPORT +void _clutter_input_pointer_a11y_maybe_handle_event (ClutterEvent *event); + G_END_DECLS #endif /* __CLUTTER_INPUT_POINTER_A11Y_H__ */ diff --color -Naur mutter-42.0/clutter/clutter/clutter-main.c mutter-42.0-patched/clutter/clutter/clutter-main.c --- mutter-42.0/clutter/clutter/clutter-main.c 2022-03-13 07:30:36.273525700 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-main.c 2022-03-22 15:32:26.113902391 +0800 @@ -741,6 +741,9 @@ void clutter_do_event (ClutterEvent *event) { + ClutterActor *event_actor = NULL; + ClutterContext *context = _clutter_context_get_default(); + /* we need the stage for the event */ if (event->any.stage == NULL) { @@ -765,8 +768,27 @@ break; } - if (_clutter_event_process_filters (event)) - return; + _clutter_input_pointer_a11y_maybe_handle_event (event); + + context->current_event = g_slist_prepend (context->current_event, event); + + if (event->any.type != CLUTTER_DEVICE_ADDED && + event->any.type != CLUTTER_DEVICE_REMOVED && + event->any.type != CLUTTER_NOTHING && + event->any.type != CLUTTER_EVENT_LAST) + { + event_actor = clutter_stage_get_event_actor (event->any.stage, event); + } + + if (_clutter_event_process_filters (event, event_actor)) + { + context->current_event = + g_slist_delete_link (context->current_event, context->current_event); + + return; + } + + context->current_event = g_slist_delete_link (context->current_event, context->current_event); /* Instead of processing events when received, we queue them up to * handle per-frame before animations, layout, and drawing. @@ -810,13 +832,8 @@ { ClutterInputDevice *device = clutter_event_get_device (event); ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - ClutterMainContext *clutter_context; - ClutterBackend *backend; ClutterActor *target; - clutter_context = _clutter_context_get_default (); - backend = clutter_context->backend; - switch (event->type) { case CLUTTER_NOTHING: @@ -858,31 +875,8 @@ break; case CLUTTER_MOTION: - if (clutter_backend_is_display_server (backend) && - !(event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC)) - { - if (_clutter_is_input_pointer_a11y_enabled (device)) - { - gfloat x, y; - - clutter_event_get_coords (event, &x, &y); - _clutter_input_pointer_a11y_on_motion_event (device, x, y); - } - } - G_GNUC_FALLTHROUGH; case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: - if (clutter_backend_is_display_server (backend)) - { - if (_clutter_is_input_pointer_a11y_enabled (device) && (event->type != CLUTTER_MOTION)) - { - _clutter_input_pointer_a11y_on_button_event (device, - event->button.button, - event->type == CLUTTER_BUTTON_PRESS); - } - } - - G_GNUC_FALLTHROUGH; case CLUTTER_SCROLL: case CLUTTER_TOUCHPAD_PINCH: case CLUTTER_TOUCHPAD_SWIPE: diff --color -Naur mutter-42.0/clutter/clutter/clutter-private.h mutter-42.0-patched/clutter/clutter/clutter-private.h --- mutter-42.0/clutter/clutter/clutter-private.h 2022-03-13 07:30:36.277525700 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-private.h 2022-03-22 15:32:32.410022663 +0800 @@ -69,6 +69,7 @@ #define CLUTTER_ACTOR_IN_PREF_WIDTH(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_WIDTH) != FALSE) #define CLUTTER_ACTOR_IN_PREF_HEIGHT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_HEIGHT) != FALSE) #define CLUTTER_ACTOR_IN_PREF_SIZE(a) ((CLUTTER_PRIVATE_FLAGS (a) & (CLUTTER_IN_PREF_HEIGHT|CLUTTER_IN_PREF_WIDTH)) != FALSE) +#define CLUTTER_ACTOR_IN_MAP_UNMAP(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_MAP_UNMAP) != FALSE) #define CLUTTER_PARAM_READABLE (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) #define CLUTTER_PARAM_WRITABLE (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS) @@ -105,6 +106,8 @@ /* Used to avoid recursion */ CLUTTER_IN_RELAYOUT = 1 << 7, + + CLUTTER_IN_MAP_UNMAP = 1 << 8, } ClutterPrivateFlags; /* diff --color -Naur mutter-42.0/clutter/clutter/clutter-stage.c mutter-42.0-patched/clutter/clutter/clutter-stage.c --- mutter-42.0/clutter/clutter/clutter-stage.c 2022-03-13 07:30:36.285525800 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-stage.c 2022-03-22 15:32:35.378543193 +0800 @@ -128,6 +128,7 @@ int update_freeze_count; gboolean pending_finish_queue_redraws; + gboolean is_activated; GHashTable *pointer_devices; GHashTable *touch_sequences; @@ -579,12 +580,16 @@ static void clutter_stage_real_activate (ClutterStage *stage) { + stage->priv->is_activated = TRUE; + clutter_stage_emit_key_focus_event (stage, TRUE); } static void clutter_stage_real_deactivate (ClutterStage *stage) { + stage->priv->is_activated = FALSE; + clutter_stage_emit_key_focus_event (stage, FALSE); } @@ -3150,53 +3155,62 @@ priv->actor_needs_immediate_relayout = TRUE; } -static void -on_device_actor_reactive_changed (ClutterActor *actor, - GParamSpec *pspec, - PointerDeviceEntry *entry) +void +clutter_stage_pointer_actor_unreactive (ClutterStage *self, + ClutterActor *actor) { - ClutterStage *self = entry->stage; + ClutterStagePrivate *priv = self->priv; + GHashTableIter iter; + gpointer value; - g_assert (!clutter_actor_get_reactive (actor)); + if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) + return; - clutter_stage_pick_and_update_device (self, - entry->device, - entry->sequence, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, - entry->coords, - CLUTTER_CURRENT_TIME); -} + g_assert (!clutter_actor_is_mapped (actor) || !clutter_actor_get_reactive (actor)); -static void -on_device_actor_destroyed (ClutterActor *actor, - PointerDeviceEntry *entry) -{ - /* Simply unset the current_actor pointer here, there's no need to - * unset has_pointer or to disconnect any signals because the actor - * is gone anyway. - */ - entry->current_actor = NULL; - g_clear_pointer (&entry->clear_area, cairo_region_destroy); - clutter_stage_repick_device (entry->stage, entry->device); + g_hash_table_iter_init (&iter, priv->pointer_devices); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + PointerDeviceEntry *entry = value; + + if (entry->current_actor != actor) + continue; + + clutter_stage_pick_and_update_device (self, + entry->device, + NULL, + CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | + CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, + entry->coords, + CLUTTER_CURRENT_TIME); + } + + g_hash_table_iter_init (&iter, priv->touch_sequences); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + PointerDeviceEntry *entry = value; + + if (entry->current_actor != actor) + continue; + + clutter_stage_pick_and_update_device (self, + entry->device, + entry->sequence, + CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | + CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, + entry->coords, + CLUTTER_CURRENT_TIME); + } + + if (actor != CLUTTER_ACTOR (self)) + g_assert (!clutter_actor_has_pointer (actor)); } static void free_pointer_device_entry (PointerDeviceEntry *entry) { if (entry->current_actor) - { - ClutterActor *actor = entry->current_actor; - - g_signal_handlers_disconnect_by_func (actor, - G_CALLBACK (on_device_actor_reactive_changed), - entry); - g_signal_handlers_disconnect_by_func (actor, - G_CALLBACK (on_device_actor_destroyed), - entry); - - _clutter_actor_set_has_pointer (actor, FALSE); - } + _clutter_actor_set_has_pointer (entry->current_actor, FALSE); g_clear_pointer (&entry->clear_area, cairo_region_destroy); @@ -3240,30 +3254,12 @@ if (entry->current_actor != actor) { if (entry->current_actor) - { - ClutterActor *old_actor = entry->current_actor; - - g_signal_handlers_disconnect_by_func (old_actor, - G_CALLBACK (on_device_actor_reactive_changed), - entry); - g_signal_handlers_disconnect_by_func (old_actor, - G_CALLBACK (on_device_actor_destroyed), - entry); - - _clutter_actor_set_has_pointer (old_actor, FALSE); - } + _clutter_actor_set_has_pointer (entry->current_actor, FALSE); entry->current_actor = actor; if (actor) - { - g_signal_connect (actor, "notify::reactive", - G_CALLBACK (on_device_actor_reactive_changed), entry); - g_signal_connect (actor, "destroy", - G_CALLBACK (on_device_actor_destroyed), entry); - - _clutter_actor_set_has_pointer (actor, TRUE); - } + _clutter_actor_set_has_pointer (actor, TRUE); } g_clear_pointer (&entry->clear_area, cairo_region_destroy); @@ -3478,7 +3474,7 @@ CLUTTER_EVENT_NONE, old_actor, new_actor, point, time_ms); - if (!_clutter_event_process_filters (event)) + if (!_clutter_event_process_filters (event, old_actor)) _clutter_actor_handle_event (old_actor, root, event); clutter_event_free (event); @@ -3492,7 +3488,7 @@ CLUTTER_EVENT_NONE, new_actor, old_actor, point, time_ms); - if (!_clutter_event_process_filters (event)) + if (!_clutter_event_process_filters (event, new_actor)) _clutter_actor_handle_event (new_actor, root, event); clutter_event_free (event); @@ -3676,7 +3672,7 @@ grab_actor : old_grab_actor, entry->coords, CLUTTER_CURRENT_TIME); - if (!_clutter_event_process_filters (event)) + if (!_clutter_event_process_filters (event, entry->current_actor)) _clutter_actor_handle_event (deepmost, topmost, event); clutter_event_free (event); } @@ -3987,3 +3983,11 @@ return NULL; } + +gboolean +clutter_stage_is_activated (ClutterStage *stage) +{ + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); + + return stage->priv->is_activated; +} diff --color -Naur mutter-42.0/clutter/clutter/clutter-stage-private.h mutter-42.0-patched/clutter/clutter/clutter-stage-private.h --- mutter-42.0/clutter/clutter/clutter-stage-private.h 2022-03-13 07:30:36.285525800 +0800 +++ mutter-42.0-patched/clutter/clutter/clutter-stage-private.h 2022-03-22 15:32:35.377543018 +0800 @@ -154,6 +154,11 @@ void clutter_stage_unlink_grab (ClutterStage *self, ClutterGrab *grab); +gboolean clutter_stage_is_activated (ClutterStage *stage); + +void clutter_stage_pointer_actor_unreactive (ClutterStage *self, + ClutterActor *actor); + G_END_DECLS #endif /* __CLUTTER_STAGE_PRIVATE_H__ */ diff --color -Naur mutter-42.0/src/backends/native/meta-stage-native.c mutter-42.0-patched/src/backends/native/meta-stage-native.c --- mutter-42.0/src/backends/native/meta-stage-native.c 2022-03-13 07:30:36.469529900 +0800 +++ mutter-42.0-patched/src/backends/native/meta-stage-native.c 2022-03-22 15:30:21.496146012 +0800 @@ -27,6 +27,7 @@ #include "backends/native/meta-stage-native.h" #include "backends/meta-backend-private.h" +#include "backends/meta-stage-private.h" #include "backends/native/meta-crtc-virtual.h" #include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-renderer-native.h" @@ -171,8 +172,22 @@ } static void +meta_stage_native_constructed (GObject *object) +{ + MetaStageNative *self = META_STAGE_NATIVE (object); + + G_OBJECT_CLASS (meta_stage_native_parent_class)->constructed (object); + + meta_stage_set_active ((MetaStage *) self->parent.wrapper, TRUE); +} + +static void meta_stage_native_class_init (MetaStageNativeClass *klass) { + GObjectClass *object_class = (GObjectClass *) klass; + + object_class->constructed = meta_stage_native_constructed; + quark_view_frame_closure = g_quark_from_static_string ("-meta-native-stage-view-frame-closure"); } diff --color -Naur mutter-42.0/src/core/display.c mutter-42.0-patched/src/core/display.c --- mutter-42.0/src/core/display.c 2022-03-13 07:30:36.489530300 +0800 +++ mutter-42.0-patched/src/core/display.c 2022-03-22 15:30:21.497146086 +0800 @@ -1436,7 +1436,6 @@ else meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface"); - meta_stage_set_active (stage, focus_window == NULL); meta_wayland_compositor_set_input_focus (compositor, focus_window); clutter_stage_repick_device (CLUTTER_STAGE (stage), diff --color -Naur mutter-42.0/src/core/events.c mutter-42.0-patched/src/core/events.c --- mutter-42.0/src/core/events.c 2022-03-13 07:30:36.489530300 +0800 +++ mutter-42.0-patched/src/core/events.c 2022-03-22 15:30:26.905562903 +0800 @@ -81,23 +81,20 @@ static MetaWindow * get_window_for_event (MetaDisplay *display, - const ClutterEvent *event) + const ClutterEvent *event, + ClutterActor *event_actor) { switch (display->event_route) { case META_EVENT_ROUTE_NORMAL: { - ClutterActor *target; MetaWindowActor *window_actor; /* Always use the key focused window for key events. */ if (IS_KEY_EVENT (event)) return stage_has_key_focus () ? display->focus_window : NULL; - target = clutter_stage_get_device_actor (clutter_event_get_stage (event), - clutter_event_get_device (event), - clutter_event_get_event_sequence (event)); - window_actor = meta_window_actor_from_actor (target); + window_actor = meta_window_actor_from_actor (event_actor); if (window_actor) return meta_window_actor_get_meta_window (window_actor); else @@ -213,7 +210,8 @@ static gboolean meta_display_handle_event (MetaDisplay *display, - const ClutterEvent *event) + const ClutterEvent *event, + ClutterActor *event_actor) { MetaBackend *backend = meta_get_backend (); MetaWindow *window = NULL; @@ -338,7 +336,7 @@ } #endif - window = get_window_for_event (display, event); + window = get_window_for_event (display, event, event_actor); display->current_time = event->any.time; @@ -540,11 +538,12 @@ static gboolean event_callback (const ClutterEvent *event, + ClutterActor *event_actor, gpointer data) { MetaDisplay *display = data; - return meta_display_handle_event (display, event); + return meta_display_handle_event (display, event, event_actor); } void diff --color -Naur mutter-42.0/src/wayland/meta-wayland-surface.c mutter-42.0-patched/src/wayland/meta-wayland-surface.c --- mutter-42.0/src/wayland/meta-wayland-surface.c 2022-03-13 07:30:36.549531500 +0800 +++ mutter-42.0-patched/src/wayland/meta-wayland-surface.c 2022-03-22 15:32:37.302878150 +0800 @@ -791,12 +791,16 @@ if ((get_buffer_width (surface) % surface->scale != 0) || (get_buffer_height (surface) % surface->scale != 0)) { - wl_resource_post_error (surface->resource, WL_SURFACE_ERROR_INVALID_SIZE, - "Buffer size (%dx%d) must be an integer multiple " - "of the buffer_scale (%d)", - get_buffer_width (surface), - get_buffer_height (surface), surface->scale); - goto cleanup; + struct wl_resource *resource = surface->resource; + pid_t pid; + + wl_client_get_credentials (wl_resource_get_client (resource), &pid, NULL, + NULL); + + g_warning ("Bug in client with pid %ld: Buffer size (%dx%d) is not an" + "integer multiple of the buffer_scale (%d).", (long) pid, + get_buffer_width (surface), get_buffer_height (surface), + surface->scale); } if (state->has_new_buffer_transform)