Index: dialogs/appearance-settings/main.c =================================================================== --- dialogs/appearance-settings/main.c (revision 29516) +++ dialogs/appearance-settings/main.c (working copy) @@ -43,10 +43,6 @@ /* Increase this number if new gtk settings have been added */ #define INITIALIZE_UINT (1) -#define DPI_DEFAULT 96 -#define DPI_MIN 50 -#define DPI_MAX 500 - enum { COLUMN_THEME_NAME, @@ -181,32 +177,13 @@ } static void -cb_custom_dpi_spin_value_changed (GtkSpinButton *custom_dpi_spin, - GtkToggleButton *custom_dpi_toggle) -{ - gint dpi; - - if (gtk_toggle_button_get_active (custom_dpi_toggle)) - { - dpi = gtk_spin_button_get_value (custom_dpi_spin); - xfconf_channel_set_int (xsettings_channel, "/Xft/DPI", dpi); - } -} - -static void cb_custom_dpi_check_button_toggled (GtkToggleButton *custom_dpi_toggle, GtkSpinButton *custom_dpi_spin) { - if (gtk_toggle_button_get_active (custom_dpi_toggle)) - { - gtk_widget_set_sensitive (GTK_WIDGET (custom_dpi_spin), TRUE); - cb_custom_dpi_spin_value_changed (custom_dpi_spin, custom_dpi_toggle); - } - else - { - gtk_widget_set_sensitive (GTK_WIDGET (custom_dpi_spin), FALSE); - xfconf_channel_set_int (xsettings_channel, "/Xft/DPI", -1); - } + gboolean active; + + active = gtk_toggle_button_get_active (custom_dpi_toggle); + gtk_widget_set_sensitive (GTK_WIDGET (custom_dpi_spin), active); } #ifdef ENABLE_SOUND_SETTINGS @@ -451,36 +428,6 @@ } } -static gdouble -appearance_settings_get_dpi_from_x (void) -{ - GdkScreen *screen; - gdouble height_dpi = 0, width_dpi = 0; - gint height_mm, width_mm; - - screen = gdk_screen_get_default (); - if (G_LIKELY (screen != NULL)) - { - width_mm = gdk_screen_get_width_mm (screen); - if (width_mm >= 1) - width_dpi = gdk_screen_get_width (screen) / (width_mm / 25.4); - else - width_dpi = 0; - - height_mm = gdk_screen_get_height_mm (screen); - if (height_mm >= 1) - height_dpi = gdk_screen_get_height (screen) / (height_mm / 25.4); - else - height_dpi = 0; - } - - if (width_dpi < DPI_MIN || width_dpi > DPI_MAX - || height_dpi < DPI_MIN || height_dpi > DPI_MAX) - return DPI_DEFAULT; - - return (width_dpi + height_dpi) / 2.00; -} - static void appearance_settings_from_gtk_settings (void) { @@ -562,10 +509,10 @@ const GValue *value, GladeXML *gxml) { - GtkWidget *widget, *spin; + GtkWidget *widget; gchar *str; guint i; - gint antialias, dpi; + gint antialias; GtkTreeModel *model; g_return_if_fail (property_name != NULL); @@ -631,25 +578,6 @@ break; } } - else if (strcmp (property_name, "/Xft/DPI") == 0) - { - widget = glade_xml_get_widget (gxml, "xft_custom_dpi_check_button"); - spin = glade_xml_get_widget (gxml, "xft_custom_dpi_spin_button"); - dpi = xfconf_channel_get_int (xsettings_channel, property_name, -1); - - if (dpi == -1) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); - gtk_widget_set_sensitive (spin, FALSE); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), appearance_settings_get_dpi_from_x ()); - } - else - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); - gtk_widget_set_sensitive (spin, TRUE); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), (gdouble) dpi); - } - } else if (strcmp (property_name, "/Net/ThemeName") == 0) { widget = glade_xml_get_widget (gxml, "gtk_theme_treeview"); @@ -827,12 +755,13 @@ g_signal_connect (G_OBJECT (antialias_check_button), "toggled", G_CALLBACK (cb_antialias_check_button_toggled), NULL); /* DPI */ - GtkWidget *custom_dpi_check = glade_xml_get_widget (gxml, "xft_custom_dpi_check_button"); GtkWidget *custom_dpi_spin = glade_xml_get_widget (gxml, "xft_custom_dpi_spin_button"); - appearance_settings_dialog_channel_property_changed (xsettings_channel, "/Xft/DPI", NULL, gxml); - g_signal_connect (G_OBJECT (custom_dpi_check), "toggled", G_CALLBACK (cb_custom_dpi_check_button_toggled), custom_dpi_spin); - g_signal_connect (G_OBJECT (custom_dpi_spin), "value-changed", G_CALLBACK (cb_custom_dpi_spin_value_changed), custom_dpi_check); + xfconf_g_property_bind (xsettings_channel, "/Xft/DPI", G_TYPE_INT, custom_dpi_spin, "value"); + GtkWidget *custom_dpi_check = glade_xml_get_widget (gxml, "xft_custom_dpi_check_button"); + g_signal_connect (custom_dpi_check, "toggled", G_CALLBACK (cb_custom_dpi_check_button_toggled), custom_dpi_spin); + xfconf_g_property_bind (xsettings_channel, "/Xfce/UseCustomDPI", G_TYPE_BOOLEAN, custom_dpi_check, "active"); + #ifdef ENABLE_SOUND_SETTINGS /* Sounds */ GtkWidget *event_sounds_frame = glade_xml_get_widget (gxml, "event_sounds_frame"); Index: dialogs/appearance-settings/appearance-dialog.glade =================================================================== --- dialogs/appearance-settings/appearance-dialog.glade (revision 29516) +++ dialogs/appearance-settings/appearance-dialog.glade (working copy) @@ -256,6 +256,7 @@ True 0 True + False False @@ -265,10 +266,11 @@ True True - 96 48 160 1 10 0 + 96 48 1000 1 10 0 True True GTK_UPDATE_IF_VALID + False False Index: xfsettingsd/xsettings.xml =================================================================== --- xfsettingsd/xsettings.xml (revision 29516) +++ xfsettingsd/xsettings.xml (working copy) @@ -5,4 +5,10 @@ + + + + + + Index: xfsettingsd/registry.c =================================================================== --- xfsettingsd/registry.c (revision 29516) +++ xfsettingsd/registry.c (working copy) @@ -74,6 +74,16 @@ | G_PARAM_STATIC_NICK \ | G_PARAM_STATIC_BLURB) +#define INCH_MM 25.4 + +/* Use a fallback DPI of 96 which should be ok-ish on most systems + * and is only applied on rare occasions */ +#define FALLBACK_DPI 96 + +/* Use the same min/max DPI as in the appearance settings dialog */ +#define MIN_DPI 48 +#define MAX_DPI 1000 + G_DEFINE_TYPE(XSettingsRegistry, xsettings_registry, G_TYPE_OBJECT); enum @@ -272,6 +282,31 @@ g_value_set_string (&properties[XSETTING_ENTRY_GTK_IMMODULE].value, NULL); } +static int +compute_xsettings_dpi (XSettingsRegistry *registry) +{ + Screen *xscreen; + int width_mm, height_mm; + int width, height; + int dpi; + + xscreen = ScreenOfDisplay (registry->priv->display, + registry->priv->screen); + width_mm = WidthMMOfScreen (xscreen); + height_mm = HeightMMOfScreen (xscreen); + dpi = FALLBACK_DPI; + + if (width_mm > 0 && height_mm > 0) + { + width = WidthOfScreen (xscreen); + height = HeightOfScreen (xscreen); + dpi = MIN (INCH_MM * width / width_mm, + INCH_MM * height / height_mm); + } + + return dpi; +} + static void cb_xsettings_registry_channel_property_changed(XfconfChannel *channel, const gchar *name, const GValue *value, XSettingsRegistry *registry) { @@ -286,6 +321,35 @@ break; } } + + if (strcmp(name, "/Xfce/UseCustomDPI") == 0) + { + if (xfconf_channel_get_bool (channel, name, FALSE) + && xfconf_channel_get_int (channel, "/Xft/DPI", -1) == -1) + { + /* The user wants to use custom DPI but the DPI value is currently + * set to -1 (default), so calculate and set the DPI now */ + xfconf_channel_set_int (channel, "/Xft/DPI", compute_xsettings_dpi (registry)); + + /* Don't update the registry now. Wait for the /Xft/DPI value + * to change and handle that property change event, not this one */ + return; + } + } + else if (strcmp (name, "/Xft/DPI") == 0) + { + if (xfconf_channel_get_int (channel, name, -1) == -1) + { + /* The DPI property has been reset to its default (-1). + * Compute a new value for it */ + xfconf_channel_set_int (channel, "/Xft/DPI", compute_xsettings_dpi (registry)); + + /* Don't update the registry now. Wait for the /Xft/DPI value + * to change and handle that property change event, no this one */ + return; + } + } + xsettings_registry_notify(registry); if (!strncmp(name, "/Xft", 4) || !strncmp(name, "/Gtk/CursorTheme", 16)) xsettings_registry_store_xrdb(registry); @@ -544,8 +608,29 @@ * font sizes with -1 DPI and a forced setting equal to the X * server's calculated DPI don't match. Need to look into * this a bit more. */ - if (strcmp (entry->name, "Xft/DPI") == 0 && g_value_get_int(&entry->value) != -1) - *(CARD32 *)pos = g_value_get_int(&entry->value) * 1024; + if (strcmp (entry->name, "Xft/DPI") == 0) + { + gint dpi; + + if (xfconf_channel_get_bool (registry->priv->channel, "/Xfce/UseCustomDPI", FALSE) && + g_value_get_int (&entry->value) != -1) + { + /* The user wants to use a custom DPI and we have a valid DPI value */ + dpi = g_value_get_int (&entry->value); + } + else + { + /* Calculate the "correct" DPI automatically */ + dpi = compute_xsettings_dpi (registry); + } + + /* Make sure to use the fallback DPI if the user-defined or computed + * value is out of range */ + dpi = dpi < MIN_DPI ? FALLBACK_DPI : (dpi > MAX_DPI ? FALLBACK_DPI : dpi); + + /* Apply the new value */ + *(CARD32 *)pos = 1024 * dpi; + } else *(CARD32 *)pos = g_value_get_int(&entry->value); pos += 4;