Commit 40910b90 authored by thomasanderson's avatar thomasanderson Committed by Commit bot

Gtk: Consider font dpi when calculating device scale factor

Gtk2 did not have a global window scaling setting (so the only way to
scale up widgets was with a custom theme).  However, it did allow font
scaling with gdk-xft-dpi (backed by XSetting Xft/DPI).

Gtk3 adds (non-fractional) global window scaling with
gdk-window-scaling-factor (XSetting Gdk/WindowScalingFactor).  To
ensure that fonts were not scaled up twice (once from
gdk-window-scaling-factor and once from gdk-xft-dpi), a new setting
was added in [1] that overrides gdk-xft-dpi: gdk-unscaled-dpi
(XSetting Gdk/UnscaledDPI).  gdk-xft-dpi was kept around for
compatibility with apps like Chromium that still need it.

When modifying these settings, an invariant should be maintained:
gdk-xft-dpi = gtk-window-scaling-factor * gdk-unscaled-dpi.  Chromium
should have been able to keep using gdk-xft-dpi, but this invariant is
violated when changing the settings using gnome-tweak-tool, where I
have gdk-window-scaling-factor = 2, gdk-unscaled-dpi = 98304, and
gdk-xft-dpi = 98304 (gdk-xft-dpi should be 196608).

[2] changed Gtk builds to use the window scaling factor, which is
incorrect because it did not consider font scaling, making fractional
scaling impossible.

This CL takes gdk-unscaled-dpi into the calculation as well, and
continues to fallback on using gdk-xft-dpi if the other variables are
unavailable, which can happen on Gtk2.

[1] https://git.gnome.org/browse/gtk+/commit/?id=4b9c08f48d6f5be43b0795d3eee462d60b5f9e1f
[2] https://codereview.chromium.org/2869763004

BUG=723931
R=erg@chromium.org,chris.coulson@canonical.com
CC=oshima@chromium.org

Review-Url: https://codereview.chromium.org/2899943002
Cr-Commit-Position: refs/heads/master@{#473966}
parent 5b17d3a9
......@@ -315,14 +315,27 @@ gfx::FontRenderParams GetGtkFontRenderParams() {
return params;
}
float GetGdkWindowScalingFactor() {
GValue scale = G_VALUE_INIT;
g_value_init(&scale, G_TYPE_INT);
if (!gdk_screen_get_setting(gdk_screen_get_default(),
"gdk-window-scaling-factor", &scale))
float GtkDpiToScaleFactor(int dpi) {
// GTK multiplies the DPI by 1024 before storing it.
return dpi / (1024 * kDefaultDPI);
}
gint GetGdkScreenSettingInt(const char* setting_name) {
GValue value = G_VALUE_INIT;
g_value_init(&value, G_TYPE_INT);
if (!gdk_screen_get_setting(gdk_screen_get_default(), setting_name, &value))
return -1;
return g_value_get_int(&value);
}
return g_value_get_int(&scale);
float GetScaleFromGdkScreenSettings() {
gint window_scale = GetGdkScreenSettingInt("gdk-window-scaling-factor");
if (window_scale <= 0)
return -1;
gint font_dpi = GetGdkScreenSettingInt("gdk-unscaled-dpi");
if (font_dpi <= 0)
return -1;
return window_scale * GtkDpiToScaleFactor(font_dpi);
}
float GetScaleFromXftDPI() {
......@@ -330,15 +343,16 @@ float GetScaleFromXftDPI() {
CHECK(gtk_settings);
gint gtk_dpi = -1;
g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, nullptr);
// GTK multiplies the DPI by 1024 before storing it.
return (gtk_dpi > 0) ? gtk_dpi / (1024 * kDefaultDPI) : -1;
if (gtk_dpi <= 0)
return -1;
return GtkDpiToScaleFactor(gtk_dpi);
}
float GetRawDeviceScaleFactor() {
if (display::Display::HasForceDeviceScaleFactor())
return display::Display::GetForcedDeviceScaleFactor();
float scale = GetGdkWindowScalingFactor();
float scale = GetScaleFromGdkScreenSettings();
if (scale > 0)
return scale;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment