Merge lp:~brandontschaefer/overlay-scrollbar/hidpi-support into lp:overlay-scrollbar

Proposed by Brandon Schaefer on 2014-04-04
Status: Approved
Approved by: Christopher Townsend on 2014-04-04
Approved revision: 388
Proposed branch: lp:~brandontschaefer/overlay-scrollbar/hidpi-support
Merge into: lp:overlay-scrollbar
Diff against target: 503 lines (+294/-33)
6 files modified
os/Makefile.am (+2/-0)
os/em-converter.c (+153/-0)
os/em-converter.h (+43/-0)
os/os-private.h (+14/-10)
os/os-scrollbar.c (+51/-21)
os/os-thumb.c (+31/-2)
To merge this branch: bzr merge lp:~brandontschaefer/overlay-scrollbar/hidpi-support
Reviewer Review Type Date Requested Status
Christopher Townsend 2014-04-04 Approve on 2014-04-04
PS Jenkins bot (community) continuous-integration Approve on 2014-04-04
Review via email: mp+214283@code.launchpad.net

Commit message

Scale up the overlay-scrollbars correctly when the DPI changes. Does not work very nice when the gtk-scaling-factor is changed.

Description of the change

Scale up the overlay-scrollbars correctly when the DPI changes. Does not work very nice when the gtk-scaling-factor is changed.

To post a comment you must log in.
Christopher Townsend (townsend) wrote :

Seems to work fine for < 2. That's good enough for now.

review: Approve
Christopher Townsend (townsend) wrote :

Ok, update looks fine as well.

review: Approve
389. By Brandon Schaefer on 2014-05-09

* Fix problem if a newly mapped monitor is plugged in and left
  to the default scale value.

Unmerged revisions

389. By Brandon Schaefer on 2014-05-09

* Fix problem if a newly mapped monitor is plugged in and left
  to the default scale value.

388. By Brandon Schaefer on 2014-04-04

* Increase the prox check by the DPI!

387. By Brandon Schaefer on 2014-03-27

* Move the setting the device scale code, becuase if we are not on gtk3 we crash!
* Fix the grip not being drawn when divison of the w/h changed the w/h to be off by 1

386. By Brandon Schaefer on 2014-03-27

* Dynamically update the scrollbar gtk allocation if we change
  monitors. (Only when are attempting to use the scrollbar do we check)

385. By Brandon Schaefer on 2014-03-27

* Set the monitor when it changes. Need to find a good way to tell gtk to re-do
  gtk allocation.

384. By Brandon Schaefer on 2014-03-25

