Merge lp:~muktupavels/compiz/gwd-hidpi into lp:compiz/0.9.13

Proposed by Alberts Muktupāvels
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: 4112
Merged at revision: 4113
Proposed branch: lp:~muktupavels/compiz/gwd-hidpi
Merge into: lp:compiz/0.9.13
Prerequisite: lp:~muktupavels/compiz/require-libmetacity-3-22
Diff against target: 346 lines (+207/-5)
5 files modified
gtk/CMakeLists.txt (+2/-0)
gtk/config.h.gtk.in (+3/-0)
gtk/window-decorator/gwd-theme-metacity.c (+27/-0)
gtk/window-decorator/gwd-theme.c (+165/-5)
gtk/window-decorator/gwd-theme.h (+10/-0)
To merge this branch: bzr merge lp:~muktupavels/compiz/gwd-hidpi
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Review via email: mp+323100@code.launchpad.net

Commit message

gtk-window-decorator: scale window decorations on HiDPI

Description of the change

This change should add full HiDPI support to gtk-window-decorator. Should work automatically and also by using GDK_SCALE and GDK_DPI_SCALE env.

This requires libmetacity 3.25.1 or newer.

P.S. This adds HiDPI support to Metacity themes, Cairo theme is still unscaled...

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Ack

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'gtk/CMakeLists.txt'
2--- gtk/CMakeLists.txt 2017-04-25 09:26:05 +0000
3+++ gtk/CMakeLists.txt 2017-04-25 09:26:05 +0000
4@@ -28,6 +28,8 @@
5 pkg_check_modules (LIBMETACITY libmetacity>=3.22.0)
6
7 if (LIBMETACITY_FOUND)
8+ compiz_pkg_check_modules (HAVE_METACITY_3_26_0 libmetacity>=3.25.1)
9+
10 set (METACITY_INCLUDE_DIRS ${LIBMETACITY_INCLUDE_DIRS})
11 set (METACITY_LIBRARIES ${LIBMETACITY_LIBRARIES})
12 else (LIBMETACITY_FOUND)
13
14=== modified file 'gtk/config.h.gtk.in'
15--- gtk/config.h.gtk.in 2017-04-25 09:26:05 +0000
16+++ gtk/config.h.gtk.in 2017-04-25 09:26:05 +0000
17@@ -1,4 +1,7 @@
18 /* Define to 1 if Metacity support is enabled */
19 #cmakedefine USE_METACITY 1
20
21+/* Define to 1 if Metacity version >= 3.25.1 */
22+#cmakedefine HAVE_METACITY_3_26_0 1
23+
24 #define GETTEXT_PACKAGE "${GETTEXT_PACKAGE}"
25
26=== modified file 'gtk/window-decorator/gwd-theme-metacity.c'
27--- gtk/window-decorator/gwd-theme-metacity.c 2017-04-25 09:26:05 +0000
28+++ gtk/window-decorator/gwd-theme-metacity.c 2017-04-25 09:26:05 +0000
29@@ -628,6 +628,11 @@
30 return;
31
32 setup_button_layout (metacity);
33+
34+#ifdef HAVE_METACITY_3_26_0
35+ meta_theme_set_scale (metacity->theme, gwd_theme_get_scale (GWD_THEME (object)));
36+ meta_theme_set_dpi (metacity->theme, gwd_theme_get_dpi (GWD_THEME (object)));
37+#endif
38 }
39
40 static void
41@@ -648,6 +653,26 @@
42 }
43
44 static void
45+gwd_theme_metacity_dpi_changed (GWDTheme *theme)
46+{
47+#ifdef HAVE_METACITY_3_26_0
48+ GWDThemeMetacity *metacity = GWD_THEME_METACITY (theme);
49+
50+ meta_theme_set_dpi (metacity->theme, gwd_theme_get_dpi (theme));
51+#endif
52+}
53+
54+static void
55+gwd_theme_metacity_scale_changed (GWDTheme *theme)
56+{
57+#ifdef HAVE_METACITY_3_26_0
58+ GWDThemeMetacity *metacity = GWD_THEME_METACITY (theme);
59+
60+ meta_theme_set_scale (metacity->theme, gwd_theme_get_scale (theme));
61+#endif
62+}
63+
64+static void
65 gwd_theme_metacity_style_updated (GWDTheme *theme)
66 {
67 GWDThemeMetacity *metacity = GWD_THEME_METACITY (theme);
68@@ -1112,6 +1137,8 @@
69 object_class->constructed = gwd_theme_metacity_constructed;
70 object_class->dispose = gwd_theme_metacity_dispose;
71
72+ theme_class->dpi_changed = gwd_theme_metacity_dpi_changed;
73+ theme_class->scale_changed = gwd_theme_metacity_scale_changed;
74 theme_class->style_updated = gwd_theme_metacity_style_updated;
75 theme_class->draw_window_decoration = gwd_theme_metacity_draw_window_decoration;
76 theme_class->calc_decoration_size = gwd_theme_metacity_calc_decoration_size;
77
78=== modified file 'gtk/window-decorator/gwd-theme.c'
79--- gtk/window-decorator/gwd-theme.c 2016-08-31 17:33:17 +0000
80+++ gtk/window-decorator/gwd-theme.c 2017-04-25 09:26:05 +0000
81@@ -34,6 +34,13 @@
82 PangoFontDescription *titlebar_font;
83
84 GtkWidget *style_window;
85+
86+ gulong monitors_changed_id;
87+ gboolean fixed_scale;
88+ gint scale;
89+
90+ gulong gtk_xft_dpi_id;
91+ gdouble dpi;
92 } GWDThemePrivate;
93
94 enum
95@@ -55,9 +62,8 @@
96 gpointer user_data)
97 {
98 decor_frame_t *frame = (decor_frame_t *) value;
99- GdkDisplay *display = gdk_display_get_default ();
100- GdkScreen *screen = gdk_display_get_default_screen (display);
101- gdouble dpi = gdk_screen_get_resolution (screen);
102+ GWDTheme *theme = GWD_THEME (user_data);
103+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
104
105 if (frame->pango_context == NULL)
106 return;
107@@ -65,14 +71,15 @@
108 /* FIXME: PangoContext created by gtk_widget_create_pango_context is not
109 * automatically updated. Resolution is not only thing that can change...
110 */
111- pango_cairo_context_set_resolution (frame->pango_context, dpi);
112+ pango_cairo_context_set_resolution (frame->pango_context,
113+ priv->dpi * priv->scale);
114 }
115
116 static void
117 style_updated_cb (GtkWidget *widget,
118 GWDTheme *theme)
119 {
120- gwd_frames_foreach (frames_update_pango_contexts, NULL);
121+ gwd_frames_foreach (frames_update_pango_contexts, theme);
122
123 GWD_THEME_GET_CLASS (theme)->style_updated (theme);
124
125@@ -103,6 +110,115 @@
126 }
127
128 static void
129+monitors_changed_cb (GdkScreen *screen,
130+ GWDTheme *theme)
131+{
132+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
133+ gint scale = gtk_widget_get_scale_factor (priv->style_window);
134+
135+ if (priv->scale == scale)
136+ return;
137+
138+ priv->scale = scale;
139+
140+ GWD_THEME_GET_CLASS (theme)->scale_changed (theme);
141+
142+ decorations_changed (wnck_screen_get_default ());
143+}
144+
145+static void
146+track_window_scale (GWDTheme *theme)
147+{
148+ GdkScreen *screen = gdk_screen_get_default ();
149+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
150+
151+ priv->monitors_changed_id = g_signal_connect (screen, "monitors-changed",
152+ G_CALLBACK (monitors_changed_cb),
153+ theme);
154+
155+ priv->fixed_scale = g_getenv ("GDK_SCALE") != NULL;
156+ priv->scale = gtk_widget_get_scale_factor (priv->style_window);
157+}
158+
159+static gdouble
160+get_unscaled_dpi (GWDTheme *theme)
161+{
162+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
163+ gint xft_dpi;
164+ gdouble dpi;
165+
166+ g_object_get (gtk_settings_get_default (), "gtk-xft-dpi", &xft_dpi, NULL);
167+
168+ if (xft_dpi > 0) {
169+ const gchar *scale_env;
170+
171+ dpi = xft_dpi / 1024.0;
172+
173+ /* When using automatic scaling gtk-xft-dpi value is unscaled, but
174+ * when it is disabled with GDK_SCALE or gdk_display_x11_set_scale then
175+ * this value will be already scaled.
176+ */
177+ if (priv->fixed_scale) {
178+ GdkScreen *screen = gdk_screen_get_default ();
179+ GValue value = G_VALUE_INIT;
180+
181+ g_value_init (&value, G_TYPE_INT);
182+
183+ if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value))
184+ dpi /= g_value_get_int (&value);
185+ }
186+
187+ /* gtk-xft-dpi value is not scaled with GDK_DPI_SCALE, we need to do
188+ * that manually if we want GDK_DPI_SCALE support in decorations.
189+ */
190+ scale_env = g_getenv ("GDK_DPI_SCALE");
191+ if (scale_env) {
192+ gdouble scale = g_ascii_strtod (scale_env, NULL);
193+
194+ if (scale != 0)
195+ dpi *= scale;
196+ }
197+ } else {
198+ dpi = 96.0;
199+ }
200+
201+ return dpi;
202+}
203+
204+static void
205+notify_gtk_xft_dpi_cb (GtkSettings *settings,
206+ GParamSpec *pspec,
207+ GWDTheme *theme)
208+{
209+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
210+ gdouble dpi = get_unscaled_dpi (theme);
211+
212+ if (priv->dpi == dpi)
213+ return;
214+
215+ priv->dpi = dpi;
216+
217+ gwd_frames_foreach (frames_update_pango_contexts, theme);
218+
219+ GWD_THEME_GET_CLASS (theme)->dpi_changed (theme);
220+
221+ decorations_changed (wnck_screen_get_default ());
222+}
223+
224+static void
225+track_xft_dpi (GWDTheme *theme)
226+{
227+ GtkSettings *settings = gtk_settings_get_default ();
228+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
229+
230+ priv->gtk_xft_dpi_id = g_signal_connect (settings, "notify::gtk-xft-dpi",
231+ G_CALLBACK (notify_gtk_xft_dpi_cb),
232+ theme);
233+
234+ priv->dpi = get_unscaled_dpi (theme);
235+}
236+
237+static void
238 gwd_theme_constructed (GObject *object)
239 {
240 GWDTheme *theme = GWD_THEME (object);
241@@ -110,6 +226,8 @@
242 G_OBJECT_CLASS (gwd_theme_parent_class)->constructed (object);
243
244 create_style_window (theme);
245+ track_window_scale (theme);
246+ track_xft_dpi (theme);
247 }
248
249 static void
250@@ -125,6 +243,20 @@
251
252 g_clear_pointer (&priv->style_window, gtk_widget_destroy);
253
254+ if (priv->monitors_changed_id != 0) {
255+ GdkScreen *screen = gdk_screen_get_default ();
256+
257+ g_signal_handler_disconnect (screen, priv->monitors_changed_id);
258+ priv->monitors_changed_id = 0;
259+ }
260+
261+ if (priv->gtk_xft_dpi_id != 0) {
262+ GtkSettings *settings = gtk_settings_get_default ();
263+
264+ g_signal_handler_disconnect (settings, priv->gtk_xft_dpi_id);
265+ priv->gtk_xft_dpi_id = 0;
266+ }
267+
268 G_OBJECT_CLASS (gwd_theme_parent_class)->dispose (object);
269 }
270
271@@ -169,6 +301,16 @@
272 }
273
274 static void
275+gwd_theme_real_dpi_changed (GWDTheme *theme)
276+{
277+}
278+
279+static void
280+gwd_theme_real_scale_changed (GWDTheme *theme)
281+{
282+}
283+
284+static void
285 gwd_theme_real_style_updated (GWDTheme *theme)
286 {
287 }
288@@ -260,6 +402,8 @@
289 object_class->get_property = gwd_theme_get_property;
290 object_class->set_property = gwd_theme_set_property;
291
292+ theme_class->dpi_changed = gwd_theme_real_dpi_changed;
293+ theme_class->scale_changed = gwd_theme_real_scale_changed;
294 theme_class->style_updated = gwd_theme_real_style_updated;
295 theme_class->get_shadow = gwd_theme_real_get_shadow;
296 theme_class->draw_window_decoration = gwd_theme_real_draw_window_decoration;
297@@ -324,6 +468,22 @@
298 return priv->settings;
299 }
300
301+gdouble
302+gwd_theme_get_dpi (GWDTheme *theme)
303+{
304+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
305+
306+ return priv->dpi;
307+}
308+
309+gint
310+gwd_theme_get_scale (GWDTheme *theme)
311+{
312+ GWDThemePrivate *priv = gwd_theme_get_instance_private (theme);
313+
314+ return priv->scale;
315+}
316+
317 GtkWidget *
318 gwd_theme_get_style_window (GWDTheme *theme)
319 {
320
321=== modified file 'gtk/window-decorator/gwd-theme.h'
322--- gtk/window-decorator/gwd-theme.h 2016-08-31 17:33:17 +0000
323+++ gtk/window-decorator/gwd-theme.h 2017-04-25 09:26:05 +0000
324@@ -37,6 +37,10 @@
325 {
326 GObjectClass parent_class;
327
328+ void (* dpi_changed) (GWDTheme *theme);
329+
330+ void (* scale_changed) (GWDTheme *theme);
331+
332 void (* style_updated) (GWDTheme *theme);
333
334 void (* get_shadow) (GWDTheme *theme,
335@@ -96,6 +100,12 @@
336 GWDSettings *
337 gwd_theme_get_settings (GWDTheme *theme);
338
339+gdouble
340+gwd_theme_get_dpi (GWDTheme *theme);
341+
342+gint
343+gwd_theme_get_scale (GWDTheme *theme);
344+
345 GtkWidget *
346 gwd_theme_get_style_window (GWDTheme *theme);
347

Subscribers

People subscribed via source and target branches