diff --git a/src/Objects/MonitorManager.vala b/src/Objects/MonitorManager.vala index 41e663c3..7a5e5ec7 100644 --- a/src/Objects/MonitorManager.vala +++ b/src/Objects/MonitorManager.vala @@ -191,13 +191,6 @@ public class Display.MonitorManager : GLib.Object { add_virtual_monitor (virtual_monitor); } - virtual_monitor.x = mutter_logical_monitor.x; - virtual_monitor.y = mutter_logical_monitor.y; - virtual_monitor.current_x = mutter_logical_monitor.x; - virtual_monitor.current_y = mutter_logical_monitor.y; - virtual_monitor.scale = mutter_logical_monitor.scale; - virtual_monitor.transform = mutter_logical_monitor.transform; - virtual_monitor.primary = mutter_logical_monitor.primary; foreach (var mutter_info in mutter_logical_monitor.monitors) { foreach (var monitor in monitors) { if (compare_monitor_with_mutter_info (monitor, mutter_info)) { @@ -213,6 +206,14 @@ public class Display.MonitorManager : GLib.Object { } } } + + virtual_monitor.x = mutter_logical_monitor.x; + virtual_monitor.y = mutter_logical_monitor.y; + virtual_monitor.current_x = mutter_logical_monitor.x; + virtual_monitor.current_y = mutter_logical_monitor.y; + virtual_monitor.scale = mutter_logical_monitor.scale; + virtual_monitor.transform = mutter_logical_monitor.transform; + virtual_monitor.primary = mutter_logical_monitor.primary; } // Look for any monitors that aren't part of a virtual monitor (hence disabled) diff --git a/src/Objects/VirtualMonitor.vala b/src/Objects/VirtualMonitor.vala index 2fd13b12..afeee76a 100644 --- a/src/Objects/VirtualMonitor.vala +++ b/src/Objects/VirtualMonitor.vala @@ -20,17 +20,45 @@ */ public class Display.VirtualMonitor : GLib.Object { + public class Scale : GLib.Object { + public double scale { get; construct; } + public string string_representation { get; construct; } + + public Scale (double scale) { + Object ( + scale: scale, + string_representation: "%d %%".printf ((int) Math.round (scale * 100)) + ); + } + } + public int x { get; set; } public int y { get; set; } public int current_x { get; set; } public int current_y { get; set; } - public double scale { get; set; } + public Gtk.SingleSelection available_scales { get; construct; } public DisplayTransform transform { get; set; } public bool primary { get; set; } public Gee.LinkedList monitors { get; construct; } public signal void modes_changed (); + public double scale { + get { + return ((Scale) available_scales.selected_item).scale; + } + set { + update_available_scales (); + for (int i = 0; i < available_scales.get_n_items (); i++) { + if (value == ((Scale) available_scales.get_item (i)).scale) { + available_scales.selected = i; + return; + } + } + critical ("Unsupported scale %f for current mode", value); + } + } + /* * Used to distinguish two VirtualMonitors from each other. * We make up and ID by sum all hashes of @@ -68,8 +96,13 @@ public class Display.VirtualMonitor : GLib.Object { } } + private ListStore available_scales_store; + construct { monitors = new Gee.LinkedList (); + + available_scales_store = new ListStore (typeof (Scale)); + available_scales = new Gtk.SingleSelection (available_scales_store); } public unowned string get_display_name () { @@ -114,6 +147,23 @@ public class Display.VirtualMonitor : GLib.Object { } } + private void update_available_scales () { + Scale[] scales = {}; + foreach (var mode in get_available_modes ()) { + if (!mode.is_current) { + continue; + } + + foreach (var scale in mode.supported_scales) { + scales += new Scale (scale); + } + + break; + } + + available_scales_store.splice (0, available_scales_store.get_n_items (), scales); + } + public Display.MonitorMode? get_mode_for_resolution (int width, int height) { foreach (var mode in get_available_modes ()) { if (mode.width == width && mode.height == height) { @@ -149,6 +199,8 @@ public class Display.VirtualMonitor : GLib.Object { mode.is_current = mode == current_mode; } } + + scale = current_mode.preferred_scale; } public static string generate_id_from_monitors (MutterReadMonitorInfo[] infos) { diff --git a/src/Widgets/DisplayWidget.vala b/src/Widgets/DisplayWidget.vala index 82a10b1e..2cbfbc5f 100644 --- a/src/Widgets/DisplayWidget.vala +++ b/src/Widgets/DisplayWidget.vala @@ -27,23 +27,6 @@ public struct Display.Resolution { } public class Display.DisplayWidget : Gtk.Box { - private static double[] scales; - private static string[] string_scales; - - static construct { - unowned var monitor_manager = MonitorManager.get_default (); - - if (monitor_manager.fractional_scale_enabled) { - scales = { 0.75, 1.00, 1.25, 1.50, 1.75, 2.00 }; - } else { - scales = { 1.00, 2.00 }; - } - - foreach (var scale in scales) { - string_scales += "%d %%".printf ((int) (scale * 100)); - } - } - public signal void set_as_primary (); public signal void check_position (); public signal void configuration_changed (); @@ -256,10 +239,24 @@ public class Display.DisplayWidget : Gtk.Box { populate_refresh_rates (); - scale_drop_down = new Gtk.DropDown.from_strings (string_scales) { + var scale_drop_down_factory = new Gtk.SignalListItemFactory (); + scale_drop_down_factory.setup.connect ((obj) => { + var list_item = (Gtk.ListItem) obj; + list_item.child = new Gtk.Label (null) { xalign = 0 }; + }); + scale_drop_down_factory.bind.connect ((obj) => { + var list_item = (Gtk.ListItem) obj; + var item = (VirtualMonitor.Scale) list_item.item; + var scale_label = (Gtk.Label) list_item.child; + scale_label.label = item.string_representation; + }); + + scale_drop_down = new Gtk.DropDown (virtual_monitor.available_scales, null) { margin_start = 12, - margin_end = 12 + margin_end = 12, + factory = scale_drop_down_factory }; + virtual_monitor.available_scales.bind_property ("selected", scale_drop_down, "selected", BIDIRECTIONAL | SYNC_CREATE); var scale_label = new Granite.HeaderLabel (_("Scaling factor")) { mnemonic_widget = scale_drop_down @@ -432,21 +429,10 @@ public class Display.DisplayWidget : Gtk.Box { } }); - virtual_monitor.notify["scale"].connect (update_selected_scale); - update_selected_scale (); - scale_drop_down.notify["selected-item"].connect ((drop_down, param_spec) => { + scale_drop_down.notify["selected-item"].connect (() => { // Prevent breaking autohide by closing popover popover.popdown (); - var i = ((Gtk.DropDown) drop_down).selected; - - if (i < 0 || i > scales.length) { - warning ("Invalid scale selected."); - return; - } - - virtual_monitor.scale = scales[i]; - configuration_changed (); }); @@ -460,14 +446,6 @@ public class Display.DisplayWidget : Gtk.Box { check_position (); } - private void update_selected_scale () { - for (uint i = 0; i < scales.length; i++) { - if (scales[i] == virtual_monitor.scale) { - scale_drop_down.selected = i; - } - } - } - private void populate_refresh_rates () { refresh_list_store.clear ();