~3v1n0/compiz/grid-lowgfx-fixes

« back to all changes in this revision

Viewing changes to gtk/window-decorator/gwd-theme.c

  • Committer: Bileto Bot
  • Author(s): Alberts Muktupāvels
  • Date: 2017-04-27 06:39:57 UTC
  • mfrom: (4105.5.5 require-libmetacity-3-22)
  • Revision ID: ci-train-bot@canonical.com-20170427063957-ke6sbatm9ba94gsw
gtk-window-decorator: scale window decorations on HiDPI (LP: #1530277)

Approved by: Marco Trevisan (Treviño)

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
    PangoFontDescription *titlebar_font;
35
35
 
36
36
    GtkWidget            *style_window;
 
37
 
 
38
    gulong                monitors_changed_id;
 
39
    gboolean              fixed_scale;
 
40
    gint                  scale;
 
41
 
 
42
    gulong                gtk_xft_dpi_id;
 
43
    gdouble               dpi;
37
44
} GWDThemePrivate;
38
45
 
39
46
enum
55
62
                              gpointer user_data)
56
63
{
57
64
    decor_frame_t *frame = (decor_frame_t *) value;
58
 
    GdkDisplay *display = gdk_display_get_default ();
59
 
    GdkScreen *screen = gdk_display_get_default_screen (display);
60
 
    gdouble dpi = gdk_screen_get_resolution (screen);
 
65
    GWDTheme *theme = GWD_THEME (user_data);
 
66
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
61
67
 
62
68
    if (frame->pango_context == NULL)
63
69
        return;
65
71
    /* FIXME: PangoContext created by gtk_widget_create_pango_context is not
66
72
     * automatically updated. Resolution is not only thing that can change...
67
73
     */
68
 
    pango_cairo_context_set_resolution (frame->pango_context, dpi);
 
74
    pango_cairo_context_set_resolution (frame->pango_context,
 
75
                                        priv->dpi * priv->scale);
69
76
}
70
77
 
71
78
static void
72
79
style_updated_cb (GtkWidget *widget,
73
80
                  GWDTheme  *theme)
74
81
{
75
 
    gwd_frames_foreach (frames_update_pango_contexts, NULL);
 
82
    gwd_frames_foreach (frames_update_pango_contexts, theme);
76
83
 
77
84
    GWD_THEME_GET_CLASS (theme)->style_updated (theme);
78
85
 
103
110
}
104
111
 
105
112
static void
 
113
monitors_changed_cb (GdkScreen *screen,
 
114
                     GWDTheme  *theme)
 
115
{
 
116
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
 
117
    gint scale = gtk_widget_get_scale_factor (priv->style_window);
 
118
 
 
119
    if (priv->scale == scale)
 
120
        return;
 
121
 
 
122
    priv->scale = scale;
 
123
 
 
124
    GWD_THEME_GET_CLASS (theme)->scale_changed (theme);
 
125
 
 
126
    decorations_changed (wnck_screen_get_default ());
 
127
}
 
128
 
 
129
static void
 
130
track_window_scale (GWDTheme *theme)
 
131
{
 
132
    GdkScreen *screen = gdk_screen_get_default ();
 
133
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
 
134
 
 
135
    priv->monitors_changed_id = g_signal_connect (screen, "monitors-changed",
 
136
                                                  G_CALLBACK (monitors_changed_cb),
 
137
                                                  theme);
 
138
 
 
139
    priv->fixed_scale = g_getenv ("GDK_SCALE") != NULL;
 
140
    priv->scale = gtk_widget_get_scale_factor (priv->style_window);
 
141
}
 
142
 
 
143
static gdouble
 
144
get_unscaled_dpi (GWDTheme *theme)
 
145
{
 
146
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
 
147
    gint xft_dpi;
 
148
    gdouble dpi;
 
149
 
 
150
    g_object_get (gtk_settings_get_default (), "gtk-xft-dpi", &xft_dpi, NULL);
 
151
 
 
152
    if (xft_dpi > 0) {
 
153
        const gchar *scale_env;
 
154
 
 
155
        dpi = xft_dpi / 1024.0;
 
156
 
 
157
        /* When using automatic scaling gtk-xft-dpi value is unscaled, but
 
158
         * when it is disabled with GDK_SCALE or gdk_display_x11_set_scale then
 
159
         * this value will be already scaled.
 
160
         */
 
161
        if (priv->fixed_scale) {
 
162
            GdkScreen *screen = gdk_screen_get_default ();
 
163
            GValue value = G_VALUE_INIT;
 
164
 
 
165
            g_value_init (&value, G_TYPE_INT);
 
166
 
 
167
            if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value))
 
168
                dpi /= g_value_get_int (&value);
 
169
        }
 
