diff -Nru mutter-42.3/clutter/clutter/clutter-actor.c mutter-42.4/clutter/clutter/clutter-actor.c --- mutter-42.3/clutter/clutter/clutter-actor.c 2022-07-04 17:06:55.400000000 +0000 +++ mutter-42.4/clutter/clutter/clutter-actor.c 2022-08-11 15:46:25.950000000 +0000 @@ -803,6 +803,8 @@ GList *stage_views; GList *grabs; + unsigned int n_pointers; + /* bitfields: KEEP AT THE END */ /* fixed position and sizes */ @@ -822,7 +824,6 @@ guint clip_to_allocation : 1; guint enable_model_view_transform : 1; guint enable_paint_unmapped : 1; - guint has_pointer : 1; guint has_key_focus : 1; guint propagated_one_redraw : 1; guint paint_volume_valid : 1; @@ -1701,7 +1702,7 @@ */ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAPPED]); - if (priv->has_pointer) + if (priv->n_pointers > 0) { ClutterActor *stage = _clutter_actor_get_stage_internal (self); @@ -1770,6 +1771,18 @@ * and the branch of the scene graph is in a stable state */ clutter_actor_update_map_state (self, MAP_STATE_CHECK); + + if (clutter_actor_has_mapped_clones (self)) + { + ClutterActorPrivate *priv = self->priv; + + /* Avoid the early return in clutter_actor_queue_relayout() */ + priv->needs_width_request = FALSE; + priv->needs_height_request = FALSE; + priv->needs_allocation = FALSE; + + clutter_actor_queue_relayout (self); + } } static inline void @@ -5403,7 +5416,7 @@ break; case PROP_HAS_POINTER: - g_value_set_boolean (value, priv->has_pointer); + g_value_set_boolean (value, priv->n_pointers > 0); break; case PROP_LAYOUT_MANAGER: @@ -5753,7 +5766,9 @@ * allocation, because apparently some code above Clutter allows * them. */ - if (!CLUTTER_ACTOR_IS_MAPPED (child) || !clutter_actor_has_allocation (child)) + if ((!CLUTTER_ACTOR_IS_MAPPED (child) && + !clutter_actor_has_mapped_clones (child)) || + !clutter_actor_has_allocation (child)) continue; child_volume = clutter_actor_get_transformed_paint_volume (child, self); @@ -11551,7 +11566,7 @@ if (self == child) { g_warning ("Cannot add the actor '%s' to itself.", - _clutter_actor_get_debug_name (self)); + _clutter_actor_get_debug_name (self)); return; } @@ -11704,6 +11719,18 @@ if (CLUTTER_ACTOR_IS_MAPPED (child)) clutter_actor_queue_redraw (child); + if (clutter_actor_has_mapped_clones (self)) + { + ClutterActorPrivate *priv = self->priv; + + /* Avoid the early return in clutter_actor_queue_relayout() */ + priv->needs_width_request = FALSE; + priv->needs_height_request = FALSE; + priv->needs_allocation = FALSE; + + clutter_actor_queue_relayout (self); + } + if (emit_actor_added) _clutter_container_emit_actor_added (CLUTTER_CONTAINER (self), child); @@ -12463,12 +12490,36 @@ g_object_notify_by_pspec (G_OBJECT (actor), obj_props[PROP_REACTIVE]); - if (!CLUTTER_ACTOR_IS_REACTIVE (actor) && priv->has_pointer) + if (!CLUTTER_ACTOR_IS_REACTIVE (actor) && priv->n_pointers > 0) { ClutterActor *stage = _clutter_actor_get_stage_internal (actor); clutter_stage_invalidate_focus (CLUTTER_STAGE (stage), actor); } + else if (CLUTTER_ACTOR_IS_REACTIVE (actor)) + { + ClutterActor *parent; + + /* Check whether the closest parent has pointer focus, + * and whether it should move to this actor. + */ + parent = priv->parent; + + while (parent) + { + if (CLUTTER_ACTOR_IS_REACTIVE (parent)) + break; + + parent = parent->priv->parent; + } + + if (parent && parent->priv->n_pointers > 0) + { + ClutterActor *stage = _clutter_actor_get_stage_internal (actor); + + clutter_stage_maybe_invalidate_focus (CLUTTER_STAGE (stage), parent); + } + } } /** @@ -14670,12 +14721,21 @@ { ClutterActorPrivate *priv = self->priv; - if (priv->has_pointer != has_pointer) + if (has_pointer) { - priv->has_pointer = has_pointer; + g_assert (CLUTTER_IS_STAGE (self) || CLUTTER_ACTOR_IS_MAPPED (self)); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_HAS_POINTER]); + priv->n_pointers++; } + else + { + g_assert (priv->n_pointers > 0); + + priv->n_pointers--; + } + + if (priv->n_pointers == 0 || priv->n_pointers == 1) + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_HAS_POINTER]); } void @@ -14746,7 +14806,7 @@ { g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - return self->priv->has_pointer; + return self->priv->n_pointers > 0; } /** @@ -16010,7 +16070,8 @@ ClutterActorPrivate *priv = self->priv; ClutterActor *child; - if (!CLUTTER_ACTOR_IS_MAPPED (self) || + if ((!CLUTTER_ACTOR_IS_MAPPED (self) && + !clutter_actor_has_mapped_clones (self)) || CLUTTER_ACTOR_IN_DESTRUCTION (self)) return; diff -Nru mutter-42.3/clutter/clutter/clutter-stage.c mutter-42.4/clutter/clutter/clutter-stage.c --- mutter-42.3/clutter/clutter/clutter-stage.c 2022-07-04 17:06:55.430000000 +0000 +++ mutter-42.4/clutter/clutter/clutter-stage.c 2022-08-11 15:46:25.990000000 +0000 @@ -3175,8 +3175,8 @@ } void -clutter_stage_invalidate_focus (ClutterStage *self, - ClutterActor *actor) +clutter_stage_maybe_invalidate_focus (ClutterStage *self, + ClutterActor *actor) { ClutterStagePrivate *priv = self->priv; GHashTableIter iter; @@ -3185,8 +3185,6 @@ if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) return; - g_assert (!clutter_actor_is_mapped (actor) || !clutter_actor_get_reactive (actor)); - g_hash_table_iter_init (&iter, priv->pointer_devices); while (g_hash_table_iter_next (&iter, NULL, &value)) { @@ -3220,6 +3218,18 @@ entry->coords, CLUTTER_CURRENT_TIME); } +} + +void +clutter_stage_invalidate_focus (ClutterStage *self, + ClutterActor *actor) +{ + if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) + return; + + g_assert (!clutter_actor_is_mapped (actor) || !clutter_actor_get_reactive (actor)); + + clutter_stage_maybe_invalidate_focus (self, actor); if (actor != CLUTTER_ACTOR (self)) g_assert (!clutter_actor_has_pointer (actor)); diff -Nru mutter-42.3/clutter/clutter/clutter-stage-private.h mutter-42.4/clutter/clutter/clutter-stage-private.h --- mutter-42.3/clutter/clutter/clutter-stage-private.h 2022-07-04 17:06:55.430000000 +0000 +++ mutter-42.4/clutter/clutter/clutter-stage-private.h 2022-08-11 15:46:25.980000000 +0000 @@ -159,6 +159,9 @@ void clutter_stage_invalidate_focus (ClutterStage *self, ClutterActor *actor); +void clutter_stage_maybe_invalidate_focus (ClutterStage *self, + ClutterActor *actor); + G_END_DECLS #endif /* __CLUTTER_STAGE_PRIVATE_H__ */ diff -Nru mutter-42.3/debian/changelog mutter-42.4/debian/changelog --- mutter-42.3/debian/changelog 2022-07-28 11:22:57.000000000 +0000 +++ mutter-42.4/debian/changelog 2022-08-12 00:05:18.000000000 +0000 @@ -1,3 +1,36 @@ +mutter (42.4-1ubuntu1) kinetic; urgency=medium + + * Merge from Debian unstable (LP: #1985856). Remaining changes: + - Add triple-buffering patch + - Add x11-Add-support-for-fractional-scaling-using-Randr.patch: + + X11: Add support for fractional scaling using Randr + - Add ubuntu/wayland-data-device-Allow-any-drag-timestamp....patch + + Allow any drag timestamp as drag start serial + - Add backends-native-kms-crtc-Don-t-compare-gamma-values-on-un.patch + + Avoid memory errors when comparing gamma values + - Add monitor-manager-Ensure-monitors-settings-after-backend-ha.patch + + Ensure privacy screen settings are applied on startup + - Add patches from GNOME !2364 + + Fix X11 selection related crash when Xwayland died + - debian/libmutter-10-0.symbols: Add symbols for triple buffering patch + * debian/patches: Refresh + + -- Marco Trevisan (Treviño) Fri, 12 Aug 2022 02:05:18 +0200 + +mutter (42.4-1) unstable; urgency=medium + + * New upstream release + * debian/patches: Refresh + * debian/libmutter-10-0.symbols: Sync with new and removed internal symbols + + -- Marco Trevisan (Treviño) Thu, 11 Aug 2022 19:21:12 -0400 + +mutter (42.3-2) unstable; urgency=medium + + * debian/libmutter-10-0.symbols: Add new symbols + + -- Jeremy Bicha Sat, 16 Jul 2022 14:14:30 +0200 + mutter (42.3-1ubuntu2) kinetic; urgency=medium * Rebuild against latest gnome-desktop diff -Nru mutter-42.3/debian/control mutter-42.4/debian/control --- mutter-42.3/debian/control 2022-07-14 15:26:15.000000000 +0000 +++ mutter-42.4/debian/control 2022-08-12 00:05:18.000000000 +0000 @@ -7,7 +7,7 @@ Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Debian GNOME Maintainers -Uploaders: Iain Lane , Jeremy Bicha , Laurent Bigonville +Uploaders: Jeremy Bicha , Laurent Bigonville Build-Depends: debhelper-compat (= 13), dh-exec, dh-sequence-gir, diff -Nru mutter-42.3/debian/libmutter-10-0.symbols mutter-42.4/debian/libmutter-10-0.symbols --- mutter-42.3/debian/libmutter-10-0.symbols 2022-07-14 15:26:15.000000000 +0000 +++ mutter-42.4/debian/libmutter-10-0.symbols 2022-08-12 00:05:18.000000000 +0000 @@ -638,6 +638,7 @@ meta_verify_monitor_spec@Base 3.28.2 meta_verify_monitors_config@Base 3.28.2 meta_virtual_modifier_get_type@Base 3.28.2 + meta_virtual_monitor_get_crtc_mode@Base 42.4 meta_virtual_monitor_get_output@Base 40.0 meta_virtual_monitor_info_free@Base 40.0 meta_virtual_monitor_info_new@Base 40.0 @@ -675,7 +676,6 @@ meta_window_allows_resize@Base 3.28.2 meta_window_appears_focused@Base 3.28.2 meta_window_begin_grab_op@Base 3.28.2 - meta_window_calculate_main_logical_monitor@Base 3.37.91 meta_window_can_close@Base 3.28.2 meta_window_can_maximize@Base 3.28.2 meta_window_can_minimize@Base 3.28.2 @@ -687,6 +687,7 @@ meta_window_client_type_get_type@Base 3.28.2 meta_window_compute_group@Base 3.28.2 meta_window_delete@Base 3.28.2 + meta_window_find_monitor_from_frame_rect@Base 42.4 meta_window_find_root_ancestor@Base 3.28.2 meta_window_focus@Base 3.28.2 meta_window_foreach_ancestor@Base 3.28.2 diff -Nru mutter-42.3/debian/patches/debian/meson-Do-not-mark-CI-test-tools-as-required.patch mutter-42.4/debian/patches/debian/meson-Do-not-mark-CI-test-tools-as-required.patch --- mutter-42.3/debian/patches/debian/meson-Do-not-mark-CI-test-tools-as-required.patch 2022-07-14 15:26:15.000000000 +0000 +++ mutter-42.4/debian/patches/debian/meson-Do-not-mark-CI-test-tools-as-required.patch 2022-08-12 00:05:18.000000000 +0000 @@ -8,7 +8,7 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build -index b19780a..25ac654 100644 +index 2e95ede..2ae3dd4 100644 --- a/meson.build +++ b/meson.build @@ -354,7 +354,7 @@ if have_tests diff -Nru mutter-42.3/debian/patches/debian/tests-Tag-unstable-tests-as-flaky.patch mutter-42.4/debian/patches/debian/tests-Tag-unstable-tests-as-flaky.patch --- mutter-42.3/debian/patches/debian/tests-Tag-unstable-tests-as-flaky.patch 2022-07-14 15:26:15.000000000 +0000 +++ mutter-42.4/debian/patches/debian/tests-Tag-unstable-tests-as-flaky.patch 2022-08-12 00:05:18.000000000 +0000 @@ -31,10 +31,10 @@ is_parallel: false, ) diff --git a/src/tests/meson.build b/src/tests/meson.build -index 2cb05d9..1b5e6e1 100644 +index ae8c0ca..572acac 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build -@@ -184,6 +184,7 @@ test_cases += [ +@@ -193,6 +193,7 @@ test_cases += [ }, { 'name': 'stage-views', @@ -42,7 +42,7 @@ 'suite': 'compositor', 'sources': [ 'stage-view-tests.c', ], }, -@@ -296,7 +297,8 @@ if have_native_tests +@@ -318,7 +319,8 @@ if have_native_tests ) test(test_case['name'], test_executable, diff -Nru mutter-42.3/debian/patches/meson-add-back-default_driver-option.patch mutter-42.4/debian/patches/meson-add-back-default_driver-option.patch --- mutter-42.3/debian/patches/meson-add-back-default_driver-option.patch 2022-07-14 15:26:15.000000000 +0000 +++ mutter-42.4/debian/patches/meson-add-back-default_driver-option.patch 2022-08-12 00:05:18.000000000 +0000 @@ -45,7 +45,7 @@ input: 'cogl-config.h.meson', output: 'cogl-config.h', diff --git a/meson.build b/meson.build -index a10232b..b19780a 100644 +index 05aeb46..2e95ede 100644 --- a/meson.build +++ b/meson.build @@ -247,6 +247,8 @@ if have_wayland_eglstream diff -Nru mutter-42.3/debian/patches/Support-Dynamic-triple-double-buffering.patch mutter-42.4/debian/patches/Support-Dynamic-triple-double-buffering.patch --- mutter-42.3/debian/patches/Support-Dynamic-triple-double-buffering.patch 2022-07-14 15:26:15.000000000 +0000 +++ mutter-42.4/debian/patches/Support-Dynamic-triple-double-buffering.patch 2022-08-12 00:05:18.000000000 +0000 @@ -798,7 +798,7 @@ return; diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c -index 9943562..0ae3050 100644 +index d19db04..19299d2 100644 --- a/src/backends/native/meta-kms-crtc.c +++ b/src/backends/native/meta-kms-crtc.c @@ -32,6 +32,12 @@ typedef struct _MetaKmsCrtcPropTable @@ -823,7 +823,7 @@ }; G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT) -@@ -467,20 +475,91 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device, +@@ -461,20 +469,91 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device, return crtc; } @@ -915,7 +915,7 @@ } static void -@@ -488,5 +567,6 @@ meta_kms_crtc_class_init (MetaKmsCrtcClass *klass) +@@ -482,5 +561,6 @@ meta_kms_crtc_class_init (MetaKmsCrtcClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -2515,10 +2515,10 @@ MetaDrmBuffer *fb); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c -index d538cc2..6ad3dba 100644 +index f5f22c7..d896114 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c -@@ -661,12 +661,18 @@ static gboolean +@@ -677,12 +677,18 @@ static gboolean dummy_power_save_page_flip_cb (gpointer user_data) { MetaRendererNative *renderer_native = user_data; @@ -2539,7 +2539,7 @@ renderer_native->power_save_page_flip_source_id = 0; return G_SOURCE_REMOVE; -@@ -678,6 +684,9 @@ meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_na +@@ -694,6 +700,9 @@ meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_na { const unsigned int timeout_ms = 100; @@ -2549,7 +2549,7 @@ if (!renderer_native->power_save_page_flip_source_id) { renderer_native->power_save_page_flip_source_id = -@@ -1386,6 +1395,26 @@ meta_renderer_native_create_view (MetaRenderer *renderer, +@@ -1402,6 +1411,26 @@ meta_renderer_native_create_view (MetaRenderer *renderer, return view; } @@ -2576,7 +2576,7 @@ static void keep_current_onscreens_alive (MetaRenderer *renderer) { -@@ -1414,6 +1443,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer) +@@ -1430,6 +1459,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer) MetaRendererClass *parent_renderer_class = META_RENDERER_CLASS (meta_renderer_native_parent_class); diff -Nru mutter-42.3/debian/patches/ubuntu/x11-Add-support-for-fractional-scaling-using-Randr.patch mutter-42.4/debian/patches/ubuntu/x11-Add-support-for-fractional-scaling-using-Randr.patch --- mutter-42.3/debian/patches/ubuntu/x11-Add-support-for-fractional-scaling-using-Randr.patch 2022-07-14 15:26:15.000000000 +0000 +++ mutter-42.4/debian/patches/ubuntu/x11-Add-support-for-fractional-scaling-using-Randr.patch 2022-08-12 00:05:18.000000000 +0000 @@ -514,7 +514,7 @@ settings, META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER)) diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h -index 12bb840..2e78b77 100644 +index edf7e45..1901847 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -48,7 +48,9 @@ typedef enum _MetaMonitorManagerCapability @@ -538,7 +538,7 @@ } MetaLogicalMonitorLayoutMode; /* The source the privacy screen change has been triggered */ -@@ -85,6 +88,7 @@ struct _MetaCrtcAssignment +@@ -86,6 +89,7 @@ struct _MetaCrtcAssignment MetaCrtc *crtc; MetaCrtcMode *mode; graphene_rect_t layout; @@ -546,7 +546,7 @@ MetaMonitorTransform transform; GPtrArray *outputs; }; -@@ -146,6 +150,7 @@ struct _MetaMonitorManager +@@ -147,6 +151,7 @@ struct _MetaMonitorManager int screen_height; GList *monitors; @@ -554,7 +554,7 @@ GList *logical_monitors; MetaLogicalMonitor *primary_logical_monitor; -@@ -162,6 +167,8 @@ struct _MetaMonitorManager +@@ -163,6 +168,8 @@ struct _MetaMonitorManager GnomePnpIds *pnp_ids; #endif @@ -563,7 +563,7 @@ MetaMonitorSwitchConfigType current_switch_config; MetaPrivacyScreenChangeState privacy_screen_change_state; -@@ -179,6 +186,9 @@ struct _MetaMonitorManager +@@ -180,6 +187,9 @@ struct _MetaMonitorManager * @apply_monitors_config: Tries to apply the given config using the given * method. Throws an error if something went wrong. * @@ -573,7 +573,7 @@ * @set_power_save_mode: Sets the #MetaPowerSave mode (for all displays). * * @change_backlight: Changes the backlight intensity to the given value (in -@@ -248,6 +258,9 @@ struct _MetaMonitorManagerClass +@@ -249,6 +259,9 @@ struct _MetaMonitorManagerClass gboolean (* set_privacy_screen_enabled) (MetaMonitorManager *manager, gboolean enabled); @@ -583,7 +583,7 @@ void (* tiled_monitor_added) (MetaMonitorManager *manager, MetaMonitor *monitor); -@@ -403,6 +416,11 @@ gboolean meta_monitor_manager_is_scale_supported (MetaMonitorManager +@@ -404,6 +417,11 @@ gboolean meta_monitor_manager_is_scale_supported (MetaMonitorManager MetaMonitorMode *monitor_mode, float scale); @@ -596,7 +596,7 @@ meta_monitor_manager_get_capabilities (MetaMonitorManager *manager); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c -index 67361ad..edb45e1 100644 +index be99b46..9bdd577 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -124,6 +124,15 @@ static gboolean @@ -899,7 +899,7 @@ if (should_reconfigure) meta_monitor_manager_reconfigure (manager); -@@ -1195,10 +1384,11 @@ meta_monitor_manager_constructed (GObject *object) +@@ -1200,10 +1389,11 @@ meta_monitor_manager_constructed (GObject *object) manager->display_config = meta_dbus_display_config_skeleton_new (); @@ -915,7 +915,7 @@ g_signal_connect_object (settings, "privacy-screen-changed", -@@ -1761,6 +1951,33 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, +@@ -1767,6 +1957,33 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, return TRUE; } @@ -949,7 +949,7 @@ static void restore_previous_config (MetaMonitorManager *manager) { -@@ -1786,6 +2003,8 @@ restore_previous_config (MetaMonitorManager *manager) +@@ -1792,6 +2009,8 @@ restore_previous_config (MetaMonitorManager *manager) g_set_object (&previous_config, oriented_config); } @@ -958,7 +958,7 @@ method = META_MONITORS_CONFIG_METHOD_TEMPORARY; if (meta_monitor_manager_apply_monitors_config (manager, previous_config, -@@ -1842,6 +2061,41 @@ request_persistent_confirmation (MetaMonitorManager *manager) +@@ -1848,6 +2067,41 @@ request_persistent_confirmation (MetaMonitorManager *manager) g_signal_emit (manager, signals[CONFIRM_DISPLAY_CHANGE], 0); } @@ -1000,7 +1000,7 @@ #define META_DISPLAY_CONFIG_MODE_FLAGS_PREFERRED (1 << 0) #define META_DISPLAY_CONFIG_MODE_FLAGS_CURRENT (1 << 1) -@@ -1869,6 +2123,7 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, +@@ -1875,6 +2129,7 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, MetaMonitorManagerCapability capabilities; int ui_scaling_factor; int max_screen_width, max_screen_height; @@ -1008,7 +1008,7 @@ g_variant_builder_init (&monitors_builder, G_VARIANT_TYPE (MONITORS_FORMAT)); -@@ -2037,6 +2292,14 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, +@@ -2043,6 +2298,14 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, } g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}")); @@ -1023,7 +1023,7 @@ capabilities = meta_monitor_manager_get_capabilities (manager); g_variant_builder_add (&properties_builder, "{sv}", -@@ -2055,6 +2318,14 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, +@@ -2061,6 +2324,14 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, "global-scale-required", g_variant_new_boolean (TRUE)); } @@ -1038,7 +1038,7 @@ ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); g_variant_builder_add (&properties_builder, "{sv}", -@@ -2099,12 +2370,14 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, +@@ -2105,12 +2376,14 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, #undef LOGICAL_MONITOR_FORMAT #undef LOGICAL_MONITORS_FORMAT @@ -1059,7 +1059,7 @@ { g_autofree float *supported_scales = NULL; int n_supported_scales; -@@ -2118,13 +2391,34 @@ meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager, +@@ -2124,13 +2397,34 @@ meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager, &n_supported_scales); for (i = 0; i < n_supported_scales; i++) { @@ -1096,7 +1096,7 @@ static gboolean is_global_scale_matching_in_config (MetaMonitorsConfig *config, float scale) -@@ -2425,6 +2719,7 @@ derive_logical_monitor_size (MetaMonitorConfig *monitor_config, +@@ -2431,6 +2725,7 @@ derive_logical_monitor_size (MetaMonitorConfig *monitor_config, switch (layout_mode) { case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: @@ -1104,7 +1104,7 @@ width = roundf (width / scale); height = roundf (height / scale); break; -@@ -2524,9 +2819,11 @@ create_logical_monitor_config_from_variant (MetaMonitorManager *manager +@@ -2530,9 +2825,11 @@ create_logical_monitor_config_from_variant (MetaMonitorManager *manager .monitor_configs = monitor_configs }; @@ -1117,7 +1117,7 @@ error)) { meta_logical_monitor_config_free (logical_monitor_config); -@@ -2547,6 +2844,7 @@ is_valid_layout_mode (MetaLogicalMonitorLayoutMode layout_mode) +@@ -2553,6 +2850,7 @@ is_valid_layout_mode (MetaLogicalMonitorLayoutMode layout_mode) { case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: @@ -1125,7 +1125,7 @@ return TRUE; } -@@ -2571,6 +2869,7 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet +@@ -2577,6 +2875,7 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet MetaMonitorsConfig *config; GList *logical_monitor_configs = NULL; GError *error = NULL; @@ -1133,7 +1133,7 @@ if (serial != manager->serial) { -@@ -2654,10 +2953,42 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet +@@ -2660,10 +2959,42 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet return TRUE; } @@ -1176,7 +1176,7 @@ config = meta_monitors_config_new (manager, logical_monitor_configs, layout_mode, -@@ -3350,6 +3681,10 @@ rebuild_monitors (MetaMonitorManager *manager) +@@ -3356,6 +3687,10 @@ rebuild_monitors (MetaMonitorManager *manager) { GList *gpus; GList *l; @@ -1187,7 +1187,7 @@ if (manager->monitors) { -@@ -3368,7 +3703,7 @@ rebuild_monitors (MetaMonitorManager *manager) +@@ -3374,7 +3709,7 @@ rebuild_monitors (MetaMonitorManager *manager) MetaOutput *output = k->data; const MetaOutputInfo *output_info = meta_output_get_info (output); @@ -1196,7 +1196,7 @@ { if (is_main_tiled_monitor_output (output)) { -@@ -3591,7 +3926,7 @@ meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager, +@@ -3597,7 +3932,7 @@ meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager, else manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; @@ -1205,7 +1205,7 @@ meta_monitor_manager_rebuild_logical_monitors_derived (manager, config); } -@@ -3600,10 +3935,14 @@ void +@@ -3606,10 +3941,14 @@ void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager, MetaMonitorsConfig *config) { @@ -2889,7 +2889,7 @@ out: set_unredirected_window (compositor_x11, window_to_unredirect); diff --git a/src/core/window.c b/src/core/window.c -index e22bd5a..5b9283f 100644 +index e7278e4..03b1aca 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -218,6 +218,7 @@ enum diff -Nru mutter-42.3/meson.build mutter-42.4/meson.build --- mutter-42.3/meson.build 2022-07-04 17:06:55.490000000 +0000 +++ mutter-42.4/meson.build 2022-08-11 15:46:26.050000000 +0000 @@ -1,5 +1,5 @@ project('mutter', 'c', - version: '42.3', + version: '42.4', meson_version: '>= 0.55.0', license: 'GPLv2+' ) diff -Nru mutter-42.3/NEWS mutter-42.4/NEWS --- mutter-42.3/NEWS 2022-07-04 17:06:55.390000000 +0000 +++ mutter-42.4/NEWS 2022-08-11 15:46:25.940000000 +0000 @@ -1,3 +1,20 @@ +42.4 +==== +* screencast: Set correct stride when using dmabufs [Pascal; !2514] +* Fix glitches in apps using subsurfaces [Robert; !2501, !2530] +* Reduce client work when entering overview [Robert; !2502] +* Highlight actors becoming reactive under the pointer [Carlos; !2533] +* Fall back to ARGB if XRGB is not supported [Daniel; !2519] +* Support direct scanout on GPUs without modifiers support [Dor; !2510] +* Fix registering as X11 window manager if GDK_BACKEND is set [Michel; !2496] +* Fixed crash [Jonas Å.; !2554] +* Plugged leak [Sebastian; !2497] +* Misc. bug fixes and cleanups [Jonas D., Dor; !2348, !2406] + +Contributors: + Dor Askayo, Jonas Dreßler, Michel Dänzer, Carlos Garnacho, Sebastian Keller, + Robert Mader, Pascal Nowack, Daniel van Vugt, Jonas Ådahl + 42.3 ==== * wayland: Fix rotation transform [Robert; !1055] diff -Nru mutter-42.3/src/backends/meta-screen-cast-stream-src.c mutter-42.4/src/backends/meta-screen-cast-stream-src.c --- mutter-42.3/src/backends/meta-screen-cast-stream-src.c 2022-07-04 17:06:55.570000000 +0000 +++ mutter-42.4/src/backends/meta-screen-cast-stream-src.c 2022-08-11 15:46:26.150000000 +0000 @@ -78,7 +78,7 @@ typedef struct _MetaPipeWireSource { - GSource base; + GSource source; MetaScreenCastStreamSrc *src; struct pw_loop *pipewire_loop; @@ -90,7 +90,7 @@ struct pw_context *pipewire_context; struct pw_core *pipewire_core; - MetaPipeWireSource *pipewire_source; + GSource *pipewire_source; struct spa_hook pipewire_core_listener; gboolean is_enabled; @@ -569,6 +569,26 @@ src); } +static int32_t +meta_screen_cast_stream_src_calculate_stride (MetaScreenCastStreamSrc *src, + struct spa_data *spa_data) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + CoglDmaBufHandle *dmabuf_handle = NULL; + + if (spa_data->type == SPA_DATA_DmaBuf) + { + dmabuf_handle = g_hash_table_lookup (priv->dmabuf_handles, + GINT_TO_POINTER (spa_data->fd)); + } + + if (dmabuf_handle) + return cogl_dma_buf_handle_get_stride (dmabuf_handle); + else + return priv->video_stride; +} + void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src, MetaScreenCastRecordFlag flags) @@ -631,10 +651,12 @@ g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove); if (do_record_frame (src, flags, spa_buffer, data, &error)) { + struct spa_data *spa_data = &spa_buffer->datas[0]; struct spa_meta_region *spa_meta_video_crop; - spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize; - spa_buffer->datas[0].chunk->stride = priv->video_stride; + spa_data->chunk->size = spa_data->maxsize; + spa_data->chunk->stride = + meta_screen_cast_stream_src_calculate_stride (src, spa_data); /* Update VideoCrop if needed */ spa_meta_video_crop = @@ -1145,7 +1167,7 @@ } static gboolean -pipewire_loop_source_prepare (GSource *base, +pipewire_loop_source_prepare (GSource *source, int *timeout) { *timeout = -1; @@ -1190,24 +1212,21 @@ pipewire_loop_source_finalize }; -static MetaPipeWireSource * -create_pipewire_source (MetaScreenCastStreamSrc *src) +static GSource * +create_pipewire_source (MetaScreenCastStreamSrc *src, + struct pw_loop *pipewire_loop) { GSource *source; MetaPipeWireSource *pipewire_source; source = g_source_new (&pipewire_source_funcs, sizeof (MetaPipeWireSource)); g_source_set_name (source, "[mutter] PipeWire"); + pipewire_source = (MetaPipeWireSource *) source; pipewire_source->src = src; - pipewire_source->pipewire_loop = pw_loop_new (NULL); - if (!pipewire_source->pipewire_loop) - { - g_source_unref ((GSource *) pipewire_source); - return NULL; - } + pipewire_source->pipewire_loop = pipewire_loop; - g_source_add_unix_fd (&pipewire_source->base, + g_source_add_unix_fd (source, pw_loop_get_fd (pipewire_source->pipewire_loop), G_IO_IN | G_IO_ERR); @@ -1215,7 +1234,7 @@ g_source_attach (source, NULL); g_source_unref (source); - return pipewire_source; + return source; } static const struct pw_core_events core_events = { @@ -1231,8 +1250,17 @@ MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (initable); MetaScreenCastStreamSrcPrivate *priv = meta_screen_cast_stream_src_get_instance_private (src); + struct pw_loop *pipewire_loop; + + pipewire_loop = pw_loop_new (NULL); + if (!pipewire_loop) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to create PipeWire loop"); + return FALSE; + } - priv->pipewire_source = create_pipewire_source (src); + priv->pipewire_source = create_pipewire_source (src, pipewire_loop); if (!priv->pipewire_source) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -1240,7 +1268,7 @@ return FALSE; } - priv->pipewire_context = pw_context_new (priv->pipewire_source->pipewire_loop, + priv->pipewire_context = pw_context_new (pipewire_loop, NULL, 0); if (!priv->pipewire_context) { @@ -1298,7 +1326,7 @@ g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy); g_clear_pointer (&priv->pipewire_core, pw_core_disconnect); g_clear_pointer (&priv->pipewire_context, pw_context_destroy); - g_clear_pointer ((GSource **) &priv->pipewire_source, g_source_destroy); + g_clear_pointer (&priv->pipewire_source, g_source_destroy); G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->dispose (object); } diff -Nru mutter-42.3/src/backends/meta-virtual-monitor.h mutter-42.4/src/backends/meta-virtual-monitor.h --- mutter-42.3/src/backends/meta-virtual-monitor.h 2022-07-04 17:06:55.570000000 +0000 +++ mutter-42.4/src/backends/meta-virtual-monitor.h 2022-08-11 15:46:26.160000000 +0000 @@ -70,6 +70,7 @@ MetaCrtc * meta_virtual_monitor_get_crtc (MetaVirtualMonitor *virtual_monitor); +META_EXPORT_TEST MetaCrtcMode * meta_virtual_monitor_get_crtc_mode (MetaVirtualMonitor *virtual_monitor); META_EXPORT_TEST diff -Nru mutter-42.3/src/backends/native/meta-pointer-constraint-native.c mutter-42.4/src/backends/native/meta-pointer-constraint-native.c --- mutter-42.3/src/backends/native/meta-pointer-constraint-native.c 2022-07-04 17:06:55.580000000 +0000 +++ mutter-42.4/src/backends/native/meta-pointer-constraint-native.c 2022-08-11 15:46:26.170000000 +0000 @@ -469,7 +469,7 @@ MetaPointerConstraintImplNative *constraint_impl_native; cairo_region_t *region; float x, y; - GArray *borders; + g_autoptr (GArray) borders = NULL; MetaLine2 motion; MetaBorder *closest_border; uint32_t directions; @@ -527,7 +527,6 @@ *x_inout = motion.b.x; *y_inout = motion.b.y; - g_array_free (borders, FALSE); } static float @@ -616,7 +615,7 @@ if (!cairo_region_contains_point (region, (int) x, (int) y)) { - GArray *borders; + g_autoptr (GArray) borders = NULL; float closest_distance_2 = FLT_MAX; MetaBorder *closest_border = NULL; ClutterSeat *seat; diff -Nru mutter-42.3/src/backends/native/meta-renderer-native.c mutter-42.4/src/backends/native/meta-renderer-native.c --- mutter-42.3/src/backends/native/meta-renderer-native.c 2022-07-04 17:06:55.590000000 +0000 +++ mutter-42.4/src/backends/native/meta-renderer-native.c 2022-08-11 15:46:26.170000000 +0000 @@ -416,12 +416,28 @@ switch (renderer_gpu_data->mode) { case META_RENDERER_NATIVE_MODE_GBM: - return choose_egl_config_from_gbm_format (egl, - egl_display, - attributes, - GBM_FORMAT_XRGB8888, - out_config, - error); + { + static const uint32_t formats[] = { + GBM_FORMAT_XRGB8888, + GBM_FORMAT_ARGB8888, + }; + int i; + + for (i = 0; i < G_N_ELEMENTS (formats); i++) + { + g_clear_error (error); + + if (choose_egl_config_from_gbm_format (egl, + egl_display, + attributes, + formats[i], + out_config, + error)) + return TRUE; + } + + return FALSE; + } case META_RENDERER_NATIVE_MODE_SURFACELESS: *out_config = EGL_NO_CONFIG_KHR; return TRUE; diff -Nru mutter-42.3/src/compositor/meta-window-actor-wayland.c mutter-42.4/src/compositor/meta-window-actor-wayland.c --- mutter-42.3/src/compositor/meta-window-actor-wayland.c 2022-07-04 17:06:55.600000000 +0000 +++ mutter-42.4/src/compositor/meta-window-actor-wayland.c 2022-08-11 15:46:26.190000000 +0000 @@ -39,27 +39,42 @@ } SurfaceTreeTraverseData; static gboolean +get_surface_actor_list (GNode *node, + gpointer data) +{ + MetaWaylandSurface *surface = node->data; + MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); + GList **surface_actors = data; + + *surface_actors = g_list_prepend (*surface_actors, surface_actor); + return FALSE; +} + +static gboolean set_surface_actor_index (GNode *node, gpointer data) { MetaWaylandSurface *surface = node->data; - MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); SurfaceTreeTraverseData *traverse_data = data; + ClutterActor *window_actor = CLUTTER_ACTOR (traverse_data->window_actor); + ClutterActor *surface_actor = + CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)); - if (clutter_actor_contains (CLUTTER_ACTOR (traverse_data->window_actor), - CLUTTER_ACTOR (surface_actor))) + if (clutter_actor_contains (window_actor, surface_actor)) { - clutter_actor_set_child_at_index ( - CLUTTER_ACTOR (traverse_data->window_actor), - CLUTTER_ACTOR (surface_actor), - traverse_data->index); + if (clutter_actor_get_child_at_index (window_actor, traverse_data->index) != + surface_actor) + { + clutter_actor_set_child_at_index (window_actor, + surface_actor, + traverse_data->index); + } } else { - clutter_actor_insert_child_at_index ( - CLUTTER_ACTOR (traverse_data->window_actor), - CLUTTER_ACTOR (surface_actor), - traverse_data->index); + clutter_actor_insert_child_at_index (window_actor, + surface_actor, + traverse_data->index); } traverse_data->index++; @@ -74,8 +89,28 @@ MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface ( META_SURFACE_ACTOR_WAYLAND (surface_actor)); GNode *root_node = surface->subsurface_branch_node; + g_autoptr (GList) surface_actors = NULL; + g_autoptr (GList) children = NULL; + GList *l; SurfaceTreeTraverseData traverse_data; + g_node_traverse (root_node, + G_IN_ORDER, + G_TRAVERSE_LEAVES, + -1, + get_surface_actor_list, + &surface_actors); + + children = clutter_actor_get_children (CLUTTER_ACTOR (actor)); + for (l = children; l; l = l->next) + { + ClutterActor *child_actor = l->data; + + if (META_IS_SURFACE_ACTOR_WAYLAND (child_actor) && + !g_list_find (surface_actors, child_actor)) + clutter_actor_remove_child (CLUTTER_ACTOR (actor), child_actor); + } + traverse_data = (SurfaceTreeTraverseData) { .window_actor = actor, .index = 0, diff -Nru mutter-42.3/src/core/window.c mutter-42.4/src/core/window.c --- mutter-42.3/src/core/window.c 2022-07-04 17:06:55.620000000 +0000 +++ mutter-42.4/src/core/window.c 2022-08-11 15:46:26.200000000 +0000 @@ -934,7 +934,7 @@ } MetaLogicalMonitor * -meta_window_calculate_main_logical_monitor (MetaWindow *window) +meta_window_find_monitor_from_frame_rect (MetaWindow *window) { MetaBackend *backend = meta_get_backend (); MetaMonitorManager *monitor_manager = @@ -1160,7 +1160,7 @@ window->compositor_private = NULL; if (window->rect.width > 0 && window->rect.height > 0) - window->monitor = meta_window_calculate_main_logical_monitor (window); + window->monitor = meta_window_find_monitor_from_frame_rect (window); else window->monitor = meta_backend_get_current_logical_monitor (backend); @@ -3646,12 +3646,38 @@ return NULL; } +MetaLogicalMonitor * +meta_window_find_monitor_from_id (MetaWindow *window) +{ + MetaContext *context = meta_display_get_context (window->display); + MetaBackend *backend = meta_context_get_backend (context); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *old_monitor = window->monitor; + MetaLogicalMonitor *new_monitor; + + new_monitor = find_monitor_by_winsys_id (window, + window->preferred_output_winsys_id); + + if (old_monitor && !new_monitor) + new_monitor = find_monitor_by_winsys_id (window, old_monitor->winsys_id); + + if (!new_monitor) + { + new_monitor = + meta_monitor_manager_get_primary_logical_monitor (monitor_manager); + } + + return new_monitor; +} + /* This is called when the monitor setup has changed. The window->monitor * reference is still "valid", but refer to the previous monitor setup */ void meta_window_update_for_monitors_changed (MetaWindow *window) { - MetaBackend *backend = meta_get_backend (); + MetaContext *context = meta_display_get_context (window->display); + MetaBackend *backend = meta_context_get_backend (context); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); const MetaLogicalMonitor *old, *new; @@ -3667,17 +3693,7 @@ } old = window->monitor; - - /* Try the preferred output first */ - new = find_monitor_by_winsys_id (window, window->preferred_output_winsys_id); - - /* Otherwise, try to find the old output on a new monitor */ - if (old && !new) - new = find_monitor_by_winsys_id (window, old->winsys_id); - - /* Fall back to primary if everything else failed */ - if (!new) - new = meta_monitor_manager_get_primary_logical_monitor (monitor_manager); + new = meta_window_find_monitor_from_id (window); if (window->tile_mode != META_TILE_NONE) { diff -Nru mutter-42.3/src/core/window-private.h mutter-42.4/src/core/window-private.h --- mutter-42.3/src/core/window-private.h 2022-07-04 17:06:55.620000000 +0000 +++ mutter-42.4/src/core/window-private.h 2022-08-11 15:46:26.200000000 +0000 @@ -849,7 +849,9 @@ MetaWorkspace *workspace); META_EXPORT_TEST -MetaLogicalMonitor * meta_window_calculate_main_logical_monitor (MetaWindow *window); +MetaLogicalMonitor * meta_window_find_monitor_from_frame_rect (MetaWindow *window); + +MetaLogicalMonitor * meta_window_find_monitor_from_id (MetaWindow *window); MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window); void meta_window_update_monitor (MetaWindow *window, diff -Nru mutter-42.3/src/tests/meson.build mutter-42.4/src/tests/meson.build --- mutter-42.3/src/tests/meson.build 2022-07-04 17:06:55.640000000 +0000 +++ mutter-42.4/src/tests/meson.build 2022-08-11 15:46:26.220000000 +0000 @@ -354,6 +354,7 @@ 'modals', 'map-fixed-size', 'client-resize-respect-constraints', + 'map-on-hotplug', ] foreach stacking_test: stacking_tests diff -Nru mutter-42.3/src/tests/screen-cast-client.c mutter-42.4/src/tests/screen-cast-client.c --- mutter-42.3/src/tests/screen-cast-client.c 2022-07-04 17:06:55.650000000 +0000 +++ mutter-42.4/src/tests/screen-cast-client.c 2022-08-11 15:46:26.230000000 +0000 @@ -83,18 +83,18 @@ typedef struct _PipeWireSource { - GSource base; + GSource source; struct pw_loop *pipewire_loop; } PipeWireSource; -static PipeWireSource *_pipewire_source; +static GSource *_pipewire_source; static struct pw_context *_pipewire_context; static struct pw_core *_pipewire_core; static struct spa_hook _pipewire_core_listener; static gboolean -pipewire_loop_source_prepare (GSource *base, +pipewire_loop_source_prepare (GSource *source, int *timeout) { *timeout = -1; @@ -133,24 +133,26 @@ pipewire_loop_source_finalize }; -static PipeWireSource * -create_pipewire_source (void) +static GSource * +create_pipewire_source (struct pw_loop *pipewire_loop) { + GSource *source; PipeWireSource *pipewire_source; - pipewire_source = - (PipeWireSource *) g_source_new (&pipewire_source_funcs, - sizeof (PipeWireSource)); - pipewire_source->pipewire_loop = pw_loop_new (NULL); - g_assert_nonnull (pipewire_source->pipewire_loop); - g_source_add_unix_fd (&pipewire_source->base, + source = g_source_new (&pipewire_source_funcs, + sizeof (PipeWireSource)); + + pipewire_source = (PipeWireSource *) source; + pipewire_source->pipewire_loop = pipewire_loop; + + g_source_add_unix_fd (source, pw_loop_get_fd (pipewire_source->pipewire_loop), G_IO_IN | G_IO_ERR); pw_loop_enter (pipewire_source->pipewire_loop); - g_source_attach (&pipewire_source->base, NULL); + g_source_attach (source, NULL); - return pipewire_source; + return source; } static void @@ -171,9 +173,15 @@ static void init_pipewire (void) { + struct pw_loop *pipewire_loop; + pw_init (NULL, NULL); - _pipewire_source = create_pipewire_source (); - _pipewire_context = pw_context_new (_pipewire_source->pipewire_loop, + + pipewire_loop = pw_loop_new (NULL); + g_assert_nonnull (pipewire_loop); + + _pipewire_source = create_pipewire_source (pipewire_loop); + _pipewire_context = pw_context_new (pipewire_loop, NULL, 0); g_assert_nonnull (_pipewire_context); _pipewire_core = pw_context_connect (_pipewire_context, NULL, 0); @@ -192,8 +200,8 @@ g_clear_pointer (&_pipewire_context, pw_context_destroy); if (_pipewire_source) { - g_source_destroy ((GSource *) _pipewire_source); - g_source_unref ((GSource *) _pipewire_source); + g_source_destroy (_pipewire_source); + g_source_unref (_pipewire_source); _pipewire_source = NULL; } } diff -Nru mutter-42.3/src/tests/stacking/client-resize-respect-constraints.metatest mutter-42.4/src/tests/stacking/client-resize-respect-constraints.metatest --- mutter-42.3/src/tests/stacking/client-resize-respect-constraints.metatest 2022-07-04 17:06:55.650000000 +0000 +++ mutter-42.4/src/tests/stacking/client-resize-respect-constraints.metatest 2022-08-11 15:46:26.230000000 +0000 @@ -4,6 +4,8 @@ # 3. Resize such that the following resize will extend beyond the screen # 4. Check that the window was moved to the position that would allow it to fit on the screen +resize_monitor primary 800 600 + new_client w wayland create w/1 csd diff -Nru mutter-42.3/src/tests/stacking/map-on-hotplug.metatest mutter-42.4/src/tests/stacking/map-on-hotplug.metatest --- mutter-42.3/src/tests/stacking/map-on-hotplug.metatest 1970-01-01 00:00:00.000000000 +0000 +++ mutter-42.4/src/tests/stacking/map-on-hotplug.metatest 2022-08-11 15:46:26.230000000 +0000 @@ -0,0 +1,20 @@ +# Test that monitor hotplugs with unmapped windows are handled + +new_client w wayland + +create w/1 csd +freeze w/1 +resize w/1 100 200 +show w/1 async + +resize_monitor primary 1024 768 + +wait + +thaw w/1 +wait +sync_shown w/1 +assert_stacking w/1 +assert_size w/1 100 200 + +destroy w/1 diff -Nru mutter-42.3/src/tests/test-runner.c mutter-42.4/src/tests/test-runner.c --- mutter-42.3/src/tests/test-runner.c 2022-07-04 17:06:55.650000000 +0000 +++ mutter-42.4/src/tests/test-runner.c 2022-08-11 15:46:26.230000000 +0000 @@ -24,6 +24,7 @@ #include #include +#include "backends/meta-virtual-monitor.h" #include "core/window-private.h" #include "meta-test/meta-context-test.h" #include "meta/util.h" @@ -41,6 +42,7 @@ GString *warning_messages; GMainLoop *loop; gulong x11_display_opened_handler_id; + MetaVirtualMonitor *virtual_monitor; } TestCase; static gboolean @@ -82,25 +84,22 @@ TestCase *test = g_new0 (TestCase, 1); MetaDisplay *display = meta_context_get_display (context); - if (!meta_is_wayland_compositor ()) + if (display->x11_display) { - meta_context_test_wait_for_x11_display (META_CONTEXT_TEST (context)); on_x11_display_opened (display, test); } else { - if (display->x11_display) - on_x11_display_opened (display, test); - else - test->x11_display_opened_handler_id = - g_signal_connect (meta_get_display (), "x11-display-opened", - G_CALLBACK (on_x11_display_opened), - test); + test->x11_display_opened_handler_id = + g_signal_connect (meta_get_display (), "x11-display-opened", + G_CALLBACK (on_x11_display_opened), + test); } test->context = context; test->clients = g_hash_table_new (g_str_hash, g_str_equal); test->loop = g_main_loop_new (NULL, FALSE); + test->virtual_monitor = meta_create_test_monitor (context, 800, 600, 60.0); return test; } @@ -119,6 +118,9 @@ test_case_dispatch (TestCase *test, GError **error) { + MetaBackend *backend = meta_context_get_backend (test->context); + ClutterActor *stage = meta_backend_get_stage (backend); + /* Wait until we've done any outstanding queued up work. * Though we add this as BEFORE_REDRAW, the iteration that runs the * BEFORE_REDRAW idles will proceed on and do the redraw, so we're @@ -128,6 +130,8 @@ test_case_loop_quit, test, NULL); + + clutter_stage_schedule_update (CLUTTER_STAGE (stage)); g_main_loop_run (test->loop); return TRUE; @@ -439,7 +443,7 @@ MetaRectangle logical_monitor_layout; int value; - logical_monitor = meta_window_calculate_main_logical_monitor (window); + logical_monitor = meta_window_find_monitor_from_frame_rect (window); g_assert_nonnull (logical_monitor); logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); @@ -634,6 +638,24 @@ if (!show_async) meta_test_client_wait_for_window_shown (client, window); } + else if (strcmp (argv[0], "sync_shown") == 0) + { + MetaWindow *window; + MetaTestClient *client; + const char *window_id; + + if (argc != 2) + BAD_COMMAND("usage: %s /", argv[0]); + + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + window = meta_test_client_find_window (client, window_id, error); + if (!window) + return FALSE; + + meta_test_client_wait_for_window_shown (client, window); + } else if (strcmp (argv[0], "resize") == 0) { if (argc != 4) @@ -985,6 +1007,29 @@ if (!meta_test_client_do (client, error, argv[0], argv[2], argv[3], NULL)) return FALSE; } + else if (strcmp (argv[0], "resize_monitor") == 0) + { + MetaBackend *backend = meta_context_get_backend (test->context); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaCrtcMode *crtc_mode; + const MetaCrtcModeInfo *crtc_mode_info; + + if (argc != 4) + BAD_COMMAND ("usage: %s ", argv[0]); + + if (strcmp (argv[1], "0") != 0 && + strcmp (argv[1], "primary") != 0) + BAD_COMMAND ("Unknown monitor %s", argv[1]); + + crtc_mode = meta_virtual_monitor_get_crtc_mode (test->virtual_monitor); + crtc_mode_info = meta_crtc_mode_get_info (crtc_mode); + meta_virtual_monitor_set_mode (test->virtual_monitor, + atoi (argv[2]), + atoi (argv[3]), + crtc_mode_info->refresh_rate); + meta_monitor_manager_reload (monitor_manager); + } else { BAD_COMMAND("Unknown command %s", argv[0]); @@ -1031,6 +1076,7 @@ meta_x11_display_set_alarm_filter (display->x11_display, NULL, NULL); g_hash_table_destroy (test->clients); + g_object_unref (test->virtual_monitor); g_free (test); return TRUE; @@ -1165,6 +1211,7 @@ success = FALSE; } + return success ? 0 : 1; } @@ -1243,7 +1290,7 @@ GPtrArray *tests; RunTestsInfo info; - context = meta_create_test_context (META_CONTEXT_TEST_TYPE_NESTED, + context = meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS, META_CONTEXT_TEST_FLAG_TEST_CLIENT); meta_context_add_option_entries (context, options, NULL); diff -Nru mutter-42.3/src/wayland/meta-wayland-actor-surface.c mutter-42.4/src/wayland/meta-wayland-actor-surface.c --- mutter-42.3/src/wayland/meta-wayland-actor-surface.c 2022-07-04 17:06:55.660000000 +0000 +++ mutter-42.4/src/wayland/meta-wayland-actor-surface.c 2022-08-11 15:46:26.230000000 +0000 @@ -321,42 +321,29 @@ { MetaWaylandActorSurfacePrivate *priv = meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role)); + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); ClutterActor *actor = CLUTTER_ACTOR (priv->actor); - float x, y, width, height; - cairo_rectangle_int_t actor_rect; - cairo_region_t *region; MetaRectangle logical_monitor_layout; - gboolean is_on_monitor; - - if (!clutter_actor_is_mapped (actor) && - !clutter_actor_has_mapped_clones (actor)) - return FALSE; - - clutter_actor_get_transformed_position (actor, &x, &y); - clutter_actor_get_transformed_size (actor, &width, &height); - - actor_rect.x = (int) roundf (x); - actor_rect.y = (int) roundf (y); - actor_rect.width = (int) roundf (x + width) - actor_rect.x; - actor_rect.height = (int) roundf (y + height) - actor_rect.y; - - /* Calculate the scaled surface actor region. */ - region = cairo_region_create_rectangle (&actor_rect); + GList *l; logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); - cairo_region_intersect_rectangle (region, - &((cairo_rectangle_int_t) { - .x = logical_monitor_layout.x, - .y = logical_monitor_layout.y, - .width = logical_monitor_layout.width, - .height = logical_monitor_layout.height, - })); - - is_on_monitor = !cairo_region_is_empty (region); - cairo_region_destroy (region); + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + ClutterStageView *stage_view = l->data; + MetaRectangle view_layout; + + clutter_stage_view_get_layout (stage_view, &view_layout); + + if (meta_rectangle_overlap (&logical_monitor_layout, + &view_layout) && + clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor), + stage_view)) + return TRUE; + } - return is_on_monitor; + return FALSE; } static void diff -Nru mutter-42.3/src/wayland/meta-wayland-dma-buf.c mutter-42.4/src/wayland/meta-wayland-dma-buf.c --- mutter-42.3/src/wayland/meta-wayland-dma-buf.c 2022-07-04 17:06:55.660000000 +0000 +++ mutter-42.4/src/wayland/meta-wayland-dma-buf.c 2022-08-11 15:46:26.240000000 +0000 @@ -1024,7 +1024,7 @@ if (format.drm_modifier != DRM_FORMAT_MOD_INVALID) continue; - if (!meta_crtc_kms_get_modifiers (crtc_kms, format.drm_format)) + if (!meta_crtc_kms_supports_format (crtc_kms, format.drm_format)) continue; g_array_append_val (formats, format); diff -Nru mutter-42.3/src/wayland/meta-wayland-subsurface.c mutter-42.4/src/wayland/meta-wayland-subsurface.c --- mutter-42.3/src/wayland/meta-wayland-subsurface.c 2022-07-04 17:06:55.660000000 +0000 +++ mutter-42.4/src/wayland/meta-wayland-subsurface.c 2022-08-11 15:46:26.240000000 +0000 @@ -293,30 +293,15 @@ } static void -unparent_actor (MetaWaylandSurface *surface) -{ - ClutterActor *actor; - ClutterActor *parent_actor; - - actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)); - if (!actor) - return; - - parent_actor = clutter_actor_get_parent (actor); - if (parent_actor) - clutter_actor_remove_child (parent_actor, actor); -} - -static void wl_subsurface_destructor (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); g_node_unlink (surface->subsurface_branch_node); - unparent_actor (surface); if (surface->sub.parent) { + meta_wayland_surface_notify_subsurface_state_changed (surface->sub.parent); wl_list_remove (&surface->sub.parent_destroy_listener.link); surface->sub.parent = NULL; } diff -Nru mutter-42.3/src/wayland/meta-window-wayland.c mutter-42.4/src/wayland/meta-window-wayland.c --- mutter-42.3/src/wayland/meta-window-wayland.c 2022-07-04 17:06:55.670000000 +0000 +++ mutter-42.4/src/wayland/meta-window-wayland.c 2022-08-11 15:46:26.250000000 +0000 @@ -490,14 +490,17 @@ } if (window->rect.width == 0 || window->rect.height == 0) - return; + { + window->monitor = meta_window_find_monitor_from_id (window); + return; + } /* Require both the current and the new monitor would be the new main monitor, * even given the resulting scale the window would end up having. This is * needed to avoid jumping back and forth between the new and the old, since * changing main monitor may cause the window to be resized so that it no * longer have that same new main monitor. */ - to = meta_window_calculate_main_logical_monitor (window); + to = meta_window_find_monitor_from_frame_rect (window); if (from == to) return; diff -Nru mutter-42.3/src/x11/meta-x11-display.c mutter-42.4/src/x11/meta-x11-display.c --- mutter-42.3/src/x11/meta-x11-display.c 2022-07-04 17:06:55.670000000 +0000 +++ mutter-42.4/src/x11/meta-x11-display.c 2022-08-11 15:46:26.250000000 +0000 @@ -1028,6 +1028,7 @@ { const char *xdisplay_name; GdkDisplay *gdk_display; + const char *gdk_backend_env = NULL; const char *gdk_gl_env = NULL; const char *old_no_at_bridge; Display *xdisplay; @@ -1042,6 +1043,10 @@ gdk_set_allowed_backends ("x11"); + gdk_backend_env = g_getenv ("GDK_BACKEND"); + /* GDK would fail to initialize with e.g. GDK_BACKEND=wayland */ + g_unsetenv ("GDK_BACKEND"); + gdk_gl_env = g_getenv ("GDK_GL"); g_setenv ("GDK_GL", "disable", TRUE); @@ -1072,6 +1077,9 @@ return FALSE; } + if (gdk_backend_env) + g_setenv("GDK_BACKEND", gdk_backend_env, TRUE); + if (gdk_gl_env) g_setenv("GDK_GL", gdk_gl_env, TRUE); else diff -Nru mutter-42.3/src/x11/window-x11.c mutter-42.4/src/x11/window-x11.c --- mutter-42.3/src/x11/window-x11.c 2022-07-04 17:06:55.680000000 +0000 +++ mutter-42.4/src/x11/window-x11.c 2022-08-11 15:46:26.260000000 +0000 @@ -1860,7 +1860,7 @@ meta_window_x11_update_main_monitor (MetaWindow *window, MetaWindowUpdateMonitorFlags flags) { - window->monitor = meta_window_calculate_main_logical_monitor (window); + window->monitor = meta_window_find_monitor_from_frame_rect (window); } static void