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
=== modified file 'launcher/SwitcherController.cpp'
--- launcher/SwitcherController.cpp 2013-01-25 19:09:28 +0000
+++ launcher/SwitcherController.cpp 2013-02-01 03:24:22 +0000
@@ -250,7 +250,7 @@
250250
251void Controller::Impl::Show(ShowMode show, SortMode sort, std::vector<AbstractLauncherIcon::Ptr> results)251void Controller::Impl::Show(ShowMode show, SortMode sort, std::vector<AbstractLauncherIcon::Ptr> results)
252{252{
253 if (results.empty())253 if (results.empty() || obj_->visible_)
254 return;254 return;
255255
256 if (sort == SortMode::FOCUS_ORDER)256 if (sort == SortMode::FOCUS_ORDER)
@@ -258,18 +258,13 @@
258 std::sort(results.begin(), results.end(), CompareSwitcherItemsPriority);258 std::sort(results.begin(), results.end(), CompareSwitcherItemsPriority);
259 }259 }
260260
261 model_.reset(new SwitcherModel(results));261 model_ = std::make_shared<SwitcherModel>(results);
262 obj_->AddChild(model_.get());262 obj_->AddChild(model_.get());
263 model_->selection_changed.connect(sigc::mem_fun(this, &Controller::Impl::OnModelSelectionChanged));263 model_->selection_changed.connect(sigc::mem_fun(this, &Controller::Impl::OnModelSelectionChanged));
264 model_->only_detail_on_viewport = (show == ShowMode::CURRENT_VIEWPORT);264 model_->only_detail_on_viewport = (show == ShowMode::CURRENT_VIEWPORT);
265265
266 SelectFirstItem();266 SelectFirstItem();
267267
268 // XXX: Workaround for a problem related to Alt+TAB which is needed since the
269 // switcher is set as the active window (LP: #1071298)
270 if (model_->Selection()->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))
271 last_active_selection_ = model_->Selection();
272
273 obj_->visible_ = true;268 obj_->visible_ = true;
274269
275 if (timeout_length > 0)270 if (timeout_length > 0)
@@ -339,8 +334,6 @@
339 view_window_->ShowWindow(true);334 view_window_->ShowWindow(true);
340 view_window_->PushToFront();335 view_window_->PushToFront();
341 view_window_->SetOpacity(1.0f);336 view_window_->SetOpacity(1.0f);
342 view_window_->EnableInputWindow(true, "Switcher", true /* take focus */, false);
343 view_window_->SetInputFocus();
344 view_window_->CaptureMouseDownAnyWhereElse(true);337 view_window_->CaptureMouseDownAnyWhereElse(true);
345 }338 }
346}339}
@@ -359,8 +352,6 @@
359 view_window_->SetLayout(main_layout_);352 view_window_->SetLayout(main_layout_);
360 view_window_->SetBackgroundColor(nux::Color(0x00000000));353 view_window_->SetBackgroundColor(nux::Color(0x00000000));
361 view_window_->SetGeometry(workarea_);354 view_window_->SetGeometry(workarea_);
362 view_window_->EnableInputWindow(true, "Switcher", false, false);
363 view_window_->InputWindowEnableStruts(false);
364 }355 }
365}356}
366357
@@ -416,13 +407,10 @@
416 view_window_->SetOpacity(0.0f);407 view_window_->SetOpacity(0.0f);
417 view_window_->ShowWindow(false);408 view_window_->ShowWindow(false);
418 view_window_->PushToBack();409 view_window_->PushToBack();
419 view_window_->EnableInputWindow(false);
420 }410 }
421411
422 ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new("(bi)", false, obj_->monitor_));412 ubus_manager_.SendMessage(UBUS_SWITCHER_SHOWN, g_variant_new("(bi)", false, obj_->monitor_));
423413
424 last_active_selection_ = nullptr;
425
426 view_.Release();414 view_.Release();
427}415}
428416
@@ -563,11 +551,13 @@
563 {551 {
564 if (model_->detail_selection)552 if (model_->detail_selection)
565 {553 {
566 window = model_->DetailSelectionWindow();554 window = model_->DetailSelectionWindow();
567 }555 }
568 else if (application == last_active_selection_ && !model_->DetailXids().empty())556 else if (application->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))
569 {557 {
570 window = model_->DetailXids()[0];558 auto const& xids = model_->DetailXids();
559 if (!xids.empty())
560 window = xids.front();
571 }561 }
572 }562 }
573 }563 }
574564
=== modified file 'launcher/SwitcherControllerImpl.h'
--- launcher/SwitcherControllerImpl.h 2013-01-25 19:09:28 +0000
+++ launcher/SwitcherControllerImpl.h 2013-02-01 03:24:22 +0000
@@ -92,8 +92,6 @@
92 nux::HLayout* main_layout_;92 nux::HLayout* main_layout_;
93 nux::Color bg_color_;93 nux::Color bg_color_;
9494
95 launcher::AbstractLauncherIcon::Ptr last_active_selection_;
96
97 UBusManager ubus_manager_;95 UBusManager ubus_manager_;
98 glib::SourceManager sources_;96 glib::SourceManager sources_;
99};97};
10098
=== modified file 'launcher/SwitcherModel.cpp'
--- launcher/SwitcherModel.cpp 2012-12-18 00:09:23 +0000
+++ launcher/SwitcherModel.cpp 2013-02-01 03:24:22 +0000
@@ -32,15 +32,14 @@
3232
3333
34SwitcherModel::SwitcherModel(std::vector<AbstractLauncherIcon::Ptr> const& icons)34SwitcherModel::SwitcherModel(std::vector<AbstractLauncherIcon::Ptr> const& icons)
35 : applications_(icons)35 : detail_selection(false)
36 , detail_selection_index(0)
37 , only_detail_on_viewport(false)
38 , applications_(icons)
36 , index_(0)39 , index_(0)
37 , last_index_(0)40 , last_index_(0)
38{41{
39 detail_selection = false;42 for (auto const& application : applications_)
40 detail_selection_index = 0;
41 only_detail_on_viewport = false;
42
43 for (auto application : applications_)
44 {43 {
45 AddChild(application.GetPointer());44 AddChild(application.GetPointer());
46 if (application->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))45 if (application->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))
@@ -136,31 +135,25 @@
136135
137std::vector<Window> SwitcherModel::DetailXids()136std::vector<Window> SwitcherModel::DetailXids()
138{137{
138 WindowManager& wm = WindowManager::Default();
139 std::vector<Window> results;139 std::vector<Window> results;
140
140 for (auto& window : Selection()->Windows())141 for (auto& window : Selection()->Windows())
141 {142 {
142 results.push_back(window->window_id());143 Window xid = window->window_id();
143 }
144144
145 WindowManager& wm = WindowManager::Default();145 if (!only_detail_on_viewport || wm.IsWindowOnCurrentDesktop(xid))
146 if (only_detail_on_viewport)146 results.push_back(xid);
147 {
148 results.erase(std::remove_if(results.begin(), results.end(),
149 [&wm](Window xid) { return !wm.IsWindowOnCurrentDesktop(xid); }),
150 results.end());
151 }147 }
152148
153 std::sort(results.begin(), results.end(), [&wm](Window first, Window second) {149 std::sort(results.begin(), results.end(), [&wm](Window first, Window second) {
154 return wm.GetWindowActiveNumber(first) > wm.GetWindowActiveNumber(second);150 return wm.GetWindowActiveNumber(first) > wm.GetWindowActiveNumber(second);
155 });151 });
156152
157153 if (Selection() == last_active_application_ && results.size() > 1)
158 if (Selection() == last_active_application_ && results.size () > 1)
159 {154 {
160 for (unsigned int i = 0; i < results.size()-1; i++)155 results.push_back(results.front());
161 {156 results.erase(results.begin());
162 std::swap (results[i], results[i+1]);
163 }
164 }157 }
165158
166 return results;159 return results;
167160
=== modified file 'plugins/unityshell/src/unityshell.cpp'
--- plugins/unityshell/src/unityshell.cpp 2013-01-30 02:11:19 +0000
+++ plugins/unityshell/src/unityshell.cpp 2013-02-01 03:24:22 +0000
@@ -877,7 +877,7 @@
877 {877 {
878 /* Create a new keybinding for the Escape key and the current modifiers,878 /* Create a new keybinding for the Escape key and the current modifiers,
879 * compiz will take of the ref-counting of the repeated actions */879 * compiz will take of the ref-counting of the repeated actions */
880 KeyCode escape = XKeysymToKeycode(screen->dpy(), XStringToKeysym("Escape"));880 KeyCode escape = XKeysymToKeycode(screen->dpy(), XK_Escape);
881 CompAction::KeyBinding binding(escape, modifiers);881 CompAction::KeyBinding binding(escape, modifiers);
882882
883 CompActionPtr &escape_action = _escape_actions[target];883 CompActionPtr &escape_action = _escape_actions[target];
@@ -1623,6 +1623,16 @@
1623 break;1623 break;
1624 }1624 }
1625 }1625 }
1626 else if (switcher_controller_->Visible())
1627 {
1628 auto const& close_key = wm.close_window_key();
1629
1630 if (key_sym == close_key.second && XModifiersToNux(event->xkey.state) == close_key.first)
1631 {
1632 switcher_controller_->Hide(false);
1633 skip_other_plugins = true;
1634 }
1635 }
16261636
1627 if (result > 0)1637 if (result > 0)
1628 {1638 {
@@ -1693,10 +1703,9 @@
1693 }1703 }
16941704
1695 if (!skip_other_plugins &&1705 if (!skip_other_plugins &&
1696 screen->otherGrabExist("deco", "move", "switcher", "resize", NULL) &&1706 screen->otherGrabExist("deco", "move", "switcher", "resize", "unity-switcher", nullptr))
1697 !switcher_controller_->Visible())
1698 {1707 {
1699 wt->ProcessForeignEvent(event, NULL);1708 wt->ProcessForeignEvent(event, nullptr);
1700 }1709 }
1701}1710}
17021711
@@ -2135,37 +2144,28 @@
21352144
2136void UnityScreen::OnLauncherEndKeyNav(GVariant* data)2145void UnityScreen::OnLauncherEndKeyNav(GVariant* data)
2137{2146{
2138 RestoreWindow(data);2147 // Return input-focus to previously focused window (before key-nav-mode was
2148 // entered)
2149 if (data && g_variant_get_boolean(data))
2150 PluginAdapter::Default().RestoreInputFocus();
2139}2151}
21402152
2141void UnityScreen::OnSwitcherStart(GVariant* data)2153void UnityScreen::OnSwitcherStart(GVariant* data)
2142{2154{
2143 if (switcher_controller_->Visible())2155 if (switcher_controller_->Visible())
2144 {2156 {
2145 SaveInputThenFocus(switcher_controller_->GetSwitcherInputWindowId());
2146 UnityWindow::SetupSharedTextures();2157 UnityWindow::SetupSharedTextures();
2147 }2158 }
2148}2159}
21492160
2150void UnityScreen::OnSwitcherEnd(GVariant* data)2161void UnityScreen::OnSwitcherEnd(GVariant* data)
2151{2162{
2152 RestoreWindow(data);
2153 UnityWindow::CleanupSharedTextures();2163 UnityWindow::CleanupSharedTextures();
21542164
2155 for (UnityWindow* uwin : fake_decorated_windows_)2165 for (UnityWindow* uwin : fake_decorated_windows_)
2156 uwin->CleanupCachedTextures();2166 uwin->CleanupCachedTextures();
2157}2167}
21582168
2159void UnityScreen::RestoreWindow(GVariant* data)
2160{
2161 bool preserve_focus = data ? g_variant_get_boolean(data) : false;
2162
2163 // Return input-focus to previously focused window (before key-nav-mode was
2164 // entered)
2165 if (preserve_focus)
2166 PluginAdapter::Default().RestoreInputFocus();
2167}
2168
2169bool UnityScreen::SaveInputThenFocus(const guint xid)2169bool UnityScreen::SaveInputThenFocus(const guint xid)
2170{2170{
2171 // get CompWindow*2171 // get CompWindow*
@@ -2270,10 +2270,74 @@
2270 return ShowHud();2270 return ShowHud();
2271}2271}
22722272
2273unsigned UnityScreen::CompizModifiersToNux(unsigned input) const
2274{
2275 unsigned modifiers = 0;
2276
2277 if (input & CompAltMask)
2278 {
2279 input &= ~CompAltMask;
2280 input |= Mod1Mask;
2281 }
2282
2283 if (modifiers & CompSuperMask)
2284 {
2285 input &= ~CompSuperMask;
2286 input |= Mod4Mask;
2287 }
2288
2289 return XModifiersToNux(input);
2290}
2291
2292unsigned UnityScreen::XModifiersToNux(unsigned input) const
2293{
2294 unsigned modifiers = 0;
2295
2296 if (input & Mod1Mask)
2297 modifiers |= nux::KEY_MODIFIER_ALT;
2298
2299 if (input & ShiftMask)
2300 modifiers |= nux::KEY_MODIFIER_SHIFT;
2301
2302 if (input & ControlMask)
2303 modifiers |= nux::KEY_MODIFIER_CTRL;
2304
2305 if (input & Mod4Mask)
2306 modifiers |= nux::KEY_MODIFIER_SUPER;
2307
2308 return modifiers;
2309}
2310
2311void UnityScreen::UpdateCloseWindowKey(CompAction::KeyBinding const& keybind)
2312{
2313 KeySym keysym = XkbKeycodeToKeysym(screen->dpy(), keybind.keycode(), 0, 0);
2314 unsigned modifiers = CompizModifiersToNux(keybind.modifiers());
2315
2316 WindowManager::Default().close_window_key = std::make_pair(modifiers, keysym);
2317}
2318
2273bool UnityScreen::initPluginActions()2319bool UnityScreen::initPluginActions()
2274{2320{
2275 CompPlugin* p = CompPlugin::find("expo");
2276 PluginAdapter& adapter = PluginAdapter::Default();2321 PluginAdapter& adapter = PluginAdapter::Default();
2322
2323 CompPlugin* p = CompPlugin::find("core");
2324
2325 if (p)
2326 {
2327 MultiActionList expoActions;
2328
2329 for (CompOption& option : p->vTable->getOptions())
2330 {
2331 if (option.name() == "close_window_key")
2332 {
2333 UpdateCloseWindowKey(option.value().action().key());
2334 break;
2335 }
2336 }
2337 }
2338
2339 p = CompPlugin::find("expo");
2340
2277 if (p)2341 if (p)
2278 {2342 {
2279 MultiActionList expoActions;2343 MultiActionList expoActions;
@@ -2477,7 +2541,8 @@
2477 }2541 }
2478 }2542 }
24792543
2480 if (WindowManager::Default().IsScaleActive() && ScaleScreen::get(screen)->getSelectedWindow() == window->id())2544 if (WindowManager::Default().IsScaleActive() &&
2545 ScaleScreen::get(screen)->getSelectedWindow() == window->id())
2481 {2546 {
2482 nux::Geometry const& scaled_geo = GetScaledGeometry();2547 nux::Geometry const& scaled_geo = GetScaledGeometry();
2483 paintInnerGlow(scaled_geo, matrix, attrib, mask);2548 paintInnerGlow(scaled_geo, matrix, attrib, mask);
@@ -3081,6 +3146,10 @@
3081 WindowManager& wm = WindowManager::Default();3146 WindowManager& wm = WindowManager::Default();
3082 wm.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height());3147 wm.viewport_layout_changed.emit(screen->vpSize().width(), screen->vpSize().height());
3083 }3148 }
3149 else if (strcmp(name, "close_window_key") == 0)
3150 {
3151 UpdateCloseWindowKey(v.action().key());
3152 }
3084 }3153 }
3085 }3154 }
3086 return status;3155 return status;
30873156
=== modified file 'plugins/unityshell/src/unityshell.h'
--- plugins/unityshell/src/unityshell.h 2013-01-22 20:15:54 +0000
+++ plugins/unityshell/src/unityshell.h 2013-02-01 03:24:22 +0000
@@ -236,7 +236,6 @@
236 void OnInitiateSpread();236 void OnInitiateSpread();
237 void OnTerminateSpread();237 void OnTerminateSpread();
238238
239 void RestoreWindow(GVariant* data);
240 bool SaveInputThenFocus(const guint xid);239 bool SaveInputThenFocus(const guint xid);
241240
242 void OnPanelStyleChanged();241 void OnPanelStyleChanged();
@@ -247,6 +246,11 @@
247 bool TopPanelBackgroundTextureNeedsUpdate() const;246 bool TopPanelBackgroundTextureNeedsUpdate() const;
248 void UpdateTopPanelBackgroundTexture();247 void UpdateTopPanelBackgroundTexture();
249248
249 unsigned CompizModifiersToNux(unsigned input) const;
250 unsigned XModifiersToNux(unsigned input) const;
251
252 void UpdateCloseWindowKey(CompAction::KeyBinding const&);
253
250 std::unique_ptr<na::TickSource> tick_source_;254 std::unique_ptr<na::TickSource> tick_source_;
251 std::unique_ptr<na::AnimationController> animation_controller_;255 std::unique_ptr<na::AnimationController> animation_controller_;
252256
253257
=== modified file 'unity-shared/WindowManager.h'
--- unity-shared/WindowManager.h 2012-12-03 15:34:23 +0000
+++ unity-shared/WindowManager.h 2013-02-01 03:24:22 +0000
@@ -26,6 +26,7 @@
2626
27// To bring in nux::Geometry we first need the Rect header, then Utils.27// To bring in nux::Geometry we first need the Rect header, then Utils.
28#include <NuxCore/Rect.h>28#include <NuxCore/Rect.h>
29#include <NuxCore/Property.h>
29#include <Nux/Utils.h>30#include <Nux/Utils.h>
3031
31#ifdef USE_X1132#ifdef USE_X11
@@ -150,6 +151,9 @@
150151
151 virtual std::string GetWindowName(Window window_id) const = 0;152 virtual std::string GetWindowName(Window window_id) const = 0;
152153
154 // Nux Modifiers, Nux Keycode (= X11 KeySym)
155 nux::Property<std::pair<unsigned, unsigned>> close_window_key;
156
153 // Signals157 // Signals
154 sigc::signal<void, Window> window_mapped;158 sigc::signal<void, Window> window_mapped;
155 sigc::signal<void, Window> window_unmapped;159 sigc::signal<void, Window> window_unmapped;