diff options
author | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2017-06-07 20:36:17 +0800 |
---|---|---|
committer | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2017-06-07 20:36:17 +0800 |
commit | 5689bb7f99a47790b08958929b4b06a21e8aecf9 (patch) | |
tree | 83faa08deb4fa7543d4fab8c94a416276e176beb | |
parent | 31c09339b636d28d424483c7c4cfcaaa9259cc42 (diff) | |
download | gnome-control-center-fractional-scaling.tar.gz |
Display: adapt display config to new Mutter interface with scaling per modefractional-scaling
New Mutter GetCurrentState now provides a list of available scales,
we need to use these values in order to define an UI that shows them all.
-rw-r--r-- | panels/display/cc-display-config-dbus.c | 84 | ||||
-rw-r--r-- | panels/display/cc-display-config-rr.c | 19 | ||||
-rw-r--r-- | panels/display/cc-display-config.c | 12 | ||||
-rw-r--r-- | panels/display/cc-display-config.h | 9 | ||||
-rw-r--r-- | panels/display/cc-display-panel.c | 135 |
5 files changed, 165 insertions, 94 deletions
diff --git a/panels/display/cc-display-config-dbus.c b/panels/display/cc-display-config-dbus.c index 29114ffce..08d08d48a 100644 --- a/panels/display/cc-display-config-dbus.c +++ b/panels/display/cc-display-config-dbus.c @@ -21,17 +21,17 @@ #include "cc-display-config-dbus.h" -#define MODE_FORMAT "(iiddu)" +#define MODE_FORMAT "(iiddadu)" #define MODES_FORMAT "a" MODE_FORMAT - #define MONITOR_SPEC_FORMAT "(ssss)" #define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})" #define MONITORS_FORMAT "a" MONITOR_FORMAT -#define LOGICAL_MONITOR_FORMAT "(iiduba" MONITOR_SPEC_FORMAT "a{sv})" +#define LOGICAL_MONITOR_MONITORS_FORMAT "a" MONITOR_SPEC_FORMAT +#define LOGICAL_MONITOR_FORMAT "(iidub" LOGICAL_MONITOR_MONITORS_FORMAT "a{sv})" #define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT -#define CURRENT_STATE_FORMAT "(u" MONITORS_FORMAT LOGICAL_MONITORS_FORMAT "ad" "a{sv})" +#define CURRENT_STATE_FORMAT "(u" MONITORS_FORMAT LOGICAL_MONITORS_FORMAT "a{sv})" typedef enum _CcDisplayModeFlags { @@ -47,6 +47,7 @@ struct _CcDisplayModeDBus int height; double refresh_rate; double preferred_scale; + GArray *supported_scales; guint32 flags; }; @@ -80,6 +81,28 @@ cc_display_mode_dbus_get_resolution (CcDisplayMode *pself, *h = self->height; } +static const double * +cc_display_mode_dbus_get_supported_scales (CcDisplayMode *pself) +{ + CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); + + return (const double *) self->supported_scales->data; +} + +static gboolean +cc_display_mode_dbus_is_supported_scale (CcDisplayMode *pself, + double scale) +{ + CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); + + guint i; + for (i = 0; i < self->supported_scales->len; i++) + if (g_array_index (self->supported_scales, double, i) == scale) + return TRUE; + return FALSE; +} + + static gboolean cc_display_mode_dbus_is_interlaced (CcDisplayMode *pself) { @@ -106,11 +129,16 @@ cc_display_mode_dbus_get_freq_f (CcDisplayMode *pself) static void cc_display_mode_dbus_init (CcDisplayModeDBus *self) { + self->supported_scales = g_array_new (TRUE, TRUE, sizeof (double)); } static void cc_display_mode_dbus_finalize (GObject *object) { + CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (object); + + g_array_free (self->supported_scales, TRUE); + G_OBJECT_CLASS (cc_display_mode_dbus_parent_class)->finalize (object); } @@ -123,6 +151,7 @@ cc_display_mode_dbus_class_init (CcDisplayModeDBusClass *klass) gobject_class->finalize = cc_display_mode_dbus_finalize; parent_class->get_resolution = cc_display_mode_dbus_get_resolution; + parent_class->get_supported_scales = cc_display_mode_dbus_get_supported_scales; parent_class->is_interlaced = cc_display_mode_dbus_is_interlaced; parent_class->get_freq = cc_display_mode_dbus_get_freq; parent_class->get_freq_f = cc_display_mode_dbus_get_freq_f; @@ -131,6 +160,8 @@ cc_display_mode_dbus_class_init (CcDisplayModeDBusClass *klass) static CcDisplayModeDBus * cc_display_mode_dbus_new (GVariant *variant) { + double d; + GVariantIter *scales_iter; CcDisplayModeDBus *self = g_object_new (CC_TYPE_DISPLAY_MODE_DBUS, NULL); g_variant_get (variant, MODE_FORMAT, @@ -138,8 +169,14 @@ cc_display_mode_dbus_new (GVariant *variant) &self->height, &self->refresh_rate, &self->preferred_scale, + &scales_iter, &self->flags); + while (g_variant_iter_next (scales_iter, "d", &d)) + g_array_append_val (self->supported_scales, d); + + g_variant_iter_free (scales_iter); + return self; } @@ -262,9 +299,6 @@ static void cc_display_config_dbus_ensure_gapless (CcDisplayConfigDBus *self); static void cc_display_config_dbus_make_linear (CcDisplayConfigDBus *self); -static gboolean -cc_display_config_dbus_is_supported_scale (CcDisplayConfigDBus *self, - double scale); static const char * @@ -623,7 +657,10 @@ cc_display_monitor_dbus_set_scale (CcDisplayMonitor *pself, { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); - if (!cc_display_config_dbus_is_supported_scale (self->config, scale)) + if (!self->current_mode) + return; + + if (!cc_display_mode_dbus_is_supported_scale (self->current_mode, scale)) return; if (!self->logical_monitor) @@ -812,8 +849,6 @@ struct _CcDisplayConfigDBus gboolean supports_changing_layout_mode; CcDisplayLayoutMode layout_mode; - GArray *supported_scales; - GList *monitors; CcDisplayMonitorDBus *primary; @@ -1115,14 +1150,6 @@ cc_display_config_dbus_apply (CcDisplayConfig *pself, return config_apply (self, CC_DISPLAY_CONFIG_METHOD_PERSISTENT, error); } -static const double * -cc_display_config_dbus_get_supported_scales (CcDisplayConfig *pself) -{ - CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); - - return (const double *) self->supported_scales->data; -} - static gboolean cc_display_config_dbus_is_layout_logical (CcDisplayConfig *pself) { @@ -1138,7 +1165,6 @@ cc_display_config_dbus_init (CcDisplayConfigDBus *self) self->supports_mirroring = TRUE; self->supports_changing_layout_mode = FALSE; self->layout_mode = CC_DISPLAY_LAYOUT_MODE_LOGICAL; - self->supported_scales = g_array_new (TRUE, TRUE, sizeof (double)); self->logical_monitors = g_hash_table_new (NULL, NULL); } @@ -1265,9 +1291,7 @@ cc_display_config_dbus_constructed (GObject *object) CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (object); GVariantIter *monitors; GVariantIter *logical_monitors; - GVariantIter *scales; GVariantIter *props; - double d; const char *s; GVariant *v; @@ -1276,12 +1300,8 @@ cc_display_config_dbus_constructed (GObject *object) &self->serial, &monitors, &logical_monitors, - &scales, &props); - while (g_variant_iter_next (scales, "d", &d)) - g_array_append_val (self->supported_scales, d); - while (g_variant_iter_next (props, "{&sv}", &s, &v)) { if (g_str_equal (s, "supports-mirroring")) @@ -1308,7 +1328,6 @@ cc_display_config_dbus_constructed (GObject *object) g_variant_iter_free (monitors); g_variant_iter_free (logical_monitors); - g_variant_iter_free (scales); g_variant_iter_free (props); G_OBJECT_CLASS (cc_display_config_dbus_parent_class)->constructed (object); @@ -1364,7 +1383,6 @@ cc_display_config_dbus_finalize (GObject *object) g_clear_pointer (&self->state, g_variant_unref); g_clear_object (&self->connection); - g_array_free (self->supported_scales, TRUE); g_list_foreach (self->monitors, (GFunc) g_object_unref, NULL); g_clear_pointer (&self->monitors, g_list_free); g_clear_pointer (&self->logical_monitors, g_hash_table_destroy); @@ -1392,7 +1410,6 @@ cc_display_config_dbus_class_init (CcDisplayConfigDBusClass *klass) parent_class->is_cloning = cc_display_config_dbus_is_cloning; parent_class->set_cloning = cc_display_config_dbus_set_cloning; parent_class->get_cloning_modes = cc_display_config_dbus_get_cloning_modes; - parent_class->get_supported_scales = cc_display_config_dbus_get_supported_scales; parent_class->is_layout_logical = cc_display_config_dbus_is_layout_logical; pspec = g_param_spec_variant ("state", @@ -1632,14 +1649,3 @@ cc_display_config_dbus_make_linear (CcDisplayConfigDBus *self) g_list_free (logical_monitors); } - -static gboolean -cc_display_config_dbus_is_supported_scale (CcDisplayConfigDBus *self, - double scale) -{ - guint i; - for (i = 0; i < self->supported_scales->len; i++) - if (g_array_index (self->supported_scales, double, i) == scale) - return TRUE; - return FALSE; -} diff --git a/panels/display/cc-display-config-rr.c b/panels/display/cc-display-config-rr.c index 805d44e67..1d979a1dd 100644 --- a/panels/display/cc-display-config-rr.c +++ b/panels/display/cc-display-config-rr.c @@ -46,6 +46,14 @@ cc_display_mode_rr_get_resolution (CcDisplayMode *pself, *h = gnome_rr_mode_get_height (self->rr_mode); } +static double rr_supported_scales[] = { 1.0, 0.0 }; + +static const double * +cc_display_mode_rr_get_supported_scales (CcDisplayMode *pself) +{ + return rr_supported_scales; +} + static gboolean cc_display_mode_rr_is_interlaced (CcDisplayMode *pself) { @@ -90,6 +98,7 @@ cc_display_mode_rr_class_init (CcDisplayModeRRClass *klass) gobject_class->finalize = cc_display_mode_rr_finalize; parent_class->get_resolution = cc_display_mode_rr_get_resolution; + parent_class->get_supported_scales = cc_display_mode_rr_get_supported_scales; parent_class->is_interlaced = cc_display_mode_rr_is_interlaced; parent_class->get_freq = cc_display_mode_rr_get_freq; parent_class->get_freq_f = cc_display_mode_rr_get_freq_f; @@ -429,9 +438,6 @@ cc_display_monitor_rr_new (GnomeRROutput *output, return CC_DISPLAY_MONITOR (self); } - -static double rr_supported_scales[] = { 1.0, 0.0 }; - struct _CcDisplayConfigRR { CcDisplayConfig parent_instance; @@ -556,12 +562,6 @@ cc_display_config_rr_get_cloning_modes (CcDisplayConfig *pself) return self->clone_modes; } -static const double * -cc_display_config_rr_get_supported_scales (CcDisplayConfig *pself) -{ - return rr_supported_scales; -} - static gboolean cc_display_config_rr_is_layout_logical (CcDisplayConfig *pself) { @@ -687,7 +687,6 @@ cc_display_config_rr_class_init (CcDisplayConfigRRClass *klass) parent_class->is_cloning = cc_display_config_rr_is_cloning; parent_class->set_cloning = cc_display_config_rr_set_cloning; parent_class->get_cloning_modes = cc_display_config_rr_get_cloning_modes; - parent_class->get_supported_scales = cc_display_config_rr_get_supported_scales; parent_class->is_layout_logical = cc_display_config_rr_is_layout_logical; pspec = g_param_spec_object ("gnome-rr-screen", diff --git a/panels/display/cc-display-config.c b/panels/display/cc-display-config.c index 237ff6b66..a70289738 100644 --- a/panels/display/cc-display-config.c +++ b/panels/display/cc-display-config.c @@ -39,6 +39,12 @@ cc_display_mode_get_resolution (CcDisplayMode *self, int *w, int *h) return CC_DISPLAY_MODE_GET_CLASS (self)->get_resolution (self, w, h); } +const double * +cc_display_mode_get_supported_scales (CcDisplayMode *self) +{ + return CC_DISPLAY_MODE_GET_CLASS (self)->get_supported_scales (self); +} + gboolean cc_display_mode_is_interlaced (CcDisplayMode *self) { @@ -272,12 +278,6 @@ cc_display_config_get_cloning_modes (CcDisplayConfig *self) return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_cloning_modes (self); } -const double * -cc_display_config_get_supported_scales (CcDisplayConfig *self) -{ - return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_supported_scales (self); -} - gboolean cc_display_config_is_layout_logical (CcDisplayConfig *self) { diff --git a/panels/display/cc-display-config.h b/panels/display/cc-display-config.h index b126a8a08..785f92a74 100644 --- a/panels/display/cc-display-config.h +++ b/panels/display/cc-display-config.h @@ -79,6 +79,7 @@ struct _CcDisplayModeClass GObjectClass parent_class; void (*get_resolution) (CcDisplayMode *self, int *w, int *h); + const double * (*get_supported_scales) (CcDisplayMode *self); gboolean (*is_interlaced) (CcDisplayMode *self); int (*get_freq) (CcDisplayMode *self); double (*get_freq_f) (CcDisplayMode *self); @@ -134,7 +135,6 @@ struct _CcDisplayConfigClass gboolean (*is_cloning) (CcDisplayConfig *self); void (*set_cloning) (CcDisplayConfig *self, gboolean clone); GList * (*get_cloning_modes) (CcDisplayConfig *self); - const double * (*get_supported_scales) (CcDisplayConfig *self); gboolean (*is_layout_logical) (CcDisplayConfig *self); }; @@ -147,7 +147,6 @@ gboolean cc_display_config_apply (CcDisplayConfig *config, GError **error); gboolean cc_display_config_is_cloning (CcDisplayConfig *config); void cc_display_config_set_cloning (CcDisplayConfig *config, gboolean clone); GList *cc_display_config_get_cloning_modes (CcDisplayConfig *config); -const double *cc_display_config_get_supported_scales (CcDisplayConfig *self); gboolean cc_display_config_is_layout_logical (CcDisplayConfig *self); const char * cc_display_monitor_get_display_name (CcDisplayMonitor *monitor); @@ -186,11 +185,9 @@ void cc_display_monitor_set_position (CcDisplayMonitor *monitor, int x, int y); void cc_display_mode_get_resolution (CcDisplayMode *mode, - int *width, - int *height); -void cc_display_mode_get_dimensions (CcDisplayMode *mode, int *width, - int *hegiht); + int *height); +const double *cc_display_mode_get_supported_scales (CcDisplayMode *self); gboolean cc_display_mode_is_interlaced (CcDisplayMode *mode); int cc_display_mode_get_freq (CcDisplayMode *mode); double cc_display_mode_get_freq_f (CcDisplayMode *mode); diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c index 9847b94db..10ce278db 100644 --- a/panels/display/cc-display-panel.c +++ b/panels/display/cc-display-panel.c @@ -82,6 +82,7 @@ struct _CcDisplayPanelPrivate GtkWidget *arrange_button; GtkWidget *res_combo; GtkWidget *freq_combo; + GtkWidget *scale_slider; GHashTable *res_freqs; GtkWidget *scaling_switch; GtkWidget *rotate_left_button; @@ -1698,6 +1699,72 @@ setup_frequency_combo_box (CcDisplayPanel *panel, gtk_combo_box_set_active (GTK_COMBO_BOX (priv->freq_combo), 0); } +static guint +n_supported_scales (CcDisplayMode *mode) +{ + const double *scales = cc_display_mode_get_supported_scales (mode); + guint n = 0; + + while (scales[n] != 0.0) + n++; + + return n; +} + +static void +setup_scaling_slider (CcDisplayPanel *panel, + CcDisplayMode *resolution_mode) +{ + CcDisplayPanelPrivate *priv = panel->priv; + guint i; + guint n; + const double *scales; + + scales = cc_display_mode_get_supported_scales (resolution_mode); + n = n_supported_scales (resolution_mode); + + if (n > 0) + { + GtkAdjustment *adj; + double current_scale; + int current_index = -1; + + current_scale = cc_display_monitor_get_scale (priv->current_output); + adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale_slider)); + + gtk_scale_clear_marks (GTK_SCALE (priv->scale_slider)); + + gtk_adjustment_set_step_increment (adj, 1); + gtk_adjustment_set_lower (adj, 0); + gtk_adjustment_set_upper (adj, n-1); + gtk_scale_set_digits (GTK_SCALE (priv->scale_slider), 0); + + for (i = 0; i < n; ++i) + { + double rounded_scale = round (scales[i] * 10) / 10; + double integral; + double fractional = modf (rounded_scale, &integral); + + if (scales[i] == current_scale || (current_index < 0 && scales[i] == 1.0)) + current_index = i; + + if (fractional != 0 && (fractional != 0.5 || integral > 0)) + continue; + + gchar *s = g_strdup_printf ("%.2lg×", scales[i]); + gtk_scale_add_mark (GTK_SCALE (priv->scale_slider), i, GTK_POS_TOP, s); + g_free (s); + } + + gtk_widget_show (priv->scale_slider); + gtk_range_set_value (GTK_RANGE (priv->scale_slider), current_index); + } + else + { + gtk_widget_hide (priv->scale_slider); + } +} + static void free_mode_list (gpointer key, gpointer value, @@ -1782,6 +1849,7 @@ setup_resolution_combo_box (CcDisplayPanel *panel, gtk_combo_box_set_active (GTK_COMBO_BOX (priv->res_combo), 0); setup_frequency_combo_box (panel, current_mode); + setup_scaling_slider (panel, current_mode); } @@ -1988,6 +2056,7 @@ res_combo_changed (GtkComboBox *combo, update_apply_button (panel); setup_frequency_combo_box (panel, mode); + setup_scaling_slider (panel, mode); } } @@ -2041,16 +2110,17 @@ underscan_switch_toggled (CcDisplayPanel *panel) update_apply_button (panel); } -static guint -n_supported_scales (CcDisplayConfig *config) +static double +scale_slider_get_selected_scale (CcDisplayPanel *panel) { - const double *scales = cc_display_config_get_supported_scales (config); - guint n = 0; + CcDisplayPanelPrivate *priv = panel->priv; + CcDisplayMode *mode = cc_display_monitor_get_mode (priv->current_output); + const double *scales = cc_display_mode_get_supported_scales (mode); + int selected = gtk_range_get_value (GTK_RANGE (priv->scale_slider)); - while (scales[n] != 0.0) - n++; + g_return_val_if_fail (selected < n_supported_scales (mode), 1.0); - return n; + return scales[selected]; } static void @@ -2058,10 +2128,18 @@ scale_slider_changed (GtkRange *slider, CcDisplayPanel *panel) { cc_display_monitor_set_scale (panel->priv->current_output, - gtk_range_get_value (slider)); + scale_slider_get_selected_scale (panel)); update_apply_button (panel); } +static char * +scale_slider_format_value (GtkScale *slider, + double value, + CcDisplayPanel *panel) +{ + return g_strdup_printf ("%.3g", scale_slider_get_selected_scale (panel)); +} + static void show_setup_dialog (CcDisplayPanel *panel) { @@ -2298,31 +2376,22 @@ show_setup_dialog (CcDisplayPanel *panel) grid_pos++; /* scale */ - if (n_supported_scales (priv->current_config) > 1) - { - GtkWidget *slider; - const double *scales = cc_display_config_get_supported_scales (priv->current_config); - guint n = n_supported_scales (priv->current_config); - guint i = 0; - - slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, - scales[0], scales[n - 1], - scales[1] - scales[0]); - gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE); - gtk_scale_set_has_origin (GTK_SCALE (slider), FALSE); - for (i = 0; i < n; i++) - { - gchar *s = g_strdup_printf ("%.1lg×", scales[i]); - gtk_scale_add_mark (GTK_SCALE (slider), scales[i], GTK_POS_TOP, s); - g_free (s); - } - gtk_range_set_value (GTK_RANGE (slider), cc_display_monitor_get_scale (priv->current_output)); - g_signal_connect (slider, "value-changed", G_CALLBACK (scale_slider_changed), panel); - - gtk_grid_attach (GTK_GRID (priv->config_grid), slider, 1, grid_pos, 1, 1); - gtk_widget_set_halign (priv->freq_combo, GTK_ALIGN_CENTER); - grid_pos++; - } + priv->scale_slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL); + gtk_widget_set_no_show_all (priv->scale_slider, TRUE); + + g_signal_connect (priv->scale_slider, "format-value", + G_CALLBACK (scale_slider_format_value), panel); + g_signal_connect (priv->scale_slider, "value-changed", + G_CALLBACK (scale_slider_changed), panel); + + gtk_scale_set_draw_value (GTK_SCALE (priv->scale_slider), TRUE); + gtk_range_set_round_digits (GTK_RANGE (priv->scale_slider), 2); + gtk_scale_set_value_pos (GTK_SCALE (priv->scale_slider), GTK_POS_BOTTOM); + gtk_scale_set_has_origin (GTK_SCALE (priv->scale_slider), FALSE); + gtk_grid_attach (GTK_GRID (priv->config_grid), + priv->scale_slider, 1, grid_pos, 1, 1); + gtk_widget_set_halign (priv->freq_combo, GTK_ALIGN_CENTER); + grid_pos++; was_clone = clone = cc_display_config_is_cloning (priv->current_config); primary = cc_display_monitor_is_primary (priv->current_output); |