Skip to content

Commit dc70536

Browse files
committed
blah
1 parent bc5f6a9 commit dc70536

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

src/nemo-desktop-manager.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ typedef struct {
5858
gulong name_owner_changed_id;
5959
gulong proxy_signals_id;
6060
gulong fallback_size_changed_id;
61+
gulong monitor_added_id;
62+
gulong monitor_removed_id;
63+
64+
gboolean has_wayland_app_hold;
6165
} NemoDesktopManagerPrivate;
6266

6367
struct _NemoDesktopManager
@@ -572,6 +576,37 @@ on_failsafe_timeout (NemoDesktopManager *manager)
572576
return G_SOURCE_REMOVE;
573577
}
574578

579+
static void
580+
on_monitor_removed_wayland (GdkDisplay *display,
581+
GdkMonitor *monitor,
582+
NemoDesktopManager *manager)
583+
{
584+
FETCH_PRIV (manager);
585+
586+
if (priv->current_run_state < RUN_STATE_RUNNING) {
587+
return;
588+
}
589+
590+
/* The compositor sent zwlr_layer_surface_v1.closed for the layer surface
591+
* associated with the removed output. gtk-layer-shell will destroy the
592+
* backing wl_surface in response. We must destroy our GtkWindow first,
593+
* before that happens, or a pending frame clock event will call
594+
* gdk_window_begin_draw_frame() on the dead wl_surface and crash. */
595+
DEBUG ("Wayland output removed - closing desktop windows immediately");
596+
597+
close_all_windows (manager);
598+
queue_update_layout (manager);
599+
}
600+
601+
static void
602+
on_monitor_added_wayland (GdkDisplay *display,
603+
GdkMonitor *monitor,
604+
NemoDesktopManager *manager)
605+
{
606+
DEBUG ("Wayland output added - queuing layout update");
607+
queue_update_layout (manager);
608+
}
609+
575610
static void
576611
connect_fallback_signals (NemoDesktopManager *manager)
577612
{
@@ -583,6 +618,20 @@ connect_fallback_signals (NemoDesktopManager *manager)
583618
"size_changed",
584619
G_CALLBACK (queue_update_layout),
585620
manager);
621+
622+
if (eel_check_is_wayland ()) {
623+
GdkDisplay *display = gdk_display_get_default ();
624+
625+
priv->monitor_removed_id = g_signal_connect (display,
626+
"monitor-removed",
627+
G_CALLBACK (on_monitor_removed_wayland),
628+
manager);
629+
630+
priv->monitor_added_id = g_signal_connect (display,
631+
"monitor-added",
632+
G_CALLBACK (on_monitor_added_wayland),
633+
manager);
634+
}
586635
}
587636

588637
static void
@@ -671,6 +720,25 @@ nemo_desktop_manager_dispose (GObject *object)
671720
priv->fallback_size_changed_id = 0;
672721
}
673722

723+
if (priv->monitor_removed_id > 0 || priv->monitor_added_id > 0) {
724+
GdkDisplay *display = gdk_display_get_default ();
725+
726+
if (priv->monitor_removed_id > 0) {
727+
g_signal_handler_disconnect (display, priv->monitor_removed_id);
728+
priv->monitor_removed_id = 0;
729+
}
730+
731+
if (priv->monitor_added_id > 0) {
732+
g_signal_handler_disconnect (display, priv->monitor_added_id);
733+
priv->monitor_added_id = 0;
734+
}
735+
}
736+
737+
if (priv->has_wayland_app_hold) {
738+
g_application_release (G_APPLICATION (nemo_application_get_singleton ()));
739+
priv->has_wayland_app_hold = FALSE;
740+
}
741+
674742
G_OBJECT_CLASS (nemo_desktop_manager_parent_class)->dispose (object);
675743
}
676744

@@ -764,6 +832,18 @@ nemo_desktop_manager_init (NemoDesktopManager *manager)
764832
}
765833

766834
connect_fallback_signals (manager);
835+
836+
if (eel_check_is_wayland ()) {
837+
/* Hold the application alive independently of any windows so that
838+
* nemo-desktop survives monitor removal (e.g. KVM switch). Without
839+
* this, gtk-layer-shell destroys our windows when the compositor
840+
* removes an output and GtkApplication exits immediately with no
841+
* windows left. The hold is released in nemo_desktop_manager_dispose
842+
* when the application is genuinely quitting. */
843+
g_application_hold (G_APPLICATION (nemo_application_get_singleton ()));
844+
priv->has_wayland_app_hold = TRUE;
845+
}
846+
767847
g_timeout_add (250, (GSourceFunc) fallback_startup_idle_cb, manager);
768848
}
769849

0 commit comments

Comments
 (0)