Merge lp:~3v1n0/unity/shield-notify-grabs into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Andrea Azzarone
Approved revision: no longer in the source branch.
Merged at revision: 3878
Proposed branch: lp:~3v1n0/unity/shield-notify-grabs
Merge into: lp:unity
Diff against target: 417 lines (+117/-19)
15 files modified
UnityCore/DBusIndicators.cpp (+11/-0)
UnityCore/DBusIndicators.h (+1/-0)
UnityCore/Indicators.h (+1/-0)
lockscreen/LockScreenAbstractShield.h (+3/-0)
lockscreen/LockScreenController.cpp (+33/-11)
lockscreen/LockScreenController.h (+2/-2)
lockscreen/LockScreenPanel.cpp (+28/-1)
lockscreen/LockScreenShield.cpp (+9/-5)
lockscreen/LockScreenShield.h (+1/-0)
plugins/unityshell/src/unityshell.cpp (+1/-0)
services/panel-main.c (+8/-0)
services/panel-service.c (+15/-0)
services/panel-service.h (+2/-0)
tests/mock_indicators.h (+1/-0)
tests/test_lockscreen_controller.cpp (+1/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/shield-notify-grabs
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+235328@code.launchpad.net

Commit message

LockScreenController: wait the primary shield to get the grab before setting the session locked

If that fails (and if the grab has never been gained during this locking session),
it's up to the Controller to decide whether the lock request has to be ignored.
So, if the primary shield fails to grab, before that the screen has ever been locked,
then we have to give up. Otherwise if it fails (but we were already locked), it's safe
to assume that this failure is due to the menus that are currently controlling the grab.

Also setup the primary shield signal connections in a shared place and use a
connection::Manager to keep track of them.

Description of the change

Correctly handle the resolution changes when a menu is open in lockscreen

To post a comment you must log in.
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: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andrea Azzarone (azzar1) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/DBusIndicators.cpp'
2--- UnityCore/DBusIndicators.cpp 2014-03-05 17:19:50 +0000
3+++ UnityCore/DBusIndicators.cpp 2014-09-20 02:04:20 +0000
4@@ -55,6 +55,7 @@
5 void Sync(GVariant* args, glib::Error const&);
6 void SyncGeometries(std::string const& name, EntryLocationMap const& locations);
7 void ShowEntriesDropdown(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y);
8+ void CloseActiveEntry();
9
10 void OnConnected();
11 void OnDisconnected();
12@@ -313,6 +314,11 @@
13 gproxy_.Call("ScrollEntry", g_variant_new("(si)", entry_id.c_str(), delta));
14 }
15
16+void DBusIndicators::Impl::CloseActiveEntry()
17+{
18+ gproxy_.Call("CloseActiveEntry");
19+}
20+
21 void DBusIndicators::Impl::Sync(GVariant* args, glib::Error const& error)
22 {
23 if (!args || error)
24@@ -489,6 +495,11 @@
25 pimpl->ShowEntriesDropdown(entries, selected, xid, x, y);
26 }
27
28+void DBusIndicators::CloseActiveEntry()
29+{
30+ pimpl->CloseActiveEntry();
31+}
32+
33 void DBusIndicators::OnEntryScroll(std::string const& entry_id, int delta)
34 {
35 pimpl->OnEntryScroll(entry_id, delta);
36
37=== modified file 'UnityCore/DBusIndicators.h'
38--- UnityCore/DBusIndicators.h 2014-03-04 13:14:12 +0000
39+++ UnityCore/DBusIndicators.h 2014-09-20 02:04:20 +0000
40@@ -40,6 +40,7 @@
41 std::vector<std::string> const& IconPaths() const;
42 void ShowEntriesDropdown(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y);
43 void SyncGeometries(std::string const& name, EntryLocationMap const& locations);
44+ void CloseActiveEntry();
45
46 protected:
47 virtual void OnEntryScroll(std::string const& entry_id, int delta);
48
49=== modified file 'UnityCore/Indicators.h'
50--- UnityCore/Indicators.h 2014-02-28 05:16:10 +0000
51+++ UnityCore/Indicators.h 2014-09-20 02:04:20 +0000
52@@ -44,6 +44,7 @@
53
54 virtual void SyncGeometries(std::string const& panel, EntryLocationMap const&) = 0;
55 virtual void ShowEntriesDropdown(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y) = 0;
56+ virtual void CloseActiveEntry() = 0;
57
58 // Signals
59 sigc::signal<void, Indicator::Ptr const&> on_object_added;
60
61=== modified file 'lockscreen/LockScreenAbstractShield.h'
62--- lockscreen/LockScreenAbstractShield.h 2014-07-24 18:51:56 +0000
63+++ lockscreen/LockScreenAbstractShield.h 2014-09-20 02:04:20 +0000
64@@ -57,9 +57,12 @@
65 nux::Property<double> scale;
66
67 using MockableBaseWindow::RemoveLayout;
68+ virtual bool HasGrab() const = 0;
69 virtual bool IsIndicatorOpen() const = 0;
70 virtual void ActivatePanel() = 0;
71
72+ sigc::signal<void> grabbed;
73+ sigc::signal<void> grab_failed;
74 sigc::signal<void, int, int> grab_motion;
75 sigc::signal<void, unsigned long, unsigned long> grab_key;
76
77
78=== modified file 'lockscreen/LockScreenController.cpp'
79--- lockscreen/LockScreenController.cpp 2014-08-27 22:12:56 +0000
80+++ lockscreen/LockScreenController.cpp 2014-09-20 02:04:20 +0000
81@@ -100,8 +100,7 @@
82 fade_animator_.finished.connect([this] {
83 if (animation::GetDirection(fade_animator_) == animation::Direction::BACKWARD)
84 {
85- motion_connection_->disconnect();
86- key_connection_->disconnect();
87+ primary_shield_connections_.Clear();
88 uscreen_connection_->block();
89 hidden_window_connection_->block();
90 session_manager_->is_locked = false;
91@@ -173,10 +172,7 @@
92 primary_shield_ = shield;
93 shield->primary = true;
94 nux::GetWindowCompositor().SetAlwaysOnFrontWindow(primary_shield_.GetPointer());
95- auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
96- motion_connection_ = shield->grab_motion.connect(move_cb);
97- auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
98- key_connection_ = shield->grab_key.connect(key_cb);
99+ SetupPrimaryShieldConnections();
100 break;
101 }
102 }
103@@ -184,6 +180,35 @@
104 ResetPostLockScreenSaver();
105 }
106
107+void Controller::SetupPrimaryShieldConnections()
108+{
109+ if (!primary_shield_.IsValid())
110+ return;
111+
112+ primary_shield_connections_.Clear();
113+
114+ auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
115+ primary_shield_connections_.Add(primary_shield_->grab_motion.connect(move_cb));
116+
117+ auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
118+ primary_shield_connections_.Add(primary_shield_->grab_key.connect(key_cb));
119+
120+ if (!session_manager_->is_locked())
121+ {
122+ primary_shield_connections_.Add(primary_shield_->grabbed.connect([this] {
123+ session_manager_->is_locked = true;
124+ }));
125+
126+ primary_shield_connections_.Add(primary_shield_->grab_failed.connect([this] {
127+ if (!session_manager_->is_locked())
128+ {
129+ LOG_ERROR(logger) << "Impossible to get the grab to lock the screen";
130+ session_manager_->unlock_requested.emit();
131+ }
132+ }));
133+ }
134+}
135+
136 void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
137 {
138 int num_monitors = monitors.size();
139@@ -233,10 +258,7 @@
140
141 primary_shield_ = shields_[primary];
142 primary_shield_->primary = true;
143- auto move_cb = sigc::mem_fun(this, &Controller::OnPrimaryShieldMotion);
144- motion_connection_ = primary_shield_->grab_motion.connect(move_cb);
145- auto key_cb = sigc::hide(sigc::hide(sigc::mem_fun(this, &Controller::ResetPostLockScreenSaver)));
146- key_connection_ = primary_shield_->grab_key.connect(key_cb);
147+ SetupPrimaryShieldConnections();
148 }
149
150 void Controller::EnsureBlankWindow()
151@@ -358,7 +380,6 @@
152 HideBlankWindow();
153
154 LockScreen();
155- session_manager_->is_locked = true;
156
157 if (prompt_activation_)
158 {
159@@ -444,6 +465,7 @@
160 shield->PushToFront();
161 });
162
163+ session_manager_->is_locked = primary_shield_->HasGrab();
164 nux::GetWindowCompositor().SetAlwaysOnFrontWindow(primary_shield_.GetPointer());
165 animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
166 }
167
168=== modified file 'lockscreen/LockScreenController.h'
169--- lockscreen/LockScreenController.h 2014-08-25 20:46:31 +0000
170+++ lockscreen/LockScreenController.h 2014-09-20 02:04:20 +0000
171@@ -66,6 +66,7 @@
172 void BlankWindowGrabEnable(bool grab);
173 void SimulateActivity();
174 void ResetPostLockScreenSaver();
175+ void SetupPrimaryShieldConnections();
176 void ActivatePanel();
177
178 void OnLockRequested(bool prompt);
179@@ -96,8 +97,7 @@
180 connection::Wrapper uscreen_connection_;
181 connection::Wrapper suspend_connection_;
182 connection::Wrapper hidden_window_connection_;
183- connection::Wrapper motion_connection_;
184- connection::Wrapper key_connection_;
185+ connection::Manager primary_shield_connections_;
186
187 glib::Source::UniquePtr lockscreen_timeout_;
188 glib::Source::UniquePtr lockscreen_delay_timeout_;
189
190=== modified file 'lockscreen/LockScreenPanel.cpp'
191--- lockscreen/LockScreenPanel.cpp 2014-07-22 01:05:07 +0000
192+++ lockscreen/LockScreenPanel.cpp 2014-09-20 02:04:20 +0000
193@@ -110,12 +110,39 @@
194 return;
195
196 indicators_view_->AddIndicator(indicator);
197+
198+ if (!active)
199+ {
200+ for (auto const& entry : indicator->GetEntries())
201+ {
202+ if (entry->active())
203+ {
204+ active = true;
205+ indicators_view_->ActivateEntry(entry->id());
206+ OnEntryActivated(GetPanelName(), entry->id(), entry->geometry());
207+ break;
208+ }
209+ }
210+ }
211+
212 QueueRelayout();
213 QueueDraw();
214 }
215
216 void Panel::RemoveIndicator(indicator::Indicator::Ptr const& indicator)
217 {
218+ if (active)
219+ {
220+ for (auto const& entry : indicator->GetEntries())
221+ {
222+ if (entry->active())
223+ {
224+ active = false;
225+ break;
226+ }
227+ }
228+ }
229+
230 indicators_view_->RemoveIndicator(indicator);
231 QueueRelayout();
232 QueueDraw();
233@@ -123,7 +150,7 @@
234
235 std::string Panel::GetPanelName() const
236 {
237- return "LockScreenPanel" + std::to_string(monitor);
238+ return "LockScreenPanel";
239 }
240
241 void Panel::OnIndicatorViewUpdated()
242
243=== modified file 'lockscreen/LockScreenShield.cpp'
244--- lockscreen/LockScreenShield.cpp 2014-08-27 22:12:56 +0000
245+++ lockscreen/LockScreenShield.cpp 2014-09-20 02:04:20 +0000
246@@ -19,7 +19,6 @@
247
248 #include "LockScreenShield.h"
249
250-#include <NuxCore/Logger.h>
251 #include <Nux/VLayout.h>
252 #include <Nux/HLayout.h>
253 #include <Nux/PaintLayer.h>
254@@ -39,8 +38,7 @@
255 {
256 namespace
257 {
258-DECLARE_LOGGER(logger, "unity.lockscreen.shield");
259-const unsigned MAX_GRAB_WAIT = 50;
260+const unsigned MAX_GRAB_WAIT = 100;
261 }
262
263 Shield::Shield(session::Manager::Ptr const& session_manager,
264@@ -123,6 +121,7 @@
265 {
266 regrab_conn_->disconnect();
267 regrab_timeout_.reset();
268+ grabbed.emit();
269 }
270 else
271 {
272@@ -132,14 +131,19 @@
273 if (cancel_on_failure)
274 {
275 regrab_timeout_.reset(new glib::Timeout(MAX_GRAB_WAIT, [this] {
276- LOG_ERROR(logger) << "Impossible to get the grab to lock the screen";
277- session_manager_->unlock_requested.emit();
278+ grab_failed.emit();
279 return false;
280 }));
281 }
282 }
283 }
284
285+bool Shield::HasGrab() const
286+{
287+ auto& wc = nux::GetWindowCompositor();
288+ return (wc.GetPointerGrabArea() == this && wc.GetKeyboardGrabArea() == this);
289+}
290+
291 void Shield::ShowPrimaryView()
292 {
293 if (primary_layout_)
294
295=== modified file 'lockscreen/LockScreenShield.h'
296--- lockscreen/LockScreenShield.h 2014-08-27 22:12:56 +0000
297+++ lockscreen/LockScreenShield.h 2014-09-20 02:04:20 +0000
298@@ -44,6 +44,7 @@
299 nux::ObjectPtr<UserPromptView> const&,
300 int monitor, bool is_primary);
301
302+ bool HasGrab() const override;
303 bool IsIndicatorOpen() const override;
304 void ActivatePanel() override;
305
306
307=== modified file 'plugins/unityshell/src/unityshell.cpp'
308--- plugins/unityshell/src/unityshell.cpp 2014-09-04 22:12:01 +0000
309+++ plugins/unityshell/src/unityshell.cpp 2014-09-20 02:04:20 +0000
310@@ -3784,6 +3784,7 @@
311 if (hud_controller_->IsVisible())
312 hud_controller_->HideHud();
313
314+ menus_->Indicators()->CloseActiveEntry();
315 launcher_controller_->ClearTooltips();
316
317 if (launcher_controller_->KeyNavIsActive())
318
319=== modified file 'services/panel-main.c'
320--- services/panel-main.c 2014-03-05 17:19:50 +0000
321+++ services/panel-main.c 2014-09-20 02:04:20 +0000
322@@ -82,6 +82,9 @@
323 " <arg type='i' name='delta' direction='in'/>"
324 " </method>"
325 ""
326+ ""
327+ " <method name='CloseActiveEntry' />"
328+ ""
329 " <signal name='EntryActivated'>"
330 " <arg type='s' name='panel_id' />"
331 " <arg type='s' name='entry_id' />"
332@@ -254,6 +257,11 @@
333 g_dbus_method_invocation_return_value (invocation, NULL);
334 g_free(entry_id);
335 }
336+ else if (g_strcmp0 (method_name, "CloseActiveEntry") == 0)
337+ {
338+ panel_service_close_active_entry (service);
339+ g_dbus_method_invocation_return_value (invocation, NULL);
340+ }
341 }
342
343 static void
344
345=== modified file 'services/panel-service.c'
346--- services/panel-service.c 2014-08-11 12:29:07 +0000
347+++ services/panel-service.c 2014-09-20 02:04:20 +0000
348@@ -2421,6 +2421,8 @@
349 IndicatorObject *object;
350 IndicatorObjectEntry *entry;
351
352+ g_return_if_fail (PANEL_IS_SERVICE (self));
353+
354 entry = get_indicator_entry_by_id (self, entry_id);
355 g_return_if_fail (entry);
356
357@@ -2437,6 +2439,8 @@
358 IndicatorObject *object;
359 IndicatorObjectEntry *entry;
360
361+ g_return_if_fail (PANEL_IS_SERVICE (self));
362+
363 entry = get_indicator_entry_by_id (self, entry_id);
364 g_return_if_fail (entry);
365
366@@ -2465,3 +2469,14 @@
367 entry, 1, direction);
368 }
369 }
370+
371+void
372+panel_service_close_active_entry (PanelService *self)
373+{
374+ g_return_if_fail (PANEL_IS_SERVICE (self));
375+
376+ if (GTK_IS_MENU (self->priv->last_menu))
377+ {
378+ gtk_menu_popdown (GTK_MENU (self->priv->last_menu));
379+ }
380+}
381
382=== modified file 'services/panel-service.h'
383--- services/panel-service.h 2014-02-06 12:02:48 +0000
384+++ services/panel-service.h 2014-09-20 02:04:20 +0000
385@@ -122,6 +122,8 @@
386 const gchar *entry_id,
387 gint32 delta);
388
389+void panel_service_close_active_entry (PanelService *self);
390+
391 G_END_DECLS
392
393 #endif /* _PANEL_SERVICE_H_ */
394
395=== modified file 'tests/mock_indicators.h'
396--- tests/mock_indicators.h 2014-02-28 05:16:10 +0000
397+++ tests/mock_indicators.h 2014-09-20 02:04:20 +0000
398@@ -36,6 +36,7 @@
399 // Implementing Indicators virtual functions
400 MOCK_METHOD2(SyncGeometries, void(std::string const&, EntryLocationMap const&));
401 MOCK_METHOD5(ShowEntriesDropdown, void(Indicator::Entries const&, Entry::Ptr const&, unsigned xid, int x, int y));
402+ MOCK_METHOD0(CloseActiveEntry, void());
403 MOCK_CONST_METHOD0(IconPaths, std::vector<std::string> const&());
404 MOCK_METHOD2(OnEntryScroll, void(std::string const&, int delta));
405 MOCK_METHOD5(OnEntryShowMenu, void(std::string const&, unsigned xid, int x, int y, unsigned button));
406
407=== modified file 'tests/test_lockscreen_controller.cpp'
408--- tests/test_lockscreen_controller.cpp 2014-07-11 17:45:39 +0000
409+++ tests/test_lockscreen_controller.cpp 2014-09-20 02:04:20 +0000
410@@ -59,6 +59,7 @@
411
412 MOCK_CONST_METHOD0(IsIndicatorOpen, bool());
413 MOCK_METHOD0(ActivatePanel, void());
414+ MOCK_CONST_METHOD0(HasGrab, bool());
415 };
416
417 struct ShieldFactoryMock : ShieldFactoryInterface