mutter/2901.patch
2023-03-16 15:44:08 -07:00

248 lines
8.5 KiB
Diff

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