Merge lp:~3v1n0/unity/overlays-grabs-handling into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 3798
Proposed branch: lp:~3v1n0/unity/overlays-grabs-handling
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/lockscreen-keys-disable
Diff against target: 332 lines (+81/-54)
6 files modified
dash/DashController.cpp (+30/-25)
dash/DashController.h (+3/-5)
dash/DashView.cpp (+2/-2)
launcher/LauncherController.cpp (+0/-12)
plugins/unityshell/src/unityshell.cpp (+45/-10)
plugins/unityshell/src/unityshell.h (+1/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/overlays-grabs-handling
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Brandon Schaefer (community) Approve
Review via email: mp+217630@code.launchpad.net

This proposal supersedes a proposal from 2014-04-25.

Commit message

UnityScreen: don't try to show Dash/Hud if the screen is grabbed

Also move the dash opening out from LauncherController, and get rid of UBus
as first initialization source, as it can only slow things down here.

Description of the change

Try to get the grab to double-check if something is already grabbing the keyboard (we could also check for pointer grabs, but here I don't see it much needed).

Although this is a round-trip request to the X server from my measurements it seems to take less than 1ms, and thus it seems acceptable.

Now we only try to show our overlays if there are no grabs around, and if there are we give 2 seconds for an ungrab-event to arrive (since we might need to wait a scale animation or a key-ungrab to happen), before giving up for good.

Also, in case we are unable to show them, we pass the key press trough.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal

Whats the best way to test this outside of a WM/Cirtrix?

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal

Code wise, looks fine, just want to test :)

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal

For anyone wanting to test this change, i've uploaded to a ppa:
https://code.launchpad.net/~brandontschaefer/+archive/unity-testing

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

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dash/DashController.cpp'
2--- dash/DashController.cpp 2014-03-21 05:23:42 +0000
3+++ dash/DashController.cpp 2014-05-02 15:06:05 +0000
4@@ -66,7 +66,6 @@
5 , create_window_(create_window)
6 , monitor_(0)
7 , visible_(false)
8- , need_show_(false)
9 , dbus_server_(dbus::BUS_NAME)
10 , ensure_timeout_(PRELOAD_TIMEOUT_LENGTH)
11 , timeline_animator_(90)
12@@ -262,20 +261,14 @@
13 HideDash();
14 }
15
16-void Controller::OnScreenUngrabbed()
17+void Controller::OnExternalShowDash(GVariant* variant)
18 {
19- LOG_DEBUG(logger) << "On Screen Ungrabbed called";
20- if (need_show_)
21- {
22- EnsureDash();
23+ EnsureDash();
24+
25+ if (!visible_)
26 ShowDash();
27- }
28-}
29-
30-void Controller::OnExternalShowDash(GVariant* variant)
31-{
32- EnsureDash();
33- visible_ ? HideDash() : ShowDash();
34+ else
35+ HideDash();
36 }
37
38 void Controller::OnExternalHideDash(GVariant* variant)
39@@ -283,31 +276,44 @@
40 HideDash();
41 }
42
43-void Controller::ShowDash()
44+bool Controller::ShowDash()
45 {
46- EnsureDash();
47+ // Don't want to show at the wrong time
48+ if (visible_)
49+ return false;
50+
51 WindowManager& wm = WindowManager::Default();
52- // Don't want to show at the wrong time
53- if (visible_ || wm.IsExpoActive() || wm.IsScaleActive())
54- return;
55+
56+ if (wm.IsExpoActive())
57+ wm.TerminateExpo();
58
59 // We often need to wait for the mouse/keyboard to be available while a plugin
60 // is finishing it's animations/cleaning up. In these cases, we patiently wait
61 // for the screen to be available again before honouring the request.
62 if (wm.IsScreenGrabbed())
63 {
64- screen_ungrabbed_slot_ = wm.screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed));
65- need_show_ = true;
66- return;
67+ screen_ungrabbed_slot_ = wm.screen_ungrabbed.connect([this] {
68+ grab_wait_.reset();
69+ ShowDash();
70+ });
71+
72+ // Let's wait ungrab event for maximum a couple of seconds...
73+ grab_wait_.reset(new glib::TimeoutSeconds(2, [this] {
74+ screen_ungrabbed_slot_->disconnect();
75+ return false;
76+ }));
77+
78+ return false;
79 }
80
81+ EnsureDash();
82 monitor_ = GetIdealMonitor();
83+ screen_ungrabbed_slot_->disconnect();
84 int launcher_width = unity::Settings::Instance().LauncherWidth(monitor_);
85 view_->SetMonitorOffset(launcher_width, panel::Style::Instance().PanelHeight(monitor_));
86 view_->AboutToShow(monitor_);
87 FocusWindow();
88
89- need_show_ = false;
90 visible_ = true;
91
92 StartShowHideTimeline();
93@@ -316,6 +322,7 @@
94
95 GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_, view_content_geo.width, view_content_geo.height);
96 ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info);
97+ return true;
98 }
99
100 void Controller::FocusWindow()
101@@ -347,8 +354,6 @@
102 if (!visible_)
103 return;
104
105- screen_ungrabbed_slot_->disconnect();
106-
107 EnsureDash();
108
109 view_->AboutToHide();
110@@ -394,7 +399,7 @@
111 view_->OnActivateRequest(variant);
112 }
113
114-gboolean Controller::CheckShortcutActivation(const char* key_string)
115+bool Controller::CheckShortcutActivation(const char* key_string)
116 {
117 if (!key_string)
118 return false;
119
120=== modified file 'dash/DashController.h'
121--- dash/DashController.h 2014-03-21 05:23:42 +0000
122+++ dash/DashController.h 2014-05-02 15:06:05 +0000
123@@ -51,7 +51,7 @@
124
125 nux::BaseWindow* window() const;
126
127- gboolean CheckShortcutActivation(const char* key_string);
128+ bool CheckShortcutActivation(const char* key_string);
129 std::vector<char> GetAllShortcuts();
130
131 nux::Property<bool> use_primary;
132@@ -60,7 +60,7 @@
133
134 void HideDash();
135 void QuicklyHideDash();
136- void ShowDash();
137+ bool ShowDash();
138
139 void ReFocusKeyInput();
140
141@@ -86,7 +86,6 @@
142 void Relayout(bool check_monitor =false);
143
144 void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);
145- void OnScreenUngrabbed();
146 void OnExternalShowDash(GVariant* variant);
147 void OnExternalHideDash(GVariant* variant);
148 void OnActivateRequest(GVariant* variant);
149@@ -103,14 +102,13 @@
150 nux::ObjectPtr<ResizingBaseWindow> window_;
151 nux::ObjectPtr<DashView> view_;
152 int monitor_;
153-
154 bool visible_;
155- bool need_show_;
156
157 connection::Wrapper screen_ungrabbed_slot_;
158 connection::Wrapper form_factor_changed_;
159 glib::DBusServer dbus_server_;
160 glib::TimeoutSeconds ensure_timeout_;
161+ glib::Source::UniquePtr grab_wait_;
162 nux::animation::AnimateValue<double> timeline_animator_;
163 UBusManager ubus_manager_;
164 };
165
166=== modified file 'dash/DashView.cpp'
167--- dash/DashView.cpp 2014-03-21 23:08:47 +0000
168+++ dash/DashView.cpp 2014-05-02 15:06:05 +0000
169@@ -1457,8 +1457,8 @@
170 {
171 for (Scope::Ptr scope: scopes_->GetScopes())
172 {
173- std::string shortcut = scope->shortcut;
174- if(shortcut.size() > 0)
175+ std::string const& shortcut = scope->shortcut;
176+ if (!shortcut.empty())
177 result.push_back(shortcut.at(0));
178 }
179 }
180
181=== modified file 'launcher/LauncherController.cpp'
182--- launcher/LauncherController.cpp 2014-03-20 00:11:08 +0000
183+++ launcher/LauncherController.cpp 2014-05-02 15:06:05 +0000
184@@ -1199,18 +1199,6 @@
185 void Controller::HandleLauncherKeyRelease(bool was_tap, int when)
186 {
187 int tap_duration = when - pimpl->launcher_key_press_time_;
188- WindowManager& wm = WindowManager::Default();
189-
190- if (tap_duration < options()->super_tap_duration && was_tap &&
191- !wm.IsTopWindowFullscreenOnMonitorWithMouse())
192- {
193- LOG_DEBUG(logger) << "Quick tap, sending activation request.";
194- pimpl->SendHomeActivationRequest();
195- }
196- else
197- {
198- LOG_DEBUG(logger) << "Tap too long: " << tap_duration;
199- }
200
201 pimpl->sources_.Remove(local::LABELS_TIMEOUT);
202 pimpl->sources_.Remove(local::KEYPRESS_TIMEOUT);
203
204=== modified file 'plugins/unityshell/src/unityshell.cpp'
205--- plugins/unityshell/src/unityshell.cpp 2014-04-30 04:29:00 +0000
206+++ plugins/unityshell/src/unityshell.cpp 2014-05-02 15:06:05 +0000
207@@ -143,6 +143,7 @@
208 const RawPixel SCALE_PADDING = 40_em;
209 const RawPixel SCALE_SPACING = 20_em;
210 const std::string RELAYOUT_TIMEOUT = "relayout-timeout";
211+const std::string HUD_UNGRAB_WAIT = "hud-ungrab-wait";
212 const std::string FIRST_RUN_STAMP = "first_run.stamp";
213 const std::string LOCKED_STAMP = "locked.stamp";
214 } // namespace local
215@@ -1703,6 +1704,8 @@
216 wm.OnScreenGrabbed();
217 else if (event->xfocus.mode == NotifyUngrab)
218 wm.OnScreenUngrabbed();
219+ else if (!screen->grabbed() && event->xfocus.mode == NotifyWhileGrabbed)
220+ wm.OnScreenGrabbed();
221
222 if (_key_nav_mode_requested)
223 {
224@@ -2062,6 +2065,7 @@
225 return false;
226
227 bool was_tap = state & CompAction::StateTermTapped;
228+ bool tap_handled = false;
229 LOG_DEBUG(logger) << "Super released: " << (was_tap ? "tapped" : "released");
230 int when = options[7].value().i(); // XEvent time in millisec
231
232@@ -2090,6 +2094,24 @@
233 {
234 QuicklistManager::Default()->Current()->Hide();
235 }
236+
237+ if (!dash_controller_->IsVisible())
238+ {
239+ if (!adapter.IsTopWindowFullscreenOnMonitorWithMouse())
240+ {
241+ if (dash_controller_->ShowDash())
242+ {
243+ tap_handled = true;
244+ ubus_manager_.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
245+ g_variant_new("(sus)", "home.scope", dash::GOTO_DASH_URI, ""));
246+ }
247+ }
248+ }
249+ else
250+ {
251+ dash_controller_->HideDash();
252+ tap_handled = true;
253+ }
254 }
255
256 super_keypressed_ = false;
257@@ -2103,7 +2125,7 @@
258 EnableCancelAction(CancelActionTarget::SHORTCUT_HINT, false);
259
260 action->setState (action->state() & (unsigned)~(CompAction::StateTermKey));
261- return true;
262+ return (was_tap && tap_handled) || !was_tap;
263 }
264
265 bool UnityScreen::showPanelFirstMenuKeyInitiate(CompAction* action,
266@@ -2471,32 +2493,45 @@
267 {
268 if (switcher_controller_->Visible())
269 {
270- LOG_ERROR(logger) << "this should never happen";
271+ LOG_ERROR(logger) << "Switcher is visible when showing HUD: this should never happen";
272 return false; // early exit if the switcher is open
273 }
274
275- if (PluginAdapter::Default().IsTopWindowFullscreenOnMonitorWithMouse())
276- {
277- return false;
278- }
279-
280 if (hud_controller_->IsVisible())
281 {
282- ubus_manager_.SendMessage(UBUS_HUD_CLOSE_REQUEST);
283+ hud_controller_->HideHud();
284 }
285 else
286 {
287+ auto& wm = WindowManager::Default();
288+
289+ if (wm.IsTopWindowFullscreenOnMonitorWithMouse())
290+ return false;
291+
292+ if (wm.IsScreenGrabbed())
293+ {
294+ hud_ungrab_slot_ = wm.screen_ungrabbed.connect([this] { ShowHud(); });
295+
296+ // Let's wait ungrab event for maximum a couple of seconds...
297+ sources_.AddTimeoutSeconds(2, [this] {
298+ hud_ungrab_slot_->disconnect();
299+ return false;
300+ }, local::HUD_UNGRAB_WAIT);
301+
302+ return false;
303+ }
304+
305 // Handles closing KeyNav (Alt+F1) if the hud is about to show
306 if (launcher_controller_->KeyNavIsActive())
307 launcher_controller_->KeyNavTerminate(false);
308
309- // If an overlay is open, it must be the dash! Close it!
310- if (launcher_controller_->IsOverlayOpen())
311+ if (dash_controller_->IsVisible())
312 dash_controller_->HideDash();
313
314 if (QuicklistManager::Default()->Current())
315 QuicklistManager::Default()->Current()->Hide();
316
317+ hud_ungrab_slot_->disconnect();
318 hud_controller_->ShowHud();
319 }
320
321
322=== modified file 'plugins/unityshell/src/unityshell.h'
323--- plugins/unityshell/src/unityshell.h 2014-04-29 00:22:03 +0000
324+++ plugins/unityshell/src/unityshell.h 2014-05-02 15:06:05 +0000
325@@ -421,6 +421,7 @@
326
327 UBusManager ubus_manager_;
328 glib::SourceManager sources_;
329+ connection::Wrapper hud_ungrab_slot_;
330
331 CompRegion buffered_compiz_damage_this_frame_;
332 CompRegion buffered_compiz_damage_last_frame_;