Backport a couple of MRs to fix blocker issues

This commit is contained in:
Adam Williamson 2023-03-16 15:44:08 -07:00
parent 275ef5ebf0
commit f60389e323
3 changed files with 541 additions and 1 deletions

247
2901.patch Normal file
View File

@ -0,0 +1,247 @@
From 74b3c9c09cc9389fffd8fae7c5af781f548e3cbc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 6 Mar 2023 23:47:02 +0100
Subject: [PATCH 1/4] clutter/frame-clock: Warn if frame clock is disposed
while dispatching
This shouldn't happen, but warn anyway to be a bit more helpful if
things go bad.
---
clutter/clutter/clutter-frame-clock.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c
index e5d1a44e2e..eeba108e15 100644
--- a/clutter/clutter/clutter-frame-clock.c
+++ b/clutter/clutter/clutter-frame-clock.c
@@ -957,6 +957,8 @@ clutter_frame_clock_dispose (GObject *object)
{
ClutterFrameClock *frame_clock = CLUTTER_FRAME_CLOCK (object);
+ g_warn_if_fail (frame_clock->state != CLUTTER_FRAME_CLOCK_STATE_DISPATCHING);
+
if (frame_clock->source)
{
g_signal_emit (frame_clock, signals[DESTROY], 0);
--
GitLab
From 607d45d24fe672efc7cae755da4ec643b9a377ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 6 Mar 2023 23:48:36 +0100
Subject: [PATCH 2/4] monitor-manager: Use guint for handle IDs
To follow convention.
---
src/backends/meta-monitor-manager-private.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index d6a92bf2ac..56431ba600 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -153,9 +153,8 @@ struct _MetaMonitorManager
GList *logical_monitors;
MetaLogicalMonitor *primary_logical_monitor;
- int dbus_name_id;
-
- int persistent_timeout_id;
+ guint dbus_name_id;
+ guint persistent_timeout_id;
guint panel_orientation_managed : 1;
--
GitLab
From f8dc4809322da31a68643fdf698d877703589e23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 6 Mar 2023 23:49:39 +0100
Subject: [PATCH 3/4] monitor-manager: Use g_clear_handle() to clean up D-Bus
name owning
---
src/backends/meta-monitor-manager.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 19cbb263d2..d3a794ea6c 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -1357,11 +1357,7 @@ meta_monitor_manager_dispose (GObject *object)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
- if (manager->dbus_name_id != 0)
- {
- g_bus_unown_name (manager->dbus_name_id);
- manager->dbus_name_id = 0;
- }
+ g_clear_handle_id (&manager->dbus_name_id, g_bus_unown_name);
g_clear_object (&manager->display_config);
g_clear_object (&manager->config_manager);
--
GitLab
From 45ba864f2d5489225a6a1b5e915061c2aad289ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 7 Mar 2023 00:06:30 +0100
Subject: [PATCH 4/4] monitor-manager: Restore old config in idle callback when
unconfirmed
We might get told to restore the old monitor configuration by the
monitor configuration prompt, in case the user pressed "revert" or
equivalent. This might be in response to a button press, and those
happen during frame clock dispatch. If we would restore an old
configuration during dispatch, it means we would reconfigure the
monitors including their stage views while dispatching, which means we'd
destroy the frame clock while it's dispatching.
Doing that causes problems, as the frame clock isn't expecting to be
destroyed mid-function. Specifically,
We'd enter
clutter_frame_clock_dispatch (clutter-frame-clock.c:811)
frame_clock_source_dispatch (clutter-frame-clock.c:839)
g_main_dispatch (gmain.c:3454)
g_main_context_dispatch (gmain.c:4172)
g_main_context_iterate.constprop.0 (gmain.c:4248)
g_main_loop_run (gmain.c:4448)
meta_context_run_main_loop (meta-context.c:482)
main (main.c:663)
which would first call
_clutter_process_event (clutter-main.c:920)
_clutter_stage_process_queued_events (clutter-stage.c:757)
handle_frame_clock_before_frame (clutter-stage-view.c:1150)
which would emit e.g. a button event all the way to a button press
handler, which would e.g. deny the new configuration:
restore_previous_config (meta-monitor-manager.c:1931)
confirm_configuration (meta-monitor-manager.c:2866)
meta_monitor_manager_confirm_configuration (meta-monitor-manager.c:2880)
meta_plugin_complete_display_change (meta-plugin.c:172)
That would then regenerate the monitor configuration and stage view
layout, which would destroy the old stage view and frame clock.
meta_stage_native_rebuild_views (meta-stage-native.c:68)
meta_backend_native_update_screen_size (meta-backend-native.c:457)
meta_backend_sync_screen_size (meta-backend.c:266)
meta_backend_monitors_changed (meta-backend.c:337)
meta_monitor_manager_notify_monitors_changed (meta-monitor-manager.c:3595)
meta_monitor_manager_rebuild (meta-monitor-manager.c:3683)
meta_monitor_manager_native_apply_monitors_config (meta-monitor-manager-native.c:343)
meta_monitor_manager_apply_monitors_config (meta-monitor-manager.c:704)
After returning back to the original clutter_frame_clock_dispatch()
frame, various state in the frame clock will be gone and we'd crash.
---
src/backends/meta-monitor-manager-private.h | 1 +
src/backends/meta-monitor-manager.c | 42 +++++++++------------
2 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index 56431ba600..f9cd9ae312 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -154,6 +154,7 @@ struct _MetaMonitorManager
MetaLogicalMonitor *primary_logical_monitor;
guint dbus_name_id;
+ guint restore_config_id;
guint persistent_timeout_id;
guint panel_orientation_managed : 1;
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index d3a794ea6c..e6df876307 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -1363,6 +1363,7 @@ meta_monitor_manager_dispose (GObject *object)
g_clear_object (&manager->config_manager);
g_clear_handle_id (&manager->persistent_timeout_id, g_source_remove);
+ g_clear_handle_id (&manager->restore_config_id, g_source_remove);
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
}
@@ -1961,12 +1962,6 @@ save_config_timeout (gpointer user_data)
return G_SOURCE_REMOVE;
}
-static void
-cancel_persistent_confirmation (MetaMonitorManager *manager)
-{
- g_clear_handle_id (&manager->persistent_timeout_id, g_source_remove);
-}
-
static void
request_persistent_confirmation (MetaMonitorManager *manager)
{
@@ -2822,9 +2817,11 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
return TRUE;
}
- if (manager->persistent_timeout_id &&
- method != META_MONITORS_CONFIG_METHOD_VERIFY)
- cancel_persistent_confirmation (manager);
+ if (method != META_MONITORS_CONFIG_METHOD_VERIFY)
+ {
+ g_clear_handle_id (&manager->restore_config_id, g_source_remove);
+ g_clear_handle_id (&manager->persistent_timeout_id, g_source_remove);
+ }
if (!meta_monitor_manager_apply_monitors_config (manager,
config,
@@ -2852,28 +2849,25 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
#undef MONITOR_CONFIGS_FORMAT
#undef LOGICAL_MONITOR_CONFIG_FORMAT
-static void
-confirm_configuration (MetaMonitorManager *manager,
- gboolean confirmed)
-{
- if (confirmed)
- meta_monitor_config_manager_save_current (manager->config_manager);
- else
- restore_previous_config (manager);
-}
-
void
meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
gboolean ok)
{
if (!manager->persistent_timeout_id)
+ return;
+
+ g_clear_handle_id (&manager->restore_config_id, g_source_remove);
+ g_clear_handle_id (&manager->persistent_timeout_id, g_source_remove);
+
+ if (ok)
{
- /* too late */
- return;
+ meta_monitor_config_manager_save_current (manager->config_manager);
+ }
+ else
+ {
+ manager->restore_config_id =
+ g_idle_add_once ((GSourceOnceFunc) restore_previous_config, manager);
}
-
- cancel_persistent_confirmation (manager);
- confirm_configuration (manager, ok);
}
static gboolean
--
GitLab

277
2912-rebased.patch Normal file
View File

@ -0,0 +1,277 @@
From 670c7cf4ccb1bd1ffa6e44507a8ffd734b0f72e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 14 Mar 2023 17:28:24 +0100
Subject: [PATCH] monitor-manager: Apply switch-config in idle callback
Just as with restoring the previous monitor configuration in case the
user clicked "revert" in GNOME Shell's monitor configuration
confirmation dialog, we need to do switch configs in an idle callback as
well.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2694
---
src/backends/meta-monitor-manager.c | 61 +++++++++++---
src/tests/native-kms-hotplug.c | 119 ++++++++++++++++++++++++++++
2 files changed, 167 insertions(+), 13 deletions(-)
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 19cbb263d2..9b24294e89 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -116,6 +116,8 @@ typedef struct _MetaMonitorManagerPrivate
gboolean has_builtin_panel;
gboolean night_light_supported;
const char *experimental_hdr;
+
+ guint switch_config_handle_id;
} MetaMonitorManagerPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitorManager, meta_monitor_manager,
@@ -1356,6 +1358,8 @@ static void
meta_monitor_manager_dispose (GObject *object)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
+ MetaMonitorManagerPrivate *priv =
+ meta_monitor_manager_get_instance_private (manager);
g_clear_handle_id (&manager->dbus_name_id, g_bus_unown_name);
@@ -1367,6 +1371,7 @@ meta_monitor_manager_dispose (GObject *object)
g_clear_handle_id (&manager->persistent_timeout_id, g_source_remove);
g_clear_handle_id (&manager->restore_config_id, g_source_remove);
+ g_clear_handle_id (&priv->switch_config_handle_id, g_source_remove);
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
}
@@ -3873,35 +3878,65 @@ meta_monitor_manager_rotate_monitor (MetaMonitorManager *manager)
g_object_unref (config);
}
-void
-meta_monitor_manager_switch_config (MetaMonitorManager *manager,
- MetaMonitorSwitchConfigType config_type)
+typedef struct
{
- GError *error = NULL;
- MetaMonitorsConfig *config;
+ MetaMonitorManager *monitor_manager;
+ MetaMonitorSwitchConfigType config_type;
+} SwitchConfigData;
- g_return_if_fail (config_type != META_MONITOR_SWITCH_CONFIG_UNKNOWN);
+static gboolean
+switch_config_idle_cb (gpointer user_data)
+{
+ SwitchConfigData *data = user_data;
+ MetaMonitorManager *monitor_manager = data->monitor_manager;
+ MetaMonitorManagerPrivate *priv =
+ meta_monitor_manager_get_instance_private (monitor_manager);
+ MetaMonitorConfigManager *config_manager = monitor_manager->config_manager;
+ MetaMonitorsConfig *config;
+ g_autoptr (GError) error = NULL;
config =
- meta_monitor_config_manager_create_for_switch_config (manager->config_manager,
- config_type);
+ meta_monitor_config_manager_create_for_switch_config (config_manager,
+ data->config_type);
if (!config)
- return;
+ return G_SOURCE_REMOVE;
- if (!meta_monitor_manager_apply_monitors_config (manager,
+ if (!meta_monitor_manager_apply_monitors_config (monitor_manager,
config,
META_MONITORS_CONFIG_METHOD_TEMPORARY,
&error))
{
g_warning ("Failed to use switch monitor configuration: %s",
error->message);
- g_error_free (error);
}
else
{
- manager->current_switch_config = config_type;
+ monitor_manager->current_switch_config = data->config_type;
}
- g_object_unref (config);
+
+ priv->switch_config_handle_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+void
+meta_monitor_manager_switch_config (MetaMonitorManager *manager,
+ MetaMonitorSwitchConfigType config_type)
+{
+ MetaMonitorManagerPrivate *priv =
+ meta_monitor_manager_get_instance_private (manager);
+ SwitchConfigData *data;
+
+ g_return_if_fail (config_type != META_MONITOR_SWITCH_CONFIG_UNKNOWN);
+
+ data = g_new0 (SwitchConfigData, 1);
+ data->monitor_manager = manager;
+ data->config_type = config_type;
+
+ g_clear_handle_id (&priv->switch_config_handle_id, g_source_remove);
+ priv->switch_config_handle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ switch_config_idle_cb,
+ data,
+ g_free);
}
gboolean
diff --git a/src/tests/native-kms-hotplug.c b/src/tests/native-kms-hotplug.c
index 4a6f2e0aac..3c60aa10a5 100644
--- a/src/tests/native-kms-hotplug.c
+++ b/src/tests/native-kms-hotplug.c
@@ -17,11 +17,16 @@
#include "config.h"
+#include <linux/input-event-codes.h>
+
+#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-private.h"
+#include "backends/meta-virtual-monitor.h"
#include "backends/native/meta-backend-native.h"
#include "backends/native/meta-udev.h"
#include "meta-test/meta-context-test.h"
#include "tests/drm-mock/drm-mock.h"
+#include "tests/meta-test-utils.h"
typedef enum _State
{
@@ -207,6 +212,118 @@ meta_test_disconnect_connect (void)
g_signal_handler_disconnect (stage, presented_handler_id);
}
+static gboolean
+on_key_release (ClutterActor *actor,
+ const ClutterEvent *event,
+ MetaMonitorManager *monitor_manager)
+{
+ if (clutter_event_get_key_symbol (event) == CLUTTER_KEY_a)
+ {
+ g_debug ("Switching config");
+ meta_monitor_manager_switch_config (monitor_manager,
+ META_MONITOR_SWITCH_CONFIG_ALL_MIRROR);
+ }
+
+ return TRUE;
+}
+
+static void
+on_monitors_changed (MetaMonitorManager *monitor_manager,
+ gboolean *monitors_changed)
+{
+ *monitors_changed = TRUE;
+}
+
+static void
+meta_test_switch_config (void)
+{
+ MetaBackend *backend = meta_context_get_backend (test_context);
+ MetaMonitorManager *monitor_manager =
+ meta_backend_get_monitor_manager (backend);
+ ClutterActor *stage = meta_backend_get_stage (backend);
+ ClutterSeat *seat = meta_backend_get_default_seat (backend);
+ g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
+ g_autoptr (MetaVirtualMonitor) virtual_monitor = NULL;
+ GList *logical_monitors;
+ MetaRectangle logical_monitor_layout;
+ gulong after_paint_handler_id;
+ gulong presented_handler_id;
+ gboolean monitors_changed;
+ g_autoptr (GError) error = NULL;
+ ClutterActor *actor;
+ State state;
+
+ after_paint_handler_id = g_signal_connect (stage, "after-paint",
+ G_CALLBACK (on_after_paint),
+ &state);
+ presented_handler_id = g_signal_connect (stage, "presented",
+ G_CALLBACK (on_presented),
+ &state);
+ g_signal_connect (monitor_manager, "monitors-changed",
+ G_CALLBACK (on_monitors_changed),
+ &monitors_changed);
+
+ logical_monitors =
+ meta_monitor_manager_get_logical_monitors (monitor_manager);
+ g_assert_cmpuint (g_list_length (logical_monitors), ==, 1);
+ logical_monitor_layout =
+ meta_logical_monitor_get_layout (logical_monitors->data);
+
+ virtual_monitor = meta_create_test_monitor (test_context,
+ logical_monitor_layout.width,
+ logical_monitor_layout.height,
+ 60.0);
+
+ actor = clutter_actor_new ();
+ g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
+ clutter_actor_insert_child_above (stage,
+ actor,
+ clutter_actor_get_first_child (stage));
+ clutter_actor_set_size (actor,
+ logical_monitor_layout.width,
+ logical_monitor_layout.height);
+ clutter_actor_set_position (actor, 0, 0);
+ clutter_actor_set_reactive (actor, TRUE);
+ clutter_actor_show (actor);
+ clutter_actor_grab_key_focus (actor);
+ g_signal_connect (actor, "key-press-event",
+ G_CALLBACK (on_key_release),
+ monitor_manager);
+
+ monitors_changed = FALSE;
+ g_signal_connect (monitor_manager, "monitors-changed",
+ G_CALLBACK (on_monitors_changed),
+ &monitors_changed);
+
+ g_debug ("Sending virtual keyboard event");
+ virtual_keyboard =
+ clutter_seat_create_virtual_device (seat, CLUTTER_KEYBOARD_DEVICE);
+ clutter_virtual_input_device_notify_key (virtual_keyboard,
+ CLUTTER_CURRENT_TIME,
+ KEY_A,
+ CLUTTER_KEY_STATE_PRESSED);
+ clutter_virtual_input_device_notify_key (virtual_keyboard,
+ CLUTTER_CURRENT_TIME,
+ KEY_A,
+ CLUTTER_KEY_STATE_RELEASED);
+
+ g_debug ("Waiting for monitors changed");
+ while (!monitors_changed)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_debug ("Waiting for being repainted");
+ state = INIT;
+ clutter_actor_queue_redraw (stage);
+ while (state != PRESENTED)
+ g_main_context_iteration (NULL, TRUE);
+
+ clutter_actor_destroy (actor);
+ g_assert_null (actor);
+
+ g_signal_handler_disconnect (stage, after_paint_handler_id);
+ g_signal_handler_disconnect (stage, presented_handler_id);
+}
+
static void
init_tests (void)
{
@@ -214,6 +331,8 @@ init_tests (void)
meta_test_reload);
g_test_add_func ("/hotplug/disconnect-connect",
meta_test_disconnect_connect);
+ g_test_add_func ("/hotplug/switch-config",
+ meta_test_switch_config);
}
int
--
GitLab

View File

@ -13,7 +13,7 @@
Name: mutter
Version: 44~rc
Release: 4%{?dist}
Release: 5%{?dist}
Summary: Window and compositing manager based on Clutter
License: GPLv2+
@ -36,6 +36,18 @@ Patch3: 0001-place-Always-center-initial-setup-fedora-welcome.patch
# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2906
Patch4: 2906.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2175809
# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2901
# Fix a crash when reverting Display settings
Patch5: 2901.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2177982
# https://gitlab.gnome.org/GNOME/mutter/-/issues/2694
# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2912
# Fix a crash when using win+P to change display configuration
# Rebased on 2901.patch
Patch6: 2912-rebased.patch
BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.41.0
BuildRequires: pkgconfig(sm)
BuildRequires: pkgconfig(libwacom)
@ -179,6 +191,10 @@ the functionality of the installed %{name} package.
%{_datadir}/mutter-%{mutter_api_version}/tests
%changelog
* Thu Mar 16 2023 Adam Williamson <awilliam@redhat.com> - 44~rc-5
- Backport MR #2901 to fix crash when reverting Display settings
- Backport MR #2912 to fix crash when using win+P shortcut
* Fri Mar 10 2023 Florian Müllner <fmuellner@redhat.com> - 44~rc-4
- Fix typo in centering patch
- Also check for possible future fedora-welcome ID