[gnome-control-center/benzea/fix-scale-after-mode-switching] display: Try harder to select a good and working scale
- From: Benjamin Berg <bberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/benzea/fix-scale-after-mode-switching] display: Try harder to select a good and working scale
- Date: Thu, 22 Oct 2020 14:09:25 +0000 (UTC)
commit f5b7948c56cfb7c75e2938a5407a08da04b91db7
Author: Benjamin Berg <bberg redhat com>
Date: Thu Oct 22 16:04:10 2020 +0200
display: Try harder to select a good and working scale
When swicthing configurations, we should ensure that the selected scale
is valid. This is complicated by the fact that it depends on other
factors whether we need a single global scale or not.
Try to retain the scale that monitors have if possible. If that does not
work, try to use the old scale of the primary monitor everywhere. This
should result in a good behaviour in most situations.
Co-authored-by: Stéphane Travostino <steph combo cc>
Fixes: #1038
panels/display/cc-display-panel.c | 59 +++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
---
diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c
index 949034442..d72bf6d18 100644
--- a/panels/display/cc-display-panel.c
+++ b/panels/display/cc-display-panel.c
@@ -172,6 +172,8 @@ config_ensure_of_type (CcDisplayPanel *panel, CcDisplayConfigType type)
{
CcDisplayConfigType current_type = config_get_current_type (panel);
GList *outputs, *l;
+ CcDisplayMonitor *current_primary = NULL;
+ gdouble old_primary_scale = -1;
/* Do not do anything if the current detected configuration type is
* identitcal to what we expect. */
@@ -181,6 +183,17 @@ config_ensure_of_type (CcDisplayPanel *panel, CcDisplayConfigType type)
reset_current_config (panel);
outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config);
+ for (l = outputs; l; l = l->next)
+ {
+ CcDisplayMonitor *output = l->data;
+
+ if (cc_display_monitor_is_primary (output))
+ {
+ current_primary = output;
+ old_primary_scale = cc_display_monitor_get_scale (current_primary);
+ break;
+ }
+ }
switch (type)
{
@@ -216,15 +229,41 @@ config_ensure_of_type (CcDisplayPanel *panel, CcDisplayConfigType type)
for (l = outputs; l; l = l->next)
{
CcDisplayMonitor *output = l->data;
+ gdouble scale;
+ CcDisplayMode *mode;
+
+ mode = cc_display_monitor_get_preferred_mode (output);
+ /* If the monitor was active, try using the current scale, otherwise
+ * try picking the preferred scale. */
+ if (cc_display_monitor_is_active (output))
+ scale = cc_display_monitor_get_scale (output);
+ else
+ scale = cc_display_mode_get_preferred_scale (mode);
+
+ /* If we cannot use the current/preferred scale, try to fall back to
+ * the previously scale of the primary monitor instead.
+ * This is not guaranteed to result in a valid configuration! */
+ if (!cc_display_config_is_scaled_mode_valid (panel->current_config,
+ mode,
+ scale))
+ {
+ if (current_primary &&
+ cc_display_config_is_scaled_mode_valid (panel->current_config,
+ mode,
+ old_primary_scale))
+ scale = old_primary_scale;
+ }
cc_display_monitor_set_active (output, cc_display_monitor_is_usable (output));
- cc_display_monitor_set_mode (output, cc_display_monitor_get_preferred_mode (output));
+ cc_display_monitor_set_mode (output, mode);
+ cc_display_monitor_set_scale (output, scale);
}
break;
case CC_DISPLAY_CONFIG_CLONE:
{
g_debug ("Creating new clone config");
+ gdouble scale;
GList *modes = cc_display_config_get_cloning_modes (panel->current_config);
gint bw, bh;
CcDisplayMode *best = NULL;
@@ -246,7 +285,23 @@ config_ensure_of_type (CcDisplayPanel *panel, CcDisplayConfigType type)
modes = modes->next;
}
- cc_display_config_set_mode_on_all_outputs (panel->current_config, best);
+
+ /* Take the preferred scale by default, */
+ scale = cc_display_mode_get_preferred_scale (best);
+ /* but prefer the old primary scale if that is valid. */
+ if (current_primary &&
+ cc_display_config_is_scaled_mode_valid (panel->current_config,
+ best,
+ old_primary_scale))
+ scale = old_primary_scale;
+
+ for (l = outputs; l; l = l->next)
+ {
+ CcDisplayMonitor *output = l->data;
+
+ cc_display_monitor_set_mode (output, best);
+ cc_display_monitor_set_scale (output, scale);
+ }
}
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]