170
 
 
171
        /* gtk-xft-dpi value is not scaled with GDK_DPI_SCALE, we need to do
 
172
         * that manually if we want GDK_DPI_SCALE support in decorations.
 
173
         */
 
174
        scale_env = g_getenv ("GDK_DPI_SCALE");
 
175
        if (scale_env) {
 
176
            gdouble scale = g_ascii_strtod (scale_env, NULL);
 
177
 
 
178
            if (scale != 0)
 
179
                dpi *= scale;
 
180
        }
 
181
    } else {
 
182
        dpi = 96.0;
 
183
    }
 
184
 
 
185
    return dpi;
 
186
}
 
187
 
 
188
static void
 
189
notify_gtk_xft_dpi_cb (GtkSettings *settings,
 
190
                       GParamSpec  *pspec,
 
191
                       GWDTheme    *theme)
 
192
{
 
193
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
 
194
    gdouble dpi = get_unscaled_dpi (theme);
 
195
 
 
196
    if (priv->dpi == dpi)
 
197
        return;
 
198
 
 
199
    priv->dpi = dpi;
 
200
 
 
201
    gwd_frames_foreach (frames_update_pango_contexts, theme);
 
202
 
 
203
    GWD_THEME_GET_CLASS (theme)->dpi_changed (theme);
 
204
 
 
205
    decorations_changed (wnck_screen_get_default ());
 
206
}
 
207
 
 
208
static void
 
209
track_xft_dpi (GWDTheme *theme)
 
210
{
 
211
    GtkSettings *settings = gtk_settings_get_default ();
 
212
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
 
213
 
 
214
    priv->gtk_xft_dpi_id = g_signal_connect (settings, "notify::gtk-xft-dpi",
 
215
                                             G_CALLBACK (notify_gtk_xft_dpi_cb),
 
216
                                             theme);
 
217
 
 
218
    priv->dpi = get_unscaled_dpi (theme);
 
219
}
 
220
 
 
221
static void
106
222
gwd_theme_constructed (GObject *object)
107
223
{
108
224
    GWDTheme *theme = GWD_THEME (object);
110
226
    G_OBJECT_CLASS (gwd_theme_parent_class)->constructed (object);
111
227
 
112
228
    create_style_window (theme);
 
229
    track_window_scale (theme);
 
230
    track_xft_dpi (theme);
113
231
}
114
232
 
115
233
static void
125
243
 
126
244
    g_clear_pointer (&priv->style_window, gtk_widget_destroy);
127
245
 
 
246
    if (priv->monitors_changed_id != 0) {
 
247
        GdkScreen *screen = gdk_screen_get_default ();
 
248
 
 
249
        g_signal_handler_disconnect (screen, priv->monitors_changed_id);
 
250
        priv->monitors_changed_id = 0;
 
251
    }
 
252
 
 
253
    if (priv->gtk_xft_dpi_id != 0) {
 
254
        GtkSettings *settings = gtk_settings_get_default ();
 
255
 
 
256
        g_signal_handler_disconnect (settings, priv->gtk_xft_dpi_id);
 
257
        priv->gtk_xft_dpi_id = 0;
 
258
    }
 
259
 
128
260
    G_OBJECT_CLASS (gwd_theme_parent_class)->dispose (object);
129
261
}
130
262
 
169
301
}
170
302
 
171
303
static void
 
304
gwd_theme_real_dpi_changed (GWDTheme *theme)
 
305
{
 
306
}
 
307
 
 
308
static void
 
309
gwd_theme_real_scale_changed (GWDTheme *theme)
 
310
{
 
311
}
 
312
 
 
313
static void
172
314
gwd_theme_real_style_updated (GWDTheme *theme)
173
315
{
174
316
}
260
402
    object_class->get_property = gwd_theme_get_property;
261
403
    object_class->set_property = gwd_theme_set_property;
262
404
 
 
405
    theme_class->dpi_changed = gwd_theme_real_dpi_changed;
 
406
    theme_class->scale_changed = gwd_theme_real_scale_changed;
263
407
    theme_class->style_updated = gwd_theme_real_style_updated;
264
408
    theme_class->get_shadow = gwd_theme_real_get_shadow;
265
409
    theme_class->draw_window_decoration = gwd_theme_real_draw_window_decoration;
324
468
    return priv->settings;
325
469
}
326
470
 
 
471
gdouble
 
472
gwd_theme_get_dpi (GWDTheme *theme)
 
473
{
 
474
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
 
475
 
 
476
    return priv->dpi;
 
477
}
 
478
 
 
479
gint
 
480
gwd_theme_get_scale (GWDTheme *theme)
 
481
{
 
482
    GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
 
483
 
 
484
    return priv->scale;
 
485
}
 
486
 
327
487
GtkWidget *
328
488
gwd_theme_get_style_window (GWDTheme *theme)
329
489
{