Merge lp:~gala-dev/gala/hidpi into lp:gala

Proposed by Rico Tzschichholz
Status: Work in progress
Proposed branch: lp:~gala-dev/gala/hidpi
Merge into: lp:gala
Diff against target: 678 lines (+203/-69)
9 files modified
lib/Utils.vala (+8/-6)
lib/WindowManager.vala (+5/-0)
plugins/notify/ConfirmationNotification.vala (+17/-8)
plugins/notify/Main.vala (+3/-3)
plugins/notify/NormalNotification.vala (+33/-14)
plugins/notify/Notification.vala (+52/-25)
plugins/notify/NotificationStack.vala (+8/-7)
plugins/notify/NotifyServer.vala (+8/-6)
src/WindowManager.vala (+69/-0)
To merge this branch: bzr merge lp:~gala-dev/gala/hidpi
Reviewer Review Type Date Requested Status
Gala developers Pending
Review via email: mp+317723@code.launchpad.net

Description of the change

Enable HiDPI on the notifications

To post a comment you must log in.

Unmerged revisions

564. By Corentin Noël

[HiDPI] Notifications are now working

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/Utils.vala'
2--- lib/Utils.vala 2016-12-31 08:08:58 +0000
3+++ lib/Utils.vala 2017-02-19 16:15:16 +0000
4@@ -25,6 +25,7 @@
5 static uint cache_clear_timeout = 0;
6
7 static Gdk.Pixbuf? close_pixbuf = null;
8+ static int close_pixbuf_scale = 0;
9
10 static construct
11 {
12@@ -290,11 +291,12 @@
13 *
14 * @return the close button pixbuf or null if it failed to load
15 */
16- public static Gdk.Pixbuf? get_close_button_pixbuf ()
17+ public static Gdk.Pixbuf? get_close_button_pixbuf (int scale_factor)
18 {
19- if (close_pixbuf == null) {
20+ if (close_pixbuf == null || close_pixbuf_scale != scale_factor) {
21 try {
22- close_pixbuf = new Gdk.Pixbuf.from_file_at_scale (Config.PKGDATADIR + "/close.svg", -1, 36, true);
23+ close_pixbuf = new Gdk.Pixbuf.from_file_at_scale (Config.PKGDATADIR + "/close.svg", -1, 36 * scale_factor, true);
24+ close_pixbuf_scale = scale_factor;
25 } catch (Error e) {
26 warning (e.message);
27 return null;
28@@ -309,10 +311,10 @@
29 *
30 * @return The close button actor
31 */
32- public static Clutter.Actor create_close_button ()
33+ public static Clutter.Actor create_close_button (int scale_factor = 1)
34 {
35 var texture = new Clutter.Texture ();
36- var pixbuf = get_close_button_pixbuf ();
37+ var pixbuf = get_close_button_pixbuf (scale_factor);
38
39 texture.reactive = true;
40
41@@ -326,7 +328,7 @@
42 // we'll just make this red so there's at least something as an
43 // indicator that loading failed. Should never happen and this
44 // works as good as some weird fallback-image-failed-to-load pixbuf
45- texture.set_size (36, 36);
46+ texture.set_size (36 * scale_factor, 36 * scale_factor);
47 texture.background_color = { 255, 0, 0, 255 };
48 }
49
50
51=== modified file 'lib/WindowManager.vala'
52--- lib/WindowManager.vala 2015-03-04 11:07:30 +0000
53+++ lib/WindowManager.vala 2017-02-19 16:15:16 +0000
54@@ -92,6 +92,11 @@
55 public abstract Meta.BackgroundGroup background_group { get; protected set; }
56
57 /**
58+ * The scale factor is the scale used by all user-facing elements
59+ */
60+ public abstract int scale_factor { get; protected set; }
61+
62+ /**
63 * Enters the modal mode, which means that all events are directed to the stage instead
64 * of the windows. This is the only way to receive keyboard events besides shortcut listeners.
65 *
66
67=== modified file 'plugins/notify/ConfirmationNotification.vala'
68--- plugins/notify/ConfirmationNotification.vala 2014-07-21 01:21:19 +0000
69+++ plugins/notify/ConfirmationNotification.vala 2017-02-19 16:15:16 +0000
70@@ -55,7 +55,7 @@
71
72 public override void update_allocation (out float content_height, AllocationFlags flags)
73 {
74- content_height = ICON_SIZE;
75+ content_height = ICON_SIZE * style_context.get_scale ();
76 }
77
78 public override void draw_content (Cairo.Context cr)
79@@ -63,14 +63,21 @@
80 if (!has_progress)
81 return;
82
83- var x = MARGIN + PADDING + ICON_SIZE + SPACING;
84- var y = MARGIN + PADDING + (ICON_SIZE - PROGRESS_HEIGHT) / 2;
85- var width = WIDTH - x - MARGIN;
86+ var scale = style_context.get_scale ();
87+ var scaled_width = WIDTH * scale;
88+ var scaled_margin = MARGIN * scale;
89+ var scaled_padding = PADDING * scale;
90+ var scaled_icon_size = ICON_SIZE * scale;
91+ var scaled_spacing = SPACING * scale;
92+ var scaled_progress_height = PROGRESS_HEIGHT * scale;
93+ var x = scaled_margin + scaled_padding + scaled_icon_size + scaled_spacing;
94+ var y = scaled_margin + scaled_padding + (scaled_icon_size - scaled_progress_height) / 2;
95+ var width = scaled_width - x - scaled_margin;
96
97 if (!transitioning)
98 draw_progress_bar (cr, x, y, width, progress);
99 else {
100- Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, MARGIN, MARGIN, WIDTH - MARGIN * 2, ICON_SIZE + PADDING * 2, 4);
101+ Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, scaled_margin, scaled_margin, scaled_width - scaled_margin * 2, scaled_icon_size + scaled_padding * 2, 4);
102 cr.clip ();
103
104 draw_progress_bar (cr, x, y + animation_slide_y_offset, width, old_progress);
105@@ -82,16 +89,18 @@
106
107 void draw_progress_bar (Cairo.Context cr, int x, float y, int width, int progress)
108 {
109+ var scale = style_context.get_scale ();
110 var fraction = (int) Math.floor (progress.clamp (0, 100) / 100.0 * width);
111
112+ var scaled_height = PROGRESS_HEIGHT * scale;
113 Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, x, y, width,
114- PROGRESS_HEIGHT, PROGRESS_HEIGHT / 2);
115+ scaled_height, scaled_height / 2);
116 cr.set_source_rgb (0.8, 0.8, 0.8);
117 cr.fill ();
118
119 if (progress > 0) {
120 Granite.Drawing.Utilities.cairo_rounded_rectangle (cr, x, y, fraction,
121- PROGRESS_HEIGHT, PROGRESS_HEIGHT / 2);
122+ scaled_height, scaled_height / 2);
123 cr.set_source_rgb (0.3, 0.3, 0.3);
124 cr.fill ();
125 }
126@@ -111,7 +120,7 @@
127
128 old_progress = this.progress;
129
130- play_update_transition (ICON_SIZE + PADDING * 2);
131+ play_update_transition ((ICON_SIZE + PADDING * 2) * style_context.get_scale ());
132 }
133
134 if (this.icon_only != icon_only) {
135
136=== modified file 'plugins/notify/Main.vala'
137--- plugins/notify/Main.vala 2014-07-18 11:12:31 +0000
138+++ plugins/notify/Main.vala 2017-02-19 16:15:16 +0000
139@@ -30,9 +30,8 @@
140 public override void initialize (Gala.WindowManager wm)
141 {
142 this.wm = wm;
143- var screen = wm.get_screen ();
144
145- stack = new NotificationStack (wm.get_screen ());
146+ stack = new NotificationStack (wm);
147 wm.ui_group.add_child (stack);
148 track_actor (stack);
149
150@@ -43,6 +42,7 @@
151 server = new NotifyServer (stack);
152
153 update_position ();
154+ unowned Meta.Screen screen = wm.get_screen ();
155 screen.monitors_changed.connect (update_position);
156 screen.workareas_changed.connect (update_position);
157
158@@ -64,7 +64,7 @@
159
160 void update_position ()
161 {
162- var screen = wm.get_screen ();
163+ unowned Meta.Screen screen = wm.get_screen ();
164 var primary = screen.get_primary_monitor ();
165 var area = screen.get_active_workspace ().get_work_area_for_monitor (primary);
166
167
168=== modified file 'plugins/notify/NormalNotification.vala'
169--- plugins/notify/NormalNotification.vala 2016-08-04 07:37:29 +0000
170+++ plugins/notify/NormalNotification.vala 2017-02-19 16:15:16 +0000
171@@ -38,6 +38,8 @@
172 } catch (Error e) {}
173 }
174
175+ public unowned Gtk.StyleContext parent_style_context { get; construct; }
176+
177 const int LABEL_SPACING = 2;
178
179 Text summary_label;
180@@ -64,6 +66,7 @@
181 var label_style_context = new Gtk.StyleContext ();
182 label_style_context.add_provider (Notification.default_css, Gtk.STYLE_PROVIDER_PRIORITY_FALLBACK);
183 label_style_context.set_path (style_path);
184+ label_style_context.set_parent (parent_style_context);
185
186 Gdk.RGBA color;
187
188@@ -93,6 +96,11 @@
189 add_child (body_label);
190 }
191
192+ public NormalNotificationContent (Gtk.StyleContext parent_style_context)
193+ {
194+ Object (parent_style_context: parent_style_context);
195+ }
196+
197 public void set_values (string summary, string body)
198 {
199 summary_label.set_markup ("<b>%s</b>".printf (fix_markup (summary)));
200@@ -119,7 +127,7 @@
201 summary_label.allocate (summary_alloc, flags);
202
203 var body_alloc = ActorBox ();
204- body_alloc.set_origin (label_x, label_y + summary_height + LABEL_SPACING);
205+ body_alloc.set_origin (label_x, label_y + summary_height + LABEL_SPACING * parent_style_context.get_scale ());
206 body_alloc.set_size (label_width, body_height);
207 body_label.allocate (body_alloc, flags);
208
209@@ -129,16 +137,22 @@
210 void get_allocation_values (out float label_x, out float label_width, out float summary_height,
211 out float body_height, out float label_height, out float label_y)
212 {
213- var height = Notification.ICON_SIZE;
214+ var scale = parent_style_context.get_scale ();
215+ var height = Notification.ICON_SIZE * scale;
216+ var width = scale * Notification.WIDTH;
217+ var margin = scale * Notification.MARGIN;
218+ var padding = scale * Notification.PADDING;
219+ var spacing = scale * Notification.SPACING;
220+ var label_spacing = scale * LABEL_SPACING;
221
222- label_x = Notification.MARGIN + Notification.PADDING + height + Notification.SPACING;
223- label_width = Notification.WIDTH - label_x - Notification.MARGIN - Notification.SPACING;
224+ label_x = margin + padding + height + spacing;
225+ label_width = width - label_x - margin - spacing;
226
227 summary_label.get_preferred_height (label_width, null, out summary_height);
228 body_label.get_preferred_height (label_width, null, out body_height);
229
230- label_height = summary_height + LABEL_SPACING + body_height;
231- label_y = Notification.MARGIN + Notification.PADDING;
232+ label_height = summary_height + label_spacing + body_height;
233+ label_y = margin + padding;
234 // center
235 if (label_height < height) {
236 label_y += (height - (int) label_height) / 2;
237@@ -168,13 +182,13 @@
238 public string body { get; construct set; }
239 public uint32 sender_pid { get; construct; }
240 public string[] notification_actions { get; construct set; }
241- public Screen screen { get; construct; }
242+ public unowned Gala.WindowManager wm { get; construct; }
243
244 Actor content_container;
245 NormalNotificationContent notification_content;
246 NormalNotificationContent? old_notification_content = null;
247
248- public NormalNotification (Screen screen, uint32 id, string summary, string body, Gdk.Pixbuf? icon,
249+ public NormalNotification (Gala.WindowManager wm, uint32 id, string summary, string body, Gdk.Pixbuf? icon,
250 NotificationUrgency urgency, int32 expire_timeout, uint32 pid, string[] actions)
251 {
252 Object (
253@@ -182,7 +196,7 @@
254 icon: icon,
255 urgency: urgency,
256 expire_timeout: expire_timeout,
257- screen: screen,
258+ wm: wm,
259 summary: summary,
260 body: body,
261 sender_pid: pid,
262@@ -192,9 +206,10 @@
263
264 construct
265 {
266+ set_scale_factor (wm.scale_factor);
267 content_container = new Actor ();
268
269- notification_content = new NormalNotificationContent ();
270+ notification_content = new NormalNotificationContent (style_context);
271 notification_content.set_values (summary, body);
272
273 content_container.add_child (notification_content);
274@@ -210,7 +225,7 @@
275 if (old_notification_content != null)
276 old_notification_content.destroy ();
277
278- old_notification_content = new NormalNotificationContent ();
279+ old_notification_content = new NormalNotificationContent (style_context);
280 old_notification_content.set_values (this.summary, this.body);
281
282 content_container.add_child (old_notification_content);
283@@ -225,7 +240,7 @@
284
285 content_height = float.max (content_height, old_content_height);
286
287- play_update_transition (content_height + PADDING * 2);
288+ play_update_transition (content_height + PADDING * 2 * style_context.get_scale ());
289
290 get_transition ("switch").completed.connect (() => {
291 if (old_notification_content != null)
292@@ -257,8 +272,10 @@
293 // the for_width is not needed in our implementation of get_preferred_height as we
294 // assume a constant width
295 notification_content.get_preferred_height (0, null, out content_height);
296+ var scale = style_context.get_scale ();
297+ var scaled_margin = MARGIN * scale;
298
299- content_container.set_clip (MARGIN, MARGIN, MARGIN * 2 + WIDTH, content_height + PADDING * 2);
300+ content_container.set_clip (scaled_margin, scaled_margin, scaled_margin * 2 + WIDTH * scale, content_height + PADDING * 2 * scale);
301 }
302
303 public override void get_preferred_height (float for_width, out float min_height, out float nat_height)
304@@ -266,7 +283,7 @@
305 float content_height;
306 notification_content.get_preferred_height (for_width, null, out content_height);
307
308- min_height = nat_height = content_height + (MARGIN + PADDING) * 2;
309+ min_height = nat_height = content_height + ((MARGIN + PADDING) * 2) * style_context.get_scale ();
310 }
311
312 public override void activate ()
313@@ -287,6 +304,7 @@
314 unowned Meta.Window? window = get_window ();
315 if (window != null) {
316 unowned Meta.Workspace workspace = window.get_workspace ();
317+ unowned Meta.Screen screen = wm.get_screen ();
318 var time = screen.get_display ().get_current_time ();
319
320 if (workspace != screen.get_active_workspace ())
321@@ -303,6 +321,7 @@
322 if (sender_pid == 0)
323 return null;
324
325+ unowned Meta.Screen screen = wm.get_screen ();
326 foreach (unowned Meta.WindowActor actor in Meta.Compositor.get_window_actors (screen)) {
327 if (actor.is_destroyed ())
328 continue;
329
330=== modified file 'plugins/notify/Notification.vala'
331--- plugins/notify/Notification.vala 2016-11-15 16:13:39 +0000
332+++ plugins/notify/Notification.vala 2017-02-19 16:15:16 +0000
333@@ -53,7 +53,7 @@
334
335 Clutter.Actor close_button;
336
337- Gtk.StyleContext style_context;
338+ protected Gtk.StyleContext style_context { get; private set; }
339
340 uint remove_timeout = 0;
341
342@@ -99,20 +99,7 @@
343 icon_container = new Actor ();
344 icon_container.add_child (icon_texture);
345
346- close_button = Utils.create_close_button ();
347- close_button.opacity = 0;
348- close_button.reactive = true;
349- close_button.set_easing_duration (300);
350-
351- var close_click = new ClickAction ();
352- close_click.clicked.connect (() => {
353- closed (id, NotificationClosedReason.DISMISSED);
354- close ();
355- });
356- close_button.add_action (close_click);
357-
358 add_child (icon_container);
359- add_child (close_button);
360
361 if (default_css == null) {
362 default_css = new Gtk.CssProvider ();
363@@ -132,6 +119,8 @@
364 style_context.add_class ("gala-notification");
365 style_context.set_path (style_path);
366
367+ create_close_button ();
368+
369 var label_style_path = style_path.copy ();
370 label_style_path.iter_add_class (1, "gala-notification");
371 label_style_path.append_type (typeof (Gtk.Label));
372@@ -227,6 +216,26 @@
373 destroy ();
374 }
375
376+ void create_close_button () {
377+ if (close_button != null)
378+ {
379+ close_button.destroy ();
380+ }
381+
382+ close_button = Utils.create_close_button (style_context.get_scale ());
383+ close_button.opacity = 0;
384+ close_button.reactive = true;
385+ close_button.set_easing_duration (300);
386+
387+ var close_click = new ClickAction ();
388+ close_click.clicked.connect (() => {
389+ closed (id, NotificationClosedReason.DISMISSED);
390+ close ();
391+ });
392+ close_button.add_action (close_click);
393+ add_child (close_button);
394+ }
395+
396 protected void update_base (Gdk.Pixbuf? icon, int32 expire_timeout)
397 {
398 this.icon = icon;
399@@ -273,6 +282,16 @@
400 }
401 }
402
403+ public void set_scale_factor (int scale_factor)
404+ {
405+ style_context.set_scale (scale_factor);
406+ width = (WIDTH + MARGIN * 2) * scale_factor;
407+ create_close_button ();
408+ if (content is Canvas) {
409+ ((Canvas) content).set_scale_factor (scale_factor);
410+ }
411+ }
412+
413 public override bool enter_event (CrossingEvent event)
414 {
415 close_button.opacity = 255;
416@@ -304,21 +323,26 @@
417
418 public override void allocate (ActorBox box, AllocationFlags flags)
419 {
420+ var scale = style_context.get_scale ();
421+ var scaled_width = WIDTH * scale;
422+ var scaled_icon_size = ICON_SIZE * scale;
423+ var scaled_margin = MARGIN * scale;
424+ var scaled_padding = PADDING * scale;
425+ var margin_padding = scaled_margin + scaled_padding;
426 var icon_alloc = ActorBox ();
427
428- icon_alloc.set_origin (icon_only ? (WIDTH - ICON_SIZE) / 2 : MARGIN + PADDING, MARGIN + PADDING);
429- icon_alloc.set_size (ICON_SIZE, ICON_SIZE);
430+ icon_alloc.set_origin (icon_only ? (scaled_width - scaled_icon_size) / 2 : margin_padding, margin_padding);
431+ icon_alloc.set_size (scaled_icon_size, scaled_icon_size);
432 icon_container.allocate (icon_alloc, flags);
433
434 var close_alloc = ActorBox ();
435- close_alloc.set_origin (MARGIN + PADDING - close_button.width / 2,
436- MARGIN + PADDING - close_button.height / 2);
437+ close_alloc.set_origin (margin_padding - close_button.width / 2, margin_padding - close_button.height / 2);
438 close_alloc.set_size (close_button.width, close_button.height);
439 close_button.allocate (close_alloc, flags);
440
441 float content_height;
442 update_allocation (out content_height, flags);
443- box.set_size (MARGIN * 2 + WIDTH, (MARGIN + PADDING) * 2 + content_height);
444+ box.set_size (scaled_margin * 2 + scaled_width, margin_padding * 2 + content_height);
445
446 base.allocate (box, flags);
447
448@@ -331,7 +355,7 @@
449
450 public override void get_preferred_height (float for_width, out float min_height, out float nat_height)
451 {
452- min_height = nat_height = ICON_SIZE + (MARGIN + PADDING) * 2;
453+ min_height = nat_height = (ICON_SIZE + (MARGIN + PADDING) * 2) * style_context.get_scale ();
454 }
455
456 protected void play_update_transition (float slide_height)
457@@ -346,7 +370,8 @@
458
459 old_texture = new Clutter.Texture ();
460 icon_container.add_child (old_texture);
461- icon_container.set_clip (0, -PADDING, ICON_SIZE, ICON_SIZE + PADDING * 2);
462+ var scale = style_context.get_scale ();
463+ icon_container.set_clip (0, -PADDING * scale, ICON_SIZE * scale, (ICON_SIZE + PADDING * 2) * scale);
464
465 if (icon != null) {
466 try {
467@@ -382,10 +407,12 @@
468 {
469 var canvas = (Canvas) content;
470
471- var x = MARGIN;
472- var y = MARGIN;
473- var width = canvas.width - MARGIN * 2;
474- var height = canvas.height - MARGIN * 2;
475+ var scale = style_context.get_scale ();
476+ var margin_scaled = MARGIN * scale;
477+ var x = margin_scaled;
478+ var y = margin_scaled;
479+ var width = canvas.width - margin_scaled * 2;
480+ var height = canvas.height - margin_scaled * 2;
481 cr.set_operator (Cairo.Operator.CLEAR);
482 cr.paint ();
483 cr.set_operator (Cairo.Operator.OVER);
484
485=== modified file 'plugins/notify/NotificationStack.vala'
486--- plugins/notify/NotificationStack.vala 2016-07-28 22:19:16 +0000
487+++ plugins/notify/NotificationStack.vala 2017-02-19 16:15:16 +0000
488@@ -29,16 +29,16 @@
489
490 public signal void animations_changed (bool running);
491
492- public Screen screen { get; construct; }
493+ public unowned Gala.WindowManager wm { get; construct; }
494
495- public NotificationStack (Screen screen)
496+ public NotificationStack (Gala.WindowManager wm)
497 {
498- Object (screen: screen);
499+ Object (wm: wm);
500 }
501
502 construct
503 {
504- width = Notification.WIDTH + 2 * Notification.MARGIN + ADDITIONAL_MARGIN;
505+ width = (Notification.WIDTH + 2 * Notification.MARGIN + ADDITIONAL_MARGIN) * wm.scale_factor;
506 clip_to_allocation = true;
507 }
508
509@@ -67,16 +67,17 @@
510 });
511
512 float height;
513- notification.get_preferred_height (Notification.WIDTH, out height, null);
514+ int scale_factor = wm.scale_factor;
515+ notification.get_preferred_height (Notification.WIDTH * scale_factor, out height, null);
516 update_positions (height);
517
518- notification.y = TOP_OFFSET;
519+ notification.y = TOP_OFFSET * scale_factor;
520 insert_child_at_index (notification, 0);
521 }
522
523 void update_positions (float add_y = 0.0f)
524 {
525- var y = add_y + TOP_OFFSET;
526+ var y = add_y + TOP_OFFSET * wm.scale_factor;
527 var i = get_n_children ();
528 var delay_step = i > 0 ? 150 / i : 0;
529 foreach (var child in get_children ()) {
530
531=== modified file 'plugins/notify/NotifyServer.vala'
532--- plugins/notify/NotifyServer.vala 2016-12-31 08:08:58 +0000
533+++ plugins/notify/NotifyServer.vala 2017-02-19 16:15:16 +0000
534@@ -170,7 +170,8 @@
535 icon = app_info.get_icon ().to_string ();
536
537 var id = (replaces_id != 0 ? replaces_id : ++id_counter);
538- var pixbuf = get_pixbuf (app_name, icon, hints);
539+ unowned Gala.WindowManager wm = stack.wm;
540+ var pixbuf = get_pixbuf (app_name, icon, hints, wm.scale_factor);
541 var timeout = (expire_timeout == uint32.MAX ? DEFAULT_TMEOUT : expire_timeout);
542
543 var urgency = NotificationUrgency.NORMAL;
544@@ -285,9 +286,10 @@
545 progress ? hints.@get ("value").get_int32 () : -1,
546 hints.@get (X_CANONICAL_PRIVATE_SYNCHRONOUS).get_string ());
547 else
548- notification = new NormalNotification (stack.screen, id, summary, body, pixbuf,
549+ notification = new NormalNotification (wm, id, summary, body, pixbuf,
550 urgency, timeout, pid, actions);
551
552+ notification.set_scale_factor (wm.scale_factor);
553 notification.action_invoked.connect (notification_action_invoked_callback);
554 notification.closed.connect (notification_closed_callback);
555 stack.show_notification (notification);
556@@ -326,7 +328,7 @@
557 return icon_fg_color;
558 }
559
560- static Gdk.Pixbuf? get_pixbuf (string app_name, string app_icon, HashTable<string, Variant> hints)
561+ static Gdk.Pixbuf? get_pixbuf (string app_name, string app_icon, HashTable<string, Variant> hints, int scale_factor)
562 {
563 // decide on the icon, order:
564 // - image-data
565@@ -338,8 +340,8 @@
566
567 Gdk.Pixbuf? pixbuf = null;
568 Variant? variant = null;
569- var size = Notification.ICON_SIZE;
570- var mask_offset = 4;
571+ var size = Notification.ICON_SIZE * scale_factor;
572+ var mask_offset = 4 * scale_factor;
573 var mask_size_offset = mask_offset * 2;
574 var has_mask = false;
575
576@@ -403,7 +405,7 @@
577 } catch (Error e) { warning (e.message); }
578 }
579 } else if (has_mask) {
580- var mask_size = Notification.ICON_SIZE;
581+ var mask_size = Notification.ICON_SIZE * scale_factor;
582 var offset_x = mask_offset;
583 var offset_y = mask_offset + 1;
584
585
586=== modified file 'src/WindowManager.vala'
587--- src/WindowManager.vala 2016-11-18 16:57:03 +0000
588+++ src/WindowManager.vala 2017-02-19 16:15:16 +0000
589@@ -68,6 +68,11 @@
590 */
591 public Meta.BackgroundGroup background_group { get; protected set; }
592
593+ /**
594+ * {@inheritDoc}
595+ */
596+ public int scale_factor { get; protected set; }
597+
598 Meta.PluginInfo info;
599
600 WindowSwitcher? winswitcher = null;
601@@ -144,6 +149,8 @@
602 WindowListener.init (screen);
603 KeyboardManager.init (display);
604
605+ compute_scale_factor ();
606+
607 // Due to a bug which enables access to the stage when using multiple monitors
608 // in the screensaver, we have to listen for changes and make sure the input area
609 // is set to NONE when we are in locked mode
610@@ -314,6 +321,68 @@
611 return false;
612 }
613
614+ /* DPI constants taken from gnome-settings-daemon/plugins/xsettings/gsd-xsettings-manager.c */
615+ private const int DPI_FALLBACK = 96;
616+ /* The minimum resolution at which we turn on a window-scale of 2 */
617+ private const int HIDPI_LIMIT = (DPI_FALLBACK * 2);
618+ /* The minimum screen height at which we turn on a window-scale of 2;
619+ * below this there just isn't enough vertical real estate for GNOME
620+ * apps to work, and it's better to just be tiny */
621+ private const int HIDPI_MIN_HEIGHT = 1200;
622+ private const int SMALLEST_4K_WIDTH = 3656;
623+
624+ void compute_scale_factor ()
625+ {
626+ var desktop_settings = new GLib.Settings ("org.gnome.desktop.interface");
627+ var desktop_scale = desktop_settings.get_int ("scaling-factor");
628+ if (desktop_scale > 0) {
629+ scale_factor = desktop_scale;
630+ } else {
631+ weak Gdk.Display? display = Gdk.Display.get_default ();
632+ weak Gdk.Screen screen = display.get_default_screen ();
633+ var primary = screen.get_primary_monitor ();
634+ var rect = Gdk.Rectangle ();
635+ screen.get_monitor_geometry (primary, out rect);
636+ var monitor_scale = screen.get_monitor_scale_factor (primary);
637+
638+ int width = rect.width * monitor_scale;
639+ int height = rect.height * monitor_scale;
640+ int width_mm = screen.get_monitor_width_mm (primary);
641+ int height_mm = screen.get_monitor_height_mm (primary);
642+
643+ if (height < HIDPI_MIN_HEIGHT)
644+ {
645+ scale_factor = 1;
646+ return;
647+ }
648+
649+ /* Somebody encoded the aspect ratio (16/9 or 16/10)
650+ * instead of the physical size */
651+ if ((width_mm == 160 && height_mm == 90) ||
652+ (width_mm == 160 && height_mm == 100) ||
653+ (width_mm == 16 && height_mm == 9) ||
654+ (width_mm == 16 && height_mm == 10))
655+ {
656+ scale_factor = 1;
657+ return;
658+ }
659+
660+ if (width_mm > 0 && height_mm > 0) {
661+ var dpi_x = (double)width / (width_mm / 25.4);
662+ var dpi_y = (double)height / (height_mm / 25.4);
663+ /* We don't completely trust these values so both
664+ must be high, and never pick higher ratio than
665+ 2 automatically */
666+ if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT) {
667+ scale_factor = 2;
668+ return;
669+ }
670+ }
671+
672+ scale_factor = 1;
673+ }
674+ }
675+
676 void configure_hotcorners ()
677 {
678 var geometry = get_screen ().get_monitor_geometry (get_screen ().get_primary_monitor ());

Subscribers

People subscribed via source and target branches