Merge lp:~3v1n0/unity/switcher-noinputwin into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 3096
Proposed branch: lp:~3v1n0/unity/switcher-noinputwin
Merge into: lp:unity
Diff against target: 387 lines (+117/-59)
6 files modified
launcher/SwitcherController.cpp (+7/-17)
launcher/SwitcherControllerImpl.h (+0/-2)
launcher/SwitcherModel.cpp (+13/-20)
plugins/unityshell/src/unityshell.cpp (+88/-19)
plugins/unityshell/src/unityshell.h (+5/-1)
unity-shared/WindowManager.h (+4/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/switcher-noinputwin
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+146031@code.launchpad.net

Commit message

SwitcherController: use again the SwitcherView as non-input window

Otherwise it could only lead to focusing troubles.
Added utilities to manage the WindowManager default close-window keybinding and using
it in our views.

Description of the change

SwitcherWindow has been made an input window some time ago to fix bug #926406. Also if that's a good workaround, it is not the best approach because it makes the WindowManager to be distracted by the switcher window as well (that should only be an overlay) moving the focus to it. This also needed a workaround to fix #1071298.

So, I disabled again the input window (we'll still be able to handle mouse events in future if needed, thanks to the grab), and to fix for good the Alt+F4 bug (lp:926406) I added few utility functions that saves into a property in WindowManager the default keybinding that should be used to close a view that now is finally dynamic.

Using it to close the Switcher (instead of the window below) and updated the code for HUD and Dash overlays.

Ap test updated. Other changes are covered by existing tests.

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Yay, im happy you fixed this problem I introduced. Everything still work, and code looks good.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Approved!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/SwitcherController.cpp'
2--- launcher/SwitcherController.cpp 2013-01-25 19:09:28 +0000
3+++ launcher/SwitcherController.cpp 2013-02-01 03:24:22 +0000
4@@ -250,7 +250,7 @@
5
6 void Controller::Impl::Show(ShowMode show, SortMode sort, std::vector<AbstractLauncherIcon::Ptr> results)
7 {
8- if (results.empty())
9+ if (results.empty() || obj_->visible_)
10 return;
11
12 if (sort == SortMode::FOCUS_ORDER)
13@@ -258,18 +258,13 @@
14 std::sort(results.begin(), results.end(), CompareSwitcherItemsPriority);
15 }
16
17- model_.reset(new SwitcherModel(results));
18+ model_ = std::make_shared<SwitcherModel>(results);
19 obj_->AddChild(model_.get());
20 model_->selection_changed.connect(sigc::mem_fun(this, &Controller::Impl::OnModelSelectionChanged));
21 model_->only_detail_on_viewport = (show == ShowMode::CURRENT_VIEWPORT);
22
23 SelectFirstItem();
24
25- // XXX: Workaround for a problem related to Alt+TAB which is needed since the
26- // switcher is set as the active window (LP: #1071298)
27- if (model_->Selection()->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))
28- last_active_selection_ = model_->Selection();
29-
30 obj_->visible_ = true;
31
32 if (timeout_length > 0)
33@@ -339,8 +334,6 @@
34 view_window_->ShowWindow(true);
35 view_window_->PushToFront();
36 view_window_->SetOpacity(1.0f);
37- view_window_->EnableInputWindow(true, "Switcher", true /* take focus */, false);
38- view_window_->SetInputFocus();
39 view_window_->CaptureMouseDownAnyWhereElse(true);
40 }
41 }
42@@ -359,8 +352,6 @@
43 view_window_->SetLayout(main_layout_);
44 view_window_->SetBackgroundColor(nux::Color(0x00000000));
45 view_window_->SetGeometry(workarea_);
46- view_window_->EnableInputWindow(true, "Switcher", false, false);
47- view_window_->InputWindowEnableStruts(false);
48 }
49 }
50
51@@ -416,13 +407,10 @@
52 view_window_->SetOpacity(0.0f);
53 view_window_->ShowWindow(false);
54 view_window_->PushToBack();
55- view_window_->EnableInputWindow(false);
56 }
57
58 ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new("(bi)", false, obj_->monitor_));
59
60- last_active_selection_ = nullptr;
61-
62 view_.Release();
63 }
64
65@@ -563,11 +551,13 @@
66 {
67 if (model_->detail_selection)
68 {
69- window = model_->DetailSelectionWindow();
70+ window = model_->DetailSelectionWindow();
71 }
72- else if (application == last_active_selection_ && !model_->DetailXids().empty())
73+ else if (application->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))
74 {
75- window = model_->DetailXids()[0];
76+ auto const& xids = model_->DetailXids();
77+ if (!xids.empty())
78+ window = xids.front();
79 }
80 }
81 }
82
83=== modified file 'launcher/SwitcherControllerImpl.h'
84--- launcher/SwitcherControllerImpl.h 2013-01-25 19:09:28 +0000
85+++ launcher/SwitcherControllerImpl.h 2013-02-01 03:24:22 +0000
86@@ -92,8 +92,6 @@
87 nux::HLayout* main_layout_;
88 nux::Color bg_color_;
89
90- launcher::AbstractLauncherIcon::Ptr last_active_selection_;
91-
92 UBusManager ubus_manager_;
93 glib::SourceManager sources_;
94 };
95
96=== modified file 'launcher/SwitcherModel.cpp'
97--- launcher/SwitcherModel.cpp 2012-12-18 00:09:23 +0000
98+++ launcher/SwitcherModel.cpp 2013-02-01 03:24:22 +0000
99@@ -32,15 +32,14 @@
100
101
102 SwitcherModel::SwitcherModel(std::vector<AbstractLauncherIcon::Ptr> const& icons)
103- : applications_(icons)
104+ : detail_selection(false)
105+ , detail_selection_index(0)
106+ , only_detail_on_viewport(false)
107+ , applications_(icons)
108 , index_(0)
109 , last_index_(0)
110 {
111- detail_selection = false;
112- detail_selection_index = 0;
113- only_detail_on_viewport = false;
114-
115- for (auto application : applications_)
116+ for (auto const& application : applications_)
117 {
118 AddChild(application.GetPointer());
119 if (application->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))
120@@ -136,31 +135,25 @@
121
122 std::vector<Window> SwitcherModel::DetailXids()
123 {
124+ WindowManager& wm = WindowManager::Default();
125 std::vector<Window> results;
126+
127 for (auto& window : Selection()->Windows())
128 {
129- results.push_back(window->window_id());
130- }
131+ Window xid = window->window_id();
132
133- WindowManager& wm = WindowManager::Default();
134- if (only_detail_on_viewport)
135- {
136- results.erase(std::remove_if(results.begin(), results.end(),
137- [&wm](Window xid) { return !wm.IsWindowOnCurrentDesktop(xid); }),
138- results.end());
139+ if (!only_detail_on_viewport || wm.IsWindowOnCurrentDesktop(xid))
140+ results.push_back(xid);
141 }
142
143 std::sort(results.begin(), results.end(), [&wm](Window first, Window second) {
144 return wm.GetWindowActiveNumber(first) > wm.GetWindowActiveNumber(second);
145 });
146
147-
148- if (Selection() == last_active_application_ && results.size () > 1)
149+ if (Selection() == last_active_application_ && results.size() > 1)
150 {
151- for (unsigned int i = 0; i < results.size()-1; i++)
152- {
153- std::swap (results[i], results[i+1]);
154- }
155+ results.push_back(results.front());
156+ results.erase(results.begin());
157 }
158
159 return results;
160
161=== modified file 'plugins/unityshell/src/unityshell.cpp'
162--- plugins/unityshell/src/unityshell.cpp 2013-01-30 02:11:19 +0000
163+++ plugins/unityshell/src/unityshell.cpp 2013-02-01 03:24:22 +0000
164@@ -877,7 +877,7 @@
165 {
166 /* Create a new keybinding for the Escape key and the current modifiers,
167 * compiz will take of the ref-counting of the repeated actions */
168- KeyCode escape = XKeysymToKeycode(screen->dpy(), XStringToKeysym("Escape"));
169+ KeyCode escape = XKeysymToKeycode(screen->dpy(), XK_Escape);
170 CompAction::KeyBinding binding(escape, modifiers);
171
172 CompActionPtr &escape_action = _escape_actions[target];
173@@ -1623,6 +1623,16 @@
174 break;
175 }
176 }
177+ else if (switcher_controller_->Visible())
178+ {
179+ auto const& close_key = wm.close_window_key();
180+
181+ if (key_sym == close_key.second && XModifiersToNux(event->xkey.state) == close_key.first)
182+ {
183+ switcher_controller_->Hide(false);
184+ skip_other_plugins = true;
185+ }
186+ }
187
188 if (result > 0)
189 {
190@@ -1693,10 +1703,9 @@
191 }
192
193 if (!skip_other_plugins &&
194- screen->otherGrabExist("deco", "move", "switcher", "resize", NULL) &&
195- !switcher_controller_->Visible())
196+ screen->otherGrabExist("deco", "move", "switcher", "resize", "unity-switcher", nullptr))
197 {
198- wt->ProcessForeignEvent(event, NULL);
199+ wt->ProcessForeignEvent(event, nullptr);
200 }
201 }
202
203@@ -2135,37 +2144,28 @@
204
205 void UnityScreen::OnLauncherEndKeyNav(GVariant* data)
206 {
207- RestoreWindow(data);
208+ // Return input-focus to previously focused window (before key-nav-mode was
209+ // entered)
210+ if (data && g_variant_get_boolean(data))
211+ PluginAdapter::Default().RestoreInputFocus();
212 }
213
214 void UnityScreen::OnSwitcherStart(GVariant* data)
215 {
216 if (switcher_controller_->Visible())
217 {
218- SaveInputThenFocus(switcher_controller_->GetSwitcherInputWindowId());
219 UnityWindow::SetupSharedTextures();
220 }
221 }
222
223 void UnityScreen::OnSwitcherEnd(GVariant* data)
224 {
225- RestoreWindow(data);
226 UnityWindow::CleanupSharedTextures();
227
228 for (UnityWindow* uwin : fake_decorated_windows_)
229 uwin->CleanupCachedTextures();
230 }
231
232-void UnityScreen::RestoreWindow(GVariant* data)
233-{
234- bool preserve_focus = data ? g_variant_get_boolean(data) : false;
235-
236- // Return input-focus to previously focused window (before key-nav-mode was
237- // entered)
238- if (preserve_focus)
239- PluginAdapter::Default().RestoreInputFocus();
240-}
241-
242 bool UnityScreen::SaveInputThenFocus(const guint xid)
243 {
244 // get CompWindow*
245@@ -2270,10 +2270,74 @@
246 return ShowHud();
247 }
248
249+unsigned UnityScreen::CompizModifiersToNux(unsigned input) const
250+{
251+ unsigned modifiers = 0;
252+
253+ if (input & CompAltMask)
254+ {
255+ input &= ~CompAltMask;
256+ input |= Mod1Mask;
257+ }
258+
259+ if (modifiers & CompSuperMask)
260+ {
261+ input &= ~CompSuperMask;
262+ input |= Mod4Mask;
263+ }
264+
265+ return XModifiersToNux(input);
266+}
267+
268+unsigned UnityScreen::XModifiersToNux(unsigned input) const
269+{
270+ unsigned modifiers = 0;
271+
272+ if (input & Mod1Mask)
273+ modifiers |= nux::KEY_MODIFIER_ALT;
274+
275+ if (input & ShiftMask)
276+ modifiers |= nux::KEY_MODIFIER_SHIFT;
277+
278+ if (input & ControlMask)
279+ modifiers |= nux::KEY_MODIFIER_CTRL;
280+
281+ if (input & Mod4Mask)
282+ modifiers |= nux::KEY_MODIFIER_SUPER;
283+
284+ return modifiers;
285+}
286+
287+void UnityScreen::UpdateCloseWindowKey(CompAction::KeyBinding const& keybind)
288+{
289+ KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
290+ unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
291+
292+ WindowManager::Default().close_window_key = std::make_pair(modifiers, keysym);
293+}
294+
295 bool UnityScreen::initPluginActions()
296 {
297- CompPlugin* p = CompPlugin::find("expo");
298 PluginAdapter& adapter = PluginAdapter::Default();
299+
300+ CompPlugin* p = CompPlugin::find("core");
301+
302+ if (p)
303+ {
304+ MultiActionList expoActions;
305+
306+ for (CompOption& option : p->vTable->getOptions())
307+ {
308+ if (option.name() == "close_window_key")
309+ {
310+ UpdateCloseWindowKey(option.value().action().key());
311+ break;
312+ }
313+ }
314+ }
315+
316+ p = CompPlugin::find("expo");
317+
318 if (p)
319 {
320 MultiActionList expoActions;
321@@ -2477,7 +2541,8 @@
322 }
323 }
324
325- if (WindowManager::Default().IsScaleActive() && ScaleScreen::get(screen)->getSelectedWindow() == window->id())
326+ if (WindowManager::Default().IsScaleActive() &&
327+ ScaleScreen::get(screen)->getSelectedWindow() == window->id())
328 {
329 nux::Geometry const& scaled_geo = GetScaledGeometry();
330 paintInnerGlow(scaled_geo, matrix, attrib, mask);
331@@ -3081,6 +3146,10 @@
332 WindowManager& wm = WindowManager::Default();
333 wm.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height());
334 }
335+ else if (strcmp(name, "close_window_key") == 0)
336+ {
337+ UpdateCloseWindowKey(v.action().key());
338+ }
339 }
340 }
341 return status;
342
343=== modified file 'plugins/unityshell/src/unityshell.h'
344--- plugins/unityshell/src/unityshell.h 2013-01-22 20:15:54 +0000
345+++ plugins/unityshell/src/unityshell.h 2013-02-01 03:24:22 +0000
346@@ -236,7 +236,6 @@
347 void OnInitiateSpread();
348 void OnTerminateSpread();
349
350- void RestoreWindow(GVariant* data);
351 bool SaveInputThenFocus(const guint xid);
352
353 void OnPanelStyleChanged();
354@@ -247,6 +246,11 @@
355 bool TopPanelBackgroundTextureNeedsUpdate() const;
356 void UpdateTopPanelBackgroundTexture();
357
358+ unsigned CompizModifiersToNux(unsigned input) const;
359+ unsigned XModifiersToNux(unsigned input) const;
360+
361+ void UpdateCloseWindowKey(CompAction::KeyBinding const&);
362+
363 std::unique_ptr<na::TickSource> tick_source_;
364 std::unique_ptr<na::AnimationController> animation_controller_;
365
366
367=== modified file 'unity-shared/WindowManager.h'
368--- unity-shared/WindowManager.h 2012-12-03 15:34:23 +0000
369+++ unity-shared/WindowManager.h 2013-02-01 03:24:22 +0000
370@@ -26,6 +26,7 @@
371
372 // To bring in nux::Geometry we first need the Rect header, then Utils.
373 #include <NuxCore/Rect.h>
374+#include <NuxCore/Property.h>
375 #include <Nux/Utils.h>
376
377 #ifdef USE_X11
378@@ -150,6 +151,9 @@
379
380 virtual std::string GetWindowName(Window window_id) const = 0;
381
382+ // Nux Modifiers, Nux Keycode (= X11 KeySym)
383+ nux::Property<std::pair<unsigned, unsigned>> close_window_key;
384+
385 // Signals
386 sigc::signal<void, Window> window_mapped;
387 sigc::signal<void, Window> window_unmapped;