* Add HiDPI Support for the overlay scrollbars

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'os/Makefile.am'
2--- os/Makefile.am 2012-04-26 14:44:19 +0000
3+++ os/Makefile.am 2014-05-09 17:06:57 +0000
4@@ -5,10 +5,12 @@
5 endif
6
7 source_h = \
8+ $(srcdir)/em-converter.h \
9 $(srcdir)/os-private.h \
10 $(srcdir)/os-scrollbar.h
11
12 source_c = \
13+ $(srcdir)/em-converter.c \
14 $(srcdir)/os-animation.c \
15 $(srcdir)/os-bar.c \
16 $(srcdir)/os-log.c \
17
18=== added file 'os/em-converter.c'
19--- os/em-converter.c 1970-01-01 00:00:00 +0000
20+++ os/em-converter.c 2014-05-09 17:06:57 +0000
21@@ -0,0 +1,153 @@
22+/* overlay-scrollbar
23+ *
24+ * Copyright © 2014 Canonical Ltd
25+ *
26+ * This library is free software; you can redistribute it and/or
27+ * modify it under the terms of the GNU Lesser General Public
28+ * License version 2.1 as published by the Free Software Foundation.
29+ *
30+ * This library is distributed in the hope that it will be useful,
31+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33+ * Lesser General Public License for more details.
34+ *
35+ * You should have received a copy of the GNU Lesser General Public
36+ * License along with this library; if not, write to the
37+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38+ * Boston, MA 02110-1301 USA
39+ *
40+ * Authored by Brandon Schaefer <brandon.schaefer@canonical.com>
41+ */
42+
43+#include "em-converter.h"
44+
45+#include <stdio.h>
46+#include <stdlib.h>
47+
48+#define BASE_DPI 96.0
49+#define PIXELS_PER_INCH 72.0
50+#define CONVERT_TO_SCALE 8.0
51+
52+#define SCALE_FATOR "scale-factor"
53+#define UNITY_GSETTINGS_SCHEMA "com.ubuntu.user-interface"
54+
55+static void
56+update_dpi_value(EMConverter* converter, double scale_value)
57+{
58+ if (!converter)
59+ return;
60+
61+ converter->dpi = BASE_DPI * scale_value;
62+}
63+
64+static void
65+parse_font_scale_factor (EMConverter* converter)
66+{
67+ float value;
68+ int raw_value;
69+ GVariant* dict;
70+ GdkScreen *screen;
71+ gchar* monitor_name;
72+
73+ g_settings_get(converter->unity_settings, SCALE_FATOR, "@a{si}", &dict);
74+
75+ screen = gtk_widget_get_screen (converter->parent);
76+
77+
78+ monitor_name = gdk_screen_get_monitor_plug_name (screen, converter->monitor);
79+ if (g_variant_lookup(dict, monitor_name, "i", &raw_value))
80+ value = raw_value / CONVERT_TO_SCALE;
81+ else
82+ value = BASE_DPI;
83+
84+ g_free (monitor_name);
85+
86+ update_dpi_value(converter, value);
87+}
88+
89+gboolean
90+set_converter_monitor (EMConverter* converter, int monitor)
91+{
92+ if (converter->monitor != monitor)
93+ {
94+ converter->monitor = monitor;
95+ parse_font_scale_factor(converter);
96+
97+ return TRUE;
98+ }
99+
100+ return FALSE;
101+}
102+
103+static void
104+font_scale_changed_callback (GSettings* settings, gchar *key, gpointer data)
105+{
106+ EMConverter* converter = (EMConverter*)data;
107+
108+ parse_font_scale_factor(converter);
109+}
110+
111+static void
112+get_unity_settings (EMConverter* converter)
113+{
114+ converter->unity_settings = g_settings_new(UNITY_GSETTINGS_SCHEMA);
115+
116+ g_signal_connect (converter->unity_settings, "changed::"SCALE_FATOR,
117+ G_CALLBACK (font_scale_changed_callback), converter);
118+}
119+
120+
121+EMConverter*
122+new_converter (GtkWidget *parent)
123+{
124+ EMConverter* converter = (EMConverter*)malloc(sizeof(EMConverter));
125+
126+ converter->monitor = 0;
127+ converter->dpi = BASE_DPI;
128+ converter->unity_settings = NULL;
129+ converter->parent = parent;
130+
131+ get_unity_settings(converter);
132+ parse_font_scale_factor(converter);
133+
134+ return converter;
135+}
136+
137+void
138+cleanup_converter (EMConverter* converter)
139+{
140+ if (converter)
141+ {
142+ if (converter->unity_settings != NULL)
143+ {
144+ g_object_unref(converter->unity_settings);
145+ converter->unity_settings = NULL;
146+ }
147+
148+ converter = NULL;
149+ }
150+}
151+
152+double
153+convert_pixels (EMConverter* converter, double pixel)
154+{
155+ if (!converter || BASE_DPI == converter->dpi)
156+ return pixel;
157+
158+ double base_ppe = BASE_DPI / PIXELS_PER_INCH;
159+ double pixels_em = pixel / base_ppe;
160+
161+ double current_ppe = converter->dpi / PIXELS_PER_INCH;
162+ double new_pixels = pixels_em * current_ppe;
163+
164+ return new_pixels;
165+}
166+
167+double
168+dpi_scale (EMConverter* converter)
169+{
170+ if (!converter)
171+ return 1.0;
172+
173+ return converter->dpi / BASE_DPI;
174+}
175
176=== added file 'os/em-converter.h'
177--- os/em-converter.h 1970-01-01 00:00:00 +0000
178+++ os/em-converter.h 2014-05-09 17:06:57 +0000
179@@ -0,0 +1,43 @@
180+/* overlay-scrollbar
181+ *
182+ * Copyright © 2014 Canonical Ltd
183+ *
184+ * This library is free software; you can redistribute it and/or
185+ * modify it under the terms of the GNU Lesser General Public
186+ * License version 2.1 as published by the Free Software Foundation.
187+ *
188+ * This library is distributed in the hope that it will be useful,
189+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
190+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
191+ * Lesser General Public License for more details.
192+ *
193+ * You should have received a copy of the GNU Lesser General Public
194+ * License along with this library; if not, write to the
195+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
196+ * Boston, MA 02110-1301 USA
197+ *
198+ * Authored by Brandon Schaefer <brandon.schaefer@canonical.com>
199+ */
200+
201+#ifndef EM_CONVERTER_H
202+#define EM_CONVERTER_H
203+
204+#include <gtk/gtk.h>
205+
206+typedef struct {
207+ int monitor;
208+ int dpi;
209+ GSettings *unity_settings;
210+ GtkWidget *parent;
211+
212+} EMConverter;
213+
214+extern double convert_pixels (EMConverter* converter, double pixel);
215+extern double dpi_scale (EMConverter* converter);
216+extern gboolean set_converter_monitor (EMConverter* converter, int monitor);
217+
218+extern EMConverter* new_converter (GtkWidget *parent);
219+extern void cleanup_converter (EMConverter* converter);
220+
221+
222+#endif /* EM_CONVERTER_H */
223
224=== modified file 'os/os-private.h'
225--- os/os-private.h 2012-11-26 14:35:24 +0000
226+++ os/os-private.h 2014-05-09 17:06:57 +0000
227@@ -23,6 +23,7 @@
228 #define __OS_PRIVATE_H__
229
230 #include <gtk/gtk.h>
231+#include "em-converter.h"
232
233 /* Tell GCC not to export internal functions. */
234 #ifdef __GNUC__
235@@ -235,16 +236,19 @@
236 GtkWindowClass parent_class;
237 };
238
239-GType os_thumb_get_type (void) G_GNUC_CONST;
240-
241-GtkWidget* os_thumb_new (GtkOrientation orientation);
242-
243-void os_thumb_resize (OsThumb *thumb,
244- gint width,
245- gint height);
246-
247-void os_thumb_set_detached (OsThumb *thumb,
248- gboolean detached);
249+GType os_thumb_get_type (void) G_GNUC_CONST;
250+
251+GtkWidget* os_thumb_new (GtkOrientation orientation);
252+
253+void os_thumb_resize (OsThumb *thumb,
254+ gint width,
255+ gint height);
256+
257+void os_thumb_set_detached (OsThumb *thumb,
258+ gboolean detached);
259+
260+void os_thumb_set_converter (OsThumb *thumb,
261+ EMConverter *converter);
262
263 G_END_DECLS
264
265
266=== modified file 'os/os-scrollbar.c'
267--- os/os-scrollbar.c 2013-12-12 10:17:22 +0000
268+++ os/os-scrollbar.c 2014-05-09 17:06:57 +0000
269@@ -116,6 +116,7 @@
270 GtkWindowGroup *window_group;
271 OsAnimation *animation;
272 OsBar *bar;
273+ EMConverter *converter;
274 OsCoordinate pointer;
275 OsCoordinate thumb_win;
276 OsEventFlags event;
277@@ -676,6 +677,7 @@
278 qdata->fine_scroll_multiplier = 1.0;
279 qdata->bar = os_bar_new ();
280 qdata->window_group = gtk_window_group_new ();
281+ qdata->converter = new_converter (widget);
282 qdata->animation = os_animation_new (RATE_ANIMATION, MAX_DURATION_SCROLLING,
283 scrolling_cb, scrolling_end_cb, widget);
284
285@@ -823,6 +825,15 @@
286 priv->state &= ~(OS_STATE_RECONNECTING);
287 }
288
289+static void
290+update_scrollbar_size_allocation(GtkScrollbar *scrollbar)
291+{
292+ /* Hack to update the size allocation if the monitor changes */
293+ GtkAllocation allocation;
294+ gtk_widget_get_allocation ((GTK_WIDGET (scrollbar)), &allocation);
295+ hijacked_scrollbar_size_allocate (GTK_WIDGET(scrollbar), &allocation);
296+}
297+
298 /* Sanitize x coordinate of thumb window. */
299 static gint
300 sanitize_x (GtkScrollbar *scrollbar,
301@@ -845,6 +856,10 @@
302
303 screen = gtk_widget_get_screen (GTK_WIDGET (scrollbar));
304 n_monitor = gdk_screen_get_monitor_at_point (screen, monitor_x, y);
305+
306+ if (set_converter_monitor(priv->converter, n_monitor))
307+ update_scrollbar_size_allocation(scrollbar);
308+
309 #ifdef USE_GTK3
310 gdk_screen_get_monitor_geometry (screen, n_monitor, &rect);
311 #else
312@@ -988,6 +1003,10 @@
313
314 screen = gtk_widget_get_screen (GTK_WIDGET (scrollbar));
315 n_monitor = gdk_screen_get_monitor_at_point (screen, x, monitor_y);
316+
317+ if (set_converter_monitor(priv->converter, n_monitor))
318+ update_scrollbar_size_allocation(scrollbar);
319+
320 #ifdef USE_GTK3
321 gdk_screen_get_monitor_geometry (screen, n_monitor, &rect);
322 #else
323@@ -1259,6 +1278,8 @@
324 G_CALLBACK (thumb_scroll_event_cb), scrollbar);
325 g_signal_connect (G_OBJECT (priv->thumb), "unmap",
326 G_CALLBACK (thumb_unmap_cb), scrollbar);
327+
328+ os_thumb_set_converter (OS_THUMB(priv->thumb), priv->converter);
329 }
330 }
331
332@@ -2820,7 +2841,7 @@
333
334 priv = get_private (GTK_WIDGET (scrollbar));
335
336- proximity_size = PROXIMITY_SIZE;
337+ proximity_size = convert_pixels (priv->converter, PROXIMITY_SIZE);
338
339 /* If the thumb is internal, enlarge the proximity area. */
340 if (priv->state & OS_STATE_INTERNAL)
341@@ -3325,6 +3346,11 @@
342 priv->animation = NULL;
343 }
344
345+ if (priv->converter != NULL)
346+ {
347+ cleanup_converter (priv->converter);
348+ }
349+
350 if (priv->bar != NULL)
351 {
352 g_object_unref (priv->bar);
353@@ -3383,8 +3409,8 @@
354 *minimal_width = *natural_width = 0;
355 else
356 {
357- *minimal_width = MIN_THUMB_HEIGHT;
358- *natural_width = THUMB_HEIGHT;
359+ *minimal_width = convert_pixels(priv->converter, MIN_THUMB_HEIGHT);
360+ *natural_width = convert_pixels(priv->converter, THUMB_HEIGHT);
361 }
362
363 return;
364@@ -3408,8 +3434,8 @@
365 *minimal_height = *natural_height = 0;
366 else
367 {
368- *minimal_height = MIN_THUMB_HEIGHT;
369- *natural_height = THUMB_HEIGHT;
370+ *minimal_height = convert_pixels(priv->converter, MIN_THUMB_HEIGHT);
371+ *natural_height = convert_pixels(priv->converter, THUMB_HEIGHT);
372 }
373
374 return;
375@@ -3720,6 +3746,10 @@
376 scrollbar = GTK_SCROLLBAR (widget);
377 priv = get_private (widget);
378
379+ int thumb_width = convert_pixels(priv->converter, THUMB_WIDTH);
380+ int thumb_height = convert_pixels(priv->converter, THUMB_HEIGHT);
381+ int bar_size = convert_pixels(priv->converter, BAR_SIZE);
382+
383 /* Get the side, then move thumb and bar accordingly. */
384 retrieve_side (scrollbar);
385
386@@ -3733,19 +3763,19 @@
387
388 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
389 {
390- priv->slider.width = THUMB_WIDTH;
391- if (priv->slider.height != MIN (THUMB_HEIGHT, allocation->height))
392+ priv->slider.width = thumb_width;
393+ if (priv->slider.height != MIN (thumb_height, allocation->height))
394 {
395- priv->slider.height = MIN (THUMB_HEIGHT, allocation->height);
396+ priv->slider.height = MIN (thumb_height, allocation->height);
397 os_thumb_resize (OS_THUMB (priv->thumb), priv->slider.width, priv->slider.height);
398 }
399
400 if (priv->side == OS_SIDE_RIGHT)
401- priv->bar_all.x = allocation->x - BAR_SIZE;
402-
403- priv->bar_all.width = BAR_SIZE;
404-
405- priv->thumb_all.width = THUMB_WIDTH;
406+ priv->bar_all.x = allocation->x - bar_size;
407+
408+ priv->bar_all.width = bar_size;
409+
410+ priv->thumb_all.width = thumb_width;
411
412 if (priv->side == OS_SIDE_RIGHT)
413 priv->thumb_all.x = allocation->x - priv->bar_all.width;
414@@ -3756,19 +3786,19 @@
415 }
416 else
417 {
418- priv->slider.height = THUMB_WIDTH;
419- if (priv->slider.width != MIN (THUMB_HEIGHT, allocation->width))
420+ priv->slider.height = thumb_width;
421+ if (priv->slider.width != MIN (thumb_height, allocation->width))
422 {
423- priv->slider.width = MIN (THUMB_HEIGHT, allocation->width);
424+ priv->slider.width = MIN (thumb_height, allocation->width);
425 os_thumb_resize (OS_THUMB (priv->thumb), priv->slider.width, priv->slider.height);
426 }
427
428 if (priv->side == OS_SIDE_BOTTOM)
429- priv->bar_all.y = allocation->y - BAR_SIZE;
430-
431- priv->bar_all.height = BAR_SIZE;
432-
433- priv->thumb_all.height = THUMB_WIDTH;
434+ priv->bar_all.y = allocation->y - bar_size;
435+
436+ priv->bar_all.height = bar_size;
437+
438+ priv->thumb_all.height = thumb_width;
439
440 if (priv->side == OS_SIDE_BOTTOM)
441 priv->thumb_all.y = allocation->y - priv->bar_all.height;
442
443=== modified file 'os/os-thumb.c'
444--- os/os-thumb.c 2013-02-02 00:46:51 +0000
445+++ os/os-thumb.c 2014-05-09 17:06:57 +0000
446@@ -53,6 +53,7 @@
447 GtkOrientation orientation;
448 GtkWidget *grabbed_widget;
449 OsAnimation *animation;
450+ EMConverter *converter;
451 OsCoordinate pointer;
452 OsCoordinate pointer_root;
453 OsEventFlags event;
454@@ -679,6 +680,13 @@
455 cr = gdk_cairo_create (gtk_widget_get_window (widget));
456 #endif
457
458+ cairo_surface_t *surface = cairo_get_target(cr);
459+ float scale = dpi_scale(priv->converter);
460+ cairo_surface_set_device_scale(surface, scale, scale);
461+
462+ width /= scale;
463+ height /= scale;
464+
465 cairo_save (cr);
466
467 cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
468@@ -815,8 +823,8 @@
469 cairo_stroke (cr);
470
471 /* Only draw the grip when the thumb is at full height. */
472- if ((priv->orientation == GTK_ORIENTATION_VERTICAL && height == THUMB_HEIGHT - 1) ||
473- (priv->orientation == GTK_ORIENTATION_HORIZONTAL && width == THUMB_HEIGHT - 1) )
474+ if ((priv->orientation == GTK_ORIENTATION_VERTICAL && height < THUMB_HEIGHT) ||
475+ (priv->orientation == GTK_ORIENTATION_HORIZONTAL && width < THUMB_HEIGHT) )
476 {
477 if (priv->orientation == GTK_ORIENTATION_VERTICAL)
478 pat = cairo_pattern_create_linear (0, 0, 0, height);
479@@ -1268,3 +1276,24 @@
480 gtk_widget_queue_draw (GTK_WIDGET (thumb));
481 }
482 }
483+
484+/**
485+* os_thumb_set_converter:
486+* @thumb: a #OsThumb
487+* @converter: an #EMConveter
488+*
489+* Sets the thumbs EMConverter, needed to scale DPI dynamically
490+**/
491+
492+void
493+os_thumb_set_converter (OsThumb* thumb,
494+ EMConverter* converter)
495+{
496+ OsThumbPrivate *priv;
497+
498+ g_return_if_fail (OS_IS_THUMB (thumb));
499+
500+ priv = thumb->priv;
501+
502+ priv->converter = converter;
503+}

Subscribers

People subscribed via source and target branches