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: | ed7085fc0db5b8af44c792b36354da20f3bc45a3 |
Proposed branch: | ~3v1n0/ubuntu/+source/mutter:ubuntu/bionic |
Merge into: | ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/bionic |
Diff against target: |
1948 lines (+1815/-0) 19 files modified
debian/changelog (+27/-0) debian/libmutter-2-0.symbols (+2/-0) debian/patches/screen-Destroy-window-actors-after-windows-while-unmanagi.patch (+106/-0) debian/patches/screen-Unset-the-active-workspace-and-remove-workspaces-o.patch (+43/-0) debian/patches/series (+16/-0) debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch (+134/-0) debian/patches/test-runner-Add-assert_focused-command.patch (+76/-0) debian/patches/test-runner-Add-dispatch-command.patch (+84/-0) debian/patches/test-runner-Add-sleep-command.patch (+82/-0) debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch (+78/-0) debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch (+116/-0) debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch (+64/-0) debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch (+125/-0) debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch (+43/-0) debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch (+109/-0) debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch (+39/-0) debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch (+247/-0) debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch (+339/-0) debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch (+85/-0) |
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Desktop | Pending | ||
Review via email: mp+369334@code.launchpad.net |
Commit message
Description of the change
Upstream cherry-picks and crash fix
To post a comment you must log in.
Revision history for this message
Iain Lane (laney) wrote : | # |
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 62c0624..9a06342 100644 |
3 | --- a/debian/changelog |
4 | +++ b/debian/changelog |
5 | @@ -1,3 +1,30 @@ |
6 | +mutter (3.28.4-0ubuntu18.04.2) UNRELEASED; urgency=medium |
7 | + |
8 | + * d/p/screen-Destroy-window-actors-after-windows-while-unmanagi.patch, |
9 | + d/p/screen-Unset-the-active-workspace-and-remove-workspaces-o.patch: |
10 | + - Destroy window actors after windows while unmanaging compositor |
11 | + (LP: #1832869) |
12 | + * d/p/window-Emit-an-error-and-return-when-trying-to-activate-a.patch: |
13 | + - window: Emit an error and return when trying to activate an unmanaged |
14 | + (LP: #1827401) |
15 | + * d/p/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch, |
16 | + d/p/test-runner-Add-assert_focused-command.patch, |
17 | + d/p/test-runner-Add-dispatch-command.patch, |
18 | + d/p/test-runner-Add-sleep-command.patch, |
19 | + d/p/tests-Add-accept_focus-command-to-runner-and-client.patch, |
20 | + d/p/tests-Add-can_take_focus-command-to-runner-and-client.patch, |
21 | + d/p/tests-Verify-focused-window-in-closed-transient-tests.patch, |
22 | + d/p/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch, |
23 | + d/p/window-x11-Accept-any-focusable-window-as-fallback-focus.patch, |
24 | + d/p/window-x11-Don-t-double-check-for-unmanaging-windows.patch, |
25 | + d/p/window-x11-Focus-the-default-window-with-delay-while-wait.patch, |
26 | + d/p/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch, |
27 | + d/p/workspace-Focus-only-ancestors-that-are-focusable.patch: |
28 | + - Workspace: Take-Input windows focus fixes (LP: #1791574) |
29 | + * debian/libmutter-2-0.symbols: Update with new symbols |
30 | + |
31 | + -- Marco Trevisan (Treviño) <marco@ubuntu.com> Mon, 08 Jul 2019 20:00:56 +0200 |
32 | + |
33 | mutter (3.28.4-0ubuntu18.04.1) bionic; urgency=medium |
34 | |
35 | * New upstream release: |
36 | diff --git a/debian/libmutter-2-0.symbols b/debian/libmutter-2-0.symbols |
37 | index 951e8e4..70b61dc 100644 |
38 | --- a/debian/libmutter-2-0.symbols |
39 | +++ b/debian/libmutter-2-0.symbols |
40 | @@ -139,6 +139,7 @@ libmutter-2.so.0 libmutter-2-0 #MINVER# |
41 | meta_compositor_sync_updates_frozen@Base 3.28.2 |
42 | meta_compositor_sync_window_geometry@Base 3.28.2 |
43 | meta_compositor_unmanage@Base 3.28.2 |
44 | + meta_compositor_unmanage_window_actors@Base 3.28.4-0ubuntu18.04.2 |
45 | meta_compositor_window_opacity_changed@Base 3.28.2 |
46 | meta_compositor_window_shape_changed@Base 3.28.2 |
47 | meta_compositor_window_surface_changed@Base 3.28.2 |
48 | @@ -1112,6 +1113,7 @@ libmutter-2.so.0 libmutter-2-0 #MINVER# |
49 | meta_stack_get_above@Base 3.28.2 |
50 | meta_stack_get_below@Base 3.28.2 |
51 | meta_stack_get_bottom@Base 3.28.2 |
52 | + meta_stack_get_default_focus_candidates@Base 3.28.4-0ubuntu18.04.2 |
53 | meta_stack_get_default_focus_window@Base 3.28.2 |
54 | meta_stack_get_default_focus_window_at_point@Base 3.28.2 |
55 | meta_stack_get_positions@Base 3.28.2 |
56 | diff --git a/debian/patches/screen-Destroy-window-actors-after-windows-while-unmanagi.patch b/debian/patches/screen-Destroy-window-actors-after-windows-while-unmanagi.patch |
57 | new file mode 100644 |
58 | index 0000000..3bf085a |
59 | --- /dev/null |
60 | +++ b/debian/patches/screen-Destroy-window-actors-after-windows-while-unmanagi.patch |
61 | @@ -0,0 +1,106 @@ |
62 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
63 | +Date: Tue, 25 Jun 2019 20:22:23 +0200 |
64 | +Subject: screen: Destroy window actors after windows while unmanaging |
65 | + compositor |
66 | + |
67 | +After commit 2e64457f4 we destroy window actors as part of compositor |
68 | +destruction, however this might emit 'actor-removed' signals on window groups |
69 | +that the shell could use to access to resources that are already free'd at this |
70 | +point (like the destroyed screen, in gnome-shell's Panel._updateSolidStyle()). |
71 | + |
72 | +So, move the actor destructions under in a new function and destroy the window |
73 | +actors as part of compositor unmanage step, just after that all the windows are |
74 | +unmanaged (as they need to have an actor around). |
75 | + |
76 | +Fixes https://gitlab.gnome.org/GNOME/mutter/issues/652 |
77 | + |
78 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/653 |
79 | +Bug-Ubuntu: https://launchpad.net/bugs/1832869 |
80 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/652 |
81 | +Applied-Upstream: 3.28.5 |
82 | +--- |
83 | + src/compositor/compositor-private.h | 2 ++ |
84 | + src/compositor/compositor.c | 30 +++++++++++++++++------------- |
85 | + src/core/screen.c | 3 +++ |
86 | + 3 files changed, 22 insertions(+), 13 deletions(-) |
87 | + |
88 | +diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h |
89 | +index 4669bc5..4582792 100644 |
90 | +--- a/src/compositor/compositor-private.h |
91 | ++++ b/src/compositor/compositor-private.h |
92 | +@@ -73,4 +73,6 @@ MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *composito |
93 | + MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor, |
94 | + MetaWindow *window); |
95 | + |
96 | ++void meta_compositor_unmanage_window_actors (MetaCompositor *compositor); |
97 | ++ |
98 | + #endif /* META_COMPOSITOR_PRIVATE_H */ |
99 | +diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c |
100 | +index 2545d2c..6d04533 100644 |
101 | +--- a/src/compositor/compositor.c |
102 | ++++ b/src/compositor/compositor.c |
103 | +@@ -145,19 +145,6 @@ meta_compositor_destroy (MetaCompositor *compositor) |
104 | + clutter_threads_remove_repaint_func (compositor->pre_paint_func_id); |
105 | + clutter_threads_remove_repaint_func (compositor->post_paint_func_id); |
106 | + |
107 | +- if (compositor->top_window_actor) |
108 | +- { |
109 | +- g_signal_handlers_disconnect_by_func (compositor->top_window_actor, |
110 | +- on_top_window_actor_destroyed, |
111 | +- compositor); |
112 | +- compositor->top_window_actor = NULL; |
113 | +- } |
114 | +- |
115 | +- g_clear_pointer (&compositor->window_group, clutter_actor_destroy); |
116 | +- g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy); |
117 | +- g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy); |
118 | +- g_clear_pointer (&compositor->windows, g_list_free); |
119 | +- |
120 | + if (compositor->have_x11_sync_object) |
121 | + meta_sync_ring_destroy (); |
122 | + } |
123 | +@@ -610,6 +597,23 @@ meta_compositor_unmanage (MetaCompositor *compositor) |
124 | + } |
125 | + } |
126 | + |
127 | ++void |
128 | ++meta_compositor_unmanage_window_actors (MetaCompositor *compositor) |
129 | ++{ |
130 | ++ if (compositor->top_window_actor) |
131 | ++ { |
132 | ++ g_signal_handlers_disconnect_by_func (compositor->top_window_actor, |
133 | ++ on_top_window_actor_destroyed, |
134 | ++ compositor); |
135 | ++ compositor->top_window_actor = NULL; |
136 | ++ } |
137 | ++ |
138 | ++ g_clear_pointer (&compositor->window_group, clutter_actor_destroy); |
139 | ++ g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy); |
140 | ++ g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy); |
141 | ++ g_clear_pointer (&compositor->windows, g_list_free); |
142 | ++} |
143 | ++ |
144 | + /** |
145 | + * meta_shape_cow_for_window: |
146 | + * @compositor: A #MetaCompositor |
147 | +diff --git a/src/core/screen.c b/src/core/screen.c |
148 | +index d7623f3..2e59754 100644 |
149 | +--- a/src/core/screen.c |
150 | ++++ b/src/core/screen.c |
151 | +@@ -41,6 +41,7 @@ |
152 | + #include "stack.h" |
153 | + #include <meta/compositor.h> |
154 | + #include <meta/meta-enum-types.h> |
155 | ++#include "compositor-private.h" |
156 | + #include "core.h" |
157 | + #include "meta-cursor-tracker-private.h" |
158 | + #include "boxes-private.h" |
159 | +@@ -844,6 +845,8 @@ meta_screen_free (MetaScreen *screen, |
160 | + |
161 | + meta_display_unmanage_windows_for_screen (display, screen, timestamp); |
162 | + |
163 | ++ meta_compositor_unmanage_window_actors (display->compositor); |
164 | ++ |
165 | + meta_prefs_remove_listener (prefs_changed_callback, screen); |
166 | + |
167 | + meta_screen_ungrab_keys (screen); |
168 | diff --git a/debian/patches/screen-Unset-the-active-workspace-and-remove-workspaces-o.patch b/debian/patches/screen-Unset-the-active-workspace-and-remove-workspaces-o.patch |
169 | new file mode 100644 |
170 | index 0000000..7c67b0c |
171 | --- /dev/null |
172 | +++ b/debian/patches/screen-Unset-the-active-workspace-and-remove-workspaces-o.patch |
173 | @@ -0,0 +1,43 @@ |
174 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
175 | +Date: Tue, 25 Jun 2019 20:22:54 +0200 |
176 | +Subject: screen: Unset the active workspace and remove workspaces on free |
177 | + |
178 | +Related to https://gitlab.gnome.org/GNOME/mutter/issues/652 |
179 | + |
180 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/653 |
181 | +Bug-Ubuntu: https://launchpad.net/bugs/1832869 |
182 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/652 |
183 | +Applied-Upstream: 3.28.5 |
184 | +--- |
185 | + src/core/screen.c | 11 +++++++++++ |
186 | + 1 file changed, 11 insertions(+) |
187 | + |
188 | +diff --git a/src/core/screen.c b/src/core/screen.c |
189 | +index 2e59754..11f3bad 100644 |
190 | +--- a/src/core/screen.c |
191 | ++++ b/src/core/screen.c |
192 | +@@ -836,6 +836,7 @@ meta_screen_free (MetaScreen *screen, |
193 | + guint32 timestamp) |
194 | + { |
195 | + MetaDisplay *display; |
196 | ++ GList *l; |
197 | + |
198 | + display = screen->display; |
199 | + |
200 | +@@ -877,6 +878,16 @@ meta_screen_free (MetaScreen *screen, |
201 | + |
202 | + g_free (screen->screen_name); |
203 | + |
204 | ++ screen->active_workspace = NULL; |
205 | ++ |
206 | ++ for (l = screen->workspaces; l;) |
207 | ++ { |
208 | ++ MetaWorkspace *workspace = l->data; |
209 | ++ l = l->next; |
210 | ++ |
211 | ++ meta_workspace_remove (workspace); |
212 | ++ } |
213 | ++ |
214 | + g_object_unref (screen); |
215 | + } |
216 | + |
217 | diff --git a/debian/patches/series b/debian/patches/series |
218 | index 5bf1aa6..8165334 100644 |
219 | --- a/debian/patches/series |
220 | +++ b/debian/patches/series |
221 | @@ -4,6 +4,22 @@ clutter-Fix-offscreen-effect-painting-of-clones.patch |
222 | bgo768531_workaround-startup-notifications.patch |
223 | monitor-manager-use-MonitorsConfig-to-track-switch_config.patch |
224 | monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch |
225 | +screen-Destroy-window-actors-after-windows-while-unmanagi.patch |
226 | +screen-Unset-the-active-workspace-and-remove-workspaces-o.patch |
227 | +workspace-Focus-only-ancestors-that-are-focusable.patch |
228 | +tests-Add-accept_focus-command-to-runner-and-client.patch |
229 | +tests-Add-can_take_focus-command-to-runner-and-client.patch |
230 | +tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch |
231 | +test-runner-Add-assert_focused-command.patch |
232 | +tests-Verify-focused-window-in-closed-transient-tests.patch |
233 | +test-runner-Add-sleep-command.patch |
234 | +test-runner-Add-dispatch-command.patch |
235 | +window-x11-Focus-the-default-window-with-delay-while-wait.patch |
236 | +window-Emit-an-error-and-return-when-trying-to-activate-a.patch |
237 | +window-x11-Don-t-double-check-for-unmanaging-windows.patch |
238 | +window-x11-Accept-any-focusable-window-as-fallback-focus.patch |
239 | +stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch |
240 | +window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch |
241 | lp1763892-a-renderer-native-Add-hardware-presentation-timing.patch |
242 | lp1763892-b-renderer-native-Advertise-_FEATURE_SWAP_THROTTLE.patch |
243 | debian/synaptics-support.patch |
244 | diff --git a/debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch b/debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch |
245 | new file mode 100644 |
246 | index 0000000..f3452b8 |
247 | --- /dev/null |
248 | +++ b/debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch |
249 | @@ -0,0 +1,134 @@ |
250 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
251 | +Date: Wed, 3 Jul 2019 18:48:07 +0200 |
252 | +Subject: stack: Add a function to get a sorted list of focus candidates |
253 | + |
254 | +Use a static function if a window can be the default focus window, and use such |
255 | +function to return a filtered list of the stack. |
256 | + |
257 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
258 | + |
259 | +(cherry picked from commit 2439255f32b4e775d4427c92a6797b8bd33e7d5a) |
260 | + |
261 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
262 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
263 | +Bug-Ubuntu: https://launchpad.net/bugs/1834583 |
264 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
265 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/660 |
266 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
267 | +Applied-Upstream: 3.28.5 |
268 | +--- |
269 | + src/core/stack.c | 55 ++++++++++++++++++++++++++++++++++++++++++------------- |
270 | + src/core/stack.h | 15 +++++++++++++++ |
271 | + 2 files changed, 57 insertions(+), 13 deletions(-) |
272 | + |
273 | +diff --git a/src/core/stack.c b/src/core/stack.c |
274 | +index fc51aa1..3a0130f 100644 |
275 | +--- a/src/core/stack.c |
276 | ++++ b/src/core/stack.c |
277 | +@@ -1176,6 +1176,27 @@ window_contains_point (MetaWindow *window, |
278 | + return POINT_IN_RECT (root_x, root_y, rect); |
279 | + } |
280 | + |
281 | ++static gboolean |
282 | ++window_can_get_default_focus (MetaWindow *window) |
283 | ++{ |
284 | ++ if (window->unmaps_pending > 0) |
285 | ++ return FALSE; |
286 | ++ |
287 | ++ if (window->unmanaging) |
288 | ++ return FALSE; |
289 | ++ |
290 | ++ if (!(window->input || window->take_focus)) |
291 | ++ return FALSE; |
292 | ++ |
293 | ++ if (!meta_window_should_be_showing (window)) |
294 | ++ return FALSE; |
295 | ++ |
296 | ++ if (window->type == META_WINDOW_DOCK) |
297 | ++ return FALSE; |
298 | ++ |
299 | ++ return TRUE; |
300 | ++} |
301 | ++ |
302 | + static MetaWindow* |
303 | + get_default_focus_window (MetaStack *stack, |
304 | + MetaWorkspace *workspace, |
305 | +@@ -1203,24 +1224,12 @@ get_default_focus_window (MetaStack *stack, |
306 | + if (window == not_this_one) |
307 | + continue; |
308 | + |
309 | +- if (window->unmaps_pending > 0) |
310 | +- continue; |
311 | +- |
312 | +- if (window->unmanaging) |
313 | +- continue; |
314 | +- |
315 | +- if (!(window->input || window->take_focus)) |
316 | +- continue; |
317 | +- |
318 | +- if (!meta_window_should_be_showing (window)) |
319 | ++ if (!window_can_get_default_focus (window)) |
320 | + continue; |
321 | + |
322 | + if (must_be_at_point && !window_contains_point (window, root_x, root_y)) |
323 | + continue; |
324 | + |
325 | +- if (window->type == META_WINDOW_DOCK) |
326 | +- continue; |
327 | +- |
328 | + return window; |
329 | + } |
330 | + |
331 | +@@ -1275,6 +1284,26 @@ meta_stack_list_windows (MetaStack *stack, |
332 | + return workspace_windows; |
333 | + } |
334 | + |
335 | ++GList * |
336 | ++meta_stack_get_default_focus_candidates (MetaStack *stack, |
337 | ++ MetaWorkspace *workspace) |
338 | ++{ |
339 | ++ GList *windows = meta_stack_list_windows (stack, workspace); |
340 | ++ GList *l; |
341 | ++ |
342 | ++ for (l = windows; l;) |
343 | ++ { |
344 | ++ GList *next = l->next; |
345 | ++ |
346 | ++ if (!window_can_get_default_focus (l->data)) |
347 | ++ windows = g_list_delete_link (windows, l); |
348 | ++ |
349 | ++ l = next; |
350 | ++ } |
351 | ++ |
352 | ++ return windows; |
353 | ++} |
354 | ++ |
355 | + int |
356 | + meta_stack_windows_cmp (MetaStack *stack, |
357 | + MetaWindow *window_a, |
358 | +diff --git a/src/core/stack.h b/src/core/stack.h |
359 | +index e82be0a..8cd7c68 100644 |
360 | +--- a/src/core/stack.h |
361 | ++++ b/src/core/stack.h |
362 | +@@ -337,6 +337,21 @@ MetaWindow* meta_stack_get_default_focus_window_at_point (MetaStack *stack, |
363 | + int root_x, |
364 | + int root_y); |
365 | + |
366 | ++/** |
367 | ++ * meta_stack_get_default_focus_candidates: |
368 | ++ * @stack: The stack to examine. |
369 | ++ * @workspace: If not %NULL, only windows on this workspace will be |
370 | ++ * returned; otherwise all windows in the stack will be |
371 | ++ * returned. |
372 | ++ * |
373 | ++ * Returns all the focus candidate windows in the stack, in order. |
374 | ++ * |
375 | ++ * Returns: (transfer container) (element-type Meta.Window): |
376 | ++ * A #GList of #MetaWindow, in stacking order, honouring layers. |
377 | ++ */ |
378 | ++GList * meta_stack_get_default_focus_candidates (MetaStack *stack, |
379 | ++ MetaWorkspace *workspace); |
380 | ++ |
381 | + /** |
382 | + * meta_stack_list_windows: |
383 | + * @stack: The stack to examine. |
384 | diff --git a/debian/patches/test-runner-Add-assert_focused-command.patch b/debian/patches/test-runner-Add-assert_focused-command.patch |
385 | new file mode 100644 |
386 | index 0000000..94d47fc |
387 | --- /dev/null |
388 | +++ b/debian/patches/test-runner-Add-assert_focused-command.patch |
389 | @@ -0,0 +1,76 @@ |
390 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
391 | +Date: Tue, 13 Nov 2018 08:37:14 +0100 |
392 | +Subject: test-runner: Add 'assert_focused' command |
393 | + |
394 | +This allows to verify which window should have the focus, which might not |
395 | +be the same as the top of the stack. |
396 | + |
397 | +It's possible to assert the case where there's no focused window using |
398 | +"NONE" as parameter. |
399 | + |
400 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
401 | +(cherry picked from commit 51f9e04ef1fa8cd7298044ac8c82e83bea425770) |
402 | + |
403 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
404 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
405 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
406 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
407 | +Applied-Upstream: 3.28.5 |
408 | +--- |
409 | + src/tests/test-runner.c | 36 ++++++++++++++++++++++++++++++++++++ |
410 | + 1 file changed, 36 insertions(+) |
411 | + |
412 | +diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c |
413 | +index 37befb4..9056d9a 100644 |
414 | +--- a/src/tests/test-runner.c |
415 | ++++ b/src/tests/test-runner.c |
416 | +@@ -273,6 +273,37 @@ test_case_assert_stacking (TestCase *test, |
417 | + return *error == NULL; |
418 | + } |
419 | + |
420 | ++static gboolean |
421 | ++test_case_assert_focused (TestCase *test, |
422 | ++ const char *expected_window, |
423 | ++ GError **error) |
424 | ++{ |
425 | ++ MetaDisplay *display = meta_get_display (); |
426 | ++ |
427 | ++ if (!display->focus_window) |
428 | ++ { |
429 | ++ if (g_strcmp0 (expected_window, "none") != 0) |
430 | ++ { |
431 | ++ g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, |
432 | ++ "focus: expected='%s', actual='none'", expected_window); |
433 | ++ } |
434 | ++ } |
435 | ++ else |
436 | ++ { |
437 | ++ const char *focused = display->focus_window->title; |
438 | ++ |
439 | ++ if (g_str_has_prefix (focused, "test/")) |
440 | ++ focused += 5; |
441 | ++ |
442 | ++ if (g_strcmp0 (focused, expected_window) != 0) |
443 | ++ g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, |
444 | ++ "focus: expected='%s', actual='%s'", |
445 | ++ expected_window, focused); |
446 | ++ } |
447 | ++ |
448 | ++ return *error == NULL; |
449 | ++} |
450 | ++ |
451 | + static gboolean |
452 | + test_case_check_xserver_stacking (TestCase *test, |
453 | + GError **error) |
454 | +@@ -496,6 +527,11 @@ test_case_do (TestCase *test, |
455 | + if (!test_case_check_xserver_stacking (test, error)) |
456 | + return FALSE; |
457 | + } |
458 | ++ else if (strcmp (argv[0], "assert_focused") == 0) |
459 | ++ { |
460 | ++ if (!test_case_assert_focused (test, argv[1], error)) |
461 | ++ return FALSE; |
462 | ++ } |
463 | + else |
464 | + { |
465 | + BAD_COMMAND("Unknown command %s", argv[0]); |
466 | diff --git a/debian/patches/test-runner-Add-dispatch-command.patch b/debian/patches/test-runner-Add-dispatch-command.patch |
467 | new file mode 100644 |
468 | index 0000000..0fcbbd7 |
469 | --- /dev/null |
470 | +++ b/debian/patches/test-runner-Add-dispatch-command.patch |
471 | @@ -0,0 +1,84 @@ |
472 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
473 | +Date: Fri, 21 Jun 2019 13:15:48 +0200 |
474 | +Subject: test-runner: Add 'dispatch' command |
475 | + |
476 | +This will only wait for events to be dispatched and processed by the server |
477 | +without waiting for client processing. |
478 | + |
479 | +Reuse the code for the wait command too. |
480 | + |
481 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
482 | +(cherry picked from commit 6022b23923fa6192c630920e9f895f185977beee) |
483 | + |
484 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
485 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
486 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
487 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
488 | +Applied-Upstream: 3.28.5 |
489 | +--- |
490 | + src/tests/test-runner.c | 38 ++++++++++++++++++++++++++++---------- |
491 | + 1 file changed, 28 insertions(+), 10 deletions(-) |
492 | + |
493 | +diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c |
494 | +index 75732c6..cdeaba2 100644 |
495 | +--- a/src/tests/test-runner.c |
496 | ++++ b/src/tests/test-runner.c |
497 | +@@ -122,6 +122,24 @@ test_case_loop_quit (gpointer data) |
498 | + return FALSE; |
499 | + } |
500 | + |
501 | ++static gboolean |
502 | ++test_case_dispatch (TestCase *test, |
503 | ++ GError **error) |
504 | ++{ |
505 | ++ /* Wait until we've done any outstanding queued up work. |
506 | ++ * Though we add this as BEFORE_REDRAW, the iteration that runs the |
507 | ++ * BEFORE_REDRAW idles will proceed on and do the redraw, so we're |
508 | ++ * waiting until after *all* frame processing. |
509 | ++ */ |
510 | ++ meta_later_add (META_LATER_BEFORE_REDRAW, |
511 | ++ test_case_loop_quit, |
512 | ++ test, |
513 | ++ NULL); |
514 | ++ g_main_loop_run (test->loop); |
515 | ++ |
516 | ++ return TRUE; |
517 | ++} |
518 | ++ |
519 | + static gboolean |
520 | + test_case_wait (TestCase *test, |
521 | + GError **error) |
522 | +@@ -138,16 +156,8 @@ test_case_wait (TestCase *test, |
523 | + if (!test_client_wait (value, error)) |
524 | + return FALSE; |
525 | + |
526 | +- /* Then wait until we've done any outstanding queued up work. |
527 | +- * Though we add this as BEFORE_REDRAW, the iteration that runs the |
528 | +- * BEFORE_REDRAW idles will proceed on and do the redraw, so we're |
529 | +- * waiting until after *all* frame processing. |
530 | +- */ |
531 | +- meta_later_add (META_LATER_BEFORE_REDRAW, |
532 | +- test_case_loop_quit, |
533 | +- test, |
534 | +- NULL); |
535 | +- g_main_loop_run (test->loop); |
536 | ++ /* Then wait until we've done any outstanding queued up work. */ |
537 | ++ test_case_dispatch (test, error); |
538 | + |
539 | + /* Then set an XSync counter ourselves and and wait until |
540 | + * we receive the resulting event - this makes sure that we've |
541 | +@@ -530,6 +540,14 @@ test_case_do (TestCase *test, |
542 | + if (!test_case_wait (test, error)) |
543 | + return FALSE; |
544 | + } |
545 | ++ else if (strcmp (argv[0], "dispatch") == 0) |
546 | ++ { |
547 | ++ if (argc != 1) |
548 | ++ BAD_COMMAND("usage: %s", argv[0]); |
549 | ++ |
550 | ++ if (!test_case_dispatch (test, error)) |
551 | ++ return FALSE; |
552 | ++ } |
553 | + else if (strcmp (argv[0], "sleep") == 0) |
554 | + { |
555 | + guint64 interval; |
556 | diff --git a/debian/patches/test-runner-Add-sleep-command.patch b/debian/patches/test-runner-Add-sleep-command.patch |
557 | new file mode 100644 |
558 | index 0000000..914c9c2 |
559 | --- /dev/null |
560 | +++ b/debian/patches/test-runner-Add-sleep-command.patch |
561 | @@ -0,0 +1,82 @@ |
562 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
563 | +Date: Tue, 18 Jun 2019 19:33:10 +0200 |
564 | +Subject: test-runner: Add 'sleep' command |
565 | + |
566 | +This allows to sleep for a given timeout in milliseconds. |
567 | + |
568 | +Rename test_case_before_redraw to test_case_loop_quit since it's a generic |
569 | +function and use it for the timeout too. |
570 | + |
571 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
572 | +(cherry picked from commit d08763c18cb25fe250b27bf296e1607e63e86400) |
573 | + |
574 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
575 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
576 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
577 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
578 | +Applied-Upstream: 3.28.5 |
579 | +--- |
580 | + src/tests/test-runner.c | 29 +++++++++++++++++++++++++++-- |
581 | + 1 file changed, 27 insertions(+), 2 deletions(-) |
582 | + |
583 | +diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c |
584 | +index 9056d9a..75732c6 100644 |
585 | +--- a/src/tests/test-runner.c |
586 | ++++ b/src/tests/test-runner.c |
587 | +@@ -113,7 +113,7 @@ test_case_new (void) |
588 | + } |
589 | + |
590 | + static gboolean |
591 | +-test_case_before_redraw (gpointer data) |
592 | ++test_case_loop_quit (gpointer data) |
593 | + { |
594 | + TestCase *test = data; |
595 | + |
596 | +@@ -144,7 +144,7 @@ test_case_wait (TestCase *test, |
597 | + * waiting until after *all* frame processing. |
598 | + */ |
599 | + meta_later_add (META_LATER_BEFORE_REDRAW, |
600 | +- test_case_before_redraw, |
601 | ++ test_case_loop_quit, |
602 | + test, |
603 | + NULL); |
604 | + g_main_loop_run (test->loop); |
605 | +@@ -157,6 +157,17 @@ test_case_wait (TestCase *test, |
606 | + return TRUE; |
607 | + } |
608 | + |
609 | ++static gboolean |
610 | ++test_case_sleep (TestCase *test, |
611 | ++ guint32 interval, |
612 | ++ GError **error) |
613 | ++{ |
614 | ++ g_timeout_add_full (G_PRIORITY_LOW, interval, test_case_loop_quit, test, NULL); |
615 | ++ g_main_loop_run (test->loop); |
616 | ++ |
617 | ++ return TRUE; |
618 | ++} |
619 | ++ |
620 | + #define BAD_COMMAND(...) \ |
621 | + G_STMT_START { \ |
622 | + g_set_error (error, \ |
623 | +@@ -519,6 +530,20 @@ test_case_do (TestCase *test, |
624 | + if (!test_case_wait (test, error)) |
625 | + return FALSE; |
626 | + } |
627 | ++ else if (strcmp (argv[0], "sleep") == 0) |
628 | ++ { |
629 | ++ guint64 interval; |
630 | ++ |
631 | ++ if (argc != 2) |
632 | ++ BAD_COMMAND("usage: %s <milliseconds>", argv[0]); |
633 | ++ |
634 | ++ if (!g_ascii_string_to_unsigned (argv[1], 10, 0, G_MAXUINT32, |
635 | ++ &interval, error)) |
636 | ++ return FALSE; |
637 | ++ |
638 | ++ if (!test_case_sleep (test, (guint32) interval, error)) |
639 | ++ return FALSE; |
640 | ++ } |
641 | + else if (strcmp (argv[0], "assert_stacking") == 0) |
642 | + { |
643 | + if (!test_case_assert_stacking (test, argv + 1, argc - 1, error)) |
644 | diff --git a/debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch b/debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch |
645 | new file mode 100644 |
646 | index 0000000..82dc33b |
647 | --- /dev/null |
648 | +++ b/debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch |
649 | @@ -0,0 +1,78 @@ |
650 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
651 | +Date: Tue, 13 Nov 2018 03:43:57 +0100 |
652 | +Subject: tests: Add 'accept_focus' command to runner and client |
653 | + |
654 | +Under the hood, calls gtk_window_set_accept_focus in the client |
655 | + |
656 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
657 | +(cherry picked from commit e1f839f48f8e49c826ba558fbc9d6842a156b28b) |
658 | + |
659 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
660 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
661 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
662 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
663 | +Applied-Upstream: 3.28.5 |
664 | +--- |
665 | + src/tests/test-client.c | 18 ++++++++++++++++++ |
666 | + src/tests/test-runner.c | 19 +++++++++++++++++++ |
667 | + 2 files changed, 37 insertions(+) |
668 | + |
669 | +diff --git a/src/tests/test-client.c b/src/tests/test-client.c |
670 | +index 5836083..1870fd2 100644 |
671 | +--- a/src/tests/test-client.c |
672 | ++++ b/src/tests/test-client.c |
673 | +@@ -161,6 +161,24 @@ process_line (const char *line) |
674 | + gtk_window_set_transient_for (GTK_WINDOW (window), |
675 | + GTK_WINDOW (parent_window)); |
676 | + } |
677 | ++ else if (strcmp (argv[0], "accept_focus") == 0) |
678 | ++ { |
679 | ++ if (argc != 3) |
680 | ++ { |
681 | ++ g_print ("usage: %s <window-id> [true|false]", argv[0]); |
682 | ++ goto out; |
683 | ++ } |
684 | ++ |
685 | ++ GtkWidget *window = lookup_window (argv[1]); |
686 | ++ if (!window) |
687 | ++ { |
688 | ++ g_print ("unknown window %s", argv[1]); |
689 | ++ goto out; |
690 | ++ } |
691 | ++ |
692 | ++ gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0; |
693 | ++ gtk_window_set_accept_focus (GTK_WINDOW (window), enabled); |
694 | ++ } |
695 | + else if (strcmp (argv[0], "show") == 0) |
696 | + { |
697 | + if (argc != 2) |
698 | +diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c |
699 | +index 8867945..613c0bb 100644 |
700 | +--- a/src/tests/test-runner.c |
701 | ++++ b/src/tests/test-runner.c |
702 | +@@ -406,6 +406,25 @@ test_case_do (TestCase *test, |
703 | + NULL)) |
704 | + return FALSE; |
705 | + } |
706 | ++ else if (strcmp (argv[0], "accept_focus") == 0) |
707 | ++ { |
708 | ++ if (argc != 3 || |
709 | ++ (g_ascii_strcasecmp (argv[2], "true") != 0 && |
710 | ++ g_ascii_strcasecmp (argv[2], "false") != 0)) |
711 | ++ BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]", |
712 | ++ argv[0]); |
713 | ++ |
714 | ++ TestClient *client; |
715 | ++ const char *window_id; |
716 | ++ if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) |
717 | ++ return FALSE; |
718 | ++ |
719 | ++ if (!test_client_do (client, error, |
720 | ++ argv[0], window_id, |
721 | ++ argv[2], |
722 | ++ NULL)) |
723 | ++ return FALSE; |
724 | ++ } |
725 | + else if (strcmp (argv[0], "show") == 0 || |
726 | + strcmp (argv[0], "hide") == 0 || |
727 | + strcmp (argv[0], "activate") == 0 || |
728 | diff --git a/debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch b/debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch |
729 | new file mode 100644 |
730 | index 0000000..03357df |
731 | --- /dev/null |
732 | +++ b/debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch |
733 | @@ -0,0 +1,116 @@ |
734 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
735 | +Date: Tue, 13 Nov 2018 04:04:22 +0100 |
736 | +Subject: tests: Add 'can_take_focus' command to runner and client |
737 | + |
738 | +Allow to set/unset WM_TAKE_FOCUS from client window. |
739 | +This is added by default by gtk, but this might not happen in other toolkits, |
740 | +so add an ability to (un)set this. |
741 | + |
742 | +So fetch the protocols with XGetWMProtocols and unset the atom. |
743 | + |
744 | +test-client now needs to depend on Xlib directly in meson build. |
745 | + |
746 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
747 | +(cherry picked from commit f2d2d473b71dbdb339c80f068c5cb3e529af2478) |
748 | + |
749 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
750 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
751 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
752 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
753 | +Applied-Upstream: 3.28.5 |
754 | +--- |
755 | + src/tests/test-client.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ |
756 | + src/tests/test-runner.c | 19 +++++++++++++++++++ |
757 | + 2 files changed, 69 insertions(+) |
758 | + |
759 | +diff --git a/src/tests/test-client.c b/src/tests/test-client.c |
760 | +index 1870fd2..aa763d5 100644 |
761 | +--- a/src/tests/test-client.c |
762 | ++++ b/src/tests/test-client.c |
763 | +@@ -179,6 +179,56 @@ process_line (const char *line) |
764 | + gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0; |
765 | + gtk_window_set_accept_focus (GTK_WINDOW (window), enabled); |
766 | + } |
767 | ++ else if (strcmp (argv[0], "can_take_focus") == 0) |
768 | ++ { |
769 | ++ if (argc != 3) |
770 | ++ { |
771 | ++ g_print ("usage: %s <window-id> [true|false]", argv[0]); |
772 | ++ goto out; |
773 | ++ } |
774 | ++ |
775 | ++ GtkWidget *window = lookup_window (argv[1]); |
776 | ++ if (!window) |
777 | ++ { |
778 | ++ g_print ("unknown window %s", argv[1]); |
779 | ++ goto out; |
780 | ++ } |
781 | ++ |
782 | ++ if (wayland) |
783 | ++ { |
784 | ++ g_print ("%s not supported under wayland", argv[0]); |
785 | ++ goto out; |
786 | ++ } |
787 | ++ |
788 | ++ GdkDisplay *display = gdk_display_get_default (); |
789 | ++ GdkWindow *gdkwindow = gtk_widget_get_window (window); |
790 | ++ Display *xdisplay = gdk_x11_display_get_xdisplay (display); |
791 | ++ Window xwindow = GDK_WINDOW_XID (gdkwindow); |
792 | ++ Atom wm_take_focus = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"); |
793 | ++ gboolean add = g_ascii_strcasecmp(argv[2], "true") == 0; |
794 | ++ Atom *protocols = NULL; |
795 | ++ Atom *new_protocols; |
796 | ++ int n_protocols = 0; |
797 | ++ int i, n = 0; |
798 | ++ |
799 | ++ gdk_display_sync (display); |
800 | ++ XGetWMProtocols (xdisplay, xwindow, &protocols, &n_protocols); |
801 | ++ new_protocols = g_new0 (Atom, n_protocols + (add ? 1 : 0)); |
802 | ++ |
803 | ++ for (i = 0; i < n_protocols; ++i) |
804 | ++ { |
805 | ++ if (protocols[i] != wm_take_focus) |
806 | ++ new_protocols[n++] = protocols[i]; |
807 | ++ } |
808 | ++ |
809 | ++ if (add) |
810 | ++ new_protocols[n++] = wm_take_focus; |
811 | ++ |
812 | ++ XSetWMProtocols (xdisplay, xwindow, new_protocols, n); |
813 | ++ |
814 | ++ XFree (new_protocols); |
815 | ++ XFree (protocols); |
816 | ++ } |
817 | + else if (strcmp (argv[0], "show") == 0) |
818 | + { |
819 | + if (argc != 2) |
820 | +diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c |
821 | +index 613c0bb..37befb4 100644 |
822 | +--- a/src/tests/test-runner.c |
823 | ++++ b/src/tests/test-runner.c |
824 | +@@ -425,6 +425,25 @@ test_case_do (TestCase *test, |
825 | + NULL)) |
826 | + return FALSE; |
827 | + } |
828 | ++ else if (strcmp (argv[0], "can_take_focus") == 0) |
829 | ++ { |
830 | ++ if (argc != 3 || |
831 | ++ (g_ascii_strcasecmp (argv[2], "true") != 0 && |
832 | ++ g_ascii_strcasecmp (argv[2], "false") != 0)) |
833 | ++ BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]", |
834 | ++ argv[0]); |
835 | ++ |
836 | ++ TestClient *client; |
837 | ++ const char *window_id; |
838 | ++ if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) |
839 | ++ return FALSE; |
840 | ++ |
841 | ++ if (!test_client_do (client, error, |
842 | ++ argv[0], window_id, |
843 | ++ argv[2], |
844 | ++ NULL)) |
845 | ++ return FALSE; |
846 | ++ } |
847 | + else if (strcmp (argv[0], "show") == 0 || |
848 | + strcmp (argv[0], "hide") == 0 || |
849 | + strcmp (argv[0], "activate") == 0 || |
850 | diff --git a/debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch b/debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch |
851 | new file mode 100644 |
852 | index 0000000..f65d295 |
853 | --- /dev/null |
854 | +++ b/debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch |
855 | @@ -0,0 +1,64 @@ |
856 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
857 | +Date: Tue, 13 Nov 2018 08:45:56 +0100 |
858 | +Subject: tests: Verify focused window in closed-transient tests |
859 | + |
860 | +Ensure that we have a focused window when closing transient windows with |
861 | +no-focus or no-take-focus atoms |
862 | + |
863 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
864 | +(cherry picked from commit fcb408ad5d8d7fec3e6a7bdaa92e5ef06b55c2c6) |
865 | + |
866 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
867 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
868 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
869 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
870 | +Applied-Upstream: 3.28.5 |
871 | +--- |
872 | + .../closed-transient-no-input-no-take-focus-parent.metatest | 2 ++ |
873 | + ...closed-transient-no-input-no-take-focus-parents.metatest | 13 ++++++++++--- |
874 | + 2 files changed, 12 insertions(+), 3 deletions(-) |
875 | + |
876 | +diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest |
877 | +index 4249c32..0c0649c 100644 |
878 | +--- a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest |
879 | ++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest |
880 | +@@ -13,9 +13,11 @@ set_parent 1/3 2 |
881 | + show 1/3 |
882 | + |
883 | + wait |
884 | ++assert_focused 1/3 |
885 | + assert_stacking 1/1 1/2 1/3 |
886 | + |
887 | + destroy 1/3 |
888 | + |
889 | + wait |
890 | ++assert_focused 1/1 |
891 | + assert_stacking 1/1 1/2 |
892 | +diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest |
893 | +index a61c640..6556803 100644 |
894 | +--- a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest |
895 | ++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest |
896 | +@@ -1,3 +1,8 @@ |
897 | ++new_client 2 x11 |
898 | ++create 2/1 |
899 | ++show 2/1 |
900 | ++wait |
901 | ++ |
902 | + new_client 1 x11 |
903 | + create 1/1 |
904 | + accept_focus 1/1 false |
905 | +@@ -15,9 +20,11 @@ set_parent 1/3 2 |
906 | + show 1/3 |
907 | + |
908 | + wait |
909 | +-assert_stacking 1/1 1/2 1/3 |
910 | ++assert_focused 1/3 |
911 | ++assert_stacking 2/1 1/1 1/2 1/3 |
912 | + |
913 | + destroy 1/3 |
914 | +-wait |
915 | + |
916 | +-assert_stacking 1/1 1/2 |
917 | ++wait |
918 | ++assert_stacking 1/1 1/2 2/1 |
919 | ++assert_focused 2/1 |
920 | diff --git a/debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch b/debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch |
921 | new file mode 100644 |
922 | index 0000000..77cc7d3 |
923 | --- /dev/null |
924 | +++ b/debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch |
925 | @@ -0,0 +1,125 @@ |
926 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
927 | +Date: Tue, 13 Nov 2018 07:48:53 +0100 |
928 | +Subject: tests, stacking: Add tests with no-input and no-take-focus windows |
929 | + |
930 | +When a window with no frame, that doesn't accept focus and that has no |
931 | +take-focus atom set is destroyed, we ended up in not changing the current_focus |
932 | +window, causing a crash. |
933 | + |
934 | +Added test cases that verify this situation. |
935 | + |
936 | +Related to https://gitlab.gnome.org/GNOME/mutter/issues/308 |
937 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
938 | +(cherry picked from commit 2fc7760ceed6f948d4f3c1dd74d4e57c7df05eea) |
939 | + |
940 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
941 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
942 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
943 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
944 | +Applied-Upstream: 3.28.5 |
945 | +--- |
946 | + src/Makefile-tests.am | 3 +++ |
947 | + ...ransient-no-input-no-take-focus-parent.metatest | 21 ++++++++++++++++++++ |
948 | + ...ansient-no-input-no-take-focus-parents.metatest | 23 ++++++++++++++++++++++ |
949 | + .../closed-transient-no-input-parent.metatest | 20 +++++++++++++++++++ |
950 | + 4 files changed, 67 insertions(+) |
951 | + create mode 100644 src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest |
952 | + create mode 100644 src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest |
953 | + create mode 100644 src/tests/stacking/closed-transient-no-input-parent.metatest |
954 | + |
955 | +diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am |
956 | +index 4be832c..3764917 100644 |
957 | +--- a/src/Makefile-tests.am |
958 | ++++ b/src/Makefile-tests.am |
959 | +@@ -15,6 +15,9 @@ dist_stacking_DATA = \ |
960 | + tests/stacking/basic-x11.metatest \ |
961 | + tests/stacking/basic-wayland.metatest \ |
962 | + tests/stacking/closed-transient.metatest \ |
963 | ++ tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest \ |
964 | ++ tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest \ |
965 | ++ tests/stacking/closed-transient-no-input-parent.metatest \ |
966 | + tests/stacking/minimized.metatest \ |
967 | + tests/stacking/mixed-windows.metatest \ |
968 | + tests/stacking/set-parent.metatest \ |
969 | +diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest |
970 | +new file mode 100644 |
971 | +index 0000000..4249c32 |
972 | +--- /dev/null |
973 | ++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest |
974 | +@@ -0,0 +1,21 @@ |
975 | ++new_client 1 x11 |
976 | ++create 1/1 |
977 | ++show 1/1 |
978 | ++ |
979 | ++create 1/2 csd |
980 | ++set_parent 1/2 1 |
981 | ++can_take_focus 1/2 false |
982 | ++accept_focus 1/2 false |
983 | ++show 1/2 |
984 | ++ |
985 | ++create 1/3 csd |
986 | ++set_parent 1/3 2 |
987 | ++show 1/3 |
988 | ++ |
989 | ++wait |
990 | ++assert_stacking 1/1 1/2 1/3 |
991 | ++ |
992 | ++destroy 1/3 |
993 | ++ |
994 | ++wait |
995 | ++assert_stacking 1/1 1/2 |
996 | +diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest |
997 | +new file mode 100644 |
998 | +index 0000000..a61c640 |
999 | +--- /dev/null |
1000 | ++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest |
1001 | +@@ -0,0 +1,23 @@ |
1002 | ++new_client 1 x11 |
1003 | ++create 1/1 |
1004 | ++accept_focus 1/1 false |
1005 | ++can_take_focus 1/1 false |
1006 | ++show 1/1 |
1007 | ++ |
1008 | ++create 1/2 csd |
1009 | ++set_parent 1/2 1 |
1010 | ++can_take_focus 1/2 false |
1011 | ++accept_focus 1/2 false |
1012 | ++show 1/2 |
1013 | ++ |
1014 | ++create 1/3 csd |
1015 | ++set_parent 1/3 2 |
1016 | ++show 1/3 |
1017 | ++ |
1018 | ++wait |
1019 | ++assert_stacking 1/1 1/2 1/3 |
1020 | ++ |
1021 | ++destroy 1/3 |
1022 | ++wait |
1023 | ++ |
1024 | ++assert_stacking 1/1 1/2 |
1025 | +diff --git a/src/tests/stacking/closed-transient-no-input-parent.metatest b/src/tests/stacking/closed-transient-no-input-parent.metatest |
1026 | +new file mode 100644 |
1027 | +index 0000000..4cadb23 |
1028 | +--- /dev/null |
1029 | ++++ b/src/tests/stacking/closed-transient-no-input-parent.metatest |
1030 | +@@ -0,0 +1,20 @@ |
1031 | ++new_client 1 x11 |
1032 | ++create 1/1 |
1033 | ++show 1/1 |
1034 | ++ |
1035 | ++create 1/2 csd |
1036 | ++set_parent 1/2 1 |
1037 | ++accept_focus 1/2 false |
1038 | ++show 1/2 |
1039 | ++ |
1040 | ++create 1/3 csd |
1041 | ++set_parent 1/3 2 |
1042 | ++show 1/3 |
1043 | ++ |
1044 | ++wait |
1045 | ++assert_stacking 1/1 1/2 1/3 |
1046 | ++ |
1047 | ++destroy 1/3 |
1048 | ++ |
1049 | ++wait |
1050 | ++assert_stacking 1/1 1/2 |
1051 | diff --git a/debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch b/debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch |
1052 | new file mode 100644 |
1053 | index 0000000..0d9d7e1 |
1054 | --- /dev/null |
1055 | +++ b/debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch |
1056 | @@ -0,0 +1,43 @@ |
1057 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1058 | +Date: Fri, 3 May 2019 20:10:47 +0200 |
1059 | +Subject: window: Emit an error and return when trying to activate an |
1060 | + unmanaged |
1061 | + |
1062 | +If something (i.e. gnome-shell or an extension) tries to activate an unmanaged |
1063 | +window, we should warn about this and avoid to perform further actions as this |
1064 | +could lead to a crash of mutter, since the window has not valid flags (like |
1065 | +workspace) set anymore at this stage. |
1066 | + |
1067 | +Fixes https://gitlab.gnome.org/GNOME/mutter/issues/580 |
1068 | + |
1069 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/564 |
1070 | + |
1071 | +(cherry picked from commit a6fc656e917fd48b8708b8d9f4bf9f8b15581313) |
1072 | + |
1073 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
1074 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
1075 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
1076 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
1077 | +Applied-Upstream: 3.28.5 |
1078 | +--- |
1079 | + src/core/window.c | 7 +++++++ |
1080 | + 1 file changed, 7 insertions(+) |
1081 | + |
1082 | +diff --git a/src/core/window.c b/src/core/window.c |
1083 | +index eaae5b0..32c9461 100644 |
1084 | +--- a/src/core/window.c |
1085 | ++++ b/src/core/window.c |
1086 | +@@ -3622,6 +3622,13 @@ meta_window_activate_full (MetaWindow *window, |
1087 | + MetaWorkspace *workspace) |
1088 | + { |
1089 | + gboolean allow_workspace_switch; |
1090 | ++ |
1091 | ++ if (window->unmanaging) |
1092 | ++ { |
1093 | ++ g_warning ("Trying to activate unmanaged window '%s'", window->desc); |
1094 | ++ return; |
1095 | ++ } |
1096 | ++ |
1097 | + meta_topic (META_DEBUG_FOCUS, |
1098 | + "_NET_ACTIVE_WINDOW message sent for %s at time %u " |
1099 | + "by client type %u.\n", |
1100 | diff --git a/debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch b/debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch |
1101 | new file mode 100644 |
1102 | index 0000000..77c2843 |
1103 | --- /dev/null |
1104 | +++ b/debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch |
1105 | @@ -0,0 +1,109 @@ |
1106 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1107 | +Date: Wed, 3 Jul 2019 11:15:36 +0200 |
1108 | +Subject: window-x11: Accept any focusable window as fallback focus |
1109 | + |
1110 | +As per commit f71151a5 we were ignoring WM_TAKE_FOCUS-only windows as focus |
1111 | +targets, however this might end-up in an infinite loop if there are multiple |
1112 | +non-input windows stacked. |
1113 | + |
1114 | +So, accept any focusable window as fallback focus target even if it's a |
1115 | +take-focus one (that might not reply to the request). |
1116 | + |
1117 | +Added a stacking test to verify this. |
1118 | + |
1119 | +Closes: https://gitlab.gnome.org/GNOME/mutter/issues/660 |
1120 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
1121 | + |
1122 | +(cherry picked from commit c327b2df95ff9979dd22bca2e0d285e1b3ba0add) |
1123 | + |
1124 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
1125 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
1126 | +Bug-Ubuntu: https://launchpad.net/bugs/1834583 |
1127 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
1128 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/660 |
1129 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
1130 | +Applied-Upstream: 3.28.5 |
1131 | +--- |
1132 | + src/Makefile-tests.am | 1 + |
1133 | + .../closed-transient-no-input-parents.metatest | 46 ++++++++++++++++++++++ |
1134 | + src/x11/window-x11.c | 2 +- |
1135 | + 3 files changed, 48 insertions(+), 1 deletion(-) |
1136 | + create mode 100644 src/tests/stacking/closed-transient-no-input-parents.metatest |
1137 | + |
1138 | +diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am |
1139 | +index eca6a7b..21d0619 100644 |
1140 | +--- a/src/Makefile-tests.am |
1141 | ++++ b/src/Makefile-tests.am |
1142 | +@@ -19,6 +19,7 @@ dist_stacking_DATA = \ |
1143 | + tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest \ |
1144 | + tests/stacking/closed-transient-no-input-parent.metatest \ |
1145 | + tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest \ |
1146 | ++ tests/stacking/closed-transient-no-input-parents.metatest \ |
1147 | + tests/stacking/minimized.metatest \ |
1148 | + tests/stacking/mixed-windows.metatest \ |
1149 | + tests/stacking/set-parent.metatest \ |
1150 | +diff --git a/src/tests/stacking/closed-transient-no-input-parents.metatest b/src/tests/stacking/closed-transient-no-input-parents.metatest |
1151 | +new file mode 100644 |
1152 | +index 0000000..e3ec2e8 |
1153 | +--- /dev/null |
1154 | ++++ b/src/tests/stacking/closed-transient-no-input-parents.metatest |
1155 | +@@ -0,0 +1,46 @@ |
1156 | ++new_client 0 x11 |
1157 | ++create 0/1 |
1158 | ++show 0/1 |
1159 | ++ |
1160 | ++new_client 1 x11 |
1161 | ++create 1/1 |
1162 | ++show 1/1 |
1163 | ++ |
1164 | ++create 1/2 csd |
1165 | ++set_parent 1/2 1 |
1166 | ++accept_focus 1/2 false |
1167 | ++show 1/2 |
1168 | ++ |
1169 | ++create 1/3 csd |
1170 | ++set_parent 1/3 2 |
1171 | ++accept_focus 1/3 false |
1172 | ++show 1/3 |
1173 | ++ |
1174 | ++create 1/4 csd |
1175 | ++set_parent 1/4 3 |
1176 | ++accept_focus 1/4 false |
1177 | ++show 1/4 |
1178 | ++ |
1179 | ++create 1/5 csd |
1180 | ++set_parent 1/5 3 |
1181 | ++show 1/5 |
1182 | ++ |
1183 | ++wait |
1184 | ++assert_focused 1/5 |
1185 | ++assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5 |
1186 | ++ |
1187 | ++destroy 1/5 |
1188 | ++dispatch |
1189 | ++ |
1190 | ++assert_focused none |
1191 | ++assert_stacking 0/1 1/1 1/2 1/3 1/4 |
1192 | ++ |
1193 | ++sleep 250 |
1194 | ++assert_focused none |
1195 | ++assert_stacking 0/1 1/1 1/2 1/3 1/4 |
1196 | ++ |
1197 | ++destroy 1/3 |
1198 | ++wait |
1199 | ++ |
1200 | ++assert_focused none |
1201 | ++assert_stacking 0/1 1/1 1/2 1/4 |
1202 | +diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c |
1203 | +index c09ba3e..7dff35e 100644 |
1204 | +--- a/src/x11/window-x11.c |
1205 | ++++ b/src/x11/window-x11.c |
1206 | +@@ -852,7 +852,7 @@ meta_window_x11_focus (MetaWindow *window, |
1207 | + if (!focus_window) |
1208 | + break; |
1209 | + |
1210 | +- if (focus_window->input) |
1211 | ++ if (focus_window->input || focus_window->take_focus) |
1212 | + break; |
1213 | + |
1214 | + if (focus_window->shaded && focus_window->frame) |
1215 | diff --git a/debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch b/debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch |
1216 | new file mode 100644 |
1217 | index 0000000..8127f55 |
1218 | --- /dev/null |
1219 | +++ b/debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch |
1220 | @@ -0,0 +1,39 @@ |
1221 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1222 | +Date: Mon, 1 Jul 2019 10:38:02 +0200 |
1223 | +Subject: window-x11: Don't double-check for unmanaging windows |
1224 | + |
1225 | +When looking for the best fallback focus window, we ignore it if it is in the |
1226 | +unmanaging state, but meta_stack_get_default_focus_window() does this is check |
1227 | +for us already. |
1228 | + |
1229 | +So, ignore the redundant test. |
1230 | + |
1231 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
1232 | + |
1233 | +(cherry picked from commit 9aee47daa984e5cc4a1ccefb3aacfbb2729cfbc1) |
1234 | + |
1235 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
1236 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
1237 | +Bug-Ubuntu: https://launchpad.net/bugs/1834583 |
1238 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
1239 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/660 |
1240 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
1241 | +Applied-Upstream: 3.28.5 |
1242 | +--- |
1243 | + src/x11/window-x11.c | 3 --- |
1244 | + 1 file changed, 3 deletions(-) |
1245 | + |
1246 | +diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c |
1247 | +index 29ea3a6..c09ba3e 100644 |
1248 | +--- a/src/x11/window-x11.c |
1249 | ++++ b/src/x11/window-x11.c |
1250 | +@@ -852,9 +852,6 @@ meta_window_x11_focus (MetaWindow *window, |
1251 | + if (!focus_window) |
1252 | + break; |
1253 | + |
1254 | +- if (focus_window->unmanaging) |
1255 | +- continue; |
1256 | +- |
1257 | + if (focus_window->input) |
1258 | + break; |
1259 | + |
1260 | diff --git a/debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch b/debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch |
1261 | new file mode 100644 |
1262 | index 0000000..9e9af63 |
1263 | --- /dev/null |
1264 | +++ b/debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch |
1265 | @@ -0,0 +1,247 @@ |
1266 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1267 | +Date: Wed, 14 Nov 2018 00:08:34 +0100 |
1268 | +Subject: window-x11: Focus the default window with delay while waiting for |
1269 | + take-focus |
1270 | + |
1271 | +When requesting to a take-focus window to acquire the input, the client may or |
1272 | +may not respond with a SetInputFocus (this doesn't happen for no-input gtk |
1273 | +windows in fact [to be fixed there too]), in such case we were unsetting the |
1274 | +focus while waiting the reply. |
1275 | + |
1276 | +In case the client won't respond, we wait for a small delay (set to 250 ms) for |
1277 | +the take-focus window to grab the input focus before setting it to the default |
1278 | +window. |
1279 | + |
1280 | +Added a test for this behavior and for the case in which a window takes the |
1281 | +focus meanwhile we're waiting to focus the default window. |
1282 | + |
1283 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
1284 | +(cherry picked from commit f71151a5dd990d935f3fbb39451f9b41f640b625) |
1285 | + |
1286 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
1287 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
1288 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
1289 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
1290 | +Applied-Upstream: 3.28.5 |
1291 | +--- |
1292 | + src/Makefile-tests.am | 1 + |
1293 | + ...parent-delayed-focus-default-cancelled.metatest | 36 ++++++++ |
1294 | + .../closed-transient-no-input-parent.metatest | 16 +++- |
1295 | + src/x11/window-x11.c | 101 ++++++++++++++++++++- |
1296 | + 4 files changed, 146 insertions(+), 8 deletions(-) |
1297 | + create mode 100644 src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest |
1298 | + |
1299 | +diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am |
1300 | +index 3764917..eca6a7b 100644 |
1301 | +--- a/src/Makefile-tests.am |
1302 | ++++ b/src/Makefile-tests.am |
1303 | +@@ -18,6 +18,7 @@ dist_stacking_DATA = \ |
1304 | + tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest \ |
1305 | + tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest \ |
1306 | + tests/stacking/closed-transient-no-input-parent.metatest \ |
1307 | ++ tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest \ |
1308 | + tests/stacking/minimized.metatest \ |
1309 | + tests/stacking/mixed-windows.metatest \ |
1310 | + tests/stacking/set-parent.metatest \ |
1311 | +diff --git a/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest b/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest |
1312 | +new file mode 100644 |
1313 | +index 0000000..38897e3 |
1314 | +--- /dev/null |
1315 | ++++ b/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest |
1316 | +@@ -0,0 +1,36 @@ |
1317 | ++new_client 2 x11 |
1318 | ++create 2/1 |
1319 | ++show 2/1 |
1320 | ++ |
1321 | ++new_client 1 x11 |
1322 | ++create 1/1 |
1323 | ++show 1/1 |
1324 | ++ |
1325 | ++create 1/2 csd |
1326 | ++set_parent 1/2 1 |
1327 | ++accept_focus 1/2 false |
1328 | ++show 1/2 |
1329 | ++ |
1330 | ++create 1/3 csd |
1331 | ++set_parent 1/3 2 |
1332 | ++show 1/3 |
1333 | ++ |
1334 | ++wait |
1335 | ++assert_focused 1/3 |
1336 | ++assert_stacking 2/1 1/1 1/2 1/3 |
1337 | ++ |
1338 | ++destroy 1/3 |
1339 | ++sleep 10 |
1340 | ++ |
1341 | ++assert_focused none |
1342 | ++assert_stacking 2/1 1/1 1/2 |
1343 | ++ |
1344 | ++activate 2/1 |
1345 | ++wait |
1346 | ++ |
1347 | ++assert_focused 2/1 |
1348 | ++assert_stacking 1/1 1/2 2/1 |
1349 | ++ |
1350 | ++sleep 250 |
1351 | ++assert_focused 2/1 |
1352 | ++assert_stacking 1/1 1/2 2/1 |
1353 | +diff --git a/src/tests/stacking/closed-transient-no-input-parent.metatest b/src/tests/stacking/closed-transient-no-input-parent.metatest |
1354 | +index 4cadb23..e0f1dc1 100644 |
1355 | +--- a/src/tests/stacking/closed-transient-no-input-parent.metatest |
1356 | ++++ b/src/tests/stacking/closed-transient-no-input-parent.metatest |
1357 | +@@ -1,3 +1,7 @@ |
1358 | ++new_client 2 x11 |
1359 | ++create 2/1 |
1360 | ++show 2/1 |
1361 | ++ |
1362 | + new_client 1 x11 |
1363 | + create 1/1 |
1364 | + show 1/1 |
1365 | +@@ -12,9 +16,15 @@ set_parent 1/3 2 |
1366 | + show 1/3 |
1367 | + |
1368 | + wait |
1369 | +-assert_stacking 1/1 1/2 1/3 |
1370 | ++assert_focused 1/3 |
1371 | ++assert_stacking 2/1 1/1 1/2 1/3 |
1372 | + |
1373 | + destroy 1/3 |
1374 | ++dispatch |
1375 | + |
1376 | +-wait |
1377 | +-assert_stacking 1/1 1/2 |
1378 | ++assert_focused none |
1379 | ++assert_stacking 2/1 1/1 1/2 |
1380 | ++ |
1381 | ++sleep 250 |
1382 | ++assert_focused 1/1 |
1383 | ++assert_stacking 2/1 1/1 1/2 |
1384 | +diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c |
1385 | +index e1c3441..29ea3a6 100644 |
1386 | +--- a/src/x11/window-x11.c |
1387 | ++++ b/src/x11/window-x11.c |
1388 | +@@ -53,6 +53,8 @@ |
1389 | + #include "backends/meta-logical-monitor.h" |
1390 | + #include "backends/x11/meta-backend-x11.h" |
1391 | + |
1392 | ++#define TAKE_FOCUS_FALLBACK_DELAY_MS 250 |
1393 | ++ |
1394 | + G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW) |
1395 | + |
1396 | + static void |
1397 | +@@ -722,6 +724,66 @@ request_take_focus (MetaWindow *window, |
1398 | + send_icccm_message (window, display->atom_WM_TAKE_FOCUS, timestamp); |
1399 | + } |
1400 | + |
1401 | ++typedef struct |
1402 | ++{ |
1403 | ++ MetaWindow *window; |
1404 | ++ guint32 timestamp; |
1405 | ++ guint timeout_id; |
1406 | ++ gulong unmanaged_id; |
1407 | ++ gulong focused_changed_id; |
1408 | ++} MetaWindowX11DelayedFocusData; |
1409 | ++ |
1410 | ++static void |
1411 | ++meta_window_x11_delayed_focus_data_free (MetaWindowX11DelayedFocusData *data) |
1412 | ++{ |
1413 | ++ g_signal_handler_disconnect (data->window, data->unmanaged_id); |
1414 | ++ g_signal_handler_disconnect (data->window->display, data->focused_changed_id); |
1415 | ++ |
1416 | ++ if (data->timeout_id) |
1417 | ++ g_source_remove (data->timeout_id); |
1418 | ++ |
1419 | ++ g_free (data); |
1420 | ++} |
1421 | ++ |
1422 | ++static gboolean |
1423 | ++focus_window_delayed_timeout (gpointer user_data) |
1424 | ++{ |
1425 | ++ MetaWindowX11DelayedFocusData *data = user_data; |
1426 | ++ MetaWindow *window = data->window; |
1427 | ++ guint32 timestamp = data->timestamp; |
1428 | ++ |
1429 | ++ data->timeout_id = 0; |
1430 | ++ meta_window_x11_delayed_focus_data_free (data); |
1431 | ++ |
1432 | ++ meta_window_focus (window, timestamp); |
1433 | ++ |
1434 | ++ return G_SOURCE_REMOVE; |
1435 | ++} |
1436 | ++ |
1437 | ++static void |
1438 | ++meta_window_x11_maybe_focus_delayed (MetaWindow *window, |
1439 | ++ guint32 timestamp) |
1440 | ++{ |
1441 | ++ MetaWindowX11DelayedFocusData *data; |
1442 | ++ |
1443 | ++ data = g_new0 (MetaWindowX11DelayedFocusData, 1); |
1444 | ++ data->window = window; |
1445 | ++ data->timestamp = timestamp; |
1446 | ++ |
1447 | ++ data->unmanaged_id = |
1448 | ++ g_signal_connect_swapped (window, "unmanaged", |
1449 | ++ G_CALLBACK (meta_window_x11_delayed_focus_data_free), |
1450 | ++ data); |
1451 | ++ |
1452 | ++ data->focused_changed_id = |
1453 | ++ g_signal_connect_swapped (window->display, "notify::focus-window", |
1454 | ++ G_CALLBACK (meta_window_x11_delayed_focus_data_free), |
1455 | ++ data); |
1456 | ++ |
1457 | ++ data->timeout_id = g_timeout_add (TAKE_FOCUS_FALLBACK_DELAY_MS, |
1458 | ++ focus_window_delayed_timeout, data); |
1459 | ++} |
1460 | ++ |
1461 | + static void |
1462 | + meta_window_x11_focus (MetaWindow *window, |
1463 | + guint32 timestamp) |
1464 | +@@ -771,14 +833,43 @@ meta_window_x11_focus (MetaWindow *window, |
1465 | + * Normally, we want to just leave the focus undisturbed until |
1466 | + * the window responds to WM_TAKE_FOCUS, but if we're unmanaging |
1467 | + * the current focus window we *need* to move the focus away, so |
1468 | +- * we focus the no_focus_window now (and set |
1469 | +- * display->focus_window to that) before sending WM_TAKE_FOCUS. |
1470 | ++ * we focus the no focus window before sending WM_TAKE_FOCUS, |
1471 | ++ * and eventually the default focus windwo excluding this one, |
1472 | ++ * if meanwhile we don't get any focus request. |
1473 | + */ |
1474 | + if (window->display->focus_window != NULL && |
1475 | + window->display->focus_window->unmanaging) |
1476 | +- meta_display_focus_the_no_focus_window (window->display, |
1477 | +- window->screen, |
1478 | +- timestamp); |
1479 | ++ { |
1480 | ++ MetaWindow *focus_window = window; |
1481 | ++ MetaWorkspace *workspace = window->workspace; |
1482 | ++ MetaStack *stack = window->screen->stack; |
1483 | ++ |
1484 | ++ while (TRUE) |
1485 | ++ { |
1486 | ++ focus_window = meta_stack_get_default_focus_window (stack, |
1487 | ++ workspace, |
1488 | ++ focus_window); |
1489 | ++ if (!focus_window) |
1490 | ++ break; |
1491 | ++ |
1492 | ++ if (focus_window->unmanaging) |
1493 | ++ continue; |
1494 | ++ |
1495 | ++ if (focus_window->input) |
1496 | ++ break; |
1497 | ++ |
1498 | ++ if (focus_window->shaded && focus_window->frame) |
1499 | ++ break; |
1500 | ++ } |
1501 | ++ |
1502 | ++ meta_display_focus_the_no_focus_window (window->display, |
1503 | ++ window->screen, |
1504 | ++ timestamp); |
1505 | ++ |
1506 | ++ if (focus_window) |
1507 | ++ meta_window_x11_maybe_focus_delayed (focus_window, |
1508 | ++ timestamp); |
1509 | ++ } |
1510 | + } |
1511 | + |
1512 | + request_take_focus (window, timestamp); |
1513 | diff --git a/debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch b/debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch |
1514 | new file mode 100644 |
1515 | index 0000000..a29f61e |
1516 | --- /dev/null |
1517 | +++ b/debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch |
1518 | @@ -0,0 +1,339 @@ |
1519 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1520 | +Date: Wed, 3 Jul 2019 12:04:08 +0200 |
1521 | +Subject: window-x11: Use any focusable window as fallback delayed focus |
1522 | + window |
1523 | + |
1524 | +As per commit f71151a5 we focus an input window if no take-focus-window accepts |
1525 | +it. This might lead to an infinite loop if there are various focusable but |
1526 | +non-input windows in the stack. |
1527 | + |
1528 | +When the current focus window is unmanaging and we're trying to focus a |
1529 | +WM_TAKE_FOCUS window, we intent to give the focus to the first focusable input |
1530 | +window in the stack. |
1531 | + |
1532 | +However, if an application (such as the Java ones) only uses non-input |
1533 | +WM_TAKE_FOCUS windows, are not requesting these ones to get the focus. This |
1534 | +might lead to a state where no window is focused, or a wrong one is. |
1535 | + |
1536 | +So, instead of only focus the first eventually input window available, try to |
1537 | +request to all the take-focus windows that are in the stack between the |
1538 | +destroyed one and the first input one to acquire the input focus. |
1539 | +Use a queue to keep track of those windows, that is passed around stealing |
1540 | +ownership, while we protect for unmanaged queued windows. |
1541 | + |
1542 | +Also, reduce the default timeout value, as the previous one might lead to an |
1543 | +excessive long wait. |
1544 | + |
1545 | +Added metatests verifying these situations. |
1546 | + |
1547 | +Closes: https://gitlab.gnome.org/GNOME/mutter/issues/660 |
1548 | +https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
1549 | + |
1550 | +(cherry picked from commit 6d8293a422b08af97d3da985d49448db32d59248) |
1551 | + |
1552 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669 |
1553 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
1554 | +Bug-Ubuntu: https://launchpad.net/bugs/1834583 |
1555 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
1556 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/660 |
1557 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
1558 | +Applied-Upstream: 3.28.5 |
1559 | +--- |
1560 | + src/Makefile-tests.am | 1 + |
1561 | + .../closed-transient-no-input-parent.metatest | 2 +- |
1562 | + ...parents-queued-default-focus-destroyed.metatest | 43 ++++++++ |
1563 | + .../closed-transient-no-input-parents.metatest | 6 +- |
1564 | + src/x11/window-x11.c | 120 ++++++++++++++++----- |
1565 | + 5 files changed, 144 insertions(+), 28 deletions(-) |
1566 | + create mode 100644 src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest |
1567 | + |
1568 | +diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am |
1569 | +index 21d0619..359f398 100644 |
1570 | +--- a/src/Makefile-tests.am |
1571 | ++++ b/src/Makefile-tests.am |
1572 | +@@ -20,6 +20,7 @@ dist_stacking_DATA = \ |
1573 | + tests/stacking/closed-transient-no-input-parent.metatest \ |
1574 | + tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest \ |
1575 | + tests/stacking/closed-transient-no-input-parents.metatest \ |
1576 | ++ tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest \ |
1577 | + tests/stacking/minimized.metatest \ |
1578 | + tests/stacking/mixed-windows.metatest \ |
1579 | + tests/stacking/set-parent.metatest \ |
1580 | +diff --git a/src/tests/stacking/closed-transient-no-input-parent.metatest b/src/tests/stacking/closed-transient-no-input-parent.metatest |
1581 | +index e0f1dc1..d0f3228 100644 |
1582 | +--- a/src/tests/stacking/closed-transient-no-input-parent.metatest |
1583 | ++++ b/src/tests/stacking/closed-transient-no-input-parent.metatest |
1584 | +@@ -25,6 +25,6 @@ dispatch |
1585 | + assert_focused none |
1586 | + assert_stacking 2/1 1/1 1/2 |
1587 | + |
1588 | +-sleep 250 |
1589 | ++sleep 150 |
1590 | + assert_focused 1/1 |
1591 | + assert_stacking 2/1 1/1 1/2 |
1592 | +diff --git a/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest b/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest |
1593 | +new file mode 100644 |
1594 | +index 0000000..49ecc51 |
1595 | +--- /dev/null |
1596 | ++++ b/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest |
1597 | +@@ -0,0 +1,43 @@ |
1598 | ++new_client 0 x11 |
1599 | ++create 0/1 |
1600 | ++show 0/1 |
1601 | ++ |
1602 | ++new_client 1 x11 |
1603 | ++create 1/1 |
1604 | ++show 1/1 |
1605 | ++ |
1606 | ++create 1/2 csd |
1607 | ++set_parent 1/2 1 |
1608 | ++accept_focus 1/2 false |
1609 | ++show 1/2 |
1610 | ++ |
1611 | ++create 1/3 csd |
1612 | ++set_parent 1/3 2 |
1613 | ++accept_focus 1/3 false |
1614 | ++show 1/3 |
1615 | ++ |
1616 | ++create 1/4 csd |
1617 | ++set_parent 1/4 3 |
1618 | ++accept_focus 1/4 false |
1619 | ++show 1/4 |
1620 | ++ |
1621 | ++create 1/5 csd |
1622 | ++set_parent 1/5 3 |
1623 | ++show 1/5 |
1624 | ++ |
1625 | ++wait |
1626 | ++assert_focused 1/5 |
1627 | ++assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5 |
1628 | ++ |
1629 | ++destroy 1/5 |
1630 | ++dispatch |
1631 | ++ |
1632 | ++assert_focused none |
1633 | ++assert_stacking 0/1 1/1 1/2 1/3 1/4 |
1634 | ++ |
1635 | ++destroy 1/2 |
1636 | ++dispatch |
1637 | ++ |
1638 | ++sleep 450 |
1639 | ++assert_focused 1/1 |
1640 | ++assert_stacking 0/1 1/1 1/3 1/4 |
1641 | +diff --git a/src/tests/stacking/closed-transient-no-input-parents.metatest b/src/tests/stacking/closed-transient-no-input-parents.metatest |
1642 | +index e3ec2e8..ee99841 100644 |
1643 | +--- a/src/tests/stacking/closed-transient-no-input-parents.metatest |
1644 | ++++ b/src/tests/stacking/closed-transient-no-input-parents.metatest |
1645 | +@@ -35,12 +35,12 @@ dispatch |
1646 | + assert_focused none |
1647 | + assert_stacking 0/1 1/1 1/2 1/3 1/4 |
1648 | + |
1649 | +-sleep 250 |
1650 | +-assert_focused none |
1651 | ++sleep 600 |
1652 | ++assert_focused 1/1 |
1653 | + assert_stacking 0/1 1/1 1/2 1/3 1/4 |
1654 | + |
1655 | + destroy 1/3 |
1656 | + wait |
1657 | + |
1658 | +-assert_focused none |
1659 | ++assert_focused 1/1 |
1660 | + assert_stacking 0/1 1/1 1/2 1/4 |
1661 | +diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c |
1662 | +index 7dff35e..60b121f 100644 |
1663 | +--- a/src/x11/window-x11.c |
1664 | ++++ b/src/x11/window-x11.c |
1665 | +@@ -53,10 +53,15 @@ |
1666 | + #include "backends/meta-logical-monitor.h" |
1667 | + #include "backends/x11/meta-backend-x11.h" |
1668 | + |
1669 | +-#define TAKE_FOCUS_FALLBACK_DELAY_MS 250 |
1670 | ++#define TAKE_FOCUS_FALLBACK_DELAY_MS 150 |
1671 | + |
1672 | + G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW) |
1673 | + |
1674 | ++static void |
1675 | ++meta_window_x11_maybe_focus_delayed (MetaWindow *window, |
1676 | ++ GQueue *other_focus_candidates, |
1677 | ++ guint32 timestamp); |
1678 | ++ |
1679 | + static void |
1680 | + meta_window_x11_init (MetaWindowX11 *window_x11) |
1681 | + { |
1682 | +@@ -727,24 +732,60 @@ request_take_focus (MetaWindow *window, |
1683 | + typedef struct |
1684 | + { |
1685 | + MetaWindow *window; |
1686 | ++ GQueue *pending_focus_candidates; |
1687 | + guint32 timestamp; |
1688 | + guint timeout_id; |
1689 | + gulong unmanaged_id; |
1690 | + gulong focused_changed_id; |
1691 | + } MetaWindowX11DelayedFocusData; |
1692 | + |
1693 | ++static void |
1694 | ++disconnect_pending_focus_window_signals (MetaWindow *window, |
1695 | ++ GQueue *focus_candidates) |
1696 | ++{ |
1697 | ++ g_signal_handlers_disconnect_by_func (window, g_queue_remove, |
1698 | ++ focus_candidates); |
1699 | ++} |
1700 | ++ |
1701 | + static void |
1702 | + meta_window_x11_delayed_focus_data_free (MetaWindowX11DelayedFocusData *data) |
1703 | + { |
1704 | + g_signal_handler_disconnect (data->window, data->unmanaged_id); |
1705 | + g_signal_handler_disconnect (data->window->display, data->focused_changed_id); |
1706 | + |
1707 | ++ if (data->pending_focus_candidates) |
1708 | ++ { |
1709 | ++ g_queue_foreach (data->pending_focus_candidates, |
1710 | ++ (GFunc) disconnect_pending_focus_window_signals, |
1711 | ++ data->pending_focus_candidates); |
1712 | ++ g_queue_free (data->pending_focus_candidates); |
1713 | ++ } |
1714 | ++ |
1715 | + if (data->timeout_id) |
1716 | + g_source_remove (data->timeout_id); |
1717 | + |
1718 | + g_free (data); |
1719 | + } |
1720 | + |
1721 | ++static void |
1722 | ++focus_candidates_maybe_take_and_focus_next (GQueue **focus_candidates_ptr, |
1723 | ++ guint32 timestamp) |
1724 | ++{ |
1725 | ++ MetaWindow *focus_window; |
1726 | ++ GQueue *focus_candidates; |
1727 | ++ |
1728 | ++ g_assert (*focus_candidates_ptr); |
1729 | ++ |
1730 | ++ if (g_queue_is_empty (*focus_candidates_ptr)) |
1731 | ++ return; |
1732 | ++ |
1733 | ++ focus_candidates = g_steal_pointer (focus_candidates_ptr); |
1734 | ++ focus_window = g_queue_pop_head (focus_candidates); |
1735 | ++ |
1736 | ++ disconnect_pending_focus_window_signals (focus_window, focus_candidates); |
1737 | ++ meta_window_x11_maybe_focus_delayed (focus_window, focus_candidates, timestamp); |
1738 | ++} |
1739 | ++ |
1740 | + static gboolean |
1741 | + focus_window_delayed_timeout (gpointer user_data) |
1742 | + { |
1743 | +@@ -752,6 +793,9 @@ focus_window_delayed_timeout (gpointer user_data) |
1744 | + MetaWindow *window = data->window; |
1745 | + guint32 timestamp = data->timestamp; |
1746 | + |
1747 | ++ focus_candidates_maybe_take_and_focus_next (&data->pending_focus_candidates, |
1748 | ++ timestamp); |
1749 | ++ |
1750 | + data->timeout_id = 0; |
1751 | + meta_window_x11_delayed_focus_data_free (data); |
1752 | + |
1753 | +@@ -762,6 +806,7 @@ focus_window_delayed_timeout (gpointer user_data) |
1754 | + |
1755 | + static void |
1756 | + meta_window_x11_maybe_focus_delayed (MetaWindow *window, |
1757 | ++ GQueue *other_focus_candidates, |
1758 | + guint32 timestamp) |
1759 | + { |
1760 | + MetaWindowX11DelayedFocusData *data; |
1761 | +@@ -769,6 +814,10 @@ meta_window_x11_maybe_focus_delayed (MetaWindow *window, |
1762 | + data = g_new0 (MetaWindowX11DelayedFocusData, 1); |
1763 | + data->window = window; |
1764 | + data->timestamp = timestamp; |
1765 | ++ data->pending_focus_candidates = other_focus_candidates; |
1766 | ++ |
1767 | ++ meta_topic (META_DEBUG_FOCUS, |
1768 | ++ "Requesting delayed focus to %s\n", window->desc); |
1769 | + |
1770 | + data->unmanaged_id = |
1771 | + g_signal_connect_swapped (window, "unmanaged", |
1772 | +@@ -784,6 +833,50 @@ meta_window_x11_maybe_focus_delayed (MetaWindow *window, |
1773 | + focus_window_delayed_timeout, data); |
1774 | + } |
1775 | + |
1776 | ++static void |
1777 | ++maybe_focus_default_window (MetaWorkspace *workspace, |
1778 | ++ MetaWindow *not_this_one, |
1779 | ++ guint32 timestamp) |
1780 | ++{ |
1781 | ++ MetaStack *stack = workspace->screen->stack; |
1782 | ++ g_autoptr (GList) focusable_windows = NULL; |
1783 | ++ g_autoptr (GQueue) focus_candidates = NULL; |
1784 | ++ GList *l; |
1785 | ++ |
1786 | ++ /* Go through all the focusable windows and try to focus them |
1787 | ++ * in order, waiting for a delay. The first one that replies to |
1788 | ++ * the request (in case of take focus windows) changing the display |
1789 | ++ * focused window, will stop the chained requests. |
1790 | ++ */ |
1791 | ++ focusable_windows = |
1792 | ++ meta_stack_get_default_focus_candidates (stack, workspace); |
1793 | ++ focus_candidates = g_queue_new (); |
1794 | ++ |
1795 | ++ for (l = g_list_last (focusable_windows); l; l = l->prev) |
1796 | ++ { |
1797 | ++ MetaWindow *focus_window = l->data; |
1798 | ++ |
1799 | ++ if (focus_window == not_this_one) |
1800 | ++ continue; |
1801 | ++ |
1802 | ++ g_queue_push_tail (focus_candidates, focus_window); |
1803 | ++ g_signal_connect_swapped (focus_window, "unmanaged", |
1804 | ++ G_CALLBACK (g_queue_remove), |
1805 | ++ focus_candidates); |
1806 | ++ |
1807 | ++ if (!META_IS_WINDOW_X11 (focus_window)) |
1808 | ++ break; |
1809 | ++ |
1810 | ++ if (focus_window->input) |
1811 | ++ break; |
1812 | ++ |
1813 | ++ if (focus_window->shaded && focus_window->frame) |
1814 | ++ break; |
1815 | ++ } |
1816 | ++ |
1817 | ++ focus_candidates_maybe_take_and_focus_next (&focus_candidates, timestamp); |
1818 | ++} |
1819 | ++ |
1820 | + static void |
1821 | + meta_window_x11_focus (MetaWindow *window, |
1822 | + guint32 timestamp) |
1823 | +@@ -840,32 +933,11 @@ meta_window_x11_focus (MetaWindow *window, |
1824 | + if (window->display->focus_window != NULL && |
1825 | + window->display->focus_window->unmanaging) |
1826 | + { |
1827 | +- MetaWindow *focus_window = window; |
1828 | +- MetaWorkspace *workspace = window->workspace; |
1829 | +- MetaStack *stack = window->screen->stack; |
1830 | +- |
1831 | +- while (TRUE) |
1832 | +- { |
1833 | +- focus_window = meta_stack_get_default_focus_window (stack, |
1834 | +- workspace, |
1835 | +- focus_window); |
1836 | +- if (!focus_window) |
1837 | +- break; |
1838 | +- |
1839 | +- if (focus_window->input || focus_window->take_focus) |
1840 | +- break; |
1841 | +- |
1842 | +- if (focus_window->shaded && focus_window->frame) |
1843 | +- break; |
1844 | +- } |
1845 | +- |
1846 | + meta_display_focus_the_no_focus_window (window->display, |
1847 | + window->screen, |
1848 | + timestamp); |
1849 | +- |
1850 | +- if (focus_window) |
1851 | +- meta_window_x11_maybe_focus_delayed (focus_window, |
1852 | +- timestamp); |
1853 | ++ maybe_focus_default_window (window->workspace, window, |
1854 | ++ timestamp); |
1855 | + } |
1856 | + } |
1857 | + |
1858 | diff --git a/debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch b/debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch |
1859 | new file mode 100644 |
1860 | index 0000000..53d4ff0 |
1861 | --- /dev/null |
1862 | +++ b/debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch |
1863 | @@ -0,0 +1,85 @@ |
1864 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1865 | +Date: Tue, 13 Nov 2018 08:31:52 +0100 |
1866 | +Subject: workspace: Focus only ancestors that are focusable |
1867 | + |
1868 | +When destroying a window that has a parent, we initially try to focus one of |
1869 | +its ancestors. However if no ancestor can be focused, then we should instead |
1870 | +focus the default focus window instead of trying to request focus for a window |
1871 | +that can't get focus anyways. |
1872 | + |
1873 | +Fixes https://gitlab.gnome.org/GNOME/mutter/issues/308 |
1874 | +(cherry picked from commit eccc791f3b3451216f957e67fec47a73b65ed2b2) |
1875 | + |
1876 | +Origin: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307 |
1877 | +Bug-Ubuntu: https://launchpad.net/bugs/1791574 |
1878 | +Bug-JetBrains: https://youtrack.jetbrains.com/issue/IDEA-198187 |
1879 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/issues/308 |
1880 | +Applied-Upstream: 3.28.5 |
1881 | +--- |
1882 | + src/core/workspace.c | 37 +++++++++++++++++++++++++++---------- |
1883 | + 1 file changed, 27 insertions(+), 10 deletions(-) |
1884 | + |
1885 | +diff --git a/src/core/workspace.c b/src/core/workspace.c |
1886 | +index a964e66..d194943 100644 |
1887 | +--- a/src/core/workspace.c |
1888 | ++++ b/src/core/workspace.c |
1889 | +@@ -85,6 +85,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData |
1890 | + MetaRectangle logical_monitor_work_area; |
1891 | + } MetaWorkspaceLogicalMonitorData; |
1892 | + |
1893 | ++typedef struct _MetaWorkspaceFocusableAncestorData |
1894 | ++{ |
1895 | ++ MetaWorkspace *workspace; |
1896 | ++ MetaWindow *out_window; |
1897 | ++} MetaWorkspaceFocusableAncestorData; |
1898 | ++ |
1899 | + static MetaWorkspaceLogicalMonitorData * |
1900 | + meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace, |
1901 | + MetaLogicalMonitor *logical_monitor) |
1902 | +@@ -1319,13 +1325,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, |
1903 | + } |
1904 | + |
1905 | + static gboolean |
1906 | +-record_ancestor (MetaWindow *window, |
1907 | +- void *data) |
1908 | ++find_focusable_ancestor (MetaWindow *window, |
1909 | ++ gpointer user_data) |
1910 | + { |
1911 | +- MetaWindow **result = data; |
1912 | ++ MetaWorkspaceFocusableAncestorData *data = user_data; |
1913 | ++ |
1914 | ++ if (!window->unmanaging && (window->input || window->take_focus) && |
1915 | ++ meta_window_located_on_workspace (window, data->workspace) && |
1916 | ++ meta_window_showing_on_its_workspace (window)) |
1917 | ++ { |
1918 | ++ data->out_window = window; |
1919 | ++ return FALSE; |
1920 | ++ } |
1921 | + |
1922 | +- *result = window; |
1923 | +- return FALSE; /* quit with the first ancestor we find */ |
1924 | ++ return TRUE; |
1925 | + } |
1926 | + |
1927 | + /* Focus ancestor of not_this_one if there is one */ |
1928 | +@@ -1347,11 +1360,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, |
1929 | + if (not_this_one) |
1930 | + { |
1931 | + MetaWindow *ancestor; |
1932 | +- ancestor = NULL; |
1933 | +- meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor); |
1934 | +- if (ancestor != NULL && |
1935 | +- meta_window_located_on_workspace (ancestor, workspace) && |
1936 | +- meta_window_showing_on_its_workspace (ancestor)) |
1937 | ++ MetaWorkspaceFocusableAncestorData data; |
1938 | ++ |
1939 | ++ data = (MetaWorkspaceFocusableAncestorData) { |
1940 | ++ .workspace = workspace, |
1941 | ++ }; |
1942 | ++ meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data); |
1943 | ++ ancestor = data.out_window; |
1944 | ++ |
1945 | ++ if (ancestor) |
1946 | + { |
1947 | + meta_topic (META_DEBUG_FOCUS, |
1948 | + "Focusing %s, ancestor of %s\n", |
Done, thanks! I think we should probably think about doing a snapshot next time, this is a lot of cherry-picks already.