summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2014-07-11 16:42:38 -0400
committerMatthias Clasen <mclasen@redhat.com>2014-07-13 15:35:23 -0400
commitfc6e2cc4b27403707bf2a9f4717442842914e626 (patch)
tree5d911997ef8c1ba99f257ab43198ec8fc4bc9ddc /gdk
parentcef6f34fb7585fc423ec999822d515d6da0e6d6f (diff)
downloadgtk+-fc6e2cc4b27403707bf2a9f4717442842914e626.tar.gz
Handle resolution changes in the GDK backend code
gdk_x11_display_set_window_scale() affects the interpretation of the Xft/DPI XSETTING - it is substituted inside GDK with the value of Gdk/UnscaledDPI xsetting. However, this change is not propagated to GTK+ and from GTK+ back to gdk_screen_set_resolution() until the main loop is run. Fix this by handling the screen resolution directly in gdk/x11. This requires duplication of code between GDK and GTK+ since we still have to handle DPI in GTK+ in the case that GdkSettings:gtk-xft-dpi is set by the application. https://bugzilla.gnome.org/show_bug.cgi?id=733076
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdkinternals.h2
-rw-r--r--gdk/gdkscreen.c25
-rw-r--r--gdk/gdkscreenprivate.h1
-rw-r--r--gdk/quartz/gdkscreen-quartz.c4
-rw-r--r--gdk/wayland/gdkscreen-wayland.c15
-rw-r--r--gdk/x11/xsettings-client.c37
6 files changed, 82 insertions, 2 deletions
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index a2c4e53a51..f58ccb0084 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -345,6 +345,8 @@ gboolean _gdk_window_update_viewable (GdkWindow *window);
void _gdk_window_process_updates_recurse (GdkWindow *window,
cairo_region_t *expose_region);
+void _gdk_screen_set_resolution (GdkScreen *screen,
+ gdouble dpi);
void _gdk_screen_close (GdkScreen *screen);
/*****************************************
diff --git a/gdk/gdkscreen.c b/gdk/gdkscreen.c
index e2cbfb7d0d..cc170c5b4b 100644
--- a/gdk/gdkscreen.c
+++ b/gdk/gdkscreen.c
@@ -462,6 +462,31 @@ gdk_screen_set_resolution (GdkScreen *screen,
if (dpi < 0)
dpi = -1.0;
+ screen->resolution_set = TRUE;
+
+ if (screen->resolution != dpi)
+ {
+ screen->resolution = dpi;
+
+ g_object_notify (G_OBJECT (screen), "resolution");
+ }
+}
+
+/* Just like gdk_screen_set_resolution(), but doesn't change
+ * screen->resolution. This is us to allow us to distinguish
+ * resolution changes that the backend picks up from resolution
+ * changes made through the public API - perhaps using
+ * g_object_set(<GtkSetting>, "gtk-xft-dpi", ...);
+ */
+void
+_gdk_screen_set_resolution (GdkScreen *screen,
+ gdouble dpi)
+{
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+
+ if (dpi < 0)
+ dpi = -1.0;
+
if (screen->resolution != dpi)
{
screen->resolution = dpi;
diff --git a/gdk/gdkscreenprivate.h b/gdk/gdkscreenprivate.h
index 23cf1bdae2..15c405604c 100644
--- a/gdk/gdkscreenprivate.h
+++ b/gdk/gdkscreenprivate.h
@@ -35,6 +35,7 @@ struct _GdkScreen
cairo_font_options_t *font_options;
gdouble resolution; /* pixels/points scale factor for fonts */
+ guint resolution_set : 1; /* resolution set through public API */
guint closed : 1;
};
diff --git a/gdk/quartz/gdkscreen-quartz.c b/gdk/quartz/gdkscreen-quartz.c
index e4d409023f..ca655a5a6a 100644
--- a/gdk/quartz/gdkscreen-quartz.c
+++ b/gdk/quartz/gdkscreen-quartz.c
@@ -75,8 +75,8 @@ gdk_quartz_screen_init (GdkQuartzScreen *quartz_screen)
NSScreen *nsscreen;
nsscreen = [[NSScreen screens] objectAtIndex:0];
- gdk_screen_set_resolution (screen,
- 72.0 * [nsscreen userSpaceScaleFactor]);
+ _gdk_screen_set_resolution (screen,
+ 72.0 * [nsscreen userSpaceScaleFactor]);
gdk_quartz_screen_calculate_layout (quartz_screen);
diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c
index 4cbc51e493..baa1bc888c 100644
--- a/gdk/wayland/gdkscreen-wayland.c
+++ b/gdk/wayland/gdkscreen-wayland.c
@@ -477,7 +477,22 @@ update_xft_settings (GdkScreen *screen)
if (screen_wayland->xft_settings.dpi != xft_settings.dpi)
{
+ double dpi = xft_settings.dpi / 1024.;
+ const char *scale_env;
+ double scale;
+
screen_wayland->xft_settings.dpi = xft_settings.dpi;
+
+ scale_env = g_getenv ("GDK_DPI_SCALE");
+ if (scale_env)
+ {
+ scale = g_ascii_strtod (scale_env, NULL);
+ if (scale != 0 && dpi > 0)
+ dpi *= scale;
+ }
+
+ _gdk_screen_set_resolution (screen, dpi);
+
notify_setting (screen, "gtk-xft-dpi");
}
}
diff --git a/gdk/x11/xsettings-client.c b/gdk/x11/xsettings-client.c
index 87b4addbea..f807e52880 100644
--- a/gdk/x11/xsettings-client.c
+++ b/gdk/x11/xsettings-client.c
@@ -402,6 +402,8 @@ static void
read_settings (GdkX11Screen *x11_screen,
gboolean do_notify)
{
+ GdkScreen *screen = GDK_SCREEN (x11_screen);
+
Atom type;
int format;
unsigned long n_items;
@@ -466,6 +468,41 @@ read_settings (GdkX11Screen *x11_screen,
g_hash_table_unref (old_list);
g_value_init (&value, G_TYPE_INT);
+
+ if (!screen->resolution_set)
+ {
+ /* This code is duplicated with gtksettings.c:settings_update_resolution().
+ * The update of the screen resolution needs to happen immediately when
+ * gdk_x11_display_set_window_scale() is called, and not wait for events
+ * to be processed, so we can't always handling it in gtksettings.c.
+ * But we can't always handle it here because the DPI can be set through
+ * GtkSettings, which we don't have access to.
+ */
+ int dpi_int = 0;
+ double dpi;
+ const char *scale_env;
+ double scale;
+
+ if (gdk_screen_get_setting (GDK_SCREEN (x11_screen),
+ "gtk-xft-dpi", &value))
+ dpi_int = g_value_get_int (&value);
+
+ if (dpi_int > 0)
+ dpi = dpi_int / 1024.;
+ else
+ dpi = -1.;
+
+ scale_env = g_getenv ("GDK_DPI_SCALE");
+ if (scale_env)
+ {
+ scale = g_ascii_strtod (scale_env, NULL);
+ if (scale != 0 && dpi > 0)
+ dpi *= scale;
+ }
+
+ _gdk_screen_set_resolution (screen, dpi);
+ }
+
if (!x11_screen->fixed_window_scale &&
gdk_screen_get_setting (GDK_SCREEN (x11_screen),
"gdk-window-scaling-factor", &value))