mirror of
https://github.com/brl/mutter.git
synced 2024-12-01 12:20:47 -05:00
monitor-manager: Reload monitor manager in idle callback
When a virtual stream is destroyed, its respective virtual monitor is destroyed too. When the virtual monitor is destroyed, mutter reloads the monitor manager. However, at this point, the virtual stream is not completely destroyed yet. The viewport of the virtual monitor still exists at this point and when the monitor manager reloads, it will try to fetch the logical monitor of the now destroyed virtual monitor, which will fail and thus gnome-shell will run into a segfault. Fix this situation by reloading the monitor manager in an idle callback. When the monitor manager reloads, the virtual monitor is completely gone, since the viewport of the virtual monitor is destroyed after the virtual monitor itself. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2864 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3307>
This commit is contained in:
parent
e70fa342a9
commit
d2122a02a3
@ -118,6 +118,7 @@ typedef struct _MetaMonitorManagerPrivate
|
|||||||
gboolean night_light_supported;
|
gboolean night_light_supported;
|
||||||
const char *experimental_hdr;
|
const char *experimental_hdr;
|
||||||
|
|
||||||
|
guint reload_monitor_manager_id;
|
||||||
guint switch_config_handle_id;
|
guint switch_config_handle_id;
|
||||||
} MetaMonitorManagerPrivate;
|
} MetaMonitorManagerPrivate;
|
||||||
|
|
||||||
@ -483,6 +484,8 @@ prepare_shutdown (MetaBackend *backend,
|
|||||||
meta_monitor_manager_get_instance_private (manager);
|
meta_monitor_manager_get_instance_private (manager);
|
||||||
|
|
||||||
priv->shutting_down = TRUE;
|
priv->shutting_down = TRUE;
|
||||||
|
|
||||||
|
g_clear_handle_id (&priv->reload_monitor_manager_id, g_source_remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -678,8 +681,12 @@ on_virtual_monitor_destroyed (MetaVirtualMonitor *virtual_monitor,
|
|||||||
priv->virtual_monitors = g_list_remove (priv->virtual_monitors,
|
priv->virtual_monitors = g_list_remove (priv->virtual_monitors,
|
||||||
virtual_monitor);
|
virtual_monitor);
|
||||||
|
|
||||||
if (!priv->shutting_down)
|
if (!priv->shutting_down && !priv->reload_monitor_manager_id)
|
||||||
meta_monitor_manager_reload (manager);
|
{
|
||||||
|
priv->reload_monitor_manager_id =
|
||||||
|
g_idle_add_once ((GSourceOnceFunc) meta_monitor_manager_reload,
|
||||||
|
manager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaVirtualMonitor *
|
MetaVirtualMonitor *
|
||||||
@ -1403,6 +1410,7 @@ meta_monitor_manager_dispose (GObject *object)
|
|||||||
g_clear_handle_id (&manager->persistent_timeout_id, g_source_remove);
|
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 (&manager->restore_config_id, g_source_remove);
|
||||||
g_clear_handle_id (&priv->switch_config_handle_id, g_source_remove);
|
g_clear_handle_id (&priv->switch_config_handle_id, g_source_remove);
|
||||||
|
g_clear_handle_id (&priv->reload_monitor_manager_id, g_source_remove);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@ -3807,6 +3815,11 @@ meta_monitor_manager_reconfigure (MetaMonitorManager *manager)
|
|||||||
void
|
void
|
||||||
meta_monitor_manager_reload (MetaMonitorManager *manager)
|
meta_monitor_manager_reload (MetaMonitorManager *manager)
|
||||||
{
|
{
|
||||||
|
MetaMonitorManagerPrivate *priv =
|
||||||
|
meta_monitor_manager_get_instance_private (manager);
|
||||||
|
|
||||||
|
g_clear_handle_id (&priv->reload_monitor_manager_id, g_source_remove);
|
||||||
|
|
||||||
meta_monitor_manager_read_current_state (manager);
|
meta_monitor_manager_read_current_state (manager);
|
||||||
meta_monitor_manager_reconfigure (manager);
|
meta_monitor_manager_reconfigure (manager);
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,7 @@ meta_test_cursor_hotplug (void)
|
|||||||
meta_wayland_test_client_finish (test_client);
|
meta_wayland_test_client_finish (test_client);
|
||||||
|
|
||||||
g_clear_object (&virtual_monitor);
|
g_clear_object (&virtual_monitor);
|
||||||
|
meta_wait_for_monitors_changed (test_context);
|
||||||
meta_wait_for_paint (test_context);
|
meta_wait_for_paint (test_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +208,7 @@ meta_test_hotplug_multi_view_invalidation (void)
|
|||||||
|
|
||||||
g_signal_handler_disconnect (cursor_sprite, texture_changed_handler_id);
|
g_signal_handler_disconnect (cursor_sprite, texture_changed_handler_id);
|
||||||
g_clear_object (&virtual_monitor);
|
g_clear_object (&virtual_monitor);
|
||||||
|
meta_wait_for_monitors_changed (test_context);
|
||||||
meta_wait_for_paint (test_context);
|
meta_wait_for_paint (test_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ meta_test_switch_config (void)
|
|||||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||||
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
||||||
g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
|
g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
|
||||||
g_autoptr (MetaVirtualMonitor) virtual_monitor = NULL;
|
MetaVirtualMonitor *virtual_monitor;
|
||||||
GList *logical_monitors;
|
GList *logical_monitors;
|
||||||
MtkRectangle logical_monitor_layout;
|
MtkRectangle logical_monitor_layout;
|
||||||
gulong after_paint_handler_id;
|
gulong after_paint_handler_id;
|
||||||
@ -327,6 +327,12 @@ meta_test_switch_config (void)
|
|||||||
|
|
||||||
g_signal_handler_disconnect (stage, after_paint_handler_id);
|
g_signal_handler_disconnect (stage, after_paint_handler_id);
|
||||||
g_signal_handler_disconnect (stage, presented_handler_id);
|
g_signal_handler_disconnect (stage, presented_handler_id);
|
||||||
|
|
||||||
|
monitors_changed = FALSE;
|
||||||
|
g_clear_object (&virtual_monitor);
|
||||||
|
while (!monitors_changed)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
|
||||||
g_signal_handler_disconnect (monitor_manager, monitors_changed_handler_id);
|
g_signal_handler_disconnect (monitor_manager, monitors_changed_handler_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user