Merge lp:~3v1n0/unity/shutdown-view into lp:unity
- shutdown-view
- Merge into trunk
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 | ||||||||
Related bugs: |
|
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://
Description of the change
Implemented a View to use the GnomeSessionMan
To post a comment you must log in.
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' |
112 | Binary 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' |
114 | Binary 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' |
116 | Binary 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' |
118 | Binary 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' |
120 | Binary 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' |
122 | Binary 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' |
124 | Binary 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' |
126 | Binary 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' |
128 | Binary 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' |
130 | Binary 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' |
132 | Binary 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' |
134 | Binary 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() |
Awesome work! Looks amazing:
Logout: i.imgur. com/T5ytfcN. png
http://
Shutdown: i.imgur. com/f4he5KH. png
http://
Code looks good, just a few more test. Approved. Will approve to merge once some more tests land :).