[devhelp] Use GtkSettings 'gtk-xft-dpi' property to keep track of Xft DPI changes



commit 28364e33f6d21e98c40fae3e232698a751848c3d
Author: Mario Sanchez Prada <mario endlessm com>
Date:   Thu Feb 26 17:57:35 2015 +0000

    Use GtkSettings 'gtk-xft-dpi' property to keep track of Xft DPI changes
    
    Use that property to find the DPI resolution for font handling, in order
    to calculate the effective font size value that needs to be passed to
    WebKitSettings when setting the default values. Also, connect to
    notify::gtk-xft-dpi so that we can update the font size whenever the
    DPI value changes, and not just on startup.
    
    Last, connect also to GtkWidget::screen-changed to keep track of
    potential changes in the associated GdkScreen, which could mean changes
    in the Xft DPI too, just in case.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745256

 src/dh-util.c   |   11 +++++-
 src/dh-window.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+), 2 deletions(-)
---
diff --git a/src/dh-util.c b/src/dh-util.c
index b93b9a4..3fadbf0 100644
--- a/src/dh-util.c
+++ b/src/dh-util.c
@@ -241,10 +241,17 @@ dh_util_create_data_uri_for_filename (const gchar *filename,
 static gdouble
 get_screen_dpi (GdkScreen *screen)
 {
-        gdouble dpi;
+        GtkSettings *settings = NULL;
+        gdouble dpi = -1;
         gdouble dp, di;
+        gint gtk_xft_dpi;
+
+        settings = gtk_settings_get_for_screen (screen);
+        if (settings != NULL) {
+                g_object_get (settings, "gtk-xft-dpi", &gtk_xft_dpi, NULL);
+                dpi = (gtk_xft_dpi != -1) ? gtk_xft_dpi / 1024.0 : -1;
+        }
 
-        dpi = gdk_screen_get_resolution (screen);
         if (dpi != -1)
                 return dpi;
 
diff --git a/src/dh-window.c b/src/dh-window.c
index aab1c17..91d463f 100644
--- a/src/dh-window.c
+++ b/src/dh-window.c
@@ -55,7 +55,11 @@ typedef struct {
 
         DhLink         *selected_search_link;
         DhSettings     *settings;
+        GtkSettings    *gtk_settings;
         guint           fonts_changed_id;
+        gulong          screen_changed_id;
+        gulong          xft_dpi_changed_id;
+
 } DhWindowPrivate;
 
 enum {
@@ -504,6 +508,73 @@ settings_fonts_changed_cb (DhSettings *settings,
         }
 }
 
+static void
+update_fonts_on_dpi_change (DhWindow *window)
+{
+        DhWindowPrivate *priv;
+        gchar *font_fixed = NULL;
+        gchar *font_variable = NULL;
+        WebKitWebView *view;
+        gint i;
+
+        priv = dh_window_get_instance_private (window);
+        dh_settings_get_selected_fonts (priv->settings, &font_fixed, &font_variable);
+        if (font_fixed != NULL && font_variable != NULL) {
+                /* change font for all pages */
+                for (i = 0; i < gtk_notebook_get_n_pages (GTK_NOTEBOOK(priv->notebook)); i++) {
+                        GtkWidget *page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), i);
+                        view = WEBKIT_WEB_VIEW (g_object_get_data (G_OBJECT (page), "web_view"));
+                        dh_util_view_set_font (view, font_fixed, font_variable);
+                }
+        }
+
+        g_free (font_fixed);
+        g_free (font_variable);
+}
+
+static void
+gtk_xft_dpi_changed_cb (GtkSettings *gtk_settings,
+                        GParamSpec  *pspec,
+                        gpointer     user_data)
+{
+        DhWindow *window = DH_WINDOW (user_data);
+        update_fonts_on_dpi_change (window);
+}
+
+static void
+screen_changed_cb (GtkWidget *window,
+                   GdkScreen *previous_screen,
+                   gpointer   user_data)
+{
+        DhWindow *dh_window = DH_WINDOW(window);
+        DhWindowPrivate *priv = dh_window_get_instance_private (dh_window);
+        GtkSettings *previous_settings = gtk_settings_get_for_screen (previous_screen);
+        GtkSettings *current_settings = gtk_widget_get_settings (window);
+
+        /* if the screen has changed we need to re-retrieve the GtkSettings object,
+           and disconnect the old signal handlers before re-connecting again */
+        if (current_settings != previous_settings) {
+                if (priv->xft_dpi_changed_id) {
+                        if (priv->gtk_settings != NULL && g_signal_handler_is_connected (priv->gtk_settings, 
priv->xft_dpi_changed_id))
+                                g_signal_handler_disconnect (priv->gtk_settings, priv->xft_dpi_changed_id);
+                        priv->xft_dpi_changed_id = 0;
+                }
+                priv->gtk_settings = NULL;
+        }
+
+        /* now store the new GtkSettings and (re)connect the signals if needed */
+        if (priv->gtk_settings == NULL) {
+                GdkScreen *screen = gtk_widget_get_screen (window);
+                priv->gtk_settings = gtk_settings_get_for_screen (screen);
+                priv->xft_dpi_changed_id =
+                        g_signal_connect (priv->gtk_settings, "notify::gtk-xft-dpi",
+                                          G_CALLBACK (gtk_xft_dpi_changed_cb), window);
+
+        }
+
+        update_fonts_on_dpi_change (dh_window);
+}
+
 static gboolean
 window_configure_event_cb (GtkWidget *window,
                            GdkEventConfigure *event,
@@ -544,6 +615,17 @@ dh_window_init (DhWindow *window)
                                                    "fonts-changed",
                                                    G_CALLBACK (settings_fonts_changed_cb),
                                                    window);
+        /* monitor GdkScreen and GtkSettings for DPI changes */
+        priv->screen_changed_id =
+                g_signal_connect (window, "screen-changed",
+                                  G_CALLBACK (screen_changed_cb), NULL);
+
+        /* we can't get the GdkScreen for the widget here, so get the
+         * GtkSettings associated to the default one instead for now */
+        priv->gtk_settings = gtk_settings_get_default ();
+        priv->xft_dpi_changed_id =
+                g_signal_connect (priv->gtk_settings, "notify::gtk-xft-dpi",
+                                  G_CALLBACK (gtk_xft_dpi_changed_cb), window);
 
         g_signal_connect (window,
                           "open-link",
@@ -582,6 +664,18 @@ dh_window_dispose (GObject *object)
                 priv->fonts_changed_id = 0;
         }
 
+        if (priv->screen_changed_id) {
+                if (g_signal_handler_is_connected (window, priv->screen_changed_id))
+                        g_signal_handler_disconnect (window, priv->screen_changed_id);
+                priv->screen_changed_id = 0;
+        }
+
+        if (priv->xft_dpi_changed_id) {
+                if (priv->gtk_settings != NULL && g_signal_handler_is_connected (priv->gtk_settings, 
priv->xft_dpi_changed_id))
+                        g_signal_handler_disconnect (priv->gtk_settings, priv->xft_dpi_changed_id);
+                priv->xft_dpi_changed_id = 0;
+        }
+
         g_clear_object (&priv->settings);
 
        /* Chain up to the parent class */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]