Merge lp:~3v1n0/unity/shutdown-view 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: 3200
Proposed branch: lp:~3v1n0/unity/shutdown-view
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/closable-window
Diff against target: 1954 lines (+1721/-8)
21 files modified
CMakeLists.txt (+1/-0)
plugins/unityshell/CMakeLists.txt (+4/-4)
plugins/unityshell/src/unityshell.cpp (+13/-1)
plugins/unityshell/src/unityshell.h (+2/-0)
po/POTFILES.in (+1/-0)
shutdown/CMakeLists.txt (+33/-0)
shutdown/SessionButton.cpp (+105/-0)
shutdown/SessionButton.h (+68/-0)
shutdown/SessionController.cpp (+235/-0)
shutdown/SessionController.h (+83/-0)
shutdown/SessionView.cpp (+326/-0)
shutdown/SessionView.h (+86/-0)
shutdown/StandaloneSession.cpp (+99/-0)
shutdown/pch/shutdown_pch.hh (+29/-0)
tests/CMakeLists.txt (+20/-1)
tests/test_mock_session_manager.h (+49/-0)
tests/test_session_button.cpp (+124/-0)
tests/test_session_controller.cpp (+162/-0)
tests/test_session_view.cpp (+280/-0)
tests/test_unity_window_view.cpp (+0/-1)
unity-shared/UnityWindowStyle.cpp (+1/-1)
To merge this branch: bzr merge lp:~3v1n0/unity/shutdown-view
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Brandon Schaefer (community) Approve
Review via email: mp+152251@code.launchpad.net

Commit message

Session: added a SessionController and View. Use the GnomeSessionManager to perform session actions

Such as suspend, hibernate, logout, lockscreen, reboot and shutdown.

Video: http://youtu.be/h_qqjOMGlrI

Description of the change

Implemented a View to use the GnomeSessionManager, added unit tests.

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

Awesome work! Looks amazing:

Logout:
http://i.imgur.com/T5ytfcN.png

Shutdown:
http://i.imgur.com/f4he5KH.png

Code looks good, just a few more test. Approved. Will approve to merge once some more tests land :).

review: Approve
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Still looks good to me. Awesome amount of tests, lets merge!

review: Approve
Revision history for this message
Michael Terry (mterry) wrote :

Mmm, mightn't this break Feature Freeze?

Revision history for this message
Adolfo Jayme Barrientos (fitojb) wrote :

@mterry: I consider this as a bug fix ;-)

@treviño: this is really cool!

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

