diff --git a/src/Objects/MonitorLayoutManager.vala b/src/Objects/MonitorLayoutManager.vala index f7cdb687..0a41c303 100644 --- a/src/Objects/MonitorLayoutManager.vala +++ b/src/Objects/MonitorLayoutManager.vala @@ -98,10 +98,13 @@ public class Display.MonitorLayoutManager : GLib.Object { foreach (var virtual_monitor in virtual_monitors) { foreach (var monitor in virtual_monitor.monitors) { + key.append ("-"); key.append (virtual_monitor.id); + key.append (virtual_monitor.is_active ? "" : ":DISABLED"); } } + key.erase (0, 1); return key.str; } } diff --git a/src/Objects/MonitorManager.vala b/src/Objects/MonitorManager.vala index 57a5b2c5..9e97c1c5 100644 --- a/src/Objects/MonitorManager.vala +++ b/src/Objects/MonitorManager.vala @@ -427,6 +427,10 @@ public class Display.MonitorManager : GLib.Object { notify_property ("is-mirrored"); } + public void on_virtual_monitor_active_changed (VirtualMonitor vm) { + layout_manager.arrange_monitors (virtual_monitors); + } + private VirtualMonitor? get_virtual_monitor_by_id (string id) { foreach (var vm in virtual_monitors) { if (vm.id == id) { diff --git a/src/Widgets/DisplayWidget.vala b/src/Widgets/DisplayWidget.vala index 7346c388..3c2ee7d9 100644 --- a/src/Widgets/DisplayWidget.vala +++ b/src/Widgets/DisplayWidget.vala @@ -102,6 +102,10 @@ public class Display.DisplayWidget : Gtk.Box { var label = new Gtk.Label (virtual_monitor_name) { halign = CENTER, valign = CENTER, + lines = 3, + ellipsize = END, + wrap = true, + wrap_mode = WORD, hexpand = true, vexpand = true }; @@ -296,7 +300,7 @@ public class Display.DisplayWidget : Gtk.Box { var grid = new Gtk.Grid (); grid.attach (primary_image, 0, 0); grid.attach (toggle_settings, 2, 0); - grid.attach (label, 0, 0, 3, 2); + grid.attach (label, 0, 1, 3, 1); append (grid); @@ -314,12 +318,17 @@ public class Display.DisplayWidget : Gtk.Box { if (use_switch.active) { remove_css_class ("disabled"); + remove_css_class (Granite.STYLE_CLASS_DIM_LABEL); + remove_css_class (Granite.STYLE_CLASS_SMALL_LABEL); } else { add_css_class ("disabled"); + add_css_class (Granite.STYLE_CLASS_DIM_LABEL); + add_css_class (Granite.STYLE_CLASS_SMALL_LABEL); } configuration_changed (); active_changed (); + popover.popdown (); }); if (!virtual_monitor.is_active) { diff --git a/src/Widgets/DisplaysOverlay.vala b/src/Widgets/DisplaysOverlay.vala index 1ca4fc1e..3fa87388 100644 --- a/src/Widgets/DisplaysOverlay.vala +++ b/src/Widgets/DisplaysOverlay.vala @@ -41,8 +41,10 @@ public class Display.DisplaysOverlay : Gtk.Box { private unowned Display.MonitorManager monitor_manager; private GalaDBus gala_dbus = null; public int active_displays { get; set; default = 0; } + private int inactive_displays = 0; private List display_widgets; + private DisplayWidget? dragging_display = null; public bool only_display { get { @@ -159,29 +161,35 @@ public class Display.DisplaysOverlay : Gtk.Box { // virtual monitor geometry and any offsets when dragging. private bool get_child_position (Gtk.Widget widget, out Gdk.Rectangle allocation) { allocation = Gdk.Rectangle (); - if (current_width != get_width () || - current_height != get_height ()) { + if ((current_width != (get_width () - inactive_displays > 0 ? 96 : 0)) || + (current_height != get_height ())) { calculate_ratio (); } - if (widget is DisplayWidget) { - var display_widget = (DisplayWidget) widget; - - int x, y, width, height; - display_widget.get_virtual_monitor_geometry (out x, out y, out width, out height); - var x_start = (int) Math.round (x * current_ratio); - var y_start = (int) Math.round (y * current_ratio); - var x_end = (int) Math.round ((x + width) * current_ratio); - var y_end = (int) Math.round ((y + height) * current_ratio); - allocation.x = default_x_margin + x_start; - allocation.y = default_y_margin + y_start; - allocation.width = x_end - x_start; - allocation.height = y_end - y_start; + if (!(widget is DisplayWidget) || !((DisplayWidget)widget).virtual_monitor.is_active) { + int n_inactive = widget.get_data ("n-inactive"); + allocation.x = 0; + allocation.width = 96; + allocation.height = 96; + allocation.y = (n_inactive - 1) * allocation.height; return true; } - return false; + + int x, y, width, height; + var display_widget = (DisplayWidget) widget; + display_widget.get_virtual_monitor_geometry (out x, out y, out width, out height); + var x_start = (int) Math.round (x * current_ratio); + var y_start = (int) Math.round (y * current_ratio); + var x_end = (int) Math.round ((x + width) * current_ratio); + var y_end = (int) Math.round ((y + height) * current_ratio); + allocation.x = default_x_margin + x_start; + allocation.y = default_y_margin + y_start; + allocation.width = x_end - x_start; + allocation.height = y_end - y_start; + + return true; } public void rescan_displays () { @@ -193,8 +201,13 @@ public class Display.DisplaysOverlay : Gtk.Box { }); active_displays = 0; + inactive_displays = 0; + foreach (var virtual_monitor in monitor_manager.virtual_monitors) { - active_displays += virtual_monitor.is_active ? 1 : 0; + if (virtual_monitor.is_active) { + active_displays++; + } + add_output (virtual_monitor); } @@ -240,14 +253,18 @@ public class Display.DisplaysOverlay : Gtk.Box { } private void change_active_displays_sensitivity () { + } private void check_configuration_change () { // check if valid (connected) int active_display_count = 0; + int inactive_displays = 0; foreach (unowned var dw in display_widgets) { if (dw.virtual_monitor.is_active) { active_display_count++; + } else { + inactive_displays++; } } @@ -306,8 +323,14 @@ public class Display.DisplaysOverlay : Gtk.Box { int added_height = 0; int max_width = int.MIN; int max_height = int.MIN; + int min_x = int.MAX; + int min_y = int.MAX; foreach (unowned var display_widget in display_widgets) { + if (!display_widget.virtual_monitor.is_active) { + continue; + } + int x, y, width, height; display_widget.get_virtual_monitor_geometry (out x, out y, out width, out height); @@ -315,16 +338,28 @@ public class Display.DisplaysOverlay : Gtk.Box { added_height += height; max_width = int.max (max_width, x + width); max_height = int.max (max_height, y + height); + min_x = int.min (min_x, x); + min_y = int.min (min_y, y); } + // Origin may not be at (0, 0) while a monitor is marked inactive but not yet applied + max_width -= min_x; + max_height -= min_y; + current_width = get_width (); + current_width -= inactive_displays > 0 ? 96 : 0; current_height = get_height (); current_ratio = double.min ( - (double) (get_width () - 24) / (double) added_width, - (double) (get_height () - 24) / (double) added_height + (double) (current_width - 24) / (double) added_width, + (double) (current_height - 24) / (double) added_height ); - default_x_margin = (int) ((get_width () - max_width * current_ratio) / 2); - default_y_margin = (int) ((get_height () - max_height * current_ratio) / 2); + + + default_x_margin = (int) (current_width - (max_width * current_ratio)) / 2; + default_x_margin += inactive_displays > 0 ? 96 : 0; // Allow for width of inactive widgets + default_x_margin -= (int) (min_x * current_ratio); // Allow for origin not being at 0, 0 + default_y_margin = (int) ((current_height - (max_height * current_ratio)) / 2); + default_y_margin -= (int) (min_y * current_ratio); // Allow for origin not being at 0, 0 } private void add_output (Display.VirtualMonitor virtual_monitor) { @@ -345,19 +380,36 @@ public class Display.DisplaysOverlay : Gtk.Box { }); display_widget.configuration_changed.connect (check_configuration_change); + + if (!display_widget.virtual_monitor.is_active) { + inactive_displays++; + display_widget.set_data ("n-inactive", inactive_displays); + } display_widget.active_changed.connect (() => { - active_displays += virtual_monitor.is_active ? 1 : -1; - change_active_displays_sensitivity (); - check_configuration_change (); - calculate_ratio (); + if (virtual_monitor.is_active) { + inactive_displays--; + display_widget.steal_data ("n-inactive"); + active_displays++; + } else { + inactive_displays++; + display_widget.set_data ("n-inactive", inactive_displays); + active_displays--; + } + + monitor_manager.on_virtual_monitor_active_changed (display_widget.virtual_monitor); + configuration_changed (true); }); } private void set_as_primary (Display.VirtualMonitor new_primary) { - foreach (unowned var widget in display_widgets) { - var virtual_monitor = widget.virtual_monitor; + foreach (unowned var display_widget in display_widgets) { + if (!display_widget.virtual_monitor.is_active) { + continue; + } + + var virtual_monitor = display_widget.virtual_monitor; var is_primary = virtual_monitor == new_primary; - widget.set_primary (is_primary); + display_widget.set_primary (is_primary); virtual_monitor.primary = is_primary; } @@ -393,6 +445,10 @@ public class Display.DisplaysOverlay : Gtk.Box { int x, y, width, height; Gdk.Rectangle overlap; foreach (unowned var other_display_widget in display_widgets) { + if (!other_display_widget.virtual_monitor.is_active) { + continue; + } + if (other_display_widget == changed_widget) { continue; } @@ -469,6 +525,10 @@ public class Display.DisplaysOverlay : Gtk.Box { int min_y = int.MAX; foreach (unowned var display_widget in display_widgets) { + if (!display_widget.virtual_monitor.is_active) { + continue; + } + int x, y, width, height; // assert (display_widget.delta_x == 0 && display_widget.delta_y == 0); display_widget.get_virtual_monitor_geometry ( @@ -486,6 +546,10 @@ public class Display.DisplaysOverlay : Gtk.Box { } foreach (unowned var display_widget in display_widgets) { + if (!display_widget.virtual_monitor.is_active) { + continue; + } + int x, y, width, height; display_widget.get_virtual_monitor_geometry ( out x, @@ -530,6 +594,10 @@ public class Display.DisplaysOverlay : Gtk.Box { Gdk.Rectangle src_rect = { x, y, width, height }; foreach (unowned var other_display_widget in display_widgets) { + if (!other_display_widget.virtual_monitor.is_active) { + continue; + } + int distance_x = 0; int distance_y = 0; if (other_display_widget == changed_widget) {