Merge lp:~3v1n0/unity/spread-launcher-desaturate into lp:unity
- spread-launcher-desaturate
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Brandon Schaefer |
Approved revision: | no longer in the source branch. |
Merged at revision: | 3577 |
Proposed branch: | lp:~3v1n0/unity/spread-launcher-desaturate |
Merge into: | lp:unity |
Diff against target: |
764 lines (+378/-74) 10 files modified
dash/DashController.h (+1/-1) hud/HudController.h (+1/-1) launcher/Launcher.cpp (+50/-9) launcher/Launcher.h (+1/-0) tests/autopilot/unity/tests/test_spread.py (+72/-2) tests/mock-base-window.h (+8/-6) tests/test_dash_controller.cpp (+21/-22) tests/test_hud_controller.cpp (+29/-19) tests/test_launcher.cpp (+194/-8) tests/test_switcher_controller_class.cpp (+1/-6) |
To merge this branch: | bzr merge lp:~3v1n0/unity/spread-launcher-desaturate |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Brandon Schaefer (community) | Approve | ||
Review via email: mp+192066@code.launchpad.net |
This proposal supersedes a proposal from 2013-10-11.
Commit message
Launcher: desaturate the inactive icons when in Spread mode
Description of the change
Desaturate the Launcher and hide tooltips when spread is initiated as designed.
Added unit and autopilot tests.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3578
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Christopher Townsend (townsend) wrote : Posted in a previous version of this proposal | # |
Seems Jenkins CI is segfaulting:
[ RUN ] TestLauncher.
Segmentation fault
I don't see that locally:(
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3578
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3582
http://
Executed test runs:
FAILURE: http://
None: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3584
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal | # |
LGTM
Brandon Schaefer (brandontschaefer) wrote : | # |
Still looks good!
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'dash/DashController.h' |
2 | --- dash/DashController.h 2013-10-03 13:18:57 +0000 |
3 | +++ dash/DashController.h 2013-10-21 23:51:09 +0000 |
4 | @@ -41,7 +41,7 @@ |
5 | namespace dash |
6 | { |
7 | |
8 | -class Controller : public unity::debug::Introspectable |
9 | +class Controller : public unity::debug::Introspectable, public sigc::trackable |
10 | { |
11 | public: |
12 | typedef std::shared_ptr<Controller> Ptr; |
13 | |
14 | === modified file 'hud/HudController.h' |
15 | --- hud/HudController.h 2013-10-16 03:42:03 +0000 |
16 | +++ hud/HudController.h 2013-10-21 23:51:09 +0000 |
17 | @@ -40,7 +40,7 @@ |
18 | namespace hud |
19 | { |
20 | |
21 | -class Controller : public unity::debug::Introspectable |
22 | +class Controller : public unity::debug::Introspectable, public sigc::trackable |
23 | { |
24 | public: |
25 | typedef std::shared_ptr<Controller> Ptr; |
26 | |
27 | === modified file 'launcher/Launcher.cpp' |
28 | --- launcher/Launcher.cpp 2013-10-04 03:55:52 +0000 |
29 | +++ launcher/Launcher.cpp 2013-10-21 23:51:09 +0000 |
30 | @@ -94,6 +94,7 @@ |
31 | const std::string START_DRAGICON_TIMEOUT = "start-dragicon-timeout"; |
32 | const std::string SCROLL_TIMEOUT = "scroll-timeout"; |
33 | const std::string ANIMATION_IDLE = "animation-idle"; |
34 | +const std::string SCALE_DESATURATE_IDLE = "scale-desaturate-idle"; |
35 | const std::string URGENT_TIMEOUT = "urgent-timeout"; |
36 | } |
37 | |
38 | @@ -173,9 +174,9 @@ |
39 | ql_manager.quicklist_closed.connect(sigc::mem_fun(this, &Launcher::RecvQuicklistClosed)); |
40 | |
41 | WindowManager& wm = WindowManager::Default(); |
42 | - wm.initiate_spread.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
43 | + wm.initiate_spread.connect(sigc::mem_fun(this, &Launcher::OnSpreadChanged)); |
44 | + wm.terminate_spread.connect(sigc::mem_fun(this, &Launcher::OnSpreadChanged)); |
45 | wm.initiate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
46 | - wm.terminate_spread.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
47 | wm.terminate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged)); |
48 | wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &Launcher::QueueDraw)); |
49 | |
50 | @@ -1125,23 +1126,30 @@ |
51 | } |
52 | } |
53 | |
54 | +// FIXME: add monitor-aware quirks! |
55 | void Launcher::DesaturateIcons() |
56 | { |
57 | - for (auto icon : *model_) |
58 | + bool inactive_only = WindowManager::Default().IsScaleActiveForGroup(); |
59 | + |
60 | + for (auto const& icon : *model_) |
61 | { |
62 | + bool desaturate = false; |
63 | + |
64 | if (icon->GetIconType () != AbstractLauncherIcon::IconType::HOME && |
65 | - icon->GetIconType () != AbstractLauncherIcon::IconType::HUD) |
66 | + icon->GetIconType () != AbstractLauncherIcon::IconType::HUD && |
67 | + (!inactive_only || !icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE))) |
68 | { |
69 | - icon->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, true); |
70 | + desaturate = true; |
71 | } |
72 | |
73 | + icon->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, desaturate); |
74 | icon->HideTooltip(); |
75 | } |
76 | } |
77 | |
78 | void Launcher::SaturateIcons() |
79 | { |
80 | - for (auto icon : *model_) |
81 | + for (auto const& icon : *model_) |
82 | { |
83 | icon->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, false); |
84 | } |
85 | @@ -1243,7 +1251,7 @@ |
86 | |
87 | bool Launcher::IsOverlayOpen() const |
88 | { |
89 | - return dash_is_open_ || hud_is_open_; |
90 | + return dash_is_open_ || hud_is_open_ || WindowManager::Default().IsScaleActive(); |
91 | } |
92 | |
93 | void Launcher::SetHidden(bool hide_launcher) |
94 | @@ -1303,8 +1311,34 @@ |
95 | void Launcher::OnPluginStateChanged() |
96 | { |
97 | WindowManager& wm = WindowManager::Default(); |
98 | - hide_machine_.SetQuirk(LauncherHideMachine::EXPO_ACTIVE, wm.IsExpoActive()); |
99 | - hide_machine_.SetQuirk(LauncherHideMachine::SCALE_ACTIVE, wm.IsScaleActive()); |
100 | + bool expo_active = wm.IsExpoActive(); |
101 | + hide_machine_.SetQuirk(LauncherHideMachine::EXPO_ACTIVE, expo_active); |
102 | + |
103 | + if (expo_active && icon_under_mouse_) |
104 | + icon_under_mouse_->HideTooltip(); |
105 | +} |
106 | + |
107 | +void Launcher::OnSpreadChanged() |
108 | +{ |
109 | + WindowManager& wm = WindowManager::Default(); |
110 | + bool active = wm.IsScaleActive(); |
111 | + hide_machine_.SetQuirk(LauncherHideMachine::SCALE_ACTIVE, active); |
112 | + |
113 | + bg_effect_helper_.enabled = active; |
114 | + |
115 | + if (active && icon_under_mouse_) |
116 | + icon_under_mouse_->HideTooltip(); |
117 | + |
118 | + if (active && (!hovered_ || wm.IsScaleActiveForGroup())) |
119 | + { |
120 | + // The icons can take some ms to update their active state, this can protect us. |
121 | + sources_.AddIdle([this] { DesaturateIcons(); return false; }, SCALE_DESATURATE_IDLE); |
122 | + } |
123 | + else |
124 | + { |
125 | + sources_.Remove(SCALE_DESATURATE_IDLE); |
126 | + SaturateIcons(); |
127 | + } |
128 | } |
129 | |
130 | LauncherHideMode Launcher::GetHideMode() const |
131 | @@ -2231,6 +2265,13 @@ |
132 | if (!hidden_) |
133 | UpdateChangeInMousePosition(dx, dy); |
134 | |
135 | + if (WindowManager::Default().IsScaleActiveForGroup()) |
136 | + { |
137 | + auto icon = MouseIconIntersection(x, y); |
138 | + if (icon && !icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE)) |
139 | + SaturateIcons(); |
140 | + } |
141 | + |
142 | // Every time the mouse moves, we check if it is inside an icon... |
143 | EventLogic(); |
144 | |
145 | |
146 | === modified file 'launcher/Launcher.h' |
147 | --- launcher/Launcher.h 2013-09-30 15:08:09 +0000 |
148 | +++ launcher/Launcher.h 2013-10-21 23:51:09 +0000 |
149 | @@ -200,6 +200,7 @@ |
150 | #endif |
151 | |
152 | void OnPluginStateChanged(); |
153 | + void OnSpreadChanged(); |
154 | |
155 | void OnSelectionChanged(AbstractLauncherIcon::Ptr const& selection); |
156 | |
157 | |
158 | === modified file 'tests/autopilot/unity/tests/test_spread.py' |
159 | --- tests/autopilot/unity/tests/test_spread.py 2013-10-08 14:08:52 +0000 |
160 | +++ tests/autopilot/unity/tests/test_spread.py 2013-10-21 23:51:09 +0000 |
161 | @@ -8,9 +8,11 @@ |
162 | |
163 | from __future__ import absolute_import |
164 | |
165 | +from autopilot.display import Display |
166 | from autopilot.matchers import Eventually |
167 | from testtools.matchers import Equals, NotEquals |
168 | from time import sleep |
169 | +from unity.emulators.icons import BFBLauncherIcon |
170 | |
171 | from unity.tests import UnityTestCase |
172 | |
173 | @@ -18,6 +20,10 @@ |
174 | class SpreadTests(UnityTestCase): |
175 | """Spread tests""" |
176 | |
177 | + def setUp(self): |
178 | + super(SpreadTests, self).setUp() |
179 | + self.launcher = self.unity.launcher.get_launcher_for_monitor(self.display.get_primary_screen()) |
180 | + |
181 | def start_test_application_windows(self, app_name, num_windows=2): |
182 | """Start a given number of windows of the requested application""" |
183 | self.process_manager.close_all_app(app_name) |
184 | @@ -44,10 +50,9 @@ |
185 | """Initiate the Spread for windows of the given app""" |
186 | icon = self.unity.launcher.model.get_icon(desktop_id=desktop_id) |
187 | self.assertThat(icon, NotEquals(None)) |
188 | - launcher = self.unity.launcher.get_launcher_for_monitor(self.display.get_primary_screen()) |
189 | |
190 | self.addCleanup(self.unity.window_manager.terminate_spread) |
191 | - launcher.click_launcher_icon(icon) |
192 | + self.launcher.click_launcher_icon(icon, move_mouse_after=False) |
193 | self.assertThat(self.unity.window_manager.scale_active_for_group, Eventually(Equals(True))) |
194 | |
195 | def assertWindowIsNotScaled(self, window): |
196 | @@ -60,6 +65,17 @@ |
197 | refresh_fn = lambda: xid in [w.x_id for w in self.process_manager.get_open_windows()] |
198 | self.assertThat(refresh_fn, Eventually(Equals(False))) |
199 | |
200 | + def assertLauncherIconsSaturated(self): |
201 | + for icon in self.unity.launcher.model.get_launcher_icons(): |
202 | + self.assertThat(icon.desaturated, Eventually(Equals(False))) |
203 | + |
204 | + def assertLauncherIconsDesaturated(self, also_active=True): |
205 | + for icon in self.unity.launcher.model.get_launcher_icons(): |
206 | + if isinstance(icon, BFBLauncherIcon) or (not also_active and icon.active): |
207 | + self.assertThat(icon.desaturated, Eventually(Equals(False))) |
208 | + else: |
209 | + self.assertThat(icon.desaturated, Eventually(Equals(True))) |
210 | + |
211 | def test_scale_application_windows(self): |
212 | """All the windows of an application must be scaled when application |
213 | spread is initiated |
214 | @@ -120,3 +136,57 @@ |
215 | |
216 | self.assertWindowIsNotScaled(target_win) |
217 | self.assertWindowIsClosed(target_xid) |
218 | + |
219 | + def test_spread_desaturate_launcher_icons(self): |
220 | + """Test that the screen spread desaturates the launcher icons""" |
221 | + self.start_test_application_windows("Calculator", 1) |
222 | + self.initiate_spread_for_screen() |
223 | + self.launcher.move_mouse_to_right_of_launcher() |
224 | + self.assertLauncherIconsDesaturated() |
225 | + |
226 | + def test_spread_saturate_launcher_icons_on_mouse_over(self): |
227 | + """Test that the screen spread re-saturates the launcher icons on mouse over""" |
228 | + win = self.start_test_application_windows("Calculator", 2)[0] |
229 | + self.initiate_spread_for_application(win.application.desktop_file) |
230 | + self.launcher.move_mouse_over_launcher() |
231 | + self.assertLauncherIconsSaturated() |
232 | + |
233 | + def test_app_spread_desaturate_inactive_launcher_icons(self): |
234 | + """Test that the app spread desaturates the inactive launcher icons""" |
235 | + win = self.start_test_application_windows("Calculator", 2)[0] |
236 | + self.initiate_spread_for_application(win.application.desktop_file) |
237 | + self.assertLauncherIconsDesaturated(also_active=False) |
238 | + |
239 | + def test_app_spread_saturate_launcher_icons_on_mouse_move(self): |
240 | + """Test that the app spread re-saturates the launcher icons on mouse move""" |
241 | + win = self.start_test_application_windows("Calculator", 2)[0] |
242 | + self.initiate_spread_for_application(win.application.desktop_file) |
243 | + self.launcher.move_mouse_to_icon(self.unity.launcher.model.get_bfb_icon()) |
244 | + self.assertLauncherIconsSaturated() |
245 | + |
246 | + def test_app_spread_saturate_launcher_icons_on_mouse_over(self): |
247 | + """Test that the app spread re-saturates the launcher icons on mouse over""" |
248 | + win = self.start_test_application_windows("Calculator", 2)[0] |
249 | + self.initiate_spread_for_application(win.application.desktop_file) |
250 | + self.launcher.move_mouse_over_launcher() |
251 | + self.assertLauncherIconsSaturated() |
252 | + |
253 | + def test_app_spread_desaturate_launcher_icons_switching_application(self): |
254 | + """Test that the app spread desaturates the launcher icons on mouse over""" |
255 | + cal_win = self.start_test_application_windows("Calculator", 2)[0] |
256 | + char_win = self.start_test_application_windows("Character Map", 2)[0] |
257 | + self.initiate_spread_for_application(char_win.application.desktop_file) |
258 | + self.initiate_spread_for_application(cal_win.application.desktop_file) |
259 | + self.assertLauncherIconsDesaturated(also_active=False) |
260 | + |
261 | + def test_spread_hides_icon_tooltip(self): |
262 | + """Tests that the screen spread hides the active tooltip.""" |
263 | + [win] = self.start_test_application_windows("Calculator", 1) |
264 | + icon = self.unity.launcher.model.get_icon(desktop_id=win.application.desktop_file) |
265 | + self.mouse.move(icon.center_x, icon.center_y) |
266 | + |
267 | + self.assertThat(lambda: icon.get_tooltip(), Eventually(NotEquals(None))) |
268 | + self.assertThat(icon.get_tooltip().active, Eventually(Equals(True))) |
269 | + |
270 | + self.initiate_spread_for_screen() |
271 | + self.assertThat(icon.get_tooltip().active, Eventually(Equals(False))) |
272 | \ No newline at end of file |
273 | |
274 | === modified file 'tests/mock-base-window.h' |
275 | --- tests/mock-base-window.h 2013-02-07 16:55:11 +0000 |
276 | +++ tests/mock-base-window.h 2013-10-21 23:51:09 +0000 |
277 | @@ -16,6 +16,7 @@ |
278 | #ifndef TESTS_MOCK_BASEWINDOW_H |
279 | #define TESTS_MOCK_BASEWINDOW_H |
280 | |
281 | +#include <gmock/gmock.h> |
282 | #include "ResizingBaseWindow.h" |
283 | |
284 | namespace unity |
285 | @@ -23,25 +24,26 @@ |
286 | namespace testmocks |
287 | { |
288 | |
289 | +using namespace testing; |
290 | + |
291 | class MockBaseWindow : public ResizingBaseWindow |
292 | { |
293 | public: |
294 | typedef nux::ObjectPtr<MockBaseWindow> Ptr; |
295 | + typedef NiceMock<MockBaseWindow> Nice; |
296 | |
297 | MockBaseWindow(ResizingBaseWindow::GeometryAdjuster const& input_adjustment, const char *name = "Mock") |
298 | : ResizingBaseWindow(name, input_adjustment) |
299 | - {} |
300 | + { |
301 | + ON_CALL(*this, SetOpacity(_)).WillByDefault(Invoke([this] (float o) { ResizingBaseWindow::SetOpacity(o); })); |
302 | + } |
303 | |
304 | MockBaseWindow(const char *name = "Mock") |
305 | - : ResizingBaseWindow(name, [](nux::Geometry const& geo) { return geo; }) |
306 | + : MockBaseWindow([](nux::Geometry const& geo) { return geo; }, name) |
307 | {} |
308 | |
309 | MOCK_METHOD2(ShowWindow, void(bool, bool)); |
310 | MOCK_METHOD1(SetOpacity, void(float)); |
311 | - |
312 | - // Really invoke the SetOpacity member function, a callthrough for use with |
313 | - // ::testing::Invoke(). |
314 | - void RealSetOpacity(float opacity) { ResizingBaseWindow::SetOpacity(opacity); } |
315 | }; |
316 | |
317 | } // namespace testmocks |
318 | |
319 | === modified file 'tests/test_dash_controller.cpp' |
320 | --- tests/test_dash_controller.cpp 2013-02-07 16:56:07 +0000 |
321 | +++ tests/test_dash_controller.cpp 2013-10-21 23:51:09 +0000 |
322 | @@ -21,6 +21,7 @@ |
323 | #include "unity-shared/DashStyle.h" |
324 | #include "unity-shared/PanelStyle.h" |
325 | #include "unity-shared/UnitySettings.h" |
326 | +#include "unity-shared/WindowManager.h" |
327 | #include "test_utils.h" |
328 | |
329 | #include <NuxCore/AnimationController.h> |
330 | @@ -32,42 +33,32 @@ |
331 | namespace |
332 | { |
333 | |
334 | -class TestDashController : public Test |
335 | +struct TestDashController : Test |
336 | { |
337 | -public: |
338 | TestDashController() |
339 | : animation_controller(tick_source) |
340 | - , base_window_(new NiceMock<testmocks::MockBaseWindow>()) |
341 | - { } |
342 | - |
343 | - virtual void SetUp() |
344 | - { |
345 | - ON_CALL(*base_window_, SetOpacity(_)) |
346 | - .WillByDefault(Invoke(base_window_.GetPointer(), |
347 | - &testmocks::MockBaseWindow::RealSetOpacity)); |
348 | - |
349 | - // Set expectations for creating the controller |
350 | - EXPECT_CALL(*base_window_, SetOpacity(0.0f)) |
351 | - .WillOnce(Invoke(base_window_.GetPointer(), |
352 | - &testmocks::MockBaseWindow::RealSetOpacity)); |
353 | - |
354 | - controller_.reset(new dash::Controller([&](){ return base_window_.GetPointer();})); |
355 | - Mock::VerifyAndClearExpectations(base_window_.GetPointer()); |
356 | - } |
357 | + , base_window_(new testmocks::MockBaseWindow::Nice()) |
358 | + , controller_(std::make_shared<dash::Controller>([this] { return base_window_.GetPointer(); })) |
359 | + {} |
360 | |
361 | protected: |
362 | nux::animation::TickSource tick_source; |
363 | nux::animation::AnimationController animation_controller; |
364 | |
365 | - dash::Controller::Ptr controller_; |
366 | - testmocks::MockBaseWindow::Ptr base_window_; |
367 | - |
368 | // required to create hidden secret global variables |
369 | Settings unity_settings_; |
370 | dash::Style dash_style_; |
371 | panel::Style panel_style_; |
372 | + |
373 | + testmocks::MockBaseWindow::Ptr base_window_; |
374 | + dash::Controller::Ptr controller_; |
375 | }; |
376 | |
377 | +TEST_F(TestDashController, Construction) |
378 | +{ |
379 | + EXPECT_CALL(*base_window_, SetOpacity(0.0f)); |
380 | + controller_ = std::make_shared<dash::Controller>([this] { return base_window_.GetPointer(); }); |
381 | +} |
382 | |
383 | TEST_F(TestDashController, TestShowAndHideDash) |
384 | { |
385 | @@ -100,5 +91,13 @@ |
386 | EXPECT_EQ(base_window_->GetOpacity(), 0.0); |
387 | } |
388 | |
389 | +TEST_F(TestDashController, DisconnectWMSignalsOnDestruction) |
390 | +{ |
391 | + auto& signal = WindowManager::Default().initiate_spread; |
392 | + size_t before = signal.size(); |
393 | + { auto controller = std::make_shared<dash::Controller>([this] { return base_window_.GetPointer(); }); } |
394 | + ASSERT_EQ(before, signal.size()); |
395 | + signal.emit(); |
396 | } |
397 | |
398 | +} |
399 | |
400 | === modified file 'tests/test_hud_controller.cpp' |
401 | --- tests/test_hud_controller.cpp 2013-02-19 15:07:36 +0000 |
402 | +++ tests/test_hud_controller.cpp 2013-10-21 23:51:09 +0000 |
403 | @@ -28,6 +28,7 @@ |
404 | #include "unity-shared/DashStyle.h" |
405 | #include "unity-shared/PanelStyle.h" |
406 | #include "unity-shared/UnitySettings.h" |
407 | +#include "unity-shared/WindowManager.h" |
408 | #include "test_utils.h" |
409 | using namespace unity; |
410 | |
411 | @@ -62,35 +63,32 @@ |
412 | }; |
413 | |
414 | |
415 | -class TestHudController : public Test |
416 | +struct TestHudController : Test |
417 | { |
418 | -public: |
419 | TestHudController() |
420 | - : view_(new NiceMock<MockHudView>) |
421 | - , base_window_(new NiceMock<testmocks::MockBaseWindow>()) |
422 | - { |
423 | - ON_CALL(*base_window_, SetOpacity(_)) |
424 | - .WillByDefault(Invoke(base_window_.GetPointer(), |
425 | - &testmocks::MockBaseWindow::RealSetOpacity)); |
426 | - |
427 | - // Set expectations for creating the controller |
428 | - EXPECT_CALL(*base_window_, SetOpacity(0.0f)); |
429 | - |
430 | - controller_.reset(new hud::Controller([&](){ return view_.GetPointer(); }, |
431 | - [&](){ return base_window_.GetPointer();})); |
432 | - } |
433 | + : view_(new NiceMock<MockHudView>) |
434 | + , base_window_(new testmocks::MockBaseWindow::Nice()) |
435 | + , controller_(std::make_shared<hud::Controller>([this] { return view_.GetPointer(); }, |
436 | + [this] { return base_window_.GetPointer(); })) |
437 | + {} |
438 | |
439 | protected: |
440 | - hud::Controller::Ptr controller_; |
441 | - MockHudView::Ptr view_; |
442 | - testmocks::MockBaseWindow::Ptr base_window_; |
443 | - |
444 | // required to create hidden secret global variables |
445 | Settings unity_settings_; |
446 | dash::Style dash_style_; |
447 | panel::Style panel_style_; |
448 | + |
449 | + MockHudView::Ptr view_; |
450 | + testmocks::MockBaseWindow::Ptr base_window_; |
451 | + hud::Controller::Ptr controller_; |
452 | }; |
453 | |
454 | +TEST_F(TestHudController, Construction) |
455 | +{ |
456 | + EXPECT_CALL(*base_window_, SetOpacity(0.0f)); |
457 | + controller_ = std::make_shared<hud::Controller>([this] { return view_.GetPointer(); }, |
458 | + [this] { return base_window_.GetPointer(); }); |
459 | +} |
460 | |
461 | TEST_F(TestHudController, TestShowAndHideHud) |
462 | { |
463 | @@ -141,4 +139,16 @@ |
464 | EXPECT_EQ(base_window_->GetOpacity(), 0.0); |
465 | } |
466 | |
467 | +TEST_F(TestHudController, DisconnectWMSignalsOnDestruction) |
468 | +{ |
469 | + auto& signal = WindowManager::Default().initiate_spread; |
470 | + size_t before = signal.size(); |
471 | + { |
472 | + auto controller = std::make_shared<hud::Controller>([this] { return view_.GetPointer(); }, |
473 | + [this] { return base_window_.GetPointer(); }); |
474 | + } |
475 | + ASSERT_EQ(before, signal.size()); |
476 | + signal.emit(); |
477 | +} |
478 | + |
479 | } |
480 | |
481 | === modified file 'tests/test_launcher.cpp' |
482 | --- tests/test_launcher.cpp 2013-10-04 00:19:56 +0000 |
483 | +++ tests/test_launcher.cpp 2013-10-21 23:51:09 +0000 |
484 | @@ -31,6 +31,7 @@ |
485 | #include "unity-shared/PanelStyle.h" |
486 | #include "unity-shared/UnitySettings.h" |
487 | #include "unity-shared/IconRenderer.h" |
488 | +#include "StandaloneWindowManager.h" |
489 | #include "test_utils.h" |
490 | |
491 | namespace unity |
492 | @@ -46,6 +47,7 @@ |
493 | { |
494 | public: |
495 | typedef nux::ObjectPtr<MockMockLauncherIcon> Ptr; |
496 | + typedef testing::NiceMock<MockMockLauncherIcon> Nice; |
497 | MockMockLauncherIcon(IconType type = IconType::APPLICATION) |
498 | : MockLauncherIcon(type) |
499 | {} |
500 | @@ -53,6 +55,7 @@ |
501 | MOCK_METHOD1(ShouldHighlightOnDrag, bool(DndData const&)); |
502 | MOCK_METHOD1(Stick, void(bool)); |
503 | MOCK_METHOD2(PerformScroll, void(ScrollDirection, Time)); |
504 | + MOCK_METHOD0(HideTooltip, void()); |
505 | }; |
506 | |
507 | } |
508 | @@ -115,6 +118,7 @@ |
509 | using Launcher::SetHidden; |
510 | using Launcher::HandleUrgentIcon; |
511 | using Launcher::SetUrgentTimer; |
512 | + using Launcher::SetIconUnderMouse; |
513 | using Launcher::urgent_timer_running_; |
514 | using Launcher::urgent_finished_time_; |
515 | using Launcher::urgent_wiggle_time_; |
516 | @@ -140,7 +144,8 @@ |
517 | }; |
518 | |
519 | TestLauncher() |
520 | - : parent_window_(new MockableBaseWindow("TestLauncherWindow")) |
521 | + : WM(dynamic_cast<StandaloneWindowManager*>(&WindowManager::Default())) |
522 | + , parent_window_(new MockableBaseWindow("TestLauncherWindow")) |
523 | , model_(new LauncherModel) |
524 | , options_(new Options) |
525 | , launcher_(new MockLauncher(parent_window_.GetPointer())) |
526 | @@ -149,6 +154,15 @@ |
527 | launcher_->SetModel(model_); |
528 | } |
529 | |
530 | + ~TestLauncher() |
531 | + { |
532 | + WM->SetScaleActiveForGroup(false); |
533 | + WM->SetScaleActive(false); |
534 | + |
535 | + if (WM->IsExpoActive()) |
536 | + WM->TerminateExpo(); |
537 | + } |
538 | + |
539 | std::vector<MockMockLauncherIcon::Ptr> AddMockIcons(unsigned number) |
540 | { |
541 | std::vector<MockMockLauncherIcon::Ptr> icons; |
542 | @@ -159,7 +173,7 @@ |
543 | |
544 | for (unsigned i = 0; i < number; ++i) |
545 | { |
546 | - MockMockLauncherIcon::Ptr icon(new MockMockLauncherIcon); |
547 | + MockMockLauncherIcon::Ptr icon(new MockMockLauncherIcon::Nice); |
548 | icon->SetCenter(nux::Point3(launcher_geo.x + icon_size/2.0f, launcher_geo.y + icon_size/2.0f * (i+1) + 1, 0), monitor); |
549 | |
550 | icons.push_back(icon); |
551 | @@ -173,6 +187,7 @@ |
552 | } |
553 | |
554 | MockUScreen uscreen; |
555 | + StandaloneWindowManager* WM; |
556 | nux::ObjectPtr<MockableBaseWindow> parent_window_; |
557 | Settings settings; |
558 | panel::Style panel_style; |
559 | @@ -688,9 +703,180 @@ |
560 | launcher_->HandleUrgentIcon(icon, current); |
561 | |
562 | EXPECT_THAT(launcher_->urgent_finished_time_.tv_sec, Gt(0)); |
563 | - EXPECT_THAT(launcher_->urgent_finished_time_.tv_nsec, Gt(0)); |
564 | -} |
565 | - |
566 | -} |
567 | -} |
568 | - |
569 | + EXPECT_THAT(launcher_->urgent_finished_time_.tv_nsec, Gt(0)); |
570 | +} |
571 | + |
572 | +TEST_F(TestLauncher, DesaturateAllIconsOnSpread) |
573 | +{ |
574 | + auto const& icons = AddMockIcons(5); |
575 | + icons[g_random_int()%icons.size()]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, true); |
576 | + |
577 | + WM->SetScaleActiveForGroup(false); |
578 | + WM->SetScaleActive(true); |
579 | + WM->initiate_spread.emit(); |
580 | + |
581 | + Utils::WaitUntilMSec([&icons] { |
582 | + for (auto const& icon : icons) |
583 | + { |
584 | + if (!icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)) |
585 | + return false; |
586 | + } |
587 | + return true; |
588 | + }); |
589 | + |
590 | + for (auto const& icon : icons) |
591 | + ASSERT_TRUE(icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
592 | +} |
593 | + |
594 | +TEST_F(TestLauncher, SaturateAllIconsOnSpreadTerminated) |
595 | +{ |
596 | + auto const& icons = AddMockIcons(5); |
597 | + icons[g_random_int()%icons.size()]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, true); |
598 | + |
599 | + for (auto const& icon : icons) |
600 | + icon->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, true); |
601 | + |
602 | + WM->SetScaleActiveForGroup(false); |
603 | + WM->SetScaleActive(false); |
604 | + WM->terminate_spread.emit(); |
605 | + |
606 | + for (auto const& icon : icons) |
607 | + ASSERT_FALSE(icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
608 | +} |
609 | + |
610 | +TEST_F(TestLauncher, SaturatesAllIconsOnSpreadWithMouseOver) |
611 | +{ |
612 | + auto const& icons = AddMockIcons(5); |
613 | + icons[g_random_int()%icons.size()]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, true); |
614 | + |
615 | + for (auto const& icon : icons) |
616 | + icon->SetQuirk(AbstractLauncherIcon::Quirk::DESAT, true); |
617 | + |
618 | + launcher_->SetHover(true); |
619 | + WM->SetScaleActiveForGroup(false); |
620 | + WM->SetScaleActive(true); |
621 | + WM->initiate_spread.emit(); |
622 | + |
623 | + Utils::WaitPendingEvents(); |
624 | + |
625 | + for (auto const& icon : icons) |
626 | + ASSERT_FALSE(icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
627 | +} |
628 | + |
629 | +TEST_F(TestLauncher, DesaturateInactiveIconsOnAppSpread) |
630 | +{ |
631 | + auto const& icons = AddMockIcons(5); |
632 | + icons[g_random_int()%icons.size()]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, true); |
633 | + |
634 | + WM->SetScaleActiveForGroup(true); |
635 | + WM->SetScaleActive(true); |
636 | + WM->initiate_spread.emit(); |
637 | + |
638 | + Utils::WaitUntilMSec([&icons] { |
639 | + for (auto const& icon : icons) |
640 | + { |
641 | + if (icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE) == icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)) |
642 | + return false; |
643 | + } |
644 | + return true; |
645 | + }); |
646 | + |
647 | + for (auto const& icon : icons) |
648 | + ASSERT_NE(icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE), icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
649 | +} |
650 | + |
651 | +TEST_F(TestLauncher, SaturatesAllIconsOnAppSpreadMouseMove) |
652 | +{ |
653 | + auto const& icons = AddMockIcons(5); |
654 | + unsigned active_idx = g_random_int()%icons.size(); |
655 | + icons[active_idx]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, true); |
656 | + |
657 | + launcher_->SetHover(true); |
658 | + WM->SetScaleActiveForGroup(true); |
659 | + WM->SetScaleActive(true); |
660 | + WM->initiate_spread.emit(); |
661 | + |
662 | + Utils::WaitUntilMSec([&icons] { |
663 | + for (auto const& icon : icons) |
664 | + { |
665 | + if (icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE) == icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)) |
666 | + return false; |
667 | + } |
668 | + return true; |
669 | + }); |
670 | + |
671 | + for (auto const& icon : icons) |
672 | + ASSERT_NE(icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE), icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
673 | + |
674 | + auto const& active_center = icons[active_idx]->GetCenter(launcher_->monitor()); |
675 | + launcher_->mouse_move.emit(active_center.x, active_center.y, 0, 0, 0, 0); |
676 | + |
677 | + for (auto const& icon : icons) |
678 | + ASSERT_NE(icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE), icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
679 | + |
680 | + auto const& other_center = icons[(active_idx+1)%icons.size()]->GetCenter(launcher_->monitor()); |
681 | + launcher_->mouse_move.emit(other_center.x, other_center.y, 0, 0, 0, 0); |
682 | + |
683 | + for (auto const& icon : icons) |
684 | + ASSERT_FALSE(icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
685 | + |
686 | + launcher_->SetHover(false); |
687 | + for (auto const& icon : icons) |
688 | + ASSERT_NE(icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE), icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
689 | + |
690 | + launcher_->SetHover(true); |
691 | + for (auto const& icon : icons) |
692 | + ASSERT_FALSE(icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
693 | +} |
694 | + |
695 | +TEST_F(TestLauncher, DesaturateActiveIconOnAppSpreadIconUpdate) |
696 | +{ |
697 | + auto const& icons = AddMockIcons(5); |
698 | + unsigned active_idx = g_random_int()%icons.size(); |
699 | + icons[active_idx]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, true); |
700 | + |
701 | + launcher_->SetHover(true); |
702 | + WM->SetScaleActiveForGroup(true); |
703 | + WM->SetScaleActive(true); |
704 | + WM->initiate_spread.emit(); |
705 | + |
706 | + Utils::WaitPendingEvents(); |
707 | + for (auto const& icon : icons) |
708 | + ASSERT_NE(icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE), icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
709 | + |
710 | + unsigned new_active_idx = (active_idx+1)%icons.size(); |
711 | + icons[active_idx]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, false); |
712 | + icons[new_active_idx]->SetQuirk(AbstractLauncherIcon::Quirk::ACTIVE, true); |
713 | + |
714 | + WM->terminate_spread.emit(); |
715 | + WM->initiate_spread.emit(); |
716 | + |
717 | + Utils::WaitPendingEvents(); |
718 | + for (auto const& icon : icons) |
719 | + ASSERT_NE(icon->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE), icon->GetQuirk(AbstractLauncherIcon::Quirk::DESAT)); |
720 | +} |
721 | + |
722 | +TEST_F(TestLauncher, HideTooltipOnSpread) |
723 | +{ |
724 | + auto icon = AddMockIcons(1).front(); |
725 | + EXPECT_CALL(*icon, HideTooltip()); |
726 | + |
727 | + launcher_->SetIconUnderMouse(icon); |
728 | + WM->SetScaleActive(true); |
729 | + WM->initiate_spread.emit(); |
730 | +} |
731 | + |
732 | +TEST_F(TestLauncher, HideTooltipOnExpo) |
733 | +{ |
734 | + auto icon = AddMockIcons(1).front(); |
735 | + EXPECT_CALL(*icon, HideTooltip()); |
736 | + |
737 | + if (!WM->IsExpoActive()) |
738 | + WM->InitiateExpo(); |
739 | + |
740 | + launcher_->SetIconUnderMouse(icon); |
741 | + WM->initiate_expo.emit(); |
742 | +} |
743 | + |
744 | +} // namespace launcher |
745 | +} // namespace unity |
746 | |
747 | === modified file 'tests/test_switcher_controller_class.cpp' |
748 | --- tests/test_switcher_controller_class.cpp 2013-06-26 17:10:45 +0000 |
749 | +++ tests/test_switcher_controller_class.cpp 2013-10-21 23:51:09 +0000 |
750 | @@ -78,13 +78,8 @@ |
751 | : WM(dynamic_cast<StandaloneWindowManager*>(&WindowManager::Default())) |
752 | , animation_controller_(tick_source_) |
753 | , mock_window_(new NiceMock<testmocks::MockBaseWindow>()) |
754 | + , controller_(std::make_shared<Controller>([this] { return mock_window_; })) |
755 | { |
756 | - ON_CALL(*mock_window_, SetOpacity(_)) |
757 | - .WillByDefault(Invoke(mock_window_.GetPointer(), |
758 | - &testmocks::MockBaseWindow::RealSetOpacity)); |
759 | - |
760 | - auto create_window = [this] { return mock_window_; }; |
761 | - controller_.reset(new Controller(create_window)); |
762 | controller_->timeout_length = 0; |
763 | |
764 | icons_.push_back(launcher::AbstractLauncherIcon::Ptr(new launcher::DesktopLauncherIcon())); |
FAILED: Continuous integration, rev:3577 jenkins. qa.ubuntu. com/job/ unity-ci/ 438/ jenkins. qa.ubuntu. com/job/ unity-saucy- amd64-ci/ 327/console jenkins. qa.ubuntu. com/job/ unity-saucy- armhf-ci/ 325/console jenkins. qa.ubuntu. com/job/ unity-saucy- i386-ci/ 326/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: 10.97.0. 26:8080/ job/unity- ci/438/ rebuild
http://