Freeze exception was accepted, re-approving! ;-)

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-03-04 15:44:32 +0000
3+++ CMakeLists.txt 2013-03-07 22:50:34 +0000
4@@ -235,6 +235,7 @@
5 add_subdirectory(plugins/unitydialog)
6 add_subdirectory(plugins/unity-mt-grab-handles)
7 add_subdirectory(shortcuts)
8+ add_subdirectory(shutdown)
9 add_subdirectory(unity-standalone)
10 endif ()
11
12
13=== modified file 'plugins/unityshell/CMakeLists.txt'
14--- plugins/unityshell/CMakeLists.txt 2013-01-08 09:07:52 +0000
15+++ plugins/unityshell/CMakeLists.txt 2013-03-07 22:50:34 +0000
16@@ -13,7 +13,7 @@
17 compiz_plugin (unityshell
18 PKGDEPS ${UNITY_PLUGIN_DEPS}
19 PLUGINDEPS composite opengl compiztoolbox scale
20- CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${PKGDATADIR}\"' -I${CMAKE_BINARY_DIR} -I${CMAKE_SOURCE_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CXXFLAGS} -I${CMAKE_SOURCE_DIR}/dash/ -I${CMAKE_SOURCE_DIR}/launcher/ -I${CMAKE_SOURCE_DIR}/hud/ -I${CMAKE_SOURCE_DIR}/panel/ -I${CMAKE_SOURCE_DIR}/shortcuts/ -I${CMAKE_SOURCE_DIR}/unity-shared/"
21+ CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${PKGDATADIR}\"' -I${CMAKE_BINARY_DIR} -I${CMAKE_SOURCE_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CXXFLAGS} -I${CMAKE_SOURCE_DIR}/dash/ -I${CMAKE_SOURCE_DIR}/launcher/ -I${CMAKE_SOURCE_DIR}/hud/ -I${CMAKE_SOURCE_DIR}/panel/ -I${CMAKE_SOURCE_DIR}/shortcuts/ -I${CMAKE_SOURCE_DIR}/shutdown/ -I${CMAKE_SOURCE_DIR}/unity-shared/"
22 LIBDIRS "${CMAKE_BINARY_DIR}/UnityCore"
23 )
24
25@@ -21,9 +21,9 @@
26 set (CMAKE_BUILD_TYPE "" CACHE STRING "Build type (Debug/Release/RelWithDebInfo/MinSizeRe)" FORCE)
27 endif()
28
29-add_dependencies(unityshell unity-core-${UNITY_API_VERSION} dash-lib launcher-lib switcher-lib hud-lib panel-lib shortcuts-lib unity-shared unity-shared-compiz)
30-target_link_libraries(unityshell unity-core-${UNITY_API_VERSION} launcher-lib dash-lib switcher-lib hud-lib panel-lib shortcuts-lib unity-shared unity-shared-bamf unity-shared-compiz)
31-set_target_properties(unityshell
32+add_dependencies(unityshell unity-core-${UNITY_API_VERSION} dash-lib launcher-lib switcher-lib hud-lib panel-lib shortcuts-lib shutdown-lib unity-shared unity-shared-compiz)
33+target_link_libraries(unityshell unity-core-${UNITY_API_VERSION} launcher-lib dash-lib switcher-lib hud-lib panel-lib shortcuts-lib shutdown-lib unity-shared unity-shared-bamf unity-shared-compiz)
34+set_target_properties(unityshell
35 PROPERTIES INSTALL_RPATH "${CACHED_UNITY_PRIVATE_DEPS_LIBRARY_DIRS}"
36 INSTALL_RPATH_USE_LINK_PATH TRUE)
37
38
39=== modified file 'plugins/unityshell/src/unityshell.cpp'
40--- plugins/unityshell/src/unityshell.cpp 2013-03-04 21:24:47 +0000
41+++ plugins/unityshell/src/unityshell.cpp 2013-03-07 22:50:34 +0000
42@@ -25,8 +25,9 @@
43 #include <Nux/BaseWindow.h>
44 #include <Nux/WindowCompositor.h>
45
46+#include <UnityCore/Lens.h>
47+#include <UnityCore/GnomeSessionManager.h>
48 #include <UnityCore/Variant.h>
49-#include <UnityCore/Lens.h>
50
51 #include "BaseWindowRaiserImp.h"
52 #include "IconRenderer.h"
53@@ -2577,6 +2578,12 @@
54 paintInnerGlow(scaled_geo, matrix, attrib, mask);
55 }
56
57+ if (uScreen->session_controller_ && uScreen->session_controller_->Visible())
58+ {
59+ // Let's darken the other windows if the session dialog is visible
60+ wAttrib.brightness *= 0.75f;
61+ }
62+
63 return gWindow->glPaint(wAttrib, matrix, region, mask);
64 }
65
66@@ -3255,6 +3262,11 @@
67 shortcut_controller_ = std::make_shared<shortcut::Controller>(base_window_raiser, shortcuts_modeller);
68 AddChild(shortcut_controller_.get());
69
70+ // Setup Session Controller
71+ auto manager = std::make_shared<session::GnomeManager>();
72+ session_controller_ = std::make_shared<session::Controller>(manager);
73+ AddChild(session_controller_.get());
74+
75 launcher_controller_->launcher().size_changed.connect([this] (nux::Area*, int w, int h) {
76 /* The launcher geometry includes 1px used to draw the right margin
77 * that must not be considered when drawing an overlay */
78
79=== modified file 'plugins/unityshell/src/unityshell.h'
80--- plugins/unityshell/src/unityshell.h 2013-02-19 18:21:22 +0000
81+++ plugins/unityshell/src/unityshell.h 2013-03-07 22:50:34 +0000
82@@ -50,6 +50,7 @@
83 #include "DebugDBusInterface.h"
84 #include "ScreenIntrospection.h"
85 #include "SwitcherController.h"
86+#include "SessionController.h"
87 #include "UBusWrapper.h"
88 #include "UnityshellPrivate.h"
89 #include "UnityShowdesktopHandler.h"
90@@ -272,6 +273,7 @@
91 switcher::Controller::Ptr switcher_controller_;
92 hud::Controller::Ptr hud_controller_;
93 shortcut::Controller::Ptr shortcut_controller_;
94+ session::Controller::Ptr session_controller_;
95 debug::DebugDBusInterface debugger_;
96
97 /* Subscription for gestures that manipulate Unity launcher */
98
99=== modified file 'po/POTFILES.in'
100--- po/POTFILES.in 2013-02-05 22:01:10 +0000
101+++ po/POTFILES.in 2013-03-07 22:50:34 +0000
102@@ -32,6 +32,7 @@
103 shortcuts/ShortcutHintPrivate.cpp
104 shortcuts/ShortcutView.cpp
105 shortcuts/CompizShortcutModeller.cpp
106+shutdown/SessionView.cpp
107 services/panel-service.c
108 unity-shared/DashStyle.cpp
109 unity-shared/SearchBar.cpp
110
111=== added file 'resources/hibernate.png'
112Binary files resources/hibernate.png 1970-01-01 00:00:00 +0000 and resources/hibernate.png 2013-03-07 22:50:34 +0000 differ
113=== added file 'resources/hibernate_highlight.png'
114Binary files resources/hibernate_highlight.png 1970-01-01 00:00:00 +0000 and resources/hibernate_highlight.png 2013-03-07 22:50:34 +0000 differ
115=== added file 'resources/lockscreen.png'
116Binary files resources/lockscreen.png 1970-01-01 00:00:00 +0000 and resources/lockscreen.png 2013-03-07 22:50:34 +0000 differ
117=== added file 'resources/lockscreen_highlight.png'
118Binary files resources/lockscreen_highlight.png 1970-01-01 00:00:00 +0000 and resources/lockscreen_highlight.png 2013-03-07 22:50:34 +0000 differ
119=== added file 'resources/logout.png'
120Binary files resources/logout.png 1970-01-01 00:00:00 +0000 and resources/logout.png 2013-03-07 22:50:34 +0000 differ
121=== added file 'resources/logout_highlight.png'
122Binary files resources/logout_highlight.png 1970-01-01 00:00:00 +0000 and resources/logout_highlight.png 2013-03-07 22:50:34 +0000 differ
123=== added file 'resources/restart.png'
124Binary files resources/restart.png 1970-01-01 00:00:00 +0000 and resources/restart.png 2013-03-07 22:50:34 +0000 differ
125=== added file 'resources/restart_highlight.png'
126Binary files resources/restart_highlight.png 1970-01-01 00:00:00 +0000 and resources/restart_highlight.png 2013-03-07 22:50:34 +0000 differ
127=== added file 'resources/shutdown.png'
128Binary files resources/shutdown.png 1970-01-01 00:00:00 +0000 and resources/shutdown.png 2013-03-07 22:50:34 +0000 differ
129=== added file 'resources/shutdown_highlight.png'
130Binary files resources/shutdown_highlight.png 1970-01-01 00:00:00 +0000 and resources/shutdown_highlight.png 2013-03-07 22:50:34 +0000 differ
131=== added file 'resources/suspend.png'
132Binary files resources/suspend.png 1970-01-01 00:00:00 +0000 and resources/suspend.png 2013-03-07 22:50:34 +0000 differ
133=== added file 'resources/suspend_highlight.png'
134Binary files resources/suspend_highlight.png 1970-01-01 00:00:00 +0000 and resources/suspend_highlight.png 2013-03-07 22:50:34 +0000 differ
135=== added directory 'shutdown'
136=== added file 'shutdown/CMakeLists.txt'
137--- shutdown/CMakeLists.txt 1970-01-01 00:00:00 +0000
138+++ shutdown/CMakeLists.txt 2013-03-07 22:50:34 +0000
139@@ -0,0 +1,33 @@
140+set(UNITY_SRC ../plugins/unityshell/src)
141+
142+set (CFLAGS
143+ ${CACHED_UNITY_DEPS_CFLAGS}
144+ ${CACHED_UNITY_DEPS_CFLAGS_OTHER}
145+ ${PIC_FLAGS}
146+ )
147+
148+string (REPLACE ";" " " CFLAGS "${CFLAGS}")
149+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CFLAGS}")
150+
151+set (LIBS ${CACHED_UNITY_DEPS_LDFLAGS} ${UNITY_STANDALONE_LADD})
152+
153+include_directories (.. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR})
154+
155+#
156+# Headers & Sources
157+#
158+set (SHUTDOWN_SOURCES
159+ SessionButton.cpp
160+ SessionController.cpp
161+ SessionView.cpp
162+ )
163+
164+add_library (shutdown-lib STATIC ${SHUTDOWN_SOURCES})
165+add_dependencies (shutdown-lib unity-core-${UNITY_API_VERSION} unity-shared)
166+add_pch(pch/shutdown_pch.hh shutdown-lib)
167+
168+#
169+# Standalone variant
170+#
171+add_executable (shutdown StandaloneSession.cpp)
172+target_link_libraries (shutdown shutdown-lib unity-shared unity-shared-standalone)
173
174=== added file 'shutdown/SessionButton.cpp'
175--- shutdown/SessionButton.cpp 1970-01-01 00:00:00 +0000
176+++ shutdown/SessionButton.cpp 2013-03-07 22:50:34 +0000
177@@ -0,0 +1,105 @@
178+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
179+/*
180+* Copyright (C) 2013 Canonical Ltd
181+*
182+* This program is free software: you can redistribute it and/or modify
183+* it under the terms of the GNU General Public License version 3 as
184+* published by the Free Software Foundation.
185+*
186+* This program is distributed in the hope that it will be useful,
187+* but WITHOUT ANY WARRANTY; without even the implied warranty of
188+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
189+* GNU General Public License for more details.
190+*
191+* You should have received a copy of the GNU General Public License
192+* along with this program. If not, see <http://www.gnu.org/licenses/>.
193+*
194+* Authored by: Marco Trevisan (Treviño) <marco@ubuntu.com>
195+*/
196+
197+#include "config.h"
198+#include "SessionButton.h"
199+
200+#include <Nux/VLayout.h>
201+#include <UnityCore/Variant.h>
202+
203+
204+namespace unity
205+{
206+namespace session
207+{
208+
209+namespace style
210+{
211+ const std::string FONT = "Ubuntu Light 12";
212+
213+ const unsigned BUTTON_SPACE = 9;
214+}
215+
216+NUX_IMPLEMENT_OBJECT_TYPE(Button);
217+
218+Button::Button(std::string const& label, std::string const& texture_name, NUX_FILE_LINE_DECL)
219+ : nux::View(NUX_FILE_LINE_PARAM)
220+ , highlighted(false)
221+ , label([this] { return label_view_->GetText(); })
222+{
223+ SetAcceptKeyNavFocusOnMouseDown(false);
224+ SetAcceptKeyNavFocusOnMouseEnter(true);
225+
226+ std::string texture_prefix = PKGDATADIR"/" + texture_name;
227+ normal_tex_.Adopt(nux::CreateTexture2DFromFile((texture_prefix + ".png").c_str(), -1, true));
228+ highlight_tex_.Adopt(nux::CreateTexture2DFromFile((texture_prefix + "_highlight.png").c_str(), -1, true));
229+
230+ auto main_layout = new nux::VLayout();
231+ main_layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER);
232+ main_layout->SetSpaceBetweenChildren(style::BUTTON_SPACE);
233+ SetLayout(main_layout);
234+
235+ image_view_ = new IconTexture(normal_tex_);
236+ image_view_->SetInputEventSensitivity(false);
237+ main_layout->AddView(image_view_, 1, nux::MINOR_POSITION_CENTER);
238+
239+ label_view_ = new StaticCairoText(label);
240+ label_view_->SetFont(style::FONT);
241+ label_view_->SetTextAlignment(StaticCairoText::AlignState::NUX_ALIGN_CENTRE);
242+ label_view_->SetTextColor(nux::color::Transparent);
243+ label_view_->SetInputEventSensitivity(false);
244+ main_layout->AddView(label_view_, 1, nux::MINOR_POSITION_CENTER);
245+
246+ mouse_enter.connect([this] (int, int, unsigned long, unsigned long) { highlighted = true; });
247+ mouse_leave.connect([this] (int, int, unsigned long, unsigned long) { highlighted = false; });
248+ mouse_click.connect([this] (int, int, unsigned long, unsigned long) { activated.emit(); });
249+
250+ begin_key_focus.connect([this] { highlighted = true; });
251+ end_key_focus.connect([this] { highlighted = false; });
252+ key_nav_focus_activate.connect([this] (Area*) { activated.emit(); });
253+
254+ highlighted.changed.connect([this] (bool value) {
255+ image_view_->SetTexture(value ? highlight_tex_ : normal_tex_);
256+ label_view_->SetTextColor(value ? nux::color::White : nux::color::Transparent);
257+ });
258+}
259+
260+void Button::Draw(nux::GraphicsEngine& ctx, bool force)
261+{
262+ GetLayout()->ProcessDraw(ctx, force);
263+}
264+
265+//
266+// Introspectable methods
267+//
268+std::string Button::GetName() const
269+{
270+ return "SessionButton";
271+}
272+
273+void Button::AddProperties(GVariantBuilder* builder)
274+{
275+ unity::variant::BuilderWrapper(builder)
276+ .add("highlighted", highlighted())
277+ .add("label", label())
278+ .add("label_visible", label_view_->GetTextColor() != nux::color::Transparent);
279+}
280+
281+} // namespace session
282+} // namespace unity
283
284=== added file 'shutdown/SessionButton.h'
285--- shutdown/SessionButton.h 1970-01-01 00:00:00 +0000
286+++ shutdown/SessionButton.h 2013-03-07 22:50:34 +0000
287@@ -0,0 +1,68 @@
288+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
289+/*
290+* Copyright (C) 2013 Canonical Ltd
291+*
292+* This program is free software: you can redistribute it and/or modify
293+* it under the terms of the GNU General Public License version 3 as
294+* published by the Free Software Foundation.
295+*
296+* This program is distributed in the hope that it will be useful,
297+* but WITHOUT ANY WARRANTY; without even the implied warranty of
298+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
299+* GNU General Public License for more details.
300+*
301+* You should have received a copy of the GNU General Public License
302+* along with this program. If not, see <http://www.gnu.org/licenses/>.
303+*
304+* Authored by: Marco Trevisan (Treviño) <marco@ubuntu.com>
305+*/
306+
307+#ifndef UNITYSHELL_SESSION_BUTTON_H
308+#define UNITYSHELL_SESSION_BUTTON_H
309+
310+#include <Nux/Nux.h>
311+#include <Nux/View.h>
312+#include <NuxCore/Property.h>
313+
314+#include "unity-shared/IconTexture.h"
315+#include "unity-shared/Introspectable.h"
316+#include "unity-shared/StaticCairoText.h"
317+
318+namespace unity
319+{
320+namespace session
321+{
322+
323+class Button : public nux::View, public debug::Introspectable
324+{
325+ NUX_DECLARE_OBJECT_TYPE(Button, nux::View);
326+public:
327+ Button(std::string const& label, std::string const& texture_name, NUX_FILE_LINE_PROTO);
328+
329+ nux::Property<bool> highlighted;
330+ nux::ROProperty<std::string> label;
331+
332+ sigc::signal<void> activated;
333+
334+protected:
335+ void Draw(nux::GraphicsEngine&, bool force);
336+
337+ // Introspectable methods
338+ std::string GetName() const;
339+ void AddProperties(GVariantBuilder* builder);
340+
341+private:
342+ friend class TestSessionButton;
343+
344+ IconTexture* image_view_;
345+ StaticCairoText* label_view_;
346+ nux::ObjectPtr<nux::BaseTexture> normal_tex_;
347+ nux::ObjectPtr<nux::BaseTexture> highlight_tex_;
348+};
349+
350+} // namespace session
351+
352+} // namespace unity
353+
354+#endif // UNITYSHELL_SESSION_BUTTON_H
355+
356
357=== added file 'shutdown/SessionController.cpp'
358--- shutdown/SessionController.cpp 1970-01-01 00:00:00 +0000
359+++ shutdown/SessionController.cpp 2013-03-07 22:50:34 +0000
360@@ -0,0 +1,235 @@
361+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
362+/*
363+* Copyright (C) 2013 Canonical Ltd
364+*
365+* This program is free software: you can redistribute it and/or modify
366+* it under the terms of the GNU General Public License version 3 as
367+* published by the Free Software Foundation.
368+*
369+* This program is distributed in the hope that it will be useful,
370+* but WITHOUT ANY WARRANTY; without even the implied warranty of
371+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
372+* GNU General Public License for more details.
373+*
374+* You should have received a copy of the GNU General Public License
375+* along with this program. If not, see <http://www.gnu.org/licenses/>.
376+*
377+* Authored by: Marco Trevisan (Treviño) <marco@ubuntu.com>
378+*/
379+
380+#include "SessionController.h"
381+
382+#include "unity-shared/UBusMessages.h"
383+#include "unity-shared/UScreen.h"
384+#include "unity-shared/WindowManager.h"
385+
386+namespace na = nux::animation;
387+
388+namespace unity
389+{
390+namespace session
391+{
392+namespace
393+{
394+const unsigned int FADE_DURATION = 100;
395+}
396+
397+Controller::Controller(session::Manager::Ptr const& manager)
398+ : manager_(manager)
399+ , bg_color_(0.0, 0.0, 0.0, 0.5)
400+ , fade_animator_(FADE_DURATION)
401+{
402+ manager_->reboot_requested.connect([this] (bool inhibitors) {
403+ Show(View::Mode::SHUTDOWN, inhibitors);
404+ });
405+
406+ manager_->shutdown_requested.connect([this] (bool inhibitors) {
407+ Show(View::Mode::FULL, inhibitors);
408+ });
409+
410+ manager_->logout_requested.connect([this] (bool inhibitors) {
411+ Show(View::Mode::LOGOUT, inhibitors);
412+ });
413+
414+ manager_->cancel_requested.connect(sigc::mem_fun(this, &Controller::Hide));
415+
416+ ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED,
417+ sigc::mem_fun(this, &Controller::OnBackgroundUpdate));
418+
419+ ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);
420+
421+ fade_animator_.updated.connect([this] (double opacity) {
422+ if (!view_window_)
423+ return;
424+
425+ view_window_->SetOpacity(opacity);
426+
427+ if (opacity == 0.0f && fade_animator_.GetFinishValue() == 0.0f)
428+ CloseWindow();
429+ });
430+}
431+
432+void Controller::OnBackgroundUpdate(GVariant* data)
433+{
434+ gdouble red, green, blue, alpha;
435+ g_variant_get(data, "(dddd)", &red, &green, &blue, &alpha);
436+ bg_color_ = nux::Color(red, green, blue, alpha);
437+
438+ if (view_)
439+ view_->background_color = bg_color_;
440+}
441+
442+void Controller::Show(View::Mode mode)
443+{
444+ Show(mode, false);
445+}
446+
447+void Controller::Show(View::Mode mode, bool inhibitors)
448+{
449+ EnsureView();
450+
451+ if (Visible() && mode == view_->mode())
452+ return;
453+
454+ WindowManager::Default().SaveInputFocus();
455+
456+ if (nux::GetWindowThread()->IsEmbeddedWindow())
457+ {
458+ view_window_->EnableInputWindow(true, view_window_->GetWindowName().c_str(), true, false);
459+ view_window_->GrabPointer();
460+ view_window_->GrabKeyboard();
461+ }
462+
463+ view_->mode = mode;
464+ view_->have_inhibitors = inhibitors;
465+ view_->live_background = true;
466+
467+ view_window_->ShowWindow(true);
468+ view_window_->PushToFront();
469+ view_window_->SetInputFocus();
470+ nux::GetWindowCompositor().SetKeyFocusArea(view_.GetPointer());
471+
472+ if (fade_animator_.CurrentState() == na::Animation::State::Running)
473+ {
474+ if (fade_animator_.GetFinishValue() == 0.0f)
475+ fade_animator_.Reverse();
476+ }
477+ else
478+ {
479+ fade_animator_.SetStartValue(0.0f).SetFinishValue(1.0f).Start();
480+ }
481+}
482+
483+nux::Point Controller::GetOffsetPerMonitor(int monitor)
484+{
485+ EnsureView();
486+
487+ auto const& view_geo = view_->GetGeometry();
488+ auto const& monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
489+
490+ nux::Point offset(adjustment_.x + monitor_geo.x, adjustment_.y + monitor_geo.y);
491+ offset.x += (monitor_geo.width - view_geo.width - adjustment_.x) / 2;
492+ offset.y += (monitor_geo.height - view_geo.height - adjustment_.y) / 2;
493+
494+ return offset;
495+}
496+
497+void Controller::ConstructView()
498+{
499+ view_ = View::Ptr(new View(manager_));
500+ view_->background_color = bg_color_;
501+ debug::Introspectable::AddChild(view_.GetPointer());
502+
503+ auto layout = new nux::HLayout(NUX_TRACKER_LOCATION);
504+ layout->SetVerticalExternalMargin(0);
505+ layout->SetHorizontalExternalMargin(0);
506+ layout->AddView(view_.GetPointer());
507+
508+ view_window_ = new nux::BaseWindow("SessionManager");
509+ view_window_->SetLayout(layout);
510+ view_window_->SetBackgroundColor(nux::color::Transparent);
511+ view_window_->SetWindowSizeMatchLayout(true);
512+ view_window_->ShowWindow(false);
513+ view_window_->SetOpacity(0.0f);
514+ view_window_->SetEnterFocusInputArea(view_.GetPointer());
515+
516+ view_window_->mouse_down_outside_pointer_grab_area.connect([this] (int, int, unsigned long, unsigned long) {
517+ CancelAndHide();
518+ });
519+
520+ view_->request_hide.connect(sigc::mem_fun(this, &Controller::Hide));
521+ view_->request_close.connect(sigc::mem_fun(this, &Controller::CancelAndHide));
522+
523+ if (nux::GetWindowThread()->IsEmbeddedWindow())
524+ {
525+ view_->size_changed.connect([this] (nux::Area*, int, int) {
526+ int monitor = UScreen::GetDefault()->GetMonitorWithMouse();
527+ auto const& offset = GetOffsetPerMonitor(monitor);
528+ view_window_->SetXY(offset.x, offset.y);
529+ });
530+ }
531+ else
532+ {
533+ view_window_->SetXY(0, 0);
534+ }
535+}
536+
537+void Controller::EnsureView()
538+{
539+ if (!view_window_)
540+ ConstructView();
541+}
542+
543+void Controller::CancelAndHide()
544+{
545+ manager_->CancelAction();
546+ Hide();
547+}
548+
549+void Controller::Hide()
550+{
551+ if (fade_animator_.CurrentState() == na::Animation::State::Running)
552+ {
553+ if (fade_animator_.GetFinishValue() == 1.0f)
554+ fade_animator_.Reverse();
555+ }
556+ else
557+ {
558+ fade_animator_.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
559+ }
560+}
561+
562+void Controller::CloseWindow()
563+{
564+ view_window_->PushToBack();
565+ view_window_->ShowWindow(false);
566+ view_window_->UnGrabPointer();
567+ view_window_->UnGrabKeyboard();
568+ view_window_->EnableInputWindow(false);
569+ view_->live_background = false;
570+
571+ nux::GetWindowCompositor().SetKeyFocusArea(nullptr);
572+ WindowManager::Default().RestoreInputFocus();
573+}
574+
575+bool Controller::Visible() const
576+{
577+ return (view_window_ && view_window_->IsVisible());
578+}
579+
580+//
581+// Introspection
582+//
583+std::string Controller::GetName() const
584+{
585+ return "SessionController";
586+}
587+
588+void Controller::AddProperties(GVariantBuilder* builder)
589+{
590+ variant::BuilderWrapper(builder)
591+ .add("visible", Visible());
592+}
593+
594+} // namespace session
595+} // namespace unity
596
597=== added file 'shutdown/SessionController.h'
598--- shutdown/SessionController.h 1970-01-01 00:00:00 +0000
599+++ shutdown/SessionController.h 2013-03-07 22:50:34 +0000
600@@ -0,0 +1,83 @@
601+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
602+/*
603+* Copyright (C) 2013 Canonical Ltd
604+*
605+* This program is free software: you can redistribute it and/or modify
606+* it under the terms of the GNU General Public License version 3 as
607+* published by the Free Software Foundation.
608+*
609+* This program is distributed in the hope that it will be useful,
610+* but WITHOUT ANY WARRANTY; without even the implied warranty of
611+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
612+* GNU General Public License for more details.
613+*
614+* You should have received a copy of the GNU General Public License
615+* along with this program. If not, see <http://www.gnu.org/licenses/>.
616+*
617+* Authored by: Marco Trevisan (Treviño) <marco@ubuntu.com>
618+*/
619+
620+#ifndef UNITYSHELL_SESSION_CONTROLLER_H
621+#define UNITYSHELL_SESSION_CONTROLLER_H
622+
623+#include <memory>
624+
625+#include <Nux/Nux.h>
626+#include <Nux/BaseWindow.h>
627+#include <Nux/HLayout.h>
628+#include <NuxCore/Color.h>
629+#include <NuxCore/Animation.h>
630+#include <UnityCore/SessionManager.h>
631+
632+#include "SessionView.h"
633+#include "unity-shared/UBusWrapper.h"
634+
635+namespace unity
636+{
637+namespace session
638+{
639+
640+class Controller : public debug::Introspectable
641+{
642+public:
643+ typedef std::shared_ptr<Controller> Ptr;
644+
645+ Controller(session::Manager::Ptr const& manager);
646+ virtual ~Controller() = default;
647+
648+ void Show(View::Mode mode);
649+ void Hide();
650+
651+ bool Visible() const;
652+
653+protected:
654+ // Introspectable
655+ std::string GetName() const;
656+ void AddProperties(GVariantBuilder* builder);
657+
658+private:
659+ friend class TestSessionController;
660+
661+ void Show(View::Mode mode, bool inhibitors);
662+ void CancelAndHide();
663+ void ConstructView();
664+ void EnsureView();
665+ void CloseWindow();
666+ void OnBackgroundUpdate(GVariant* data);
667+ nux::Point GetOffsetPerMonitor(int monitor);
668+
669+ View::Ptr view_;
670+ nux::ObjectPtr<nux::BaseWindow> view_window_;
671+ nux::Point adjustment_;
672+ session::Manager::Ptr manager_;
673+
674+ nux::Color bg_color_;
675+
676+ nux::animation::AnimateValue<double> fade_animator_;
677+ UBusManager ubus_manager_;
678+};
679+
680+}
681+}
682+
683+#endif
684
685=== added file 'shutdown/SessionView.cpp'
686--- shutdown/SessionView.cpp 1970-01-01 00:00:00 +0000
687+++ shutdown/SessionView.cpp 2013-03-07 22:50:34 +0000
688@@ -0,0 +1,326 @@
689+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
690+/*
691+* Copyright (C) 2013 Canonical Ltd
692+*
693+* This program is free software: you can redistribute it and/or modify
694+* it under the terms of the GNU General Public License version 3 as
695+* published by the Free Software Foundation.
696+*
697+* This program is distributed in the hope that it will be useful,
698+* but WITHOUT ANY WARRANTY; without even the implied warranty of
699+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
700+* GNU General Public License for more details.
701+*
702+* You should have received a copy of the GNU General Public License
703+* along with this program. If not, see <http://www.gnu.org/licenses/>.
704+*
705+* Authored by: Marco Trevisan (Treviño) <marco@ubuntu.com>
706+*/
707+
708+#include "SessionView.h"
709+#include "SessionButton.h"
710+
711+#include <Nux/VLayout.h>
712+#include <UnityCore/GLibWrapper.h>
713+#include <UnityCore/Variant.h>
714+#include <glib/gi18n-lib.h>
715+
716+namespace unity
717+{
718+namespace session
719+{
720+
721+namespace style
722+{
723+ const std::string FONT = "Ubuntu Light";
724+ const std::string TITLE_FONT = FONT+" 15";
725+ const std::string SUBTITLE_FONT = FONT+" 12";
726+
727+ const unsigned LEFT_RIGHT_PADDING = 30;
728+ const unsigned TOP_PADDING = 19;
729+ const unsigned BOTTOM_PADDING = 12;
730+ const unsigned MAIN_SPACE = 10;
731+ const unsigned BUTTONS_SPACE = 20;
732+}
733+
734+NUX_IMPLEMENT_OBJECT_TYPE(View);
735+
736+View::View(Manager::Ptr const& manager)
737+ : mode(Mode::FULL)
738+ , manager_(manager)
739+{
740+ closable = true;
741+ auto main_layout = new nux::VLayout();
742+ main_layout->SetTopAndBottomPadding(style::TOP_PADDING, style::BOTTOM_PADDING);
743+ main_layout->SetLeftAndRightPadding(style::LEFT_RIGHT_PADDING);
744+ main_layout->SetSpaceBetweenChildren(style::MAIN_SPACE);
745+ SetLayout(main_layout);
746+
747+ title_ = new StaticCairoText("");
748+ title_->SetFont(style::TITLE_FONT);
749+ title_->SetTextAlignment(StaticCairoText::AlignState::NUX_ALIGN_LEFT);
750+ title_->SetInputEventSensitivity(false);
751+ title_->SetVisible(false);
752+ main_layout->AddView(title_);
753+
754+ subtitle_ = new StaticCairoText("");
755+ subtitle_->SetFont(style::SUBTITLE_FONT);
756+ subtitle_->SetTextAlignment(StaticCairoText::AlignState::NUX_ALIGN_LEFT);
757+ subtitle_->SetInputEventSensitivity(false);
758+ subtitle_->SetLines(std::numeric_limits<int>::min());
759+ subtitle_->SetLineSpacing(2);
760+ main_layout->AddView(subtitle_);
761+
762+ buttons_layout_ = new nux::HLayout();
763+ buttons_layout_->SetSpaceBetweenChildren(style::BUTTONS_SPACE);
764+ main_layout->AddLayout(buttons_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_PERCENTAGE, 0.0f);
765+
766+ GetBoundingArea()->mouse_click.connect([this] (int, int, unsigned long, unsigned long) { request_close.emit(); });
767+
768+ have_inhibitors.changed.connect(sigc::hide(sigc::mem_fun(this, &View::UpdateText)));
769+
770+ mode.SetSetterFunction([this] (Mode& target, Mode new_mode) {
771+ if (new_mode == Mode::SHUTDOWN && !manager_->CanShutdown())
772+ new_mode = Mode::LOGOUT;
773+
774+ if (target != new_mode)
775+ {
776+ target = new_mode;
777+ return true;
778+ }
779+
780+ return false;
781+ });
782+
783+ mode.changed.connect([this] (Mode m) {
784+ UpdateText();
785+ Populate();
786+ });
787+
788+ UpdateText();
789+ Populate();
790+}
791+
792+void View::UpdateText()
793+{
794+ const char* message = nullptr;
795+ auto const& real_name = manager_->RealName();
796+ auto const& name = (real_name.empty() ? manager_->UserName() : real_name);
797+
798+ if (mode() == Mode::SHUTDOWN)
799+ {
800+ title_->SetText(_("Shut Down"));
801+ title_->SetVisible(true);
802+
803+ if (have_inhibitors())
804+ {
805+ message = _("Hi %s, you have open files that you might want to save " \
806+ "before shutting down. Are you sure you want to continue?");
807+ }
808+ else
809+ {
810+ message = _("Goodbye %s! Are you sure you want to close all programs " \
811+ "and shut down the computer?");
812+ }
813+ }
814+ else if (mode() == Mode::LOGOUT)
815+ {
816+ title_->SetText(_("Log Out"));
817+ title_->SetVisible(true);
818+
819+ if (have_inhibitors())
820+ {
821+ message = _("Hi %s, you have open files that you might want to save " \
822+ "before logging out. Are you sure you want to continue?");
823+ }
824+ else
825+ {
826+ message = _("Goodbye %s! Are you sure you want to close all programs " \
827+ "and log out from your account?");
828+ }
829+ }
830+ else
831+ {
832+ title_->SetVisible(false);
833+
834+ if (have_inhibitors())
835+ {
836+ message = _("Hi %s, you have open files that you might want to save " \
837+ "before shutting down.\nWould you like to…");
838+ }
839+ else
840+ {
841+ message = _("Goodbye %s! Would you like to…");
842+ }
843+ }
844+
845+ subtitle_->SetText(glib::String(g_strdup_printf(message, name.c_str())).Str());
846+}
847+
848+void View::Populate()
849+{
850+ debug::Introspectable::RemoveAllChildren();
851+ buttons_layout_->Clear();
852+
853+ if (mode() == Mode::LOGOUT)
854+ {
855+ auto* button = new Button(_("Lock"), "lockscreen", NUX_TRACKER_LOCATION);
856+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::LockScreen));
857+ AddButton(button);
858+
859+ button = new Button(_("Logout"), "logout", NUX_TRACKER_LOCATION);
860+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Logout));
861+ AddButton(button);
862+ }
863+ else
864+ {
865+ if (mode() == Mode::FULL)
866+ {
867+ auto* button = new Button(_("Lock"), "lockscreen", NUX_TRACKER_LOCATION);
868+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::LockScreen));
869+ AddButton(button);
870+
871+ if (manager_->CanSuspend())
872+ {
873+ button = new Button(_("Suspend"), "suspend", NUX_TRACKER_LOCATION);
874+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Suspend));
875+ AddButton(button);
876+ }
877+
878+ if (manager_->CanHibernate())
879+ {
880+ button = new Button(_("Hibernate"), "hibernate", NUX_TRACKER_LOCATION);
881+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Hibernate));
882+ AddButton(button);
883+ }
884+ }
885+
886+ if (manager_->CanShutdown())
887+ {
888+ auto* button = new Button(_("Shutdown"), "shutdown", NUX_TRACKER_LOCATION);
889+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Shutdown));
890+ AddButton(button);
891+
892+ button = new Button(_("Restart"), "restart", NUX_TRACKER_LOCATION);
893+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Reboot));
894+ AddButton(button);
895+ }
896+ else if (mode() == Mode::FULL)
897+ {
898+ auto* button = new Button(_("Logout"), "logout", NUX_TRACKER_LOCATION);
899+ button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::Logout));
900+ AddButton(button);
901+ }
902+ }
903+}
904+
905+void View::AddButton(Button* button)
906+{
907+ button->activated.connect([this] {request_hide.emit();});
908+ buttons_layout_->AddView(button);
909+ debug::Introspectable::AddChild(button);
910+
911+ // This resets back the keyboard focus to the view when a button is unselected
912+ button->highlighted.changed.connect([this] (bool value) {
913+ if (!value)
914+ nux::GetWindowCompositor().SetKeyFocusArea(this);
915+ });
916+
917+ // This function ensures that when an item is activated, the button state
918+ // is reset as soon as the parent window has been closed.
919+ button->activated.connect([this, button] {
920+ auto* top_win = static_cast<nux::BaseWindow*>(GetTopLevelViewWindow());
921+ if (top_win && top_win->IsVisible())
922+ {
923+ auto conn = std::make_shared<sigc::connection>();
924+ *conn = top_win->sigHidden.connect([this, button, conn] (nux::BaseWindow*) {
925+ button->highlighted = false;
926+ conn->disconnect();
927+ });
928+ }
929+ else
930+ {
931+ button->highlighted = false;
932+ }
933+ });
934+}
935+
936+void View::PreLayoutManagement()
937+{
938+ subtitle_->SetMaximumWidth(buttons_layout_->GetContentWidth());
939+
940+ nux::View::PreLayoutManagement();
941+}
942+
943+nux::Geometry View::GetBackgroundGeometry()
944+{
945+ return GetGeometry();
946+}
947+
948+void View::DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip)
949+{
950+ view_layout_->ProcessDraw(GfxContext, force_draw);
951+}
952+
953+nux::Area* View::FindKeyFocusArea(unsigned etype, unsigned long key_code, unsigned long modifiers)
954+{
955+ if (etype != nux::NUX_KEYDOWN)
956+ return UnityWindowView::FindKeyFocusArea(etype, key_code, modifiers);
957+
958+ if (key_code == NUX_VK_LEFT || key_code == NUX_VK_RIGHT)
959+ {
960+ nux::InputArea* focused = nux::GetWindowCompositor().GetKeyFocusArea();
961+
962+ if (!focused || focused == this || !focused->IsChildOf(this))
963+ {
964+ if (key_code == NUX_VK_LEFT)
965+ {
966+ return buttons_layout_->GetChildren().front();
967+ }
968+ else if (key_code == NUX_VK_RIGHT)
969+ {
970+ return buttons_layout_->GetChildren().back();
971+ }
972+ }
973+ }
974+ else if (key_code == NUX_VK_ESCAPE)
975+ {
976+ nux::InputArea* focused = nux::GetWindowCompositor().GetKeyFocusArea();
977+
978+ if (!focused || !focused->IsMouseInside())
979+ return this;
980+ }
981+
982+ return UnityWindowView::FindKeyFocusArea(etype, key_code, modifiers);
983+}
984+
985+nux::Area* View::KeyNavIteration(nux::KeyNavDirection direction)
986+{
987+ if (direction == nux::KEY_NAV_LEFT)
988+ return buttons_layout_->GetChildren().back();
989+ else if (direction == nux::KEY_NAV_RIGHT)
990+ return buttons_layout_->GetChildren().front();
991+
992+ return nux::View::KeyNavIteration(direction);
993+}
994+
995+//
996+// Introspectable methods
997+//
998+std::string View::GetName() const
999+{
1000+ return "SessionView";
1001+}
1002+
1003+void View::AddProperties(GVariantBuilder* builder)
1004+{
1005+ UnityWindowView::AddProperties(builder);
1006+ variant::BuilderWrapper(builder)
1007+ .add("mode", static_cast<int>(mode()))
1008+ .add("inhibitors", have_inhibitors())
1009+ .add("title",title_->GetText())
1010+ .add("subtitle",subtitle_->GetText());
1011+}
1012+
1013+} // namespace session
1014+} // namespace unity
1015
1016=== added file 'shutdown/SessionView.h'
1017--- shutdown/SessionView.h 1970-01-01 00:00:00 +0000
1018+++ shutdown/SessionView.h 2013-03-07 22:50:34 +0000
1019@@ -0,0 +1,86 @@
1020+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1021+/*
1022+* Copyright (C) 2013 Canonical Ltd
1023+*
1024+* This program is free software: you can redistribute it and/or modify
1025+* it under the terms of the GNU General Public License version 3 as
1026+* published by the Free Software Foundation.
1027+*
1028+* This program is distributed in the hope that it will be useful,
1029+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1030+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1031+* GNU General Public License for more details.
1032+*
1033+* You should have received a copy of the GNU General Public License
1034+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1035+*
1036+* Authored by: Marco Trevisan (Treviño) <marco@ubuntu.com>
1037+*/
1038+
1039+#ifndef UNITYSHELL_SESSION_VIEW_H
1040+#define UNITYSHELL_SESSION_VIEW_H
1041+
1042+#include <Nux/Nux.h>
1043+#include <Nux/View.h>
1044+#include <Nux/HLayout.h>
1045+
1046+#include "unity-shared/UnityWindowView.h"
1047+
1048+namespace unity
1049+{
1050+class StaticCairoText;
1051+namespace session
1052+{
1053+class Button;
1054+
1055+class View : public ui::UnityWindowView
1056+{
1057+ NUX_DECLARE_OBJECT_TYPE(View, ui::UnityWindowView);
1058+public:
1059+ typedef nux::ObjectPtr<View> Ptr;
1060+
1061+ enum class Mode
1062+ {
1063+ FULL,
1064+ SHUTDOWN,
1065+ LOGOUT
1066+ };
1067+
1068+ View(Manager::Ptr const& manager);
1069+
1070+ nux::Property<Mode> mode;
1071+ nux::Property<bool> have_inhibitors;
1072+
1073+ sigc::signal<void> request_hide;
1074+
1075+protected:
1076+ void PreLayoutManagement();
1077+ void DrawOverlay(nux::GraphicsEngine&, bool force, nux::Geometry const&);
1078+ nux::Geometry GetBackgroundGeometry();
1079+
1080+ nux::Area* FindKeyFocusArea(unsigned etype, unsigned long key, unsigned long mod);
1081+ nux::Area* KeyNavIteration(nux::KeyNavDirection);
1082+
1083+ // Introspectable methods
1084+ std::string GetName() const;
1085+ void AddProperties(GVariantBuilder* builder);
1086+
1087+private:
1088+ friend class TestSessionView;
1089+
1090+ void UpdateText();
1091+ void Populate();
1092+ void AddButton(Button*);
1093+
1094+ Manager::Ptr manager_;
1095+ StaticCairoText* title_;
1096+ StaticCairoText* subtitle_;
1097+ nux::HLayout* buttons_layout_;
1098+};
1099+
1100+} // namespace session
1101+
1102+} // namespace unity
1103+
1104+#endif // UNITYSHELL_SESSION_VIEW_H
1105+
1106
1107=== added file 'shutdown/StandaloneSession.cpp'
1108--- shutdown/StandaloneSession.cpp 1970-01-01 00:00:00 +0000
1109+++ shutdown/StandaloneSession.cpp 2013-03-07 22:50:34 +0000
1110@@ -0,0 +1,99 @@
1111+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1112+/*
1113+ * Copyright (C) 2013 Canonical Ltd
1114+ *
1115+ * This program is free software: you can redistribute it and/or modify
1116+ * it under the terms of the GNU General Public License version 3 as
1117+ * published by the Free Software Foundation.
1118+ *
1119+ * This program is distributed in the hope that it will be useful,
1120+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1121+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1122+ * GNU General Public License for more details.
1123+ *
1124+ * You should have received a copy of the GNU General Public License
1125+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1126+ *
1127+ * Authored by: Marco Trevisan <marco@ubuntu.com>
1128+ */
1129+
1130+#include "config.h"
1131+#include <glib/gi18n-lib.h>
1132+#include <gtk/gtk.h>
1133+#include <Nux/Nux.h>
1134+#include <Nux/NuxTimerTickSource.h>
1135+#include <Nux/WindowThread.h>
1136+#include <NuxCore/AnimationController.h>
1137+
1138+#include "unity-shared/BackgroundEffectHelper.h"
1139+#include "SessionController.h"
1140+#include "unity-shared/UnitySettings.h"
1141+
1142+using namespace unity;
1143+
1144+class MockSessionManager : public session::Manager
1145+{
1146+public:
1147+ MockSessionManager() = default;
1148+
1149+ std::string RealName() const { return "Marco Trevisan"; }
1150+ std::string UserName() const { return "marco"; }
1151+
1152+ void LockScreen() { std::cout << "LockScreen" << std::endl; }
1153+ void Logout() { std::cout << "Logout" << std::endl; }
1154+ void Reboot() { std::cout << "Reboot" << std::endl; }
1155+ void Shutdown() { std::cout << "Shutdown" << std::endl; }
1156+ void Suspend() { std::cout << "Suspend" << std::endl; }
1157+ void Hibernate() { std::cout << "Hibernate" << std::endl; }
1158+
1159+ void CancelAction() { std::cout << "CancelAction" << std::endl; }
1160+
1161+ bool CanShutdown() const {return true;}
1162+ bool CanSuspend() const {return true;}
1163+ bool CanHibernate() const {return true;}
1164+};
1165+
1166+struct SessionWindow
1167+{
1168+ SessionWindow()
1169+ : wt(nux::CreateGUIThread("Unity Session Controller", 1024, 300, 0, &SessionWindow::ThreadWidgetInit, this))
1170+ , animation_controller(tick_source)
1171+ {}
1172+
1173+ void Show()
1174+ {
1175+ wt->Run(nullptr);
1176+ }
1177+
1178+private:
1179+ void Init();
1180+
1181+ static void ThreadWidgetInit(nux::NThread* thread, void* self)
1182+ {
1183+ static_cast<SessionWindow*>(self)->Init();
1184+ }
1185+
1186+ unity::Settings settings;
1187+ std::shared_ptr<nux::WindowThread> wt;
1188+ nux::NuxTimerTickSource tick_source;
1189+ nux::animation::AnimationController animation_controller;
1190+ session::Controller::Ptr controller;
1191+};
1192+
1193+void SessionWindow::Init()
1194+{
1195+ BackgroundEffectHelper::blur_type = BLUR_NONE;
1196+ auto manager = std::make_shared<MockSessionManager>();
1197+ controller = std::make_shared<session::Controller>(manager);
1198+ manager->shutdown_requested.emit(false);
1199+}
1200+
1201+int main(int argc, char** argv)
1202+{
1203+ gtk_init(&argc, &argv);
1204+
1205+ nux::NuxInitialize(0);
1206+ SessionWindow().Show();
1207+
1208+ return 0;
1209+}
1210
1211=== added directory 'shutdown/pch'
1212=== added file 'shutdown/pch/shutdown_pch.hh'
1213--- shutdown/pch/shutdown_pch.hh 1970-01-01 00:00:00 +0000
1214+++ shutdown/pch/shutdown_pch.hh 2013-03-07 22:50:34 +0000
1215@@ -0,0 +1,29 @@
1216+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1217+/*
1218+ * Copyright (C) 2012 Canonical Ltd
1219+ *
1220+ * This program is free software: you can redistribute it and/or modify
1221+ * it under the terms of the GNU General Public License version 3 as
1222+ * published by the Free Software Foundation.
1223+ *
1224+ * This program is distributed in the hope that it will be useful,
1225+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1226+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1227+ * GNU General Public License for more details.
1228+ *
1229+ * You should have received a copy of the GNU General Public License
1230+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1231+ *
1232+ * Authored by: Jussi Pakkanen <jussi.pakkanen@canonical.com>
1233+ */
1234+
1235+/*
1236+ * These are the precompiled header includes for this module.
1237+ * Only system header files can be listed here.
1238+ */
1239+
1240+#include <memory>
1241+
1242+#include <Nux/Nux.h>
1243+#include <NuxCore/Property.h>
1244+#include <UnityCore/GnomeSessionManager.h>
1245
1246=== modified file 'tests/CMakeLists.txt'
1247--- tests/CMakeLists.txt 2013-03-07 22:50:33 +0000
1248+++ tests/CMakeLists.txt 2013-03-07 22:50:34 +0000
1249@@ -49,6 +49,7 @@
1250 include_directories (${CMAKE_SOURCE_DIR}/panel)
1251 include_directories (${CMAKE_SOURCE_DIR}/hud)
1252 include_directories (${CMAKE_SOURCE_DIR}/shortcuts)
1253+include_directories (${CMAKE_SOURCE_DIR}/shutdown)
1254 include_directories (${CMAKE_SOURCE_DIR}/unity-shared)
1255 # We can't have convenience libs so we need to rebuild with what we need
1256 # Please keep actual test files alphabetically at top and then files
1257@@ -244,6 +245,9 @@
1258 test_result_renderer.cpp
1259 test_resultviewgrid.cpp
1260 test_searchbar.cpp
1261+ test_session_button.cpp
1262+ test_session_controller.cpp
1263+ test_session_view.cpp
1264 test_shortcut_controller.cpp
1265 test_shortcut_modeller_compiz.cpp
1266 test_shortcut_view.cpp
1267@@ -280,7 +284,22 @@
1268 gmockmount.c
1269 gmockvolume.c
1270 )
1271- target_link_libraries(test-gtest test-gtest-plainc gtest gmock unity-shared ${LIBS} launcher-lib unity-shared-bamf unity-shared-standalone shortcuts-lib previews-lib hud-lib switcher-lib dash-lib panel-lib)
1272+ target_link_libraries(test-gtest
1273+ test-gtest-plainc
1274+ gtest
1275+ gmock
1276+ unity-shared
1277+ ${LIBS}
1278+ launcher-lib
1279+ unity-shared-bamf
1280+ unity-shared-standalone
1281+ shortcuts-lib
1282+ previews-lib
1283+ hud-lib
1284+ switcher-lib
1285+ shutdown-lib
1286+ dash-lib
1287+ panel-lib)
1288 add_test(UnityGTest test-gtest)
1289 endif (ENABLE_X_SUPPORT)
1290 endif (GTEST_SRC_DIR AND
1291
1292=== added file 'tests/test_mock_session_manager.h'
1293--- tests/test_mock_session_manager.h 1970-01-01 00:00:00 +0000
1294+++ tests/test_mock_session_manager.h 2013-03-07 22:50:34 +0000
1295@@ -0,0 +1,49 @@
1296+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1297+/*
1298+ * Copyright (C) 2013 Canonical Ltd
1299+ *
1300+ * This program is free software: you can redistribute it and/or modify
1301+ * it under the terms of the GNU General Public License version 3 as
1302+ * published by the Free Software Foundation.
1303+ *
1304+ * This program is distributed in the hope that it will be useful,
1305+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1306+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1307+ * GNU General Public License for more details.
1308+ *
1309+ * You should have received a copy of the GNU General Public License
1310+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1311+ *
1312+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
1313+ */
1314+
1315+#include <gmock/gmock.h>
1316+#include <UnityCore/SessionManager.h>
1317+
1318+namespace unity
1319+{
1320+namespace session
1321+{
1322+
1323+struct MockManager : Manager
1324+{
1325+ typedef std::shared_ptr<MockManager> Ptr;
1326+
1327+ MOCK_CONST_METHOD0(RealName, std::string());
1328+ MOCK_CONST_METHOD0(UserName, std::string());
1329+
1330+ MOCK_METHOD0(LockScreen, void());
1331+ MOCK_METHOD0(Logout, void());
1332+ MOCK_METHOD0(Reboot, void());
1333+ MOCK_METHOD0(Shutdown, void());
1334+ MOCK_METHOD0(Suspend, void());
1335+ MOCK_METHOD0(Hibernate, void());
1336+ MOCK_METHOD0(CancelAction, void());
1337+
1338+ MOCK_CONST_METHOD0(CanShutdown, bool());
1339+ MOCK_CONST_METHOD0(CanSuspend, bool());
1340+ MOCK_CONST_METHOD0(CanHibernate, bool());
1341+};
1342+
1343+} // session
1344+} // unity
1345\ No newline at end of file
1346
1347=== added file 'tests/test_session_button.cpp'
1348--- tests/test_session_button.cpp 1970-01-01 00:00:00 +0000
1349+++ tests/test_session_button.cpp 2013-03-07 22:50:34 +0000
1350@@ -0,0 +1,124 @@
1351+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1352+/*
1353+ * Copyright (C) 2013 Canonical Ltd
1354+ *
1355+ * This program is free software: you can redistribute it and/or modify
1356+ * it under the terms of the GNU General Public License version 3 as
1357+ * published by the Free Software Foundation.
1358+ *
1359+ * This program is distributed in the hope that it will be useful,
1360+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1361+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1362+ * GNU General Public License for more details.
1363+ *
1364+ * You should have received a copy of the GNU General Public License
1365+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1366+ *
1367+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
1368+ */
1369+
1370+#include <gmock/gmock.h>
1371+#include "SessionButton.h"
1372+
1373+using namespace unity::session;
1374+
1375+namespace unity
1376+{
1377+namespace session
1378+{
1379+
1380+struct TestSessionButton : testing::Test
1381+{
1382+ struct ButtonWrap : Button
1383+ {
1384+ ButtonWrap() : Button("ButtonLabel", "hibernate") {}
1385+
1386+ using Button::AcceptKeyNavFocusOnMouseEnter;
1387+ using Button::AcceptKeyNavFocusOnMouseDown;
1388+ using Button::image_view_;
1389+ using Button::highlight_tex_;
1390+ using Button::normal_tex_;
1391+ using Button::label_view_;
1392+ };
1393+
1394+ ButtonWrap button;
1395+};
1396+
1397+TEST_F(TestSessionButton, Construct)
1398+{
1399+ EXPECT_FALSE(button.highlighted());
1400+ EXPECT_EQ(button.label(), "ButtonLabel");
1401+ EXPECT_TRUE(button.AcceptKeyNavFocusOnMouseEnter());
1402+ EXPECT_FALSE(button.AcceptKeyNavFocusOnMouseDown());
1403+}
1404+
1405+TEST_F(TestSessionButton, HighlightUpdatesTextures)
1406+{
1407+ button.highlighted = true;
1408+ EXPECT_EQ(button.image_view_->texture(), button.highlight_tex_);
1409+}
1410+
1411+TEST_F(TestSessionButton, HighlightShowsText)
1412+{
1413+ button.highlighted = true;
1414+ EXPECT_NE(button.label_view_->GetTextColor(), nux::color::Transparent);
1415+}
1416+
1417+TEST_F(TestSessionButton, UnHighlightUpdatesTextures)
1418+{
1419+ button.highlighted = true;
1420+ button.highlighted = false;
1421+ EXPECT_EQ(button.image_view_->texture(), button.normal_tex_);
1422+}
1423+
1424+TEST_F(TestSessionButton, UnHighlightHidesText)
1425+{
1426+ button.highlighted = true;
1427+ button.highlighted = false;
1428+ EXPECT_EQ(button.label_view_->GetTextColor(), nux::color::Transparent);
1429+}
1430+
1431+TEST_F(TestSessionButton, MouseEnterHighlights)
1432+{
1433+ button.mouse_enter.emit(0, 0, 0, 0);
1434+ EXPECT_TRUE(button.highlighted());
1435+}
1436+
1437+TEST_F(TestSessionButton, MouseLeaveUnhighlights)
1438+{
1439+ button.highlighted = true;
1440+ button.mouse_leave.emit(0, 0, 0, 0);
1441+ EXPECT_FALSE(button.highlighted());
1442+}
1443+
1444+TEST_F(TestSessionButton, MouseClickActivatesIt)
1445+{
1446+ bool activated = false;
1447+ button.activated.connect([&activated] { activated = true; });
1448+ button.mouse_click.emit(0, 0, 0, 0);
1449+ EXPECT_TRUE(activated);
1450+}
1451+
1452+TEST_F(TestSessionButton, KeyFocusBeginHighlights)
1453+{
1454+ button.begin_key_focus.emit();
1455+ EXPECT_TRUE(button.highlighted());
1456+}
1457+
1458+TEST_F(TestSessionButton, KeyFocusEndUnhighlights)
1459+{
1460+ button.highlighted = true;
1461+ button.end_key_focus.emit();
1462+ EXPECT_FALSE(button.highlighted());
1463+}
1464+
1465+TEST_F(TestSessionButton, KeyFocusActivatesIt)
1466+{
1467+ bool activated = false;
1468+ button.activated.connect([&activated] { activated = true; });
1469+ button.key_nav_focus_activate.emit(&button);
1470+ EXPECT_TRUE(activated);
1471+}
1472+
1473+} // session
1474+} // unity
1475\ No newline at end of file
1476
1477=== added file 'tests/test_session_controller.cpp'
1478--- tests/test_session_controller.cpp 1970-01-01 00:00:00 +0000
1479+++ tests/test_session_controller.cpp 2013-03-07 22:50:34 +0000
1480@@ -0,0 +1,162 @@
1481+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1482+/*
1483+ * Copyright (C) 2013 Canonical Ltd
1484+ *
1485+ * This program is free software: you can redistribute it and/or modify
1486+ * it under the terms of the GNU General Public License version 3 as
1487+ * published by the Free Software Foundation.
1488+ *
1489+ * This program is distributed in the hope that it will be useful,
1490+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1491+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1492+ * GNU General Public License for more details.
1493+ *
1494+ * You should have received a copy of the GNU General Public License
1495+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1496+ *
1497+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
1498+ */
1499+
1500+#include <gmock/gmock.h>
1501+#include <Nux/NuxTimerTickSource.h>
1502+#include <NuxCore/AnimationController.h>
1503+#include "test_mock_session_manager.h"
1504+#include "SessionController.h"
1505+#include "UnitySettings.h"
1506+
1507+namespace unity
1508+{
1509+namespace session
1510+{
1511+
1512+const unsigned ANIMATION_DURATION = 90 * 1000; // in microseconds
1513+
1514+struct TestSessionController : testing::Test
1515+{
1516+ TestSessionController()
1517+ : animation_controller(tick_source)
1518+ , manager(std::make_shared<testing::NiceMock<MockManager>>())
1519+ , controller(manager)
1520+ {
1521+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(true));
1522+ }
1523+
1524+ struct ControllerWrap : Controller
1525+ {
1526+ ControllerWrap(Manager::Ptr const& manager) : Controller(manager) {}
1527+
1528+ using Controller::view_;
1529+ using Controller::view_window_;
1530+ };
1531+
1532+ nux::NuxTimerTickSource tick_source;
1533+ nux::animation::AnimationController animation_controller;
1534+ unity::Settings settings;
1535+ MockManager::Ptr manager;
1536+ ControllerWrap controller;
1537+};
1538+
1539+TEST_F(TestSessionController, Construct)
1540+{
1541+ EXPECT_FALSE(controller.Visible());
1542+}
1543+
1544+struct ShowMode : TestSessionController, testing::WithParamInterface<View::Mode> {};
1545+INSTANTIATE_TEST_CASE_P(TestSessionController, ShowMode,
1546+ testing::Values(View::Mode::SHUTDOWN, View::Mode::LOGOUT, View::Mode::FULL));
1547+
1548+TEST_P(/*TestSessionController*/ShowMode, Show)
1549+{
1550+ controller.Show(GetParam());
1551+ EXPECT_TRUE(controller.Visible());
1552+ EXPECT_EQ(controller.view_->mode(), GetParam());
1553+ EXPECT_EQ(nux::GetWindowCompositor().GetKeyFocusArea(), controller.view_.GetPointer());
1554+ EXPECT_TRUE(controller.view_->live_background());
1555+}
1556+
1557+TEST_F(TestSessionController, Hide)
1558+{
1559+ controller.Show(View::Mode::FULL);
1560+ ASSERT_TRUE(controller.Visible());
1561+ EXPECT_CALL(*manager, CancelAction()).Times(0);
1562+
1563+ controller.Hide();
1564+ tick_source.tick(ANIMATION_DURATION);
1565+
1566+ EXPECT_FALSE(controller.Visible());
1567+ EXPECT_FALSE(controller.view_->live_background());
1568+}
1569+
1570+struct Inhibited : TestSessionController, testing::WithParamInterface<bool> {};
1571+INSTANTIATE_TEST_CASE_P(TestSessionController, Inhibited, testing::Values(true, false));
1572+
1573+TEST_P(/*TestSessionController*/Inhibited, RebootRequested)
1574+{
1575+ manager->reboot_requested.emit(GetParam());
1576+ EXPECT_TRUE(controller.Visible());
1577+ EXPECT_EQ(controller.view_->mode(), View::Mode::SHUTDOWN);
1578+ EXPECT_EQ(controller.view_->have_inhibitors(), GetParam());
1579+}
1580+
1581+TEST_P(/*TestSessionController*/Inhibited, ShutdownRequested)
1582+{
1583+ manager->shutdown_requested.emit(GetParam());
1584+ EXPECT_TRUE(controller.Visible());
1585+ EXPECT_EQ(controller.view_->mode(), View::Mode::FULL);
1586+ EXPECT_EQ(controller.view_->have_inhibitors(), GetParam());
1587+}
1588+
1589+TEST_P(/*TestSessionController*/Inhibited, LogoutRequested)
1590+{
1591+ manager->logout_requested.emit(GetParam());
1592+ EXPECT_TRUE(controller.Visible());
1593+ EXPECT_EQ(controller.view_->mode(), View::Mode::LOGOUT);
1594+ EXPECT_EQ(controller.view_->have_inhibitors(), GetParam());
1595+}
1596+
1597+TEST_F(TestSessionController, CancelRequested)
1598+{
1599+ controller.Show(View::Mode::FULL);
1600+ ASSERT_TRUE(controller.Visible());
1601+
1602+ EXPECT_CALL(*manager, CancelAction()).Times(0);
1603+ manager->cancel_requested.emit();
1604+ tick_source.tick(ANIMATION_DURATION);
1605+ EXPECT_FALSE(controller.Visible());
1606+}
1607+
1608+TEST_F(TestSessionController, RequestHide)
1609+{
1610+ controller.Show(View::Mode::FULL);
1611+ ASSERT_TRUE(controller.Visible());
1612+
1613+ EXPECT_CALL(*manager, CancelAction()).Times(0);
1614+ controller.view_->request_hide.emit();
1615+ tick_source.tick(ANIMATION_DURATION);
1616+ EXPECT_FALSE(controller.Visible());
1617+}
1618+
1619+TEST_F(TestSessionController, RequestClose)
1620+{
1621+ controller.Show(View::Mode::FULL);
1622+ ASSERT_TRUE(controller.Visible());
1623+
1624+ EXPECT_CALL(*manager, CancelAction());
1625+ controller.view_->request_close.emit();
1626+ tick_source.tick(ANIMATION_DURATION);
1627+ EXPECT_FALSE(controller.Visible());
1628+}
1629+
1630+TEST_F(TestSessionController, HidesAndCancelOnClickOutside)
1631+{
1632+ controller.Show(View::Mode::FULL);
1633+ ASSERT_TRUE(controller.Visible());
1634+
1635+ EXPECT_CALL(*manager, CancelAction());
1636+ controller.view_window_->mouse_down_outside_pointer_grab_area.emit(0, 0, 0, 0);
1637+ tick_source.tick(ANIMATION_DURATION);
1638+ EXPECT_FALSE(controller.Visible());
1639+}
1640+
1641+} // session
1642+} // unity
1643\ No newline at end of file
1644
1645=== added file 'tests/test_session_view.cpp'
1646--- tests/test_session_view.cpp 1970-01-01 00:00:00 +0000
1647+++ tests/test_session_view.cpp 2013-03-07 22:50:34 +0000
1648@@ -0,0 +1,280 @@
1649+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1650+/*
1651+ * Copyright (C) 2013 Canonical Ltd
1652+ *
1653+ * This program is free software: you can redistribute it and/or modify
1654+ * it under the terms of the GNU General Public License version 3 as
1655+ * published by the Free Software Foundation.
1656+ *
1657+ * This program is distributed in the hope that it will be useful,
1658+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1659+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1660+ * GNU General Public License for more details.
1661+ *
1662+ * You should have received a copy of the GNU General Public License
1663+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1664+ *
1665+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
1666+ */
1667+
1668+#include <gmock/gmock.h>
1669+#include "test_mock_session_manager.h"
1670+#include "SessionButton.h"
1671+#include "SessionView.h"
1672+#include "UnitySettings.h"
1673+
1674+namespace unity
1675+{
1676+namespace session
1677+{
1678+
1679+struct TestSessionView : testing::Test
1680+{
1681+ TestSessionView()
1682+ : manager(std::make_shared<testing::NiceMock<MockManager>>())
1683+ , view(manager)
1684+ {}
1685+
1686+ struct ViewWrap : View
1687+ {
1688+ ViewWrap(Manager::Ptr const& manager) : View(manager) {}
1689+
1690+ std::string GetTitle() const { return title_->IsVisible() ? title_->GetText() : ""; }
1691+ std::string GetSubTitle() const { return subtitle_->GetText(); }
1692+
1693+ std::list<Button*> GetButtons() const
1694+ {
1695+ std::list<Button*> buttons;
1696+
1697+ for (auto const& button : buttons_layout_->GetChildren())
1698+ {
1699+ auto session_button = dynamic_cast<Button*>(button);
1700+ EXPECT_NE(session_button, nullptr);
1701+
1702+ if (!session_button)
1703+ return std::list<Button*>();
1704+
1705+ buttons.push_back(session_button);
1706+ }
1707+
1708+ return buttons;
1709+ }
1710+
1711+ Button* GetButtonByLabel(std::string const& label) const
1712+ {
1713+ for (auto const& button : GetButtons())
1714+ {
1715+ if (button->label() == label)
1716+ return button;
1717+ }
1718+
1719+ return nullptr;
1720+ }
1721+ };
1722+
1723+ void TearDown()
1724+ {
1725+ nux::GetWindowCompositor().SetKeyFocusArea(nullptr);
1726+ }
1727+
1728+ unity::Settings settings;
1729+ MockManager::Ptr manager;
1730+ ViewWrap view;
1731+};
1732+
1733+TEST_F(TestSessionView, Construct)
1734+{
1735+ EXPECT_TRUE(view.closable());
1736+ EXPECT_FALSE(view.have_inhibitors());
1737+ EXPECT_EQ(view.mode(), View::Mode::FULL);
1738+}
1739+
1740+TEST_F(TestSessionView, RequestCloseOnBoundingAreaClick)
1741+{
1742+ bool request_close = false;
1743+ view.request_close.connect([&request_close] { request_close = true; });
1744+ view.GetBoundingArea()->mouse_click.emit(0, 0, 0, 0);
1745+ EXPECT_TRUE(request_close);
1746+}
1747+
1748+TEST_F(TestSessionView, ModeChange)
1749+{
1750+ view.mode = View::Mode::LOGOUT;
1751+ EXPECT_EQ(view.mode, View::Mode::LOGOUT);
1752+
1753+ view.mode = View::Mode::FULL;
1754+ EXPECT_EQ(view.mode, View::Mode::FULL);
1755+}
1756+
1757+TEST_F(TestSessionView, ModeChangeOnShutdownSupported)
1758+{
1759+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(true));
1760+
1761+ view.mode = View::Mode::SHUTDOWN;
1762+ EXPECT_EQ(view.mode, View::Mode::SHUTDOWN);
1763+}
1764+
1765+TEST_F(TestSessionView, ModeChangeOnShutdownUnsupported)
1766+{
1767+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(false));
1768+
1769+ view.mode = View::Mode::SHUTDOWN;
1770+ EXPECT_EQ(view.mode, View::Mode::LOGOUT);
1771+}
1772+
1773+TEST_F(TestSessionView, FullModeButtons)
1774+{
1775+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(true));
1776+ ON_CALL(*manager, CanSuspend()).WillByDefault(testing::Return(true));
1777+ ON_CALL(*manager, CanHibernate()).WillByDefault(testing::Return(true));
1778+ view.mode.changed.emit(View::Mode::FULL);
1779+
1780+ EXPECT_EQ(view.GetButtonByLabel("Logout"), nullptr);
1781+ EXPECT_NE(view.GetButtonByLabel("Lock"), nullptr);
1782+ EXPECT_NE(view.GetButtonByLabel("Suspend"), nullptr);
1783+ EXPECT_NE(view.GetButtonByLabel("Hibernate"), nullptr);
1784+ EXPECT_NE(view.GetButtonByLabel("Shutdown"), nullptr);
1785+ EXPECT_NE(view.GetButtonByLabel("Restart"), nullptr);
1786+
1787+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(false));
1788+ view.mode.changed.emit(View::Mode::FULL);
1789+
1790+ EXPECT_NE(view.GetButtonByLabel("Logout"), nullptr);
1791+ EXPECT_EQ(view.GetButtonByLabel("Shutdown"), nullptr);
1792+ EXPECT_EQ(view.GetButtonByLabel("Restart"), nullptr);
1793+
1794+ ON_CALL(*manager, CanSuspend()).WillByDefault(testing::Return(false));
1795+ view.mode.changed.emit(View::Mode::FULL);
1796+
1797+ EXPECT_EQ(view.GetButtonByLabel("Suspend"), nullptr);
1798+
1799+ ON_CALL(*manager, CanHibernate()).WillByDefault(testing::Return(false));
1800+ view.mode.changed.emit(View::Mode::FULL);
1801+
1802+ EXPECT_EQ(view.GetButtonByLabel("Hibernate"), nullptr);
1803+}
1804+
1805+TEST_F(TestSessionView, ShutdownModeButtons)
1806+{
1807+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(true));
1808+ view.mode = View::Mode::SHUTDOWN;
1809+
1810+ EXPECT_EQ(view.GetButtons().size(), 2);
1811+ EXPECT_NE(view.GetButtonByLabel("Shutdown"), nullptr);
1812+ EXPECT_NE(view.GetButtonByLabel("Restart"), nullptr);
1813+}
1814+
1815+TEST_F(TestSessionView, LogoutModeButtons)
1816+{
1817+ view.mode = View::Mode::LOGOUT;
1818+
1819+ EXPECT_EQ(view.GetButtons().size(), 2);
1820+ EXPECT_NE(view.GetButtonByLabel("Logout"), nullptr);
1821+ EXPECT_NE(view.GetButtonByLabel("Lock"), nullptr);
1822+}
1823+
1824+TEST_F(TestSessionView, FullModeTitle)
1825+{
1826+ EXPECT_TRUE(view.GetTitle().empty());
1827+}
1828+
1829+TEST_F(TestSessionView, ShutdownModeTitle)
1830+{
1831+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(true));
1832+ view.mode = View::Mode::SHUTDOWN;
1833+
1834+ EXPECT_EQ(view.GetTitle(), "Shut Down");
1835+}
1836+
1837+TEST_F(TestSessionView, LogoutModeTitle)
1838+{
1839+ view.mode = View::Mode::LOGOUT;
1840+
1841+ EXPECT_EQ(view.GetTitle(), "Log Out");
1842+}
1843+
1844+TEST_F(TestSessionView, ButtonsActivateRequestsHide)
1845+{
1846+ bool request_hide = false;
1847+ view.request_hide.connect([&request_hide] { request_hide = true; });
1848+
1849+ auto button = view.GetButtonByLabel("Lock");
1850+ ASSERT_NE(button, nullptr);
1851+ button->activated.emit();
1852+
1853+ EXPECT_TRUE(request_hide);
1854+}
1855+
1856+TEST_F(TestSessionView, ButtonsActivateDeselectButton)
1857+{
1858+ auto button = view.GetButtonByLabel("Lock");
1859+ ASSERT_NE(button, nullptr);
1860+ button->highlighted = true;
1861+ button->activated.emit();
1862+
1863+ EXPECT_FALSE(button->highlighted());
1864+}
1865+
1866+TEST_F(TestSessionView, LockButtonActivateLocks)
1867+{
1868+ EXPECT_CALL(*manager, LockScreen());
1869+ auto button = view.GetButtonByLabel("Lock");
1870+ ASSERT_NE(button, nullptr);
1871+ button->activated.emit();
1872+}
1873+
1874+TEST_F(TestSessionView, LogoutButtonActivateLogouts)
1875+{
1876+ view.mode = View::Mode::LOGOUT;
1877+ EXPECT_CALL(*manager, Logout());
1878+ auto button = view.GetButtonByLabel("Logout");
1879+ ASSERT_NE(button, nullptr);
1880+ button->activated.emit();
1881+}
1882+
1883+TEST_F(TestSessionView, SuspendButtonActivateSuspends)
1884+{
1885+ ON_CALL(*manager, CanSuspend()).WillByDefault(testing::Return(true));
1886+ view.mode.changed.emit(View::Mode::FULL);
1887+
1888+ EXPECT_CALL(*manager, Suspend());
1889+ auto button = view.GetButtonByLabel("Suspend");
1890+ ASSERT_NE(button, nullptr);
1891+ button->activated.emit();
1892+}
1893+
1894+TEST_F(TestSessionView, HibernateButtonActivateHibernates)
1895+{
1896+ ON_CALL(*manager, CanHibernate()).WillByDefault(testing::Return(true));
1897+ view.mode.changed.emit(View::Mode::FULL);
1898+
1899+ EXPECT_CALL(*manager, Hibernate());
1900+ auto button = view.GetButtonByLabel("Hibernate");
1901+ ASSERT_NE(button, nullptr);
1902+ button->activated.emit();
1903+}
1904+
1905+TEST_F(TestSessionView, ShutdownButtonActivateShutsdown)
1906+{
1907+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(true));
1908+ view.mode = View::Mode::SHUTDOWN;
1909+
1910+ EXPECT_CALL(*manager, Shutdown());
1911+ auto button = view.GetButtonByLabel("Shutdown");
1912+ ASSERT_NE(button, nullptr);
1913+ button->activated.emit();
1914+}
1915+
1916+TEST_F(TestSessionView, RebootButtonActivateReboots)
1917+{
1918+ ON_CALL(*manager, CanShutdown()).WillByDefault(testing::Return(true));
1919+ view.mode = View::Mode::SHUTDOWN;
1920+
1921+ EXPECT_CALL(*manager, Reboot());
1922+ auto button = view.GetButtonByLabel("Restart");
1923+ ASSERT_NE(button, nullptr);
1924+ button->activated.emit();
1925+}
1926+
1927+} // session
1928+} // unity
1929\ No newline at end of file
1930
1931=== modified file 'tests/test_unity_window_view.cpp'
1932--- tests/test_unity_window_view.cpp 2013-03-07 22:50:33 +0000
1933+++ tests/test_unity_window_view.cpp 2013-03-07 22:50:34 +0000
1934@@ -21,7 +21,6 @@
1935 #include "UnityWindowView.h"
1936 #include "UnitySettings.h"
1937 #include "WindowManager.h"
1938-#include "test_utils.h"
1939 #include <Nux/VLayout.h>
1940
1941 using namespace unity;
1942
1943=== modified file 'unity-shared/UnityWindowStyle.cpp'
1944--- unity-shared/UnityWindowStyle.cpp 2013-03-07 22:50:33 +0000
1945+++ unity-shared/UnityWindowStyle.cpp 2013-03-07 22:50:34 +0000
1946@@ -50,7 +50,7 @@
1947
1948 int UnityWindowStyle::GetCloseButtonPadding() const
1949 {
1950- return 2;
1951+ return 3;
1952 }
1953
1954 UnityWindowStyle::BaseTexturePtr UnityWindowStyle::GetCloseIcon()