Merge ~3v1n0/ubuntu/+source/mutter:ubuntu/bionic into ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/bionic
- Git
- lp:~3v1n0/ubuntu/+source/mutter
- ubuntu/bionic
- Merge into ubuntu/bionic
Proposed by
Marco Trevisan (Treviño)
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | b154de179b5d063103bf958fb30e4544e2527d55 | ||||||||||||
Proposed branch: | ~3v1n0/ubuntu/+source/mutter:ubuntu/bionic | ||||||||||||
Merge into: | ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/bionic | ||||||||||||
Diff against target: |
1319 lines (+1031/-226) 9 files modified
debian/changelog (+18/-0) debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch (+53/-0) debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch (+294/-0) debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch (+372/-0) debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch (+53/-0) debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch (+37/-0) debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch (+198/-0) debian/patches/series (+6/-1) dev/null (+0/-225) |
||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt (community) | Approve | ||
Ubuntu Desktop | Pending | ||
Review via email: mp+366676@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- ce3f911... by Marco Trevisan (Treviño)
-
debian/patches: Ignore new symbols added in switch-config
No need to export new symbols for this one
Revision history for this message
Daniel van Vugt (vanvugt) wrote : | # |
It looks like this has landed. Please close this MP.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/debian/changelog b/debian/changelog |
2 | index 99219d6..a1467bf 100644 |
3 | --- a/debian/changelog |
4 | +++ b/debian/changelog |
5 | @@ -1,3 +1,21 @@ |
6 | +mutter (3.28.3+git20190124-0ubuntu18.04.3) UNRELEASED; urgency=medium |
7 | + |
8 | + * d/p/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch, |
9 | + d/p/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch: |
10 | + - Ensure switch display mode is cyclic (LP: #1772811) |
11 | + * d/p/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch, |
12 | + d/p/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch: |
13 | + - Implement keycode remap to keysyms on virtual key devices (LP: #1827029) |
14 | + |
15 | + [ Daniel van Vugt ] |
16 | + * d/p/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch, |
17 | + d/p/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch: |
18 | + - Add support for high frame rate displays (LP: #1763892) |
19 | + * d/p/clutter-Smooth-out-master-clock-to-smooth-visuals.patch: |
20 | + - Dropped |
21 | + |
22 | + -- Marco Trevisan (Treviño) <marco@ubuntu.com> Mon, 29 Apr 2019 23:29:24 -0500 |
23 | + |
24 | mutter (3.28.3+git20190124-0ubuntu18.04.2) bionic; urgency=medium |
25 | |
26 | * control: Add Breaks on budgie-desktop verions broken by this upload. |
27 | diff --git a/debian/patches/clutter-Smooth-out-master-clock-to-smooth-visuals.patch b/debian/patches/clutter-Smooth-out-master-clock-to-smooth-visuals.patch |
28 | deleted file mode 100644 |
29 | index 2239837..0000000 |
30 | --- a/debian/patches/clutter-Smooth-out-master-clock-to-smooth-visuals.patch |
31 | +++ /dev/null |
32 | @@ -1,225 +0,0 @@ |
33 | -From: Daniel van Vugt <daniel.van.vugt@canonical.com> |
34 | -Date: Fri, 16 Feb 2018 02:50:59 -0600 |
35 | -Subject: clutter: Smooth out master clock to smooth visuals |
36 | - |
37 | -Clutter's master clock was jittery because it included errors in cur_tick |
38 | -such as dispatch delays due to other sources. Dispatch could also occur up |
39 | -to 1ms early since GSource can only be timed to the millisecond. All of this |
40 | -could impact the visual smoothness of animations as they are displayed on |
41 | -the steady interval of the monitor, but spacially moving in less regular |
42 | -steps derived from the dispatch times. |
43 | - |
44 | -The simple fix is to ignore any jitter in dispatch timing. Try a little |
45 | -bit harder to use a precise interval that will better match the display |
46 | -hardware, and smoother visuals will follow. |
47 | - |
48 | -Bug: https://gitlab.gnome.org/GNOME/mutter/issues/25 |
49 | -Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/70 |
50 | ---- |
51 | - clutter/clutter/clutter-master-clock-default.c | 134 +++++++++++++++++-------- |
52 | - 1 file changed, 93 insertions(+), 41 deletions(-) |
53 | - |
54 | -diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c |
55 | -index 7b2df0d..97b6d13 100644 |
56 | ---- a/clutter/clutter/clutter-master-clock-default.c |
57 | -+++ b/clutter/clutter/clutter-master-clock-default.c |
58 | -@@ -69,8 +69,10 @@ struct _ClutterMasterClockDefault |
59 | - /* the previous state of the clock, in usecs, used to compute the delta */ |
60 | - gint64 prev_tick; |
61 | - |
62 | -+ /* the ideal frame interval in usecs (inverse of your max refresh rate) */ |
63 | -+ gint64 frame_interval; |
64 | -+ |
65 | - #ifdef CLUTTER_ENABLE_DEBUG |
66 | -- gint64 frame_budget; |
67 | - gint64 remaining_budget; |
68 | - #endif |
69 | - |
70 | -@@ -264,6 +266,41 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock, |
71 | - } |
72 | - } |
73 | - |
74 | -+static gint64 |
75 | -+estimate_next_presentation_time (ClutterMasterClockDefault *master_clock) |
76 | -+{ |
77 | -+ gint64 frame_phase, now, now_phase, undershoot; |
78 | -+ |
79 | -+ /* In future if this was updated from the backend's (maximum) refresh rate |
80 | -+ * then that would fix: https://bugzilla.gnome.org/show_bug.cgi?id=781296 |
81 | -+ */ |
82 | -+ master_clock->frame_interval = G_USEC_PER_SEC / |
83 | -+ clutter_get_default_frame_rate (); |
84 | -+ |
85 | -+ now = g_source_get_time (master_clock->source); |
86 | -+ now_phase = now % master_clock->frame_interval; |
87 | -+ |
88 | -+ /* To be precise we would like to use: |
89 | -+ * frame_phase = a_recent_hardware_presentation_time % frame_interval; |
90 | -+ * where hardware_presentation_time must be using the same clock as |
91 | -+ * g_source_get_time. Unfortunately they're different clocks right now |
92 | -+ * so we can't. |
93 | -+ * Alternatively, we could replace g_source_get_time in future with the |
94 | -+ * current time in the clutter/cogl presentation clock, but that function |
95 | -+ * also doesn't exist yet. |
96 | -+ * Until we can get either of those, zero is fine. It just means latency |
97 | -+ * will be suboptimal by half a frame on average. We still get maximum |
98 | -+ * smoothness this way... |
99 | -+ */ |
100 | -+ frame_phase = 0; |
101 | -+ |
102 | -+ undershoot = frame_phase - now_phase; |
103 | -+ if (undershoot < 0) |
104 | -+ undershoot += master_clock->frame_interval; |
105 | -+ |
106 | -+ return now + undershoot; |
107 | -+} |
108 | -+ |
109 | - /* |
110 | - * master_clock_next_frame_delay: |
111 | - * @master_clock: a #ClutterMasterClock |
112 | -@@ -276,7 +313,8 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock, |
113 | - static gint |
114 | - master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock) |
115 | - { |
116 | -- gint64 now, next; |
117 | -+ gint64 now, target_presentation_time, ideal_render_start; /* timestamps */ |
118 | -+ gint64 ideal_prerender_time, lateness; /* deltas */ |
119 | - gint swap_delay; |
120 | - |
121 | - if (!master_clock_is_running (master_clock)) |
122 | -@@ -307,46 +345,45 @@ master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock) |
123 | - return 0; |
124 | - } |
125 | - |
126 | -- if (master_clock->prev_tick == 0) |
127 | -- { |
128 | -- /* If we weren't previously running, then draw the next frame |
129 | -- * immediately |
130 | -- */ |
131 | -- CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately"); |
132 | -- return 0; |
133 | -- } |
134 | -- |
135 | -- /* Otherwise, wait at least 1/frame_rate seconds since we last |
136 | -- * started a frame |
137 | -- */ |
138 | - now = g_source_get_time (master_clock->source); |
139 | - |
140 | -- next = master_clock->prev_tick; |
141 | -- |
142 | -- /* If time has gone backwards then there's no way of knowing how |
143 | -- long we should wait so let's just dispatch immediately */ |
144 | -- if (now <= next) |
145 | -+ /* As first preference, try to carry on smoothly from the previous frame, |
146 | -+ * even if that means we start rendering frame 2 before frame 1 has been |
147 | -+ * presented. This is why we ignore estimate_next_presentation_time here... |
148 | -+ */ |
149 | -+ target_presentation_time = master_clock->prev_tick + |
150 | -+ master_clock->frame_interval; |
151 | -+ ideal_prerender_time = master_clock->frame_interval; |
152 | -+ ideal_render_start = target_presentation_time - ideal_prerender_time; |
153 | -+ lateness = now - ideal_render_start; |
154 | -+ |
155 | -+ /* If we just woke from idle then try to improve the smoothness of the first |
156 | -+ * two frames some more. Otherwise the first frame would appear too old |
157 | -+ * relative to the second frame. |
158 | -+ */ |
159 | -+ if (lateness >= master_clock->frame_interval) |
160 | - { |
161 | -- CLUTTER_NOTE (SCHEDULER, "Time has gone backwards"); |
162 | -- |
163 | -- return 0; |
164 | -+ target_presentation_time = estimate_next_presentation_time (master_clock); |
165 | -+ ideal_render_start = target_presentation_time - ideal_prerender_time; |
166 | -+ lateness = now - ideal_render_start; |
167 | - } |
168 | - |
169 | -- next += (1000000L / clutter_get_default_frame_rate ()); |
170 | -- |
171 | -- if (next <= now) |
172 | -+ if (lateness > 0) |
173 | - { |
174 | -- CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs", |
175 | -- 1000000L / (gulong) clutter_get_default_frame_rate ()); |
176 | -- |
177 | -+ CLUTTER_NOTE (SCHEDULER, "No wait required. We're already late."); |
178 | - return 0; |
179 | - } |
180 | - else |
181 | - { |
182 | -- CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs", |
183 | -- (next - now) / 1000); |
184 | -- |
185 | -- return (next - now) / 1000; |
186 | -+ /* We +1 here to avoid premature dispatches that would otherwise occur |
187 | -+ * repeatedly during the 1ms before 'ideal_render_start'. We don't care |
188 | -+ * if this makes the final dispatch 1ms late because the smoothing |
189 | -+ * algorithm corrects that, and it's much better than attempting to |
190 | -+ * render more frames than the hardware can physically display... |
191 | -+ */ |
192 | -+ gint millisec_delay = -lateness / 1000 + 1; |
193 | -+ CLUTTER_NOTE (SCHEDULER, "Waiting %dms", millisec_delay); |
194 | -+ return millisec_delay; |
195 | - } |
196 | - } |
197 | - |
198 | -@@ -532,16 +569,34 @@ clutter_clock_dispatch (GSource *source, |
199 | - ClutterMasterClockDefault *master_clock = clock_source->master_clock; |
200 | - gboolean stages_updated = FALSE; |
201 | - GSList *stages; |
202 | -- |
203 | -- CLUTTER_NOTE (SCHEDULER, "Master clock [tick]"); |
204 | -+ gint64 smooth_tick; |
205 | - |
206 | - _clutter_threads_acquire_lock (); |
207 | - |
208 | - /* Get the time to use for this frame */ |
209 | -- master_clock->cur_tick = g_source_get_time (source); |
210 | -+ smooth_tick = estimate_next_presentation_time (master_clock); |
211 | -+ if (smooth_tick <= master_clock->prev_tick) |
212 | -+ { |
213 | -+ /* Ordinarily this will never happen. But after we fix bug 781296, it |
214 | -+ * could happen in the rare case when the ideal frame_interval changes, |
215 | -+ * such as video mode switching or hotplugging monitors. As such it is |
216 | -+ * not considered a bug (unless it's happening without mode switching |
217 | -+ * or hotplugging). |
218 | -+ */ |
219 | -+ CLUTTER_NOTE (SCHEDULER, "Master clock [tick] was premature (skipped)"); |
220 | -+ _clutter_threads_release_lock (); |
221 | -+ return G_SOURCE_CONTINUE; |
222 | -+ } |
223 | -+ |
224 | -+ master_clock->cur_tick = smooth_tick; |
225 | -+ if (master_clock->prev_tick) |
226 | -+ CLUTTER_NOTE (SCHEDULER, "Master clock [tick] %+ldus", |
227 | -+ (long) (master_clock->cur_tick - master_clock->prev_tick)); |
228 | -+ else |
229 | -+ CLUTTER_NOTE (SCHEDULER, "Master clock [tick] startup"); |
230 | - |
231 | - #ifdef CLUTTER_ENABLE_DEBUG |
232 | -- master_clock->remaining_budget = master_clock->frame_budget; |
233 | -+ master_clock->remaining_budget = master_clock->frame_interval; |
234 | - #endif |
235 | - |
236 | - /* We need to protect ourselves against stages being destroyed during |
237 | -@@ -580,7 +635,7 @@ clutter_clock_dispatch (GSource *source, |
238 | - |
239 | - _clutter_threads_release_lock (); |
240 | - |
241 | -- return TRUE; |
242 | -+ return G_SOURCE_CONTINUE; |
243 | - } |
244 | - |
245 | - static void |
246 | -@@ -612,10 +667,7 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self) |
247 | - self->idle = FALSE; |
248 | - self->ensure_next_iteration = FALSE; |
249 | - self->paused = FALSE; |
250 | -- |
251 | --#ifdef CLUTTER_ENABLE_DEBUG |
252 | -- self->frame_budget = G_USEC_PER_SEC / 60; |
253 | --#endif |
254 | -+ self->frame_interval = G_USEC_PER_SEC / 60; /* Will be refined at runtime */ |
255 | - |
256 | - g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW); |
257 | - g_source_set_can_recurse (source, FALSE); |
258 | diff --git a/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch b/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch |
259 | new file mode 100644 |
260 | index 0000000..e2d3140 |
261 | --- /dev/null |
262 | +++ b/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch |
263 | @@ -0,0 +1,53 @@ |
264 | +From: Andrea Azzarone <andrea.azzarone@canonical.com> |
265 | +Date: Tue, 22 Jan 2019 11:20:37 -0600 |
266 | +Subject: clutter/x11: Consider remapped keys when guessing the keycode from |
267 | + the keysym |
268 | + |
269 | +Since e3e933c4 a keyval can be temporarily remapped to an unused keycode. Due to |
270 | +some limitations in XTestFakeKeyEvent, the remapping has to be done in the first |
271 | +xkb group/layout. In case there are two or more keyboard layouts enabled and the |
272 | +selected keyboard layout is not the first, clutter_keymap_x11_keycode_for_keyval |
273 | +will fail to retrieve the correct keycode for a remapped keyval. Let's use the |
274 | +reserved_keycodes map in order to retrieve the correct keycode if needed. |
275 | + |
276 | +Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/443 |
277 | + |
278 | +GNOME-Bug: https://gitlab.gnome.org/GNOME/mutter/issues/443 |
279 | +Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1827029 |
280 | +Origin: https://gitlab.gnome.org/GNOME/mutter/commit/24b4c82 |
281 | +Applied-Upstream: 3.28.4 |
282 | +--- |
283 | + clutter/clutter/x11/clutter-keymap-x11.c | 20 ++++++++++++++++++++ |
284 | + 1 file changed, 20 insertions(+) |
285 | + |
286 | +diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c |
287 | +index 5dd40a9..f1bdf16 100644 |
288 | +--- a/clutter/clutter/x11/clutter-keymap-x11.c |
289 | ++++ b/clutter/clutter/x11/clutter-keymap-x11.c |
290 | +@@ -1005,6 +1005,26 @@ clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11, |
291 | + } |
292 | + } |
293 | + |
294 | ++ if (!found) |
295 | ++ { |
296 | ++ GHashTableIter iter; |
297 | ++ gpointer key, value; |
298 | ++ |
299 | ++ g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes); |
300 | ++ while (!found && g_hash_table_iter_next (&iter, &key, &value)) |
301 | ++ { |
302 | ++ guint reserved_keycode = GPOINTER_TO_UINT (key); |
303 | ++ guint reserved_keysym = GPOINTER_TO_UINT (value); |
304 | ++ |
305 | ++ if (keyval == reserved_keysym) |
306 | ++ { |
307 | ++ *keycode_out = reserved_keycode; |
308 | ++ *level_out = 0; |
309 | ++ found = TRUE; |
310 | ++ } |
311 | ++ } |
312 | ++ } |
313 | ++ |
314 | + g_free (keys); |
315 | + return found; |
316 | + } |
317 | diff --git a/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch b/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch |
318 | new file mode 100644 |
319 | index 0000000..944e1ea |
320 | --- /dev/null |
321 | +++ b/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch |
322 | @@ -0,0 +1,294 @@ |
323 | +From: Andrea Azzarone <azzaronea@gmail.com> |
324 | +Date: Fri, 13 Jul 2018 07:49:38 -0500 |
325 | +Subject: clutter/x11: Implement keycode remap to keysyms on virtual key |
326 | + devices |
327 | + |
328 | +Keycode lookup can fail for serveral reasons, e.g. if there is no combination of |
329 | +modifiers and keycodes that can produce the target keysym with the current |
330 | +keyboard layout. |
331 | + |
332 | +In case the keycode lookup fails, remap temporarily the keysym to an unused |
333 | +keycodes. |
334 | + |
335 | +Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/109 |
336 | + |
337 | +GNOME-Bug: https://gitlab.gnome.org/GNOME/mutter/issues/109 |
338 | +Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1827029 |
339 | +Origin: https://gitlab.gnome.org/GNOME/mutter/commit/6198d389 |
340 | +Applied-Upstream: 3.28.4 |
341 | +--- |
342 | + clutter/clutter/x11/clutter-keymap-x11.c | 167 +++++++++++++++++++++ |
343 | + clutter/clutter/x11/clutter-keymap-x11.h | 6 +- |
344 | + .../clutter/x11/clutter-virtual-input-device-x11.c | 19 ++- |
345 | + 3 files changed, 186 insertions(+), 6 deletions(-) |
346 | + |
347 | +diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c |
348 | +index c34e676..5dd40a9 100644 |
349 | +--- a/clutter/clutter/x11/clutter-keymap-x11.c |
350 | ++++ b/clutter/clutter/x11/clutter-keymap-x11.c |
351 | +@@ -79,6 +79,9 @@ struct _ClutterKeymapX11 |
352 | + guint current_cache_serial; |
353 | + DirectionCacheEntry group_direction_cache[4]; |
354 | + int current_group; |
355 | ++ |
356 | ++ GHashTable *reserved_keycodes; |
357 | ++ GQueue *available_keycodes; |
358 | + #endif |
359 | + |
360 | + guint caps_lock_state : 1; |
361 | +@@ -441,16 +444,100 @@ clutter_keymap_x11_set_property (GObject *gobject, |
362 | + } |
363 | + } |
364 | + |
365 | ++#ifdef HAVE_XKB |
366 | ++static void |
367 | ++clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11) |
368 | ++{ |
369 | ++ Display *dpy = clutter_x11_get_default_display (); |
370 | ++ GHashTableIter iter; |
371 | ++ gpointer key, value; |
372 | ++ |
373 | ++ g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes); |
374 | ++ while (g_hash_table_iter_next (&iter, &key, &value)) |
375 | ++ { |
376 | ++ guint reserved_keycode = GPOINTER_TO_UINT (key); |
377 | ++ guint reserved_keysym = GPOINTER_TO_UINT (value); |
378 | ++ guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0); |
379 | ++ |
380 | ++ /* If an available keycode is no longer mapped to the stored keysym, then |
381 | ++ * the keycode should not be considered available anymore and should be |
382 | ++ * removed both from the list of available and reserved keycodes. |
383 | ++ */ |
384 | ++ if (reserved_keysym != actual_keysym) |
385 | ++ { |
386 | ++ g_hash_table_iter_remove (&iter); |
387 | ++ g_queue_remove (keymap_x11->available_keycodes, key); |
388 | ++ } |
389 | ++ } |
390 | ++} |
391 | ++ |
392 | ++static gboolean |
393 | ++clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11, |
394 | ++ KeyCode keycode, |
395 | ++ KeySym keysym) |
396 | ++{ |
397 | ++ if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb) |
398 | ++ { |
399 | ++ Display *dpy = clutter_x11_get_default_display (); |
400 | ++ XkbDescPtr xkb = get_xkb (keymap_x11); |
401 | ++ XkbMapChangesRec changes; |
402 | ++ |
403 | ++ XFlush (dpy); |
404 | ++ |
405 | ++ xkb->device_spec = XkbUseCoreKbd; |
406 | ++ memset (&changes, 0, sizeof(changes)); |
407 | ++ |
408 | ++ if (keysym != NoSymbol) |
409 | ++ { |
410 | ++ int types[XkbNumKbdGroups] = { XkbOneLevelIndex }; |
411 | ++ XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes); |
412 | ++ XkbKeySymEntry (xkb, keycode, 0, 0) = keysym; |
413 | ++ } |
414 | ++ else |
415 | ++ { |
416 | ++ /* Reset to NoSymbol */ |
417 | ++ XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes); |
418 | ++ } |
419 | ++ |
420 | ++ changes.changed = XkbKeySymsMask | XkbKeyTypesMask; |
421 | ++ changes.first_key_sym = keycode; |
422 | ++ changes.num_key_syms = 1; |
423 | ++ changes.first_type = 0; |
424 | ++ changes.num_types = xkb->map->num_types; |
425 | ++ XkbChangeMap (dpy, xkb, &changes); |
426 | ++ |
427 | ++ XFlush (dpy); |
428 | ++ |
429 | ++ return TRUE; |
430 | ++ } |
431 | ++ |
432 | ++ return FALSE; |
433 | ++} |
434 | ++#endif |
435 | ++ |
436 | + static void |
437 | + clutter_keymap_x11_finalize (GObject *gobject) |
438 | + { |
439 | + ClutterKeymapX11 *keymap; |
440 | + ClutterEventTranslator *translator; |
441 | ++ GHashTableIter iter; |
442 | ++ gpointer key, value; |
443 | + |
444 | + keymap = CLUTTER_KEYMAP_X11 (gobject); |
445 | + translator = CLUTTER_EVENT_TRANSLATOR (keymap); |
446 | + |
447 | + #ifdef HAVE_XKB |
448 | ++ clutter_keymap_x11_refresh_reserved_keycodes (keymap); |
449 | ++ g_hash_table_iter_init (&iter, keymap->reserved_keycodes); |
450 | ++ while (g_hash_table_iter_next (&iter, &key, &value)) |
451 | ++ { |
452 | ++ guint keycode = GPOINTER_TO_UINT (key); |
453 | ++ clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol); |
454 | ++ } |
455 | ++ |
456 | ++ g_hash_table_destroy (keymap->reserved_keycodes); |
457 | ++ g_queue_free (keymap->available_keycodes); |
458 | ++ |
459 | + _clutter_backend_remove_event_translator (keymap->backend, translator); |
460 | + |
461 | + if (keymap->xkb_desc != NULL) |
462 | +@@ -460,6 +547,7 @@ clutter_keymap_x11_finalize (GObject *gobject) |
463 | + G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject); |
464 | + } |
465 | + |
466 | ++ |
467 | + static void |
468 | + clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass) |
469 | + { |
470 | +@@ -483,6 +571,11 @@ clutter_keymap_x11_init (ClutterKeymapX11 *keymap) |
471 | + { |
472 | + keymap->current_direction = PANGO_DIRECTION_NEUTRAL; |
473 | + keymap->current_group = -1; |
474 | ++ |
475 | ++#ifdef HAVE_XKB |
476 | ++ keymap->reserved_keycodes = g_hash_table_new (NULL, NULL); |
477 | ++ keymap->available_keycodes = g_queue_new (); |
478 | ++#endif |
479 | + } |
480 | + |
481 | + static ClutterTranslateReturn |
482 | +@@ -766,6 +859,80 @@ clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11, |
483 | + } |
484 | + } |
485 | + |
486 | ++#ifdef HAVE_XKB |
487 | ++static guint |
488 | ++clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11) |
489 | ++{ |
490 | ++ if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb) |
491 | ++ { |
492 | ++ clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11); |
493 | ++ |
494 | ++ if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5) |
495 | ++ { |
496 | ++ Display *dpy = clutter_x11_get_default_display (); |
497 | ++ XkbDescPtr xkb = get_xkb (keymap_x11); |
498 | ++ guint i; |
499 | ++ |
500 | ++ for (i = xkb->max_key_code; i >= xkb->min_key_code; --i) |
501 | ++ { |
502 | ++ if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol) |
503 | ++ return i; |
504 | ++ } |
505 | ++ } |
506 | ++ |
507 | ++ return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes)); |
508 | ++ } |
509 | ++ |
510 | ++ return 0; |
511 | ++} |
512 | ++#endif |
513 | ++ |
514 | ++gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11, |
515 | ++ guint keyval, |
516 | ++ guint *keycode_out) |
517 | ++{ |
518 | ++ g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE); |
519 | ++ g_return_val_if_fail (keyval != 0, FALSE); |
520 | ++ g_return_val_if_fail (keycode_out != NULL, FALSE); |
521 | ++ |
522 | ++#ifdef HAVE_XKB |
523 | ++ *keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11); |
524 | ++ |
525 | ++ if (*keycode_out == NoSymbol) |
526 | ++ { |
527 | ++ g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval); |
528 | ++ return FALSE; |
529 | ++ } |
530 | ++ |
531 | ++ if (!clutter_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval)) |
532 | ++ { |
533 | ++ g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval); |
534 | ++ return FALSE; |
535 | ++ } |
536 | ++ |
537 | ++ g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval)); |
538 | ++ g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out)); |
539 | ++ |
540 | ++ return TRUE; |
541 | ++#else |
542 | ++ return FALSE; |
543 | ++#endif |
544 | ++} |
545 | ++ |
546 | ++void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11, |
547 | ++ guint keycode) |
548 | ++{ |
549 | ++ g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11)); |
550 | ++ |
551 | ++#ifdef HAVE_XKB |
552 | ++ if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) || |
553 | ++ g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1) |
554 | ++ return; |
555 | ++ |
556 | ++ g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)); |
557 | ++#endif |
558 | ++} |
559 | ++ |
560 | + void |
561 | + clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, |
562 | + uint32_t level, |
563 | +diff --git a/clutter/clutter/x11/clutter-keymap-x11.h b/clutter/clutter/x11/clutter-keymap-x11.h |
564 | +index 4b5b403..4decb44 100644 |
565 | +--- a/clutter/clutter/x11/clutter-keymap-x11.h |
566 | ++++ b/clutter/clutter/x11/clutter-keymap-x11.h |
567 | +@@ -58,7 +58,11 @@ gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11, |
568 | + void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11, |
569 | + uint32_t level, |
570 | + gboolean enable); |
571 | +- |
572 | ++gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11, |
573 | ++ guint keyval, |
574 | ++ guint *keycode_out); |
575 | ++void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11, |
576 | ++ guint keycode); |
577 | + G_END_DECLS |
578 | + |
579 | + #endif /* __CLUTTER_KEYMAP_X11_H__ */ |
580 | +diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c |
581 | +index e16ba3f..cab26c3 100644 |
582 | +--- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c |
583 | ++++ b/clutter/clutter/x11/clutter-virtual-input-device-x11.c |
584 | +@@ -143,8 +143,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu |
585 | + |
586 | + if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level)) |
587 | + { |
588 | +- g_warning ("No keycode found for keyval %x in current group", keyval); |
589 | +- return; |
590 | ++ level = 0; |
591 | ++ |
592 | ++ if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode)) |
593 | ++ { |
594 | ++ g_warning ("No keycode found for keyval %x in current group", keyval); |
595 | ++ return; |
596 | ++ } |
597 | + } |
598 | + |
599 | + if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) && |
600 | +@@ -155,9 +160,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu |
601 | + (KeyCode) keycode, |
602 | + key_state == CLUTTER_KEY_STATE_PRESSED, 0); |
603 | + |
604 | +- if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) && |
605 | +- key_state == CLUTTER_KEY_STATE_RELEASED) |
606 | +- clutter_keymap_x11_latch_modifiers (keymap, level, FALSE); |
607 | ++ |
608 | ++ if (key_state == CLUTTER_KEY_STATE_RELEASED) |
609 | ++ { |
610 | ++ if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode)) |
611 | ++ clutter_keymap_x11_latch_modifiers (keymap, level, FALSE); |
612 | ++ clutter_keymap_x11_release_keycode_if_needed (keymap, keycode); |
613 | ++ } |
614 | + } |
615 | + |
616 | + static void |
617 | diff --git a/debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch b/debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch |
618 | new file mode 100644 |
619 | index 0000000..1e5958e |
620 | --- /dev/null |
621 | +++ b/debian/patches/lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch |
622 | @@ -0,0 +1,372 @@ |
623 | +From: Daniel van Vugt <daniel.van.vugt@canonical.com> |
624 | +Date: Fri, 3 May 2019 11:31:08 -0500 |
625 | +Subject: renderer-native: Add hardware presentation timing |
626 | + |
627 | +Add support for getting hardware presentation times from KMS (Wayland |
628 | +sessions). Also implement cogl_get_clock_time which is required to compare |
629 | +and judge the age of presentation timestamps. |
630 | + |
631 | +For single monitor systems this is straightforward. For multi-monitor |
632 | +systems though we have to choose a display to sync to. The compositor |
633 | +already partially solves this for us in the case of only one display |
634 | +updating because it will only use the subset of monitors that are |
635 | +changing. In the case of multiple monitors consuming the same frame |
636 | +concurrently however, we choose the fastest one (in use at the time). |
637 | + |
638 | +Patch 1 of 2 |
639 | + |
640 | +Origin: https://gitlab.gnome.org/vanvugt/mutter/commits/add-vsync-3.28 |
641 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=781296 |
642 | +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1763892 |
643 | +Applied-Upstream: https://gitlab.gnome.org/vanvugt/mutter/commit/e9e4b2b7 |
644 | +Forwarded: yes |
645 | +Last-Update: 2019-03-13 |
646 | +--- |
647 | + src/Makefile.am | 25 ++++++++++- |
648 | + src/backends/native/meta-gpu-kms.c | 69 +++++++++++++++++++++++++++--- |
649 | + src/backends/native/meta-gpu-kms.h | 3 ++ |
650 | + src/backends/native/meta-renderer-native.c | 38 +++++++++++++++- |
651 | + src/meta-marshal.list | 1 + |
652 | + 5 files changed, 128 insertions(+), 8 deletions(-) |
653 | + create mode 100644 src/meta-marshal.list |
654 | + |
655 | +diff --git a/src/Makefile.am b/src/Makefile.am |
656 | +index bcb3505..13862e9 100644 |
657 | +--- a/src/Makefile.am |
658 | ++++ b/src/Makefile.am |
659 | +@@ -51,6 +51,8 @@ mutter_built_sources = \ |
660 | + $(dbus_login1_built_sources) \ |
661 | + meta/meta-enum-types.h \ |
662 | + meta-enum-types.c \ |
663 | ++ meta-marshal.c \ |
664 | ++ meta-marshal.h \ |
665 | + $(NULL) |
666 | + |
667 | + if HAVE_REMOTE_DESKTOP |
668 | +@@ -653,6 +655,7 @@ EXTRA_DIST += \ |
669 | + libmutter.pc.in \ |
670 | + meta-enum-types.h.in \ |
671 | + meta-enum-types.c.in \ |
672 | ++ meta-marshal.list \ |
673 | + org.freedesktop.login1.xml \ |
674 | + org.gnome.Mutter.DisplayConfig.xml \ |
675 | + org.gnome.Mutter.IdleMonitor.xml \ |
676 | +@@ -666,7 +669,10 @@ BUILT_SOURCES = \ |
677 | + $(libmutterinclude_built_headers) |
678 | + |
679 | + MUTTER_STAMP_FILES = stamp-meta-enum-types.h |
680 | +-CLEANFILES += $(MUTTER_STAMP_FILES) |
681 | ++CLEANFILES += \ |
682 | ++ $(MUTTER_STAMP_FILES) \ |
683 | ++ meta-marshal.c \ |
684 | ++ meta-marshal.h |
685 | + |
686 | + meta/meta-enum-types.h: stamp-meta-enum-types.h Makefile |
687 | + @true |
688 | +@@ -760,3 +766,20 @@ endef |
689 | + $(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@ |
690 | + %-server-protocol.h : $(srcdir)/wayland/protocol/%.xml |
691 | + $(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@ |
692 | ++ |
693 | ++meta_marshal_opts = --prefix=meta_marshal --internal |
694 | ++ |
695 | ++meta-marshal.h: meta-marshal.list |
696 | ++ $(AM_V_GEN)$(GLIB_GENMARSHAL) \ |
697 | ++ --header \ |
698 | ++ $(meta_marshal_opts) \ |
699 | ++ --output=$@ \ |
700 | ++ $< |
701 | ++ |
702 | ++meta-marshal.c: meta-marshal.list meta-marshal.h |
703 | ++ $(AM_V_GEN)$(GLIB_GENMARSHAL) \ |
704 | ++ --include-header=meta-marshal.h \ |
705 | ++ $(meta_marshal_opts) \ |
706 | ++ --body \ |
707 | ++ --output=$@ \ |
708 | ++ $< |
709 | +diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c |
710 | +index 815caf5..02649c5 100644 |
711 | +--- a/src/backends/native/meta-gpu-kms.c |
712 | ++++ b/src/backends/native/meta-gpu-kms.c |
713 | +@@ -27,6 +27,7 @@ |
714 | + #include <errno.h> |
715 | + #include <poll.h> |
716 | + #include <string.h> |
717 | ++#include <time.h> |
718 | + #include <xf86drm.h> |
719 | + #include <xf86drmMode.h> |
720 | + |
721 | +@@ -51,6 +52,7 @@ typedef struct _MetaGpuKmsFlipClosureContainer |
722 | + { |
723 | + GClosure *flip_closure; |
724 | + MetaGpuKms *gpu_kms; |
725 | ++ MetaCrtc *crtc; |
726 | + } MetaGpuKmsFlipClosureContainer; |
727 | + |
728 | + struct _MetaGpuKms |
729 | +@@ -61,6 +63,8 @@ struct _MetaGpuKms |
730 | + char *file_path; |
731 | + GSource *source; |
732 | + |
733 | ++ clockid_t clock_id; |
734 | ++ |
735 | + drmModeConnector **connectors; |
736 | + unsigned int n_connectors; |
737 | + |
738 | +@@ -166,18 +170,26 @@ meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms, |
739 | + |
740 | + static void |
741 | + invoke_flip_closure (GClosure *flip_closure, |
742 | +- MetaGpuKms *gpu_kms) |
743 | ++ MetaGpuKms *gpu_kms, |
744 | ++ MetaCrtc *crtc, |
745 | ++ int64_t page_flip_time_ns) |
746 | + { |
747 | + GValue params[] = { |
748 | + G_VALUE_INIT, |
749 | +- G_VALUE_INIT |
750 | ++ G_VALUE_INIT, |
751 | ++ G_VALUE_INIT, |
752 | ++ G_VALUE_INIT, |
753 | + }; |
754 | + |
755 | + g_value_init (¶ms[0], G_TYPE_POINTER); |
756 | + g_value_set_pointer (¶ms[0], flip_closure); |
757 | + g_value_init (¶ms[1], G_TYPE_OBJECT); |
758 | + g_value_set_object (¶ms[1], gpu_kms); |
759 | +- g_closure_invoke (flip_closure, NULL, 2, params, NULL); |
760 | ++ g_value_init (¶ms[2], G_TYPE_OBJECT); |
761 | ++ g_value_set_object (¶ms[2], crtc); |
762 | ++ g_value_init (¶ms[3], G_TYPE_INT64); |
763 | ++ g_value_set_int64 (¶ms[3], page_flip_time_ns); |
764 | ++ g_closure_invoke (flip_closure, NULL, 4, params, NULL); |
765 | + g_closure_unref (flip_closure); |
766 | + } |
767 | + |
768 | +@@ -217,6 +229,7 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms, |
769 | + |
770 | + MetaGpuKmsFlipClosureContainer * |
771 | + meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, |
772 | ++ MetaCrtc *crtc, |
773 | + GClosure *flip_closure) |
774 | + { |
775 | + MetaGpuKmsFlipClosureContainer *closure_container; |
776 | +@@ -224,7 +237,8 @@ meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, |
777 | + closure_container = g_new0 (MetaGpuKmsFlipClosureContainer, 1); |
778 | + *closure_container = (MetaGpuKmsFlipClosureContainer) { |
779 | + .flip_closure = flip_closure, |
780 | +- .gpu_kms = gpu_kms |
781 | ++ .gpu_kms = gpu_kms, |
782 | ++ .crtc = crtc |
783 | + }; |
784 | + |
785 | + return closure_container; |
786 | +@@ -264,6 +278,7 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms, |
787 | + int kms_fd = meta_gpu_kms_get_fd (gpu_kms); |
788 | + |
789 | + closure_container = meta_gpu_kms_wrap_flip_closure (gpu_kms, |
790 | ++ crtc, |
791 | + flip_closure); |
792 | + |
793 | + ret = drmModePageFlip (kms_fd, |
794 | +@@ -297,6 +312,23 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms, |
795 | + return TRUE; |
796 | + } |
797 | + |
798 | ++static int64_t |
799 | ++timespec_to_nanoseconds (const struct timespec *ts) |
800 | ++{ |
801 | ++ const int64_t one_billion = 1000000000; |
802 | ++ |
803 | ++ return ((int64_t) ts->tv_sec) * one_billion + ts->tv_nsec; |
804 | ++} |
805 | ++ |
806 | ++static int64_t |
807 | ++timeval_to_nanoseconds (const struct timeval *tv) |
808 | ++{ |
809 | ++ int64_t usec = ((int64_t) tv->tv_sec) * G_USEC_PER_SEC + tv->tv_usec; |
810 | ++ int64_t nsec = usec * 1000; |
811 | ++ |
812 | ++ return nsec; |
813 | ++} |
814 | ++ |
815 | + static void |
816 | + page_flip_handler (int fd, |
817 | + unsigned int frame, |
818 | +@@ -307,8 +339,12 @@ page_flip_handler (int fd, |
819 | + MetaGpuKmsFlipClosureContainer *closure_container = user_data; |
820 | + GClosure *flip_closure = closure_container->flip_closure; |
821 | + MetaGpuKms *gpu_kms = closure_container->gpu_kms; |
822 | ++ struct timeval page_flip_time = {sec, usec}; |
823 | + |
824 | +- invoke_flip_closure (flip_closure, gpu_kms); |
825 | ++ invoke_flip_closure (flip_closure, |
826 | ++ gpu_kms, |
827 | ++ closure_container->crtc, |
828 | ++ timeval_to_nanoseconds (&page_flip_time)); |
829 | + meta_gpu_kms_flip_closure_container_free (closure_container); |
830 | + } |
831 | + |
832 | +@@ -381,6 +417,17 @@ meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms) |
833 | + return gpu_kms->file_path; |
834 | + } |
835 | + |
836 | ++int64_t |
837 | ++_meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms) |
838 | ++{ |
839 | ++ struct timespec ts; |
840 | ++ |
841 | ++ if (clock_gettime (gpu_kms->clock_id, &ts)) |
842 | ++ return 0; |
843 | ++ |
844 | ++ return timespec_to_nanoseconds (&ts); |
845 | ++} |
846 | ++ |
847 | + void |
848 | + meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms, |
849 | + uint64_t state) |
850 | +@@ -680,6 +727,17 @@ init_crtcs (MetaGpuKms *gpu_kms, |
851 | + meta_gpu_take_crtcs (gpu, crtcs); |
852 | + } |
853 | + |
854 | ++static void |
855 | ++init_frame_clock (MetaGpuKms *gpu_kms) |
856 | ++{ |
857 | ++ uint64_t uses_monotonic; |
858 | ++ |
859 | ++ if (drmGetCap (gpu_kms->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &uses_monotonic) != 0) |
860 | ++ uses_monotonic = 0; |
861 | ++ |
862 | ++ gpu_kms->clock_id = uses_monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME; |
863 | ++} |
864 | ++ |
865 | + static void |
866 | + init_outputs (MetaGpuKms *gpu_kms, |
867 | + MetaKmsResources *resources) |
868 | +@@ -809,6 +867,7 @@ meta_gpu_kms_read_current (MetaGpu *gpu, |
869 | + init_modes (gpu_kms, resources.resources); |
870 | + init_crtcs (gpu_kms, &resources); |
871 | + init_outputs (gpu_kms, &resources); |
872 | ++ init_frame_clock (gpu_kms); |
873 | + |
874 | + meta_kms_resources_release (&resources); |
875 | + |
876 | +diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h |
877 | +index 01c3f2c..c12246c 100644 |
878 | +--- a/src/backends/native/meta-gpu-kms.h |
879 | ++++ b/src/backends/native/meta-gpu-kms.h |
880 | +@@ -81,6 +81,8 @@ int meta_gpu_kms_get_fd (MetaGpuKms *gpu_kms); |
881 | + |
882 | + const char * meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms); |
883 | + |
884 | ++int64_t _meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms); |
885 | ++ |
886 | + void meta_gpu_kms_get_max_buffer_size (MetaGpuKms *gpu_kms, |
887 | + int *max_width, |
888 | + int *max_height); |
889 | +@@ -97,6 +99,7 @@ gboolean meta_drm_mode_equal (const drmModeModeInfo *one, |
890 | + float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *mode); |
891 | + |
892 | + MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, |
893 | ++ MetaCrtc *crtc, |
894 | + GClosure *flip_closure); |
895 | + |
896 | + void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container); |
897 | +diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c |
898 | +index 470da88..0fd104b 100644 |
899 | +--- a/src/backends/native/meta-renderer-native.c |
900 | ++++ b/src/backends/native/meta-renderer-native.c |
901 | +@@ -61,6 +61,7 @@ |
902 | + #include "backends/native/meta-monitor-manager-kms.h" |
903 | + #include "backends/native/meta-renderer-native.h" |
904 | + #include "backends/native/meta-renderer-native-gles3.h" |
905 | ++#include "meta-marshal.h" |
906 | + #include "cogl/cogl.h" |
907 | + #include "core/boxes-private.h" |
908 | + |
909 | +@@ -1157,6 +1158,8 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen) |
910 | + static void |
911 | + on_crtc_flipped (GClosure *closure, |
912 | + MetaGpuKms *gpu_kms, |
913 | ++ MetaCrtc *crtc, |
914 | ++ int64_t page_flip_time_ns, |
915 | + MetaRendererView *view) |
916 | + { |
917 | + ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view); |
918 | +@@ -1167,6 +1170,24 @@ on_crtc_flipped (GClosure *closure, |
919 | + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; |
920 | + MetaRendererNative *renderer_native = onscreen_native->renderer_native; |
921 | + MetaGpuKms *render_gpu = onscreen_native->render_gpu; |
922 | ++ CoglFrameInfo *frame_info; |
923 | ++ float refresh_rate; |
924 | ++ |
925 | ++ frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); |
926 | ++ refresh_rate = crtc && crtc->current_mode ? |
927 | ++ crtc->current_mode->refresh_rate : |
928 | ++ 0.0f; |
929 | ++ |
930 | ++ /* Only keep the frame info for the fastest CRTC in use, which may not be |
931 | ++ * the first one to complete a flip. By only telling the compositor about the |
932 | ++ * fastest monitor(s) we direct it to produce new frames fast enough to |
933 | ++ * satisfy all monitors. |
934 | ++ */ |
935 | ++ if (refresh_rate >= frame_info->refresh_rate) |
936 | ++ { |
937 | ++ frame_info->presentation_time = page_flip_time_ns; |
938 | ++ frame_info->refresh_rate = refresh_rate; |
939 | ++ } |
940 | + |
941 | + if (gpu_kms != render_gpu) |
942 | + { |
943 | +@@ -1297,7 +1318,9 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native, |
944 | + return FALSE; |
945 | + |
946 | + closure_container = |
947 | +- meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu, flip_closure); |
948 | ++ meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu, |
949 | ++ NULL, |
950 | ++ flip_closure); |
951 | + |
952 | + acquire_attribs = (EGLAttrib[]) { |
953 | + EGL_DRM_FLIP_EVENT_DATA_NV, |
954 | +@@ -1540,7 +1563,7 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen) |
955 | + flip_closure = g_cclosure_new (G_CALLBACK (on_crtc_flipped), |
956 | + g_object_ref (view), |
957 | + (GClosureNotify) flip_closure_destroyed); |
958 | +- g_closure_set_marshal (flip_closure, g_cclosure_marshal_VOID__OBJECT); |
959 | ++ g_closure_set_marshal (flip_closure, meta_marshal_VOID__OBJECT_OBJECT_INT64); |
960 | + |
961 | + /* Either flip the CRTC's of the monitor info, if we are drawing just part |
962 | + * of the stage, or all of the CRTC's if we are drawing the whole stage. |
963 | +@@ -2673,6 +2696,15 @@ meta_renderer_native_create_offscreen (MetaRendererNative *renderer, |
964 | + return fb; |
965 | + } |
966 | + |
967 | ++static int64_t |
968 | ++meta_renderer_native_get_clock_time (CoglContext *context) |
969 | ++{ |
970 | ++ CoglRenderer *cogl_renderer = cogl_context_get_renderer (context); |
971 | ++ MetaGpuKms *gpu_kms = cogl_renderer->custom_winsys_user_data; |
972 | ++ |
973 | ++ return _meta_gpu_kms_get_current_time_ns (gpu_kms); |
974 | ++} |
975 | ++ |
976 | + static const CoglWinsysVtable * |
977 | + get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) |
978 | + { |
979 | +@@ -2701,6 +2733,8 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) |
980 | + vtable.onscreen_swap_buffers_with_damage = |
981 | + meta_onscreen_native_swap_buffers_with_damage; |
982 | + |
983 | ++ vtable.context_get_clock_time = meta_renderer_native_get_clock_time; |
984 | ++ |
985 | + vtable_inited = TRUE; |
986 | + } |
987 | + |
988 | +diff --git a/src/meta-marshal.list b/src/meta-marshal.list |
989 | +new file mode 100644 |
990 | +index 0000000..c1f4781 |
991 | +--- /dev/null |
992 | ++++ b/src/meta-marshal.list |
993 | +@@ -0,0 +1 @@ |
994 | ++VOID:OBJECT,OBJECT,INT64 |
995 | diff --git a/debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch b/debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch |
996 | new file mode 100644 |
997 | index 0000000..9a6a64d |
998 | --- /dev/null |
999 | +++ b/debian/patches/lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch |
1000 | @@ -0,0 +1,53 @@ |
1001 | +From: Daniel van Vugt <daniel.van.vugt@canonical.com> |
1002 | +Date: Fri, 3 May 2019 11:31:08 -0500 |
1003 | +Subject: renderer-native: Advertise _FEATURE_SWAP_THROTTLE |
1004 | + |
1005 | +Because it is implemented and always on. By advertising this fact |
1006 | +the master clock is able to sync to the native refresh rate instead |
1007 | +of always using the fallback of 60.00Hz. |
1008 | + |
1009 | +Patch 2 of 2 |
1010 | + |
1011 | +Origin: https://gitlab.gnome.org/vanvugt/mutter/commits/add-vsync-3.28 |
1012 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=781296 |
1013 | +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1763892 |
1014 | +Applied-Upstream: https://gitlab.gnome.org/vanvugt/mutter/commit/e8c27603 |
1015 | +Forwarded: yes |
1016 | +Last-Update: 2019-03-13 |
1017 | +--- |
1018 | + src/backends/native/meta-renderer-native.c | 15 +++++++++++++-- |
1019 | + 1 file changed, 13 insertions(+), 2 deletions(-) |
1020 | + |
1021 | +diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c |
1022 | +index 0fd104b..dce7981 100644 |
1023 | +--- a/src/backends/native/meta-renderer-native.c |
1024 | ++++ b/src/backends/native/meta-renderer-native.c |
1025 | +@@ -1997,6 +1997,13 @@ meta_renderer_native_init_egl_context (CoglContext *cogl_context, |
1026 | + COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, |
1027 | + TRUE); |
1028 | + |
1029 | ++ /* COGL_WINSYS_FEATURE_SWAP_THROTTLE is always true for this renderer |
1030 | ++ * because we have the call to wait_for_pending_flips on every frame. |
1031 | ++ */ |
1032 | ++ COGL_FLAGS_SET (cogl_context->winsys_features, |
1033 | ++ COGL_WINSYS_FEATURE_SWAP_THROTTLE, |
1034 | ++ TRUE); |
1035 | ++ |
1036 | + #ifdef HAVE_EGL_DEVICE |
1037 | + if (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_EGL_DEVICE) |
1038 | + COGL_FLAGS_SET (cogl_context->features, |
1039 | +@@ -2625,8 +2632,12 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, |
1040 | + } |
1041 | + |
1042 | + onscreen = cogl_onscreen_new (context, width, height); |
1043 | +- cogl_onscreen_set_swap_throttled (onscreen, |
1044 | +- _clutter_get_sync_to_vblank ()); |
1045 | ++ |
1046 | ++ /* We have wait_for_pending_flips hardcoded, so throttling always. */ |
1047 | ++ cogl_onscreen_set_swap_throttled (onscreen, TRUE); |
1048 | ++ if (!_clutter_get_sync_to_vblank ()) |
1049 | ++ g_warning ("Request to disable sync-to-vblank is being ignored. " |
1050 | ++ "MetaRendererNative does not support disabling it."); |
1051 | + |
1052 | + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), error)) |
1053 | + { |
1054 | diff --git a/debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch b/debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch |
1055 | new file mode 100644 |
1056 | index 0000000..5512752 |
1057 | --- /dev/null |
1058 | +++ b/debian/patches/monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch |
1059 | @@ -0,0 +1,37 @@ |
1060 | +From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com> |
1061 | +Date: Thu, 11 Oct 2018 08:16:26 -0500 |
1062 | +Subject: monitor-manager: Don't use switch-config when ensuring configuration |
1063 | + |
1064 | +Switch-configs are only to be used in certain circumstances (see |
1065 | +meta_monitor_manager_can_switch_config()) so when ensuring |
1066 | +configuration and attempting to create a linear configuration, use the |
1067 | +linear configuration constructor function directly without going via the |
1068 | +switch config method, otherwise we might incorrectly fall back to the |
1069 | +fallback configuration (only enable primary monitor). |
1070 | + |
1071 | +This is a regression introduced by 6267732bec97773. |
1072 | + |
1073 | +Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/342 |
1074 | + |
1075 | +Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1772811 |
1076 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/262 |
1077 | +Applied-Upstream: yes, 3.32.0 |
1078 | +--- |
1079 | + src/backends/meta-monitor-manager.c | 4 +--- |
1080 | + 1 file changed, 1 insertion(+), 3 deletions(-) |
1081 | + |
1082 | +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c |
1083 | +index fde61eb..39ed813 100644 |
1084 | +--- a/src/backends/meta-monitor-manager.c |
1085 | ++++ b/src/backends/meta-monitor-manager.c |
1086 | +@@ -582,9 +582,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) |
1087 | + g_clear_object (&config); |
1088 | + } |
1089 | + |
1090 | +- config = |
1091 | +- meta_monitor_config_manager_create_for_switch_config (manager->config_manager, |
1092 | +- META_MONITOR_SWITCH_CONFIG_ALL_LINEAR); |
1093 | ++ config = meta_monitor_config_manager_create_linear (manager->config_manager); |
1094 | + if (config) |
1095 | + { |
1096 | + if (!meta_monitor_manager_apply_monitors_config (manager, |
1097 | diff --git a/debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch b/debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch |
1098 | new file mode 100644 |
1099 | index 0000000..a791f59 |
1100 | --- /dev/null |
1101 | +++ b/debian/patches/monitor-manager-use-MonitorsConfig-to-track-switch_config.patch |
1102 | @@ -0,0 +1,198 @@ |
1103 | +From: Daniel Drake <drake@endlessm.com> |
1104 | +Date: Wed, 29 Aug 2018 19:34:53 -0500 |
1105 | +Subject: monitor-manager: use MonitorsConfig to track switch_config |
1106 | + |
1107 | +When constructing MetaMonitorsConfig objects, store which type |
1108 | +of switch_config they are for (or UNKNOWN if it is not such |
1109 | +type of config). |
1110 | + |
1111 | +Stop unconditionally setting current_switch_config to UNKNOWN when |
1112 | +handling monitors changed events. Instead, set it to the switch_config |
1113 | +type stored in the MonitorsConfig in the codepath that updates logical |
1114 | +state. In addition to being called in the hotplug case along the same |
1115 | +code flow that generates monitors changed events, this is also called |
1116 | +in the coldplug case where a secondary monitor was connected before |
1117 | +mutter was started. |
1118 | + |
1119 | +When creating the default linear display config, create it as a |
1120 | +switch_config so that internal state gets updated to represent |
1121 | +linear mode when this config is used. |
1122 | + |
1123 | +The previous behaviour of unconditionally resetting current_switch_config |
1124 | +to UNKNOWN was breaking the internal state machine for display config |
1125 | +switching, causing misbehaviour in gnome-shell's switchMonitor UI when |
1126 | +using display switch hotkeys. The lack of internal tracking when the |
1127 | +displays are already in the default "Join Displays" linear mode was |
1128 | +then causing the first display switch hotkey press to do nothing |
1129 | +(it would attempt to select "Join Displays" mode, but that was already |
1130 | +active). |
1131 | + |
1132 | +Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/281 |
1133 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/213 |
1134 | + |
1135 | +Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1772811 |
1136 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/213 |
1137 | +Applied-Upstream: yes, 3.30.1 |
1138 | +--- |
1139 | + src/backends/meta-monitor-config-manager.c | 36 +++++++++++++++++++++++++----- |
1140 | + src/backends/meta-monitor-config-manager.h | 7 ++++++ |
1141 | + src/backends/meta-monitor-manager.c | 25 ++++++++++++++++----- |
1142 | + 3 files changed, 56 insertions(+), 12 deletions(-) |
1143 | + |
1144 | +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c |
1145 | +index 197892b..ce61547 100644 |
1146 | +--- a/src/backends/meta-monitor-config-manager.c |
1147 | ++++ b/src/backends/meta-monitor-config-manager.c |
1148 | +@@ -1007,6 +1007,7 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager |
1149 | + MetaMonitorSwitchConfigType config_type) |
1150 | + { |
1151 | + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; |
1152 | ++ MetaMonitorsConfig *config; |
1153 | + |
1154 | + if (!meta_monitor_manager_can_switch_config (monitor_manager)) |
1155 | + return NULL; |
1156 | +@@ -1014,18 +1015,27 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager |
1157 | + switch (config_type) |
1158 | + { |
1159 | + case META_MONITOR_SWITCH_CONFIG_ALL_MIRROR: |
1160 | +- return create_for_switch_config_all_mirror (config_manager); |
1161 | ++ config = create_for_switch_config_all_mirror (config_manager); |
1162 | ++ break; |
1163 | + case META_MONITOR_SWITCH_CONFIG_ALL_LINEAR: |
1164 | +- return meta_monitor_config_manager_create_linear (config_manager); |
1165 | ++ config = meta_monitor_config_manager_create_linear (config_manager); |
1166 | ++ break; |
1167 | + case META_MONITOR_SWITCH_CONFIG_EXTERNAL: |
1168 | +- return create_for_switch_config_external (config_manager); |
1169 | ++ config = create_for_switch_config_external (config_manager); |
1170 | ++ break; |
1171 | + case META_MONITOR_SWITCH_CONFIG_BUILTIN: |
1172 | +- return create_for_switch_config_builtin (config_manager); |
1173 | ++ config = create_for_switch_config_builtin (config_manager); |
1174 | ++ break; |
1175 | + case META_MONITOR_SWITCH_CONFIG_UNKNOWN: |
1176 | ++ default: |
1177 | + g_warn_if_reached (); |
1178 | +- break; |
1179 | ++ return NULL; |
1180 | + } |
1181 | +- return NULL; |
1182 | ++ |
1183 | ++ if (config) |
1184 | ++ _meta_monitors_config_set_switch_config (config, config_type); |
1185 | ++ |
1186 | ++ return config; |
1187 | + } |
1188 | + |
1189 | + void |
1190 | +@@ -1217,6 +1227,19 @@ meta_monitors_config_key_equal (gconstpointer data_a, |
1191 | + return TRUE; |
1192 | + } |
1193 | + |
1194 | ++MetaMonitorSwitchConfigType |
1195 | ++_meta_monitors_config_get_switch_config (MetaMonitorsConfig *config) |
1196 | ++{ |
1197 | ++ return config->switch_config; |
1198 | ++} |
1199 | ++ |
1200 | ++void |
1201 | ++_meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, |
1202 | ++ MetaMonitorSwitchConfigType switch_config) |
1203 | ++{ |
1204 | ++ config->switch_config = switch_config; |
1205 | ++} |
1206 | ++ |
1207 | + MetaMonitorsConfig * |
1208 | + meta_monitors_config_new_full (GList *logical_monitor_configs, |
1209 | + GList *disabled_monitor_specs, |
1210 | +@@ -1232,6 +1255,7 @@ meta_monitors_config_new_full (GList *logical_monitor_con |
1211 | + disabled_monitor_specs); |
1212 | + config->layout_mode = layout_mode; |
1213 | + config->flags = flags; |
1214 | ++ config->switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; |
1215 | + |
1216 | + return config; |
1217 | + } |
1218 | +diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h |
1219 | +index 269d8e1..4ac0b1d 100644 |
1220 | +--- a/src/backends/meta-monitor-config-manager.h |
1221 | ++++ b/src/backends/meta-monitor-config-manager.h |
1222 | +@@ -69,6 +69,8 @@ struct _MetaMonitorsConfig |
1223 | + MetaMonitorsConfigFlag flags; |
1224 | + |
1225 | + MetaLogicalMonitorLayoutMode layout_mode; |
1226 | ++ |
1227 | ++ MetaMonitorSwitchConfigType switch_config; |
1228 | + }; |
1229 | + |
1230 | + #define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ()) |
1231 | +@@ -124,6 +126,11 @@ MetaMonitorsConfig * meta_monitors_config_new (MetaMonitorManager *mon |
1232 | + MetaLogicalMonitorLayoutMode layout_mode, |
1233 | + MetaMonitorsConfigFlag flags); |
1234 | + |
1235 | ++MetaMonitorSwitchConfigType _meta_monitors_config_get_switch_config (MetaMonitorsConfig *config); |
1236 | ++ |
1237 | ++void _meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, |
1238 | ++ MetaMonitorSwitchConfigType switch_config); |
1239 | ++ |
1240 | + unsigned int meta_monitors_config_key_hash (gconstpointer config_key); |
1241 | + |
1242 | + gboolean meta_monitors_config_key_equal (gconstpointer config_key_a, |
1243 | +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c |
1244 | +index ec18600..fde61eb 100644 |
1245 | +--- a/src/backends/meta-monitor-manager.c |
1246 | ++++ b/src/backends/meta-monitor-manager.c |
1247 | +@@ -582,7 +582,9 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) |
1248 | + g_clear_object (&config); |
1249 | + } |
1250 | + |
1251 | +- config = meta_monitor_config_manager_create_linear (manager->config_manager); |
1252 | ++ config = |
1253 | ++ meta_monitor_config_manager_create_for_switch_config (manager->config_manager, |
1254 | ++ META_MONITOR_SWITCH_CONFIG_ALL_LINEAR); |
1255 | + if (config) |
1256 | + { |
1257 | + if (!meta_monitor_manager_apply_monitors_config (manager, |
1258 | +@@ -2652,8 +2654,6 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager) |
1259 | + static void |
1260 | + meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager) |
1261 | + { |
1262 | +- manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; |
1263 | +- |
1264 | + meta_backend_monitors_changed (manager->backend); |
1265 | + |
1266 | + g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0); |
1267 | +@@ -2710,10 +2710,17 @@ meta_monitor_manager_update_logical_state (MetaMonitorManager *manager, |
1268 | + MetaMonitorsConfig *config) |
1269 | + { |
1270 | + if (config) |
1271 | +- manager->layout_mode = config->layout_mode; |
1272 | ++ { |
1273 | ++ manager->layout_mode = config->layout_mode; |
1274 | ++ manager->current_switch_config = |
1275 | ++ _meta_monitors_config_get_switch_config (config); |
1276 | ++ } |
1277 | + else |
1278 | +- manager->layout_mode = |
1279 | +- meta_monitor_manager_get_default_layout_mode (manager); |
1280 | ++ { |
1281 | ++ manager->layout_mode = |
1282 | ++ meta_monitor_manager_get_default_layout_mode (manager); |
1283 | ++ manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; |
1284 | ++ } |
1285 | + |
1286 | + meta_monitor_manager_rebuild_logical_monitors (manager, config); |
1287 | + } |
1288 | +@@ -2755,6 +2762,12 @@ void |
1289 | + meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager, |
1290 | + MetaMonitorsConfig *config) |
1291 | + { |
1292 | ++ if (config) |
1293 | ++ manager->current_switch_config = |
1294 | ++ _meta_monitors_config_get_switch_config (config); |
1295 | ++ else |
1296 | ++ manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; |
1297 | ++ |
1298 | + manager->layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; |
1299 | + |
1300 | + meta_monitor_manager_rebuild_logical_monitors_derived (manager, config); |
1301 | diff --git a/debian/patches/series b/debian/patches/series |
1302 | index 198db5a..8ff6307 100644 |
1303 | --- a/debian/patches/series |
1304 | +++ b/debian/patches/series |
1305 | @@ -1,8 +1,13 @@ |
1306 | theme-use-gtk_render_icon_suface-to-paint-button-icon.patch |
1307 | theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch |
1308 | -clutter-Smooth-out-master-clock-to-smooth-visuals.patch |
1309 | clutter-Fix-offscreen-effect-painting-of-clones.patch |
1310 | bgo768531_workaround-startup-notifications.patch |
1311 | +monitor-manager-use-MonitorsConfig-to-track-switch_config.patch |
1312 | +monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch |
1313 | +clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch |
1314 | +clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch |
1315 | +lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch |
1316 | +lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch |
1317 | debian/synaptics-support.patch |
1318 | debian/skip-failing-tests.patch |
1319 | debian/skip-failing-tests-325.patch |
Looking good.