Merge lp:~azzar1/unity/unmap-on-shutdown into lp:unity

Proposed by Andrea Azzarone
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 3885
Proposed branch: lp:~azzar1/unity/unmap-on-shutdown
Merge into: lp:unity
Diff against target: 903 lines (+587/-26)
19 files modified
UnityCore/GLibDBusProxy.cpp (+100/-3)
UnityCore/GLibDBusProxy.h (+6/-0)
UnityCore/GLibWrapper-inl.h (+12/-0)
UnityCore/GLibWrapper.h (+1/-0)
UnityCore/GnomeSessionManager.cpp (+0/-1)
lockscreen/CMakeLists.txt (+2/-0)
lockscreen/LockScreenController.cpp (+10/-1)
lockscreen/LockScreenController.h (+4/-1)
lockscreen/ShutdownNotifier.cpp (+152/-0)
lockscreen/ShutdownNotifier.h (+51/-0)
lockscreen/SuspendNotifier.cpp (+153/-0)
lockscreen/SuspendNotifier.h (+51/-0)
plugins/unityshell/src/unityshell.cpp (+1/-18)
unity-shared/PluginAdapter.cpp (+34/-0)
unity-shared/PluginAdapter.h (+3/-0)
unity-shared/StandaloneWindowManager.h (+2/-0)
unity-shared/UScreen.cpp (+2/-1)
unity-shared/UScreen.h (+0/-1)
unity-shared/WindowManager.h (+3/-0)
To merge this branch: bzr merge lp:~azzar1/unity/unmap-on-shutdown
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Marco Trevisan (Treviño) Approve
Review via email: mp+237997@code.launchpad.net

Commit message

Unmap all windows during shutdown.

Description of the change

== Problem ==
#1370017 Unity Lockscreen shows unlocked desktop while shutting down

== Fix ==
Unmap all windows during shutdown.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Very nice... Just few comments.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) :
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) :
Revision history for this message
Andrea Azzarone (azzar1) :
Revision history for this message
Andrea Azzarone (azzar1) :
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Some comments.

Can you also move SignalHandlers definition to use an std::unordered_map?

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

> Some comments.
>
> Can you also move SignalHandlers definition to use an std::unordered_map?

Done.

Revision history for this message
Andrea Azzarone (azzar1) :
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

+1

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/GLibDBusProxy.cpp'
2--- UnityCore/GLibDBusProxy.cpp 2013-11-19 18:48:35 +0000
3+++ UnityCore/GLibDBusProxy.cpp 2014-10-22 15:33:14 +0000
4@@ -21,7 +21,7 @@
5
6 #include "GLibDBusProxy.h"
7
8-#include <map>
9+#include <unordered_map>
10 #include <memory>
11 #include <NuxCore/Logger.h>
12 #include <vector>
13@@ -30,6 +30,8 @@
14 #include "GLibSignal.h"
15 #include "GLibSource.h"
16
17+#include <gio/gunixfdlist.h>
18+
19 namespace unity
20 {
21 namespace glib
22@@ -47,7 +49,7 @@
23 {
24 public:
25 typedef std::vector<ReplyCallback> Callbacks;
26- typedef std::map<string, Callbacks> SignalHandlers;
27+ typedef std::unordered_map<string, Callbacks> SignalHandlers;
28
29 Impl(DBusProxy* owner,
30 string const& name,
31@@ -74,6 +76,12 @@
32 GCancellable *cancellable,
33 GDBusCallFlags flags,
34 int timeout_msec);
35+ void CallWithUnixFdList(std::string const& method_name,
36+ GVariant* parameters,
37+ CallFinishedCallback const& callback,
38+ GCancellable *cancellable,
39+ GDBusCallFlags flags,
40+ int timeout_msec);
41
42 void Connect(string const& signal_name, ReplyCallback const& callback);
43 void DisconnectSignal(string const& signal_name);
44@@ -85,6 +93,7 @@
45
46 static void OnProxyConnectCallback(GObject* source, GAsyncResult* res, gpointer impl);
47 static void OnCallCallback(GObject* source, GAsyncResult* res, gpointer call_data);
48+ static void OnCallWithUnixFdListCallback(GObject* source, GAsyncResult* res, gpointer call_data);
49
50 struct CallData
51 {
52@@ -399,6 +408,50 @@
53 data);
54 }
55
56+void DBusProxy::Impl::CallWithUnixFdList(string const& method_name,
57+ GVariant* parameters,
58+ CallFinishedCallback const& callback,
59+ GCancellable* cancellable,
60+ GDBusCallFlags flags,
61+ int timeout_msec)
62+{
63+ GCancellable* target_canc = cancellable != NULL ? cancellable : cancellable_;
64+
65+ if (!proxy_)
66+ {
67+ glib::Variant sinked_parameters(parameters);
68+ glib::Object<GCancellable> canc(target_canc, glib::AddRef());
69+ WaitForProxy(canc, timeout_msec, [this, method_name, sinked_parameters, callback, canc, flags, timeout_msec] (glib::Error const& err)
70+ {
71+ if (err)
72+ {
73+ callback(glib::Variant(), err);
74+ LOG_WARNING(logger) << "Cannot call method " << method_name
75+ << ": " << err;
76+ }
77+ else
78+ {
79+ CallWithUnixFdList(method_name, sinked_parameters, callback, canc, flags, timeout_msec);
80+ }
81+ });
82+ return;
83+ }
84+
85+ CallData* data = new CallData();
86+ data->callback = callback;
87+ data->method_name = method_name;
88+
89+ g_dbus_proxy_call_with_unix_fd_list(proxy_,
90+ method_name.c_str(),
91+ parameters,
92+ flags,
93+ timeout_msec,
94+ nullptr,
95+ target_canc,
96+ DBusProxy::Impl::OnCallWithUnixFdListCallback,
97+ data);
98+}
99+
100 void DBusProxy::Impl::OnCallCallback(GObject* source, GAsyncResult* res, gpointer call_data)
101 {
102 glib::Error error;
103@@ -407,7 +460,7 @@
104
105 if (error)
106 {
107- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
108+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
109 {
110 // silently ignore, don't even invoke callback, FIXME: really?
111 return;
112@@ -425,6 +478,39 @@
113 data->callback(result, error);
114 }
115
116+void DBusProxy::Impl::OnCallWithUnixFdListCallback(GObject* source, GAsyncResult* res, gpointer call_data)
117+{
118+ glib::Object<GUnixFDList> fd_list;
119+
120+ glib::Error error;
121+ std::unique_ptr<CallData> data(static_cast<CallData*>(call_data));
122+ glib::Variant result(g_dbus_proxy_call_with_unix_fd_list_finish(G_DBUS_PROXY(source), &fd_list, res, &error), glib::StealRef());
123+
124+ if (error)
125+ {
126+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
127+ {
128+ // silently ignore, don't even invoke callback, FIXME: really?
129+ return;
130+ }
131+ else
132+ {
133+ LOG_WARNING(logger) << "Calling method \"" << data->method_name
134+ << "\" on object path: \""
135+ << g_dbus_proxy_get_object_path(G_DBUS_PROXY(source))
136+ << "\" failed: " << error;
137+ }
138+ }
139+
140+ if (data->callback)
141+ {
142+ gint idx;
143+ g_variant_get(result, "(h)", &idx);
144+ gint fd = g_unix_fd_list_get(fd_list, idx, nullptr);
145+ data->callback(glib::Variant(fd), error);
146+ }
147+}
148+
149 void DBusProxy::Impl::Connect(std::string const& signal_name, ReplyCallback const& callback)
150 {
151 if (!callback)
152@@ -487,6 +573,17 @@
153 timeout_msec);
154 }
155
156+void DBusProxy::CallWithUnixFdList(std::string const& method_name,
157+ GVariant* parameters,
158+ CallFinishedCallback const& callback,
159+ GCancellable *cancellable,
160+ GDBusCallFlags flags,
161+ int timeout_msec)
162+{
163+ pimpl->CallWithUnixFdList(method_name, parameters, callback, cancellable,
164+ flags, timeout_msec);
165+}
166+
167 glib::Variant DBusProxy::GetProperty(std::string const& name) const
168 {
169 if (IsConnected())
170
171=== modified file 'UnityCore/GLibDBusProxy.h'
172--- UnityCore/GLibDBusProxy.h 2013-03-25 12:09:41 +0000
173+++ UnityCore/GLibDBusProxy.h 2014-10-22 15:33:14 +0000
174@@ -64,6 +64,12 @@
175 GCancellable *cancellable = nullptr,
176 GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NONE,
177 int timeout_msec = -1);
178+ void CallWithUnixFdList(std::string const& method_name,
179+ GVariant* parameters = nullptr,
180+ CallFinishedCallback const& callback = nullptr,
181+ GCancellable *cancellable = nullptr,
182+ GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NONE,
183+ int timeout_msec = -1);
184
185 bool IsConnected() const;
186
187
188=== modified file 'UnityCore/GLibWrapper-inl.h'
189--- UnityCore/GLibWrapper-inl.h 2012-07-04 20:16:06 +0000
190+++ UnityCore/GLibWrapper-inl.h 2014-10-22 15:33:14 +0000
191@@ -94,6 +94,18 @@
192 }
193
194 template <typename T>
195+T** Object<T>::operator&()
196+{
197+ if (object_)
198+ {
199+ g_object_unref(object_);
200+ object_ = nullptr;
201+ }
202+
203+ return &object_;
204+}
205+
206+template <typename T>
207 Object<T>::operator bool() const
208 {
209 return bool(object_);
210
211=== modified file 'UnityCore/GLibWrapper.h'
212--- UnityCore/GLibWrapper.h 2013-05-17 16:52:19 +0000
213+++ UnityCore/GLibWrapper.h 2014-10-22 15:33:14 +0000
214@@ -56,6 +56,7 @@
215 operator T* () const;
216 operator bool() const;
217 T* operator->() const;
218+ T** operator&();
219 T* RawPtr() const;
220 // Release ownership of the object. No unref will occur.
221 T* Release();
222
223=== modified file 'UnityCore/GnomeSessionManager.cpp'
224--- UnityCore/GnomeSessionManager.cpp 2014-05-16 04:59:06 +0000
225+++ UnityCore/GnomeSessionManager.cpp 2014-10-22 15:33:14 +0000
226@@ -432,7 +432,6 @@
227 return;
228 }
229
230- // FIXME (andy) we should ask gnome-session to emit the logind signal
231 prompt ? manager_->prompt_lock_requested.emit() : manager_->lock_requested.emit();
232 }
233
234
235=== modified file 'lockscreen/CMakeLists.txt'
236--- lockscreen/CMakeLists.txt 2014-04-18 11:45:59 +0000
237+++ lockscreen/CMakeLists.txt 2014-10-22 15:33:14 +0000
238@@ -27,6 +27,8 @@
239 LockScreenAcceleratorController.cpp
240 LockScreenAccelerators.cpp
241 ScreenSaverDBusManager.cpp
242+ ShutdownNotifier.cpp
243+ SuspendNotifier.cpp
244 UserAuthenticatorPam.cpp
245 UserPromptView.cpp
246 )
247
248=== modified file 'lockscreen/LockScreenController.cpp'
249--- lockscreen/LockScreenController.cpp 2014-09-19 18:18:08 +0000
250+++ lockscreen/LockScreenController.cpp 2014-10-22 15:33:14 +0000
251@@ -20,6 +20,7 @@
252 #include "LockScreenController.h"
253
254 #include <UnityCore/DBusIndicators.h>
255+#include <UnityCore/GLibDBusProxy.h>
256 #include <NuxCore/Logger.h>
257
258 #include "LockScreenShield.h"
259@@ -59,6 +60,7 @@
260 , session_manager_(session_manager)
261 , upstart_wrapper_(upstart_wrapper)
262 , shield_factory_(shield_factory)
263+ , suspend_notifier_(std::make_shared<SuspendNotifier>())
264 , fade_animator_(LOCK_FADE_DURATION)
265 , blank_window_animator_(IDLE_FADE_DURATION)
266 , test_mode_(test_mode)
267@@ -77,7 +79,7 @@
268 });
269 hidden_window_connection_->block();
270
271- suspend_connection_ = uscreen->suspending.connect([this] {
272+ suspend_notifier_->RegisterInterest([this](){
273 if (Settings::Instance().lock_on_suspend())
274 session_manager_->PromptLockScreen();
275 });
276@@ -440,6 +442,11 @@
277 indicators_ = std::make_shared<indicator::LockScreenDBusIndicators>();
278 upstart_wrapper_->Emit("desktop-lock");
279
280+ shutdown_notifier_ = std::make_shared<ShutdownNotifier>();
281+ shutdown_notifier_->RegisterInterest([](){
282+ WindowManager::Default().UnmapAllNoNuxWindowsSync();
283+ });
284+
285 accelerator_controller_ = std::make_shared<AcceleratorController>(session_manager_);
286 auto activate_key = WindowManager::Default().activate_indicators_key();
287 auto accelerator = std::make_shared<Accelerator>(activate_key.second, 0, activate_key.first);
288@@ -478,6 +485,8 @@
289
290 void Controller::OnUnlockRequested()
291 {
292+ shutdown_notifier_.reset();
293+
294 lockscreen_timeout_.reset();
295 screensaver_post_lock_timeout_.reset();
296
297
298=== modified file 'lockscreen/LockScreenController.h'
299--- lockscreen/LockScreenController.h 2014-09-19 18:18:08 +0000
300+++ lockscreen/LockScreenController.h 2014-10-22 15:33:14 +0000
301@@ -27,6 +27,8 @@
302 #include "LockScreenShieldFactory.h"
303 #include "LockScreenAcceleratorController.h"
304 #include "ScreenSaverDBusManager.h"
305+#include "ShutdownNotifier.h"
306+#include "SuspendNotifier.h"
307 #include "UserPromptView.h"
308 #include "unity-shared/BackgroundEffectHelper.h"
309 #include "unity-shared/UpstartWrapper.h"
310@@ -86,6 +88,8 @@
311 AcceleratorController::Ptr accelerator_controller_;
312 UpstartWrapper::Ptr upstart_wrapper_;
313 ShieldFactoryInterface::Ptr shield_factory_;
314+ ShutdownNotifier::Ptr shutdown_notifier_;
315+ SuspendNotifier::Ptr suspend_notifier_;
316
317 nux::animation::AnimateValue<double> fade_animator_;
318 nux::animation::AnimateValue<double> blank_window_animator_;
319@@ -95,7 +99,6 @@
320 BlurType old_blur_type_;
321
322 connection::Wrapper uscreen_connection_;
323- connection::Wrapper suspend_connection_;
324 connection::Wrapper hidden_window_connection_;
325 connection::Manager primary_shield_connections_;
326
327
328=== added file 'lockscreen/ShutdownNotifier.cpp'
329--- lockscreen/ShutdownNotifier.cpp 1970-01-01 00:00:00 +0000
330+++ lockscreen/ShutdownNotifier.cpp 2014-10-22 15:33:14 +0000
331@@ -0,0 +1,152 @@
332+/*
333+ * Copyright (C) 2014 Canonical Ltd
334+ *
335+ * This program is free software: you can redistribute it and/or modify
336+ * it under the terms of the GNU General Public License version 3 as
337+ * published by the Free Software Foundation.
338+ *
339+ * This program is distributed in the hope that it will be useful,
340+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
341+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
342+ * GNU General Public License for more details.
343+ *
344+ * You should have received a copy of the GNU General Public License
345+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
346+ *
347+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
348+ */
349+
350+#include "ShutdownNotifier.h"
351+
352+#include <NuxCore/Logger.h>
353+#include "UnityCore/GLibDBusProxy.h"
354+
355+namespace unity
356+{
357+namespace lockscreen
358+{
359+
360+DECLARE_LOGGER(logger, "unity.lockscreen.shutdownnotifier");
361+
362+//
363+// Private Implementation
364+//
365+
366+class ShutdownNotifier::Impl
367+{
368+public:
369+ Impl();
370+ ~Impl();
371+
372+ bool RegisterInterest(ShutdownCallback const& cb);
373+ void UnregisterInterest();
374+
375+ void Inhibit();
376+ void Uninhibit();
377+ bool IsInhibited() const;
378+
379+private:
380+ std::shared_ptr<glib::DBusProxy> logind_proxy_;
381+ ShutdownCallback cb_;
382+ gint delay_inhibit_fd_;
383+};
384+
385+ShutdownNotifier::Impl::Impl()
386+ : logind_proxy_(std::make_shared<glib::DBusProxy>("org.freedesktop.login1",
387+ "/org/freedesktop/login1",
388+ "org.freedesktop.login1.Manager",
389+ G_BUS_TYPE_SYSTEM))
390+ , delay_inhibit_fd_(-1)
391+{}
392+
393+ShutdownNotifier::Impl::~Impl()
394+{
395+ UnregisterInterest();
396+}
397+
398+bool ShutdownNotifier::Impl::RegisterInterest(ShutdownCallback const& cb)
399+{
400+ if (!cb or cb_)
401+ return false;
402+
403+ cb_ = cb;
404+
405+ Inhibit();
406+
407+ logind_proxy_->Connect("PrepareForShutdown", [this](GVariant* variant) {
408+ bool active = glib::Variant(variant).GetBool();
409+
410+ if (active)
411+ {
412+ cb_();
413+ UnregisterInterest();
414+ }
415+ });
416+
417+ return true;
418+}
419+
420+void ShutdownNotifier::Impl::UnregisterInterest()
421+{
422+ if (!cb_)
423+ return;
424+
425+ Uninhibit();
426+
427+ logind_proxy_->DisconnectSignal("PrepareForShutdown");
428+ cb_ = nullptr;
429+}
430+
431+void ShutdownNotifier::Impl::Inhibit()
432+{
433+ if (IsInhibited())
434+ return;
435+
436+ GVariant* args = g_variant_new("(ssss)", "shutdown", "Unity Lockscreen", "Screen is locked", "delay");
437+
438+ logind_proxy_->CallWithUnixFdList("Inhibit", args, [this] (GVariant* variant, glib::Error const& e) {
439+ if (e)
440+ {
441+ LOG_ERROR(logger) << "Failed to inhbit suspend";
442+ }
443+ delay_inhibit_fd_ = glib::Variant(variant).GetInt32();
444+ });
445+}
446+
447+void ShutdownNotifier::Impl::Uninhibit()
448+{
449+ if (!IsInhibited())
450+ return;
451+
452+ close(delay_inhibit_fd_);
453+ delay_inhibit_fd_ = -1;
454+}
455+
456+bool ShutdownNotifier::Impl::IsInhibited() const
457+{
458+ return delay_inhibit_fd_ != -1;
459+}
460+
461+//
462+// End Private Implementation
463+//
464+
465+ShutdownNotifier::ShutdownNotifier()
466+ : pimpl_(new(Impl))
467+{}
468+
469+ShutdownNotifier::~ShutdownNotifier()
470+{}
471+
472+bool ShutdownNotifier::RegisterInterest(ShutdownCallback const& cb)
473+{
474+ return pimpl_->RegisterInterest(cb);
475+}
476+
477+void ShutdownNotifier::UnregisterInterest()
478+{
479+ pimpl_->UnregisterInterest();
480+}
481+
482+}
483+}
484
485=== added file 'lockscreen/ShutdownNotifier.h'
486--- lockscreen/ShutdownNotifier.h 1970-01-01 00:00:00 +0000
487+++ lockscreen/ShutdownNotifier.h 2014-10-22 15:33:14 +0000
488@@ -0,0 +1,51 @@
489+/*
490+ * Copyright (C) 2014 Canonical Ltd
491+ *
492+ * This program is free software: you can redistribute it and/or modify
493+ * it under the terms of the GNU General Public License version 3 as
494+ * published by the Free Software Foundation.
495+ *
496+ * This program is distributed in the hope that it will be useful,
497+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
498+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
499+ * GNU General Public License for more details.
500+ *
501+ * You should have received a copy of the GNU General Public License
502+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
503+ *
504+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
505+ */
506+
507+#ifndef UNITY_LOCKSCREEN_SHUTDOWN_NOTIFIER
508+#define UNITY_LOCKSCREEN_SHUTDOWN_NOTIFIER
509+
510+#include <memory>
511+#include <functional>
512+
513+namespace unity
514+{
515+namespace lockscreen
516+{
517+
518+typedef std::function<void()> ShutdownCallback;
519+
520+class ShutdownNotifier
521+{
522+public:
523+ typedef std::shared_ptr<ShutdownNotifier> Ptr;
524+
525+ ShutdownNotifier();
526+ ~ShutdownNotifier();
527+
528+ bool RegisterInterest(ShutdownCallback const&);
529+ void UnregisterInterest();
530+
531+private:
532+ class Impl;
533+ std::unique_ptr<Impl> pimpl_;
534+};
535+
536+}
537+}
538+
539+#endif
540
541=== added file 'lockscreen/SuspendNotifier.cpp'
542--- lockscreen/SuspendNotifier.cpp 1970-01-01 00:00:00 +0000
543+++ lockscreen/SuspendNotifier.cpp 2014-10-22 15:33:14 +0000
544@@ -0,0 +1,153 @@
545+/*
546+ * Copyright (C) 2014 Canonical Ltd
547+ *
548+ * This program is free software: you can redistribute it and/or modify
549+ * it under the terms of the GNU General Public License version 3 as
550+ * published by the Free Software Foundation.
551+ *
552+ * This program is distributed in the hope that it will be useful,
553+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
554+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
555+ * GNU General Public License for more details.
556+ *
557+ * You should have received a copy of the GNU General Public License
558+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
559+ *
560+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
561+ */
562+
563+#include "SuspendNotifier.h"
564+
565+#include <NuxCore/Logger.h>
566+#include "UnityCore/GLibDBusProxy.h"
567+
568+namespace unity
569+{
570+namespace lockscreen
571+{
572+
573+DECLARE_LOGGER(logger, "unity.lockscreen.suspendnotifier");
574+
575+//
576+// Private Implementation
577+//
578+
579+class SuspendNotifier::Impl
580+{
581+public:
582+ Impl();
583+ ~Impl();
584+
585+ bool RegisterInterest(SuspendCallback const& cb);
586+ void UnregisterInterest();
587+
588+ void Inhibit();
589+ void Uninhibit();
590+ bool IsInhibited() const;
591+
592+private:
593+ std::shared_ptr<glib::DBusProxy> logind_proxy_;
594+ SuspendCallback cb_;
595+ gint delay_inhibit_fd_;
596+};
597+
598+SuspendNotifier::Impl::Impl()
599+ : logind_proxy_(std::make_shared<glib::DBusProxy>("org.freedesktop.login1",
600+ "/org/freedesktop/login1",
601+ "org.freedesktop.login1.Manager",
602+ G_BUS_TYPE_SYSTEM))
603+ , delay_inhibit_fd_(-1)
604+{}
605+
606+SuspendNotifier::Impl::~Impl()
607+{
608+ UnregisterInterest();
609+}
610+
611+bool SuspendNotifier::Impl::RegisterInterest(SuspendCallback const& cb)
612+{
613+ if (!cb or cb_)
614+ return false;
615+
616+ cb_ = cb;
617+
618+ Inhibit();
619+
620+ logind_proxy_->Connect("PrepareForSleep", [this](GVariant* variant) {
621+ bool active = glib::Variant(variant).GetBool();
622+
623+ if (active) // suspending
624+ {
625+ cb_();
626+ Uninhibit();
627+ }
628+ else // resuming
629+ {
630+ Inhibit();
631+ }
632+ });
633+
634+ return true;
635+}
636+
637+void SuspendNotifier::Impl::UnregisterInterest()
638+{
639+ Uninhibit();
640+
641+ logind_proxy_->DisconnectSignal("PrepareForSleep");
642+ cb_ = nullptr;
643+}
644+
645+void SuspendNotifier::Impl::Inhibit()
646+{
647+ if (IsInhibited())
648+ return;
649+
650+ GVariant* args = g_variant_new("(ssss)", "sleep", "Unity Lockscreen", "Unity wants to lock screen before suspending.", "delay");
651+
652+ logind_proxy_->CallWithUnixFdList("Inhibit", args, [this] (GVariant* variant, glib::Error const& e) {
653+ if (e)
654+ {
655+ LOG_ERROR(logger) << "Failed to inhbit suspend";
656+ }
657+ delay_inhibit_fd_ = glib::Variant(variant).GetInt32();
658+ });
659+}
660+
661+void SuspendNotifier::Impl::Uninhibit()
662+{
663+ if (!IsInhibited())
664+ return;
665+
666+ close(delay_inhibit_fd_);
667+ delay_inhibit_fd_ = -1;
668+}
669+
670+bool SuspendNotifier::Impl::IsInhibited() const
671+{
672+ return delay_inhibit_fd_ != -1;
673+}
674+
675+//
676+// End Private Implementation
677+//
678+
679+SuspendNotifier::SuspendNotifier()
680+ : pimpl_(new(Impl))
681+{}
682+
683+SuspendNotifier::~SuspendNotifier()
684+{}
685+
686+bool SuspendNotifier::RegisterInterest(SuspendCallback const& cb)
687+{
688+ return pimpl_->RegisterInterest(cb);
689+}
690+
691+void SuspendNotifier::UnregisterInterest()
692+{
693+ pimpl_->UnregisterInterest();
694+}
695+
696+}
697+}
698
699=== added file 'lockscreen/SuspendNotifier.h'
700--- lockscreen/SuspendNotifier.h 1970-01-01 00:00:00 +0000
701+++ lockscreen/SuspendNotifier.h 2014-10-22 15:33:14 +0000
702@@ -0,0 +1,51 @@
703+/*
704+ * Copyright (C) 2014 Canonical Ltd
705+ *
706+ * This program is free software: you can redistribute it and/or modify
707+ * it under the terms of the GNU General Public License version 3 as
708+ * published by the Free Software Foundation.
709+ *
710+ * This program is distributed in the hope that it will be useful,
711+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
712+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
713+ * GNU General Public License for more details.
714+ *
715+ * You should have received a copy of the GNU General Public License
716+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
717+ *
718+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
719+ */
720+
721+#ifndef UNITY_LOCKSCREEN_SUSPEND_NOTIFIER
722+#define UNITY_LOCKSCREEN_SHUTDOWN_NOTIFIER
723+
724+#include <memory>
725+#include <functional>
726+
727+namespace unity
728+{
729+namespace lockscreen
730+{
731+
732+typedef std::function<void()> SuspendCallback;
733+
734+class SuspendNotifier
735+{
736+public:
737+ typedef std::shared_ptr<SuspendNotifier> Ptr;
738+
739+ SuspendNotifier();
740+ ~SuspendNotifier();
741+
742+ bool RegisterInterest(SuspendCallback const&);
743+ void UnregisterInterest();
744+
745+private:
746+ class Impl;
747+ std::unique_ptr<Impl> pimpl_;
748+};
749+
750+}
751+}
752+
753+#endif
754\ No newline at end of file
755
756=== modified file 'plugins/unityshell/src/unityshell.cpp'
757--- plugins/unityshell/src/unityshell.cpp 2014-10-16 15:10:15 +0000
758+++ plugins/unityshell/src/unityshell.cpp 2014-10-22 15:33:14 +0000
759@@ -2795,23 +2795,6 @@
760 return "Unity";
761 }
762
763-bool isNuxWindow(CompWindow* value)
764-{
765- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
766- auto id = value->id();
767-
768- // iterate loop by hand rather than use std::find as this is considerably faster
769- // we care about performance here because of the high frequency in which this function is
770- // called (nearly every frame)
771- unsigned int size = xwns.size();
772- for (unsigned int i = 0; i < size; ++i)
773- {
774- if (xwns[i] == id)
775- return true;
776- }
777- return false;
778-}
779-
780 void UnityScreen::RaiseInputWindows()
781 {
782 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
783@@ -4094,7 +4077,7 @@
784 , close_icon_state_(decoration::WidgetState::NORMAL)
785 , deco_win_(uScreen->deco_manager_->HandleWindow(window))
786 , need_fake_deco_redraw_(false)
787- , is_nux_window_(isNuxWindow(window))
788+ , is_nux_window_(PluginAdapter::IsNuxWindow(window))
789 {
790 WindowInterface::setHandler(window);
791 GLWindowInterface::setHandler(gWindow);
792
793=== modified file 'unity-shared/PluginAdapter.cpp'
794--- unity-shared/PluginAdapter.cpp 2014-08-13 23:32:39 +0000
795+++ unity-shared/PluginAdapter.cpp 2014-10-22 15:33:14 +0000
796@@ -1454,6 +1454,40 @@
797 _last_focused_window = NULL;
798 }
799
800+void PluginAdapter::UnmapAllNoNuxWindowsSync()
801+{
802+ for (auto const& window : m_Screen->windows())
803+ {
804+ if (!IsNuxWindow(window) && (window->isMapped() || window->isViewable()))
805+ {
806+ if (window->overrideRedirect())
807+ {
808+ XUnmapWindow(m_Screen->dpy(), window->id());
809+ }
810+ else
811+ {
812+ window->hide();
813+ }
814+ }
815+ }
816+
817+ XSync(m_Screen->dpy(), False);
818+}
819+
820+bool PluginAdapter::IsNuxWindow(CompWindow* value)
821+{
822+ std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
823+ auto id = value->id();
824+
825+ unsigned int size = xwns.size();
826+ for (unsigned int i = 0; i < size; ++i)
827+ {
828+ if (xwns[i] == id)
829+ return true;
830+ }
831+ return false;
832+}
833+
834 void PluginAdapter::AddProperties(debug::IntrospectionData& wrapper)
835 {
836 wrapper.add(GetScreenGeometry())
837
838=== modified file 'unity-shared/PluginAdapter.h'
839--- unity-shared/PluginAdapter.h 2014-04-02 21:42:12 +0000
840+++ unity-shared/PluginAdapter.h 2014-10-22 15:33:14 +0000
841@@ -193,6 +193,9 @@
842
843 Window GetTopWindowAbove(Window xid) const;
844
845+ void UnmapAllNoNuxWindowsSync();
846+ static bool IsNuxWindow(CompWindow* value);
847+
848 protected:
849 PluginAdapter(CompScreen* screen);
850 void AddProperties(debug::IntrospectionData&);
851
852=== modified file 'unity-shared/StandaloneWindowManager.h'
853--- unity-shared/StandaloneWindowManager.h 2014-04-02 21:42:12 +0000
854+++ unity-shared/StandaloneWindowManager.h 2014-10-22 15:33:14 +0000
855@@ -163,6 +163,8 @@
856 virtual std::string GetStringProperty(Window window_id, Atom) const;
857 virtual std::vector<long> GetCardinalProperty(Window window_id, Atom) const;
858
859+ virtual void UnmapAllNoNuxWindowsSync() {};
860+
861 // Mock functions
862 StandaloneWindow::Ptr GetWindowByXid(Window window_id) const;
863 void AddStandaloneWindow(StandaloneWindow::Ptr const& window);
864
865=== modified file 'unity-shared/UScreen.cpp'
866--- unity-shared/UScreen.cpp 2014-08-05 21:22:40 +0000
867+++ unity-shared/UScreen.cpp 2014-10-22 15:33:14 +0000
868@@ -40,7 +40,8 @@
869 proxy_.Connect("PrepareForSleep", [this] (GVariant* data) {
870 gboolean val;
871 g_variant_get(data, "(b)", &val);
872- val ? suspending.emit() : resuming.emit();
873+ if (!val)
874+ resuming.emit();
875 });
876
877 Refresh();
878
879=== modified file 'unity-shared/UScreen.h'
880--- unity-shared/UScreen.h 2014-04-08 16:29:49 +0000
881+++ unity-shared/UScreen.h 2014-10-22 15:33:14 +0000
882@@ -51,7 +51,6 @@
883
884 // <void, primary_monitor, monitors>
885 sigc::signal<void, int, std::vector<nux::Geometry> const&> changed;
886- sigc::signal<void> suspending;
887 sigc::signal<void> resuming;
888
889 const std::string GetMonitorName(int output_number) const;
890
891=== modified file 'unity-shared/WindowManager.h'
892--- unity-shared/WindowManager.h 2014-08-13 23:32:39 +0000
893+++ unity-shared/WindowManager.h 2014-10-22 15:33:14 +0000
894@@ -169,6 +169,9 @@
895 virtual std::string GetStringProperty(Window, Atom) const = 0;
896 virtual std::vector<long> GetCardinalProperty(Window, Atom) const = 0;
897
898+ virtual void UnmapAllNoNuxWindowsSync() = 0;
899+
900+
901 // Nux Modifiers, Nux Keycode (= X11 KeySym)
902 nux::Property<std::pair<unsigned, unsigned>> close_window_key;
903 nux::Property<std::pair<unsigned, unsigned>> activate_indicators_key;