From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= Date: Wed, 27 Mar 2019 05:42:41 +0100 Subject: display: Support UI scaled logical monitor mode When this mode is selected we need to assume that all the monitors are scaled by their scaling and the global UI scale. Origin: https://gitlab.gnome.org/3v1n0/gnome-control-center/commits/layout-global-scale Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1820850 Forwarded: No, MPs will follow shortly --- panels/display/cc-display-arrangement.c | 25 ++++++++++++++++---- panels/display/cc-display-config-dbus.c | 41 ++++++++++++++++++++++++++++++--- panels/display/cc-display-config.c | 26 +++++++++++++++++++++ panels/display/cc-display-config.h | 4 ++++ 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/panels/display/cc-display-arrangement.c b/panels/display/cc-display-arrangement.c index a55aa6a..3b755d7 100644 --- a/panels/display/cc-display-arrangement.c +++ b/panels/display/cc-display-arrangement.c @@ -99,6 +99,7 @@ apply_rotation_to_geometry (CcDisplayMonitor *output, static void get_scaled_geometry (CcDisplayConfig *config, CcDisplayMonitor *output, + double max_scale, int *x, int *y, int *w, @@ -117,6 +118,10 @@ get_scaled_geometry (CcDisplayConfig *config, if (cc_display_config_is_layout_logical (config)) { double scale = cc_display_monitor_get_scale (output); + + if (cc_display_config_layout_use_ui_scale (config)) + scale /= ceil (max_scale); + *w = round (*w / scale); *h = round (*h / scale); } @@ -134,6 +139,7 @@ get_bounding_box (CcDisplayConfig *config, gint *max_h) { GList *outputs, *l; + gdouble max_scale; g_assert (x1 && y1 && x2 && y2); @@ -141,6 +147,7 @@ get_bounding_box (CcDisplayConfig *config, *x2 = *y2 = G_MININT; *max_w = 0; *max_h = 0; + max_scale = cc_display_config_get_maximum_scaling (config); outputs = cc_display_config_get_monitors (config); for (l = outputs; l; l = l->next) @@ -151,7 +158,7 @@ get_bounding_box (CcDisplayConfig *config, if (!cc_display_monitor_is_useful (output)) continue; - get_scaled_geometry (config, output, &x, &y, &w, &h); + get_scaled_geometry (config, output, max_scale, &x, &y, &w, &h); *x1 = MIN (*x1, x); *y1 = MIN (*y1, y); @@ -171,8 +178,10 @@ monitor_get_drawing_rect (CcDisplayArrangement *self, gint *y2) { gdouble x, y; + gdouble max_scale; - get_scaled_geometry (self->config, output, x1, y1, x2, y2); + max_scale = cc_display_config_get_maximum_scaling (self->config); + get_scaled_geometry (self->config, output, max_scale, x1, y1, x2, y2); /* get_scaled_geometry returns the width and height */ *x2 = *x1 + *x2; @@ -325,10 +334,12 @@ find_best_snapping (CcDisplayConfig *config, GList *outputs, *l; gint x1, y1, x2, y2; gint w, h; + double max_scale; g_assert (snap_data != NULL); - get_scaled_geometry (config, snap_output, &x1, &y1, &w, &h); + max_scale = cc_display_config_get_maximum_scaling (config); + get_scaled_geometry (config, snap_output, max_scale, &x1, &y1, &w, &h); x2 = x1 + w; y2 = y1 + h; @@ -344,6 +355,7 @@ find_best_snapping (CcDisplayConfig *config, gint left_snap_pos; gint right_snap_pos; gdouble dist_x, dist_y; + gdouble max_scale; gdouble tmp; if (output == snap_output) @@ -352,7 +364,8 @@ find_best_snapping (CcDisplayConfig *config, if (!cc_display_monitor_is_useful (output)) continue; - get_scaled_geometry (config, output, &_x1, &_y1, &_w, &_h); + max_scale = cc_display_config_get_maximum_scaling (config); + get_scaled_geometry (config, output, max_scale, &_x1, &_y1, &_w, &_h); _x2 = _x1 + _w; _y2 = _y1 + _h; @@ -952,11 +965,13 @@ try_snap_output (CcDisplayConfig *config, { SnapData snap_data; gint x, y, w, h; + gdouble max_scale; if (!cc_display_monitor_is_useful (output)) return FALSE; - get_scaled_geometry (config, output, &x, &y, &w, &h); + max_scale = cc_display_config_get_maximum_scaling (config); + get_scaled_geometry (config, output, max_scale, &x, &y, &w, &h); snap_data.snapped = SNAP_DIR_NONE; snap_data.mon_x = x; diff --git a/panels/display/cc-display-config-dbus.c b/panels/display/cc-display-config-dbus.c index e14f745..27a9498 100644 --- a/panels/display/cc-display-config-dbus.c +++ b/panels/display/cc-display-config-dbus.c @@ -1045,7 +1045,8 @@ cc_display_monitor_dbus_new (GVariant *variant, typedef enum _CcDisplayLayoutMode { CC_DISPLAY_LAYOUT_MODE_LOGICAL = 1, - CC_DISPLAY_LAYOUT_MODE_PHYSICAL = 2 + CC_DISPLAY_LAYOUT_MODE_PHYSICAL = 2, + CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL = 3 } CcDisplayLayoutMode; typedef enum _CcDisplayConfigMethod @@ -1538,7 +1539,15 @@ cc_display_config_dbus_is_layout_logical (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); - return self->layout_mode == CC_DISPLAY_LAYOUT_MODE_LOGICAL; + return self->layout_mode == CC_DISPLAY_LAYOUT_MODE_LOGICAL || + self->layout_mode == CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL; +} + +static gboolean +cc_display_config_dbus_layout_use_ui_scale (CcDisplayConfig *pself) +{ + CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); + return self->layout_mode == CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL; } static gboolean @@ -1898,7 +1907,7 @@ cc_display_config_dbus_constructed (GObject *object) guint32 u = 0; g_variant_get (v, "u", &u); if (u >= CC_DISPLAY_LAYOUT_MODE_LOGICAL && - u <= CC_DISPLAY_LAYOUT_MODE_PHYSICAL) + u <= CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL) self->layout_mode = u; } } @@ -2025,6 +2034,7 @@ cc_display_config_dbus_class_init (CcDisplayConfigDBusClass *klass) parent_class->set_minimum_size = cc_display_config_dbus_set_minimum_size; parent_class->get_panel_orientation_managed = cc_display_config_dbus_get_panel_orientation_managed; + parent_class->layout_use_ui_scale = cc_display_config_dbus_layout_use_ui_scale; pspec = g_param_spec_variant ("state", "GVariant", @@ -2085,6 +2095,26 @@ logical_monitor_is_rotated (CcDisplayLogicalMonitor *lm) } } +static double +get_maximum_scale (CcDisplayConfig *config) +{ + GList *outputs, *l; + double max_scale = 1.0; + outputs = cc_display_config_get_monitors (config); + + for (l = outputs; l; l = l->next) + { + CcDisplayMonitor *output = l->data; + + if (!cc_display_monitor_is_useful (output)) + continue; + + max_scale = MAX (max_scale, cc_display_monitor_get_scale (output)); + } + + return max_scale; +} + static int logical_monitor_width (CcDisplayLogicalMonitor *lm) { @@ -2103,6 +2133,11 @@ logical_monitor_width (CcDisplayLogicalMonitor *lm) if (monitor->config->layout_mode == CC_DISPLAY_LAYOUT_MODE_LOGICAL) return round (width / lm->scale); + if (monitor->config->layout_mode == CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + double max_scale = get_maximum_scale(CC_DISPLAY_CONFIG (monitor->config)); + return round ((width * ceil (max_scale)) / lm->scale); + } else return width; } diff --git a/panels/display/cc-display-config.c b/panels/display/cc-display-config.c index 852b54f..7cbf80a 100644 --- a/panels/display/cc-display-config.c +++ b/panels/display/cc-display-config.c @@ -705,3 +705,29 @@ cc_display_config_update_ui_numbers_names (CcDisplayConfig *self) cc_display_monitor_set_ui_info (monitor, current_ui_number, ui_name); } } + +gboolean +cc_display_config_layout_use_ui_scale (CcDisplayConfig *self) +{ + return CC_DISPLAY_CONFIG_GET_CLASS (self)->layout_use_ui_scale (self); +} + +double +cc_display_config_get_maximum_scaling (CcDisplayConfig *self) +{ + GList *outputs, *l; + double max_scale = 1.0; + outputs = cc_display_config_get_monitors (self); + + for (l = outputs; l; l = l->next) + { + CcDisplayMonitor *output = l->data; + + if (!cc_display_monitor_is_useful (output)) + continue; + + max_scale = MAX (max_scale, cc_display_monitor_get_scale (output)); + } + + return max_scale; +} diff --git a/panels/display/cc-display-config.h b/panels/display/cc-display-config.h index df6333c..a9dbc37 100644 --- a/panels/display/cc-display-config.h +++ b/panels/display/cc-display-config.h @@ -184,6 +184,7 @@ struct _CcDisplayConfigClass CcDisplayMode *mode, double scale); gboolean (* get_panel_orientation_managed) (CcDisplayConfig *self); + gboolean (*layout_use_ui_scale) (CcDisplayConfig *self); }; @@ -213,6 +214,9 @@ gboolean cc_display_config_is_scaled_mode_valid (CcDisplayConfig gboolean cc_display_config_get_panel_orientation_managed (CcDisplayConfig *self); void cc_display_config_update_ui_numbers_names (CcDisplayConfig *self); +gboolean cc_display_config_layout_use_ui_scale (CcDisplayConfig *self); + +double cc_display_config_get_maximum_scaling (CcDisplayConfig *self); const char* cc_display_monitor_get_display_name (CcDisplayMonitor *monitor); gboolean cc_display_monitor_is_active (CcDisplayMonitor *monitor);