Merge lp:~alan-griffiths/miral/fix-focus-when-active-window-closes into lp:miral

Proposed by Alan Griffiths
Status: Merged
Merged at revision: 155
Proposed branch: lp:~alan-griffiths/miral/fix-focus-when-active-window-closes
Merge into: lp:miral
Diff against target: 364 lines (+82/-123)
8 files modified
include/miral/window_management_policy.h (+2/-0)
miral-kiosk/kiosk_window_manager.cpp (+1/-36)
miral-kiosk/kiosk_window_manager.h (+2/-1)
miral-shell/canonical_window_manager.cpp (+14/-45)
miral-shell/canonical_window_manager.h (+2/-1)
miral-shell/tiling_window_manager.cpp (+1/-36)
miral-shell/tiling_window_manager.h (+2/-1)
miral/basic_window_manager.cpp (+58/-3)
To merge this branch: bzr merge lp:~alan-griffiths/miral/fix-focus-when-active-window-closes
Reviewer Review Type Date Requested Status
Cemil Azizoglu (community) Approve
Review via email: mp+292160@code.launchpad.net

Commit message

Fix focus loss when the active window closes

Description of the change

Fix focus loss when the active window closes

Easiest example:

$ miral-shell --startup gnome-mahjongg

Show the "About" window and close it. Expect focus to return to the main window - and now it does.

To post a comment you must log in.
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

LGTM

review: Approve
155. By Alan Griffiths

Hoist common code from XXX::handle_delete_window() to calling context in BasicWindowManager::remove_surface()

156. By Alan Griffiths

Make selecting an active window part of the interface

157. By Alan Griffiths

Put refocus-on-close logic into BasicWindowManager::remove_surface()

158. By Alan Griffiths

Make clang happy

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/miral/window_management_policy.h'
2--- include/miral/window_management_policy.h 2016-04-14 13:55:48 +0000
3+++ include/miral/window_management_policy.h 2016-04-19 16:34:41 +0000
4@@ -46,6 +46,8 @@
5 virtual bool handle_pointer_event(MirPointerEvent const* event) = 0;
6 virtual void handle_raise_window(WindowInfo& window_info) = 0;
7
8+ virtual auto select_active_window(miral::Window const& hint) -> miral::Window = 0;
9+
10 virtual ~WindowManagementPolicy() = default;
11 WindowManagementPolicy() = default;
12 WindowManagementPolicy(WindowManagementPolicy const&) = delete;
13
14=== modified file 'miral-kiosk/kiosk_window_manager.cpp'
15--- miral-kiosk/kiosk_window_manager.cpp 2016-04-15 09:39:08 +0000
16+++ miral-kiosk/kiosk_window_manager.cpp 2016-04-19 16:34:41 +0000
17@@ -137,43 +137,8 @@
18 window_info.window.rename(modifications.name.value());
19 }
20
21-void KioskWindowManagerPolicy::handle_delete_window(WindowInfo& window_info)
22+void KioskWindowManagerPolicy::handle_delete_window(WindowInfo& /*window_info*/)
23 {
24- auto const session = window_info.window.session();
25- auto const& window = window_info.window;
26-
27- if (auto const parent = window_info.parent)
28- {
29- auto& siblings = tools->info_for(parent).children;
30-
31- for (auto i = begin(siblings); i != end(siblings); ++i)
32- {
33- if (window == *i)
34- {
35- siblings.erase(i);
36- break;
37- }
38- }
39- }
40-
41- auto& windows = tools->info_for(session).windows;
42-
43- for (auto i = begin(windows); i != end(windows); ++i)
44- {
45- if (window == *i)
46- {
47- windows.erase(i);
48- break;
49- }
50- }
51-
52- window_info.window.destroy_surface();
53-
54- if (windows.empty() && session == tools->focused_application())
55- {
56- tools->focus_next_application();
57- select_active_window(tools->focused_window());
58- }
59 }
60
61 auto KioskWindowManagerPolicy::handle_set_state(WindowInfo& window_info, MirSurfaceState value)
62
63=== modified file 'miral-kiosk/kiosk_window_manager.h'
64--- miral-kiosk/kiosk_window_manager.h 2016-04-15 09:39:08 +0000
65+++ miral-kiosk/kiosk_window_manager.h 2016-04-19 16:34:41 +0000
66@@ -59,6 +59,8 @@
67
68 void generate_decorations_for(miral::WindowInfo& window_info) override;
69
70+ auto select_active_window(miral::Window const& window) -> miral::Window override;
71+
72 private:
73 static const int modifier_mask =
74 mir_input_event_modifier_alt |
75@@ -67,7 +69,6 @@
76 mir_input_event_modifier_ctrl |
77 mir_input_event_modifier_meta;
78
79- auto select_active_window(miral::Window const& window) -> miral::Window;
80 auto transform_set_state(miral::WindowInfo& window_info, MirSurfaceState value) -> MirSurfaceState;
81 void raise_splash_session() const;
82
83
84=== modified file 'miral-shell/canonical_window_manager.cpp'
85--- miral-shell/canonical_window_manager.cpp 2016-04-15 10:20:08 +0000
86+++ miral-shell/canonical_window_manager.cpp 2016-04-19 16:34:41 +0000
87@@ -381,24 +381,7 @@
88
89 void CanonicalWindowManagerPolicy::handle_delete_window(WindowInfo& window_info)
90 {
91- auto const& session = window_info.window.session();
92- auto& window = window_info.window;
93-
94- fullscreen_surfaces.erase(window);
95-
96- if (auto const parent = window_info.parent)
97- {
98- auto& siblings = tools->info_for(parent).children;
99-
100- for (auto i = begin(siblings); i != end(siblings); ++i)
101- {
102- if (window == *i)
103- {
104- siblings.erase(i);
105- break;
106- }
107- }
108- }
109+ fullscreen_surfaces.erase(window_info.window);
110
111 if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata))
112 {
113@@ -406,25 +389,7 @@
114 tools->forget(titlebar->window);
115 }
116
117- auto& windows = tools->info_for(session).windows;
118-
119- for (auto i = begin(windows); i != end(windows); ++i)
120- {
121- if (window == *i)
122- {
123- windows.erase(i);
124- break;
125- }
126- }
127-
128- window.destroy_surface();
129-
130- if (windows.empty() && session == tools->focused_application())
131- {
132- active_window_.reset();
133- tools->focus_next_application();
134- select_active_window(tools->focused_window());
135- }
136+ active_window_.reset();
137 }
138
139 auto CanonicalWindowManagerPolicy::handle_set_state(WindowInfo& window_info, MirSurfaceState value)
140@@ -756,12 +721,12 @@
141 }
142 }
143
144-void CanonicalWindowManagerPolicy::select_active_window(Window const& window)
145+auto CanonicalWindowManagerPolicy::select_active_window(Window const& hint) -> miral::Window
146 {
147- if (window == active_window_)
148- return;
149+ if (hint == active_window_)
150+ return hint ;
151
152- if (!window)
153+ if (!hint)
154 {
155 if (auto const active_surface = active_window_)
156 {
157@@ -776,10 +741,10 @@
158 tools->set_focus_to({});
159
160 active_window_.reset();
161- return;
162+ return hint;
163 }
164
165- auto const& info_for = tools->info_for(window);
166+ auto const& info_for = tools->info_for(hint);
167
168 if (info_for.can_be_active())
169 {
170@@ -791,7 +756,7 @@
171 titlebar->paint_titlebar(0x3F);
172 }
173 }
174- auto& info = tools->info_for(window);
175+ auto& info = tools->info_for(hint);
176 if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(info.userdata))
177 {
178 titlebar->paint_titlebar(0xFF);
179@@ -808,13 +773,17 @@
180 if (spinner_info.windows.size() > 0)
181 tools->raise_tree(spinner_info.windows[0]);
182 }
183+
184+ return hint;
185 }
186 else
187 {
188 // Cannot have input focus - try the parent
189 if (auto const parent = info_for.parent)
190- select_active_window(parent);
191+ return select_active_window(parent);
192 }
193+
194+ return {};
195 }
196
197 auto CanonicalWindowManagerPolicy::active_window() const
198
199=== modified file 'miral-shell/canonical_window_manager.h'
200--- miral-shell/canonical_window_manager.h 2016-04-15 10:20:08 +0000
201+++ miral-shell/canonical_window_manager.h 2016-04-19 16:34:41 +0000
202@@ -75,6 +75,8 @@
203
204 void generate_decorations_for(miral::WindowInfo& window_info) override;
205
206+ auto select_active_window(miral::Window const& hint) -> miral::Window override;
207+
208 private:
209 static const int modifier_mask =
210 mir_input_event_modifier_alt |
211@@ -88,7 +90,6 @@
212 void resize(Point cursor);
213 void toggle(MirSurfaceState state);
214
215- void select_active_window(miral::Window const& window);
216 auto active_window() const -> miral::Window;
217
218 bool resize(miral::Window const& window, Point cursor, Point old_cursor);
219
220=== modified file 'miral-shell/tiling_window_manager.cpp'
221--- miral-shell/tiling_window_manager.cpp 2016-04-14 14:37:35 +0000
222+++ miral-shell/tiling_window_manager.cpp 2016-04-19 16:34:41 +0000
223@@ -177,43 +177,8 @@
224 window_info.window.rename(modifications.name.value());
225 }
226
227-void TilingWindowManagerPolicy::handle_delete_window(WindowInfo& window_info)
228+void TilingWindowManagerPolicy::handle_delete_window(WindowInfo& /*window_info*/)
229 {
230- auto const session = window_info.window.session();
231- auto const& window = window_info.window;
232-
233- if (auto const parent = window_info.parent)
234- {
235- auto& siblings = tools->info_for(parent).children;
236-
237- for (auto i = begin(siblings); i != end(siblings); ++i)
238- {
239- if (window == *i)
240- {
241- siblings.erase(i);
242- break;
243- }
244- }
245- }
246-
247- auto& windows = tools->info_for(session).windows;
248-
249- for (auto i = begin(windows); i != end(windows); ++i)
250- {
251- if (window == *i)
252- {
253- windows.erase(i);
254- break;
255- }
256- }
257-
258- window_info.window.destroy_surface();
259-
260- if (windows.empty() && session == tools->focused_application())
261- {
262- tools->focus_next_application();
263- select_active_window(tools->focused_window());
264- }
265 }
266
267 auto TilingWindowManagerPolicy::handle_set_state(WindowInfo& window_info, MirSurfaceState value)
268
269=== modified file 'miral-shell/tiling_window_manager.h'
270--- miral-shell/tiling_window_manager.h 2016-04-14 14:16:54 +0000
271+++ miral-shell/tiling_window_manager.h 2016-04-19 16:34:41 +0000
272@@ -67,6 +67,8 @@
273
274 void generate_decorations_for(miral::WindowInfo& window_info) override;
275
276+ auto select_active_window(miral::Window const& window) -> miral::Window override;
277+
278 private:
279 static const int modifier_mask =
280 mir_input_event_modifier_alt |
281@@ -85,7 +87,6 @@
282 void update_tiles(Rectangles const& displays);
283 void update_surfaces(miral::ApplicationInfo& info, Rectangle const& old_tile, Rectangle const& new_tile);
284 void drag(miral::WindowInfo& window_info, Point to, Point from, Rectangle bounds);
285- auto select_active_window(miral::Window const& window) -> miral::Window;
286 auto transform_set_state(miral::WindowInfo& window_info, MirSurfaceState value) -> MirSurfaceState;
287
288 static void clip_to_tile(mir::scene::SurfaceCreationParameters& parameters, Rectangle const& tile);
289
290=== modified file 'miral/basic_window_manager.cpp'
291--- miral/basic_window_manager.cpp 2016-04-15 09:11:31 +0000
292+++ miral/basic_window_manager.cpp 2016-04-19 16:34:41 +0000
293@@ -103,13 +103,68 @@
294 }
295
296 void miral::BasicWindowManager::remove_surface(
297- std::shared_ptr<scene::Session> const& /*session*/,
298+ std::shared_ptr<scene::Session> const& session,
299 std::weak_ptr<scene::Surface> const& surface)
300 {
301 std::lock_guard<decltype(mutex)> lock(mutex);
302- policy->handle_delete_window(info_for(surface));
303-
304+ bool const is_active_window{surface.lock() == focus_controller->focused_surface()};
305+
306+ auto& info = info_for(surface);
307+
308+ if (auto const parent = info.parent)
309+ {
310+ auto& siblings = info_for(parent).children;
311+
312+ for (auto i = begin(siblings); i != end(siblings); ++i)
313+ {
314+ if (info.window == *i)
315+ {
316+ siblings.erase(i);
317+ break;
318+ }
319+ }
320+ }
321+
322+ auto& windows = info_for(session).windows;
323+
324+ for (auto i = begin(windows); i != end(windows); ++i)
325+ {
326+ if (info.window == *i)
327+ {
328+ windows.erase(i);
329+ break;
330+ }
331+ }
332+
333+ policy->handle_delete_window(info);
334+
335+ session->destroy_surface(surface);
336+
337+ auto const parent = info.parent;
338+
339+ // NB this invalidates info, but we want to keep access to "parent".
340 window_info.erase(surface);
341+
342+ if (is_active_window)
343+ {
344+ // Try to make the parent active
345+ if (parent)
346+ {
347+ if (policy->select_active_window(parent))
348+ return;
349+ }
350+
351+ // Ought to find top window of same application, but we don't
352+ // have the API (yet), so find any suitable top-level-window
353+ for (auto const& tlw : windows)
354+ {
355+ if (policy->select_active_window(tlw))
356+ return;
357+ }
358+
359+ focus_next_application();
360+ policy->select_active_window(focused_window());
361+ }
362 }
363
364 void miral::BasicWindowManager::forget(Window const& window)

Subscribers

People subscribed via source and target branches