Merge lp:~3v1n0/unity/launcher-controller-ensure-new into lp:unity

Proposed by Marco Trevisan (Treviño) on 2012-07-25
Status: Merged
Approved by: Marco Trevisan (Treviño) on 2012-07-26
Approved revision: 2556
Merged at revision: 2521
Proposed branch: lp:~3v1n0/unity/launcher-controller-ensure-new
Merge into: lp:unity
Diff against target: 985 lines (+566/-172)
11 files modified
launcher/EdgeBarrierController.cpp (+18/-5)
launcher/EdgeBarrierController.h (+1/-0)
launcher/LauncherController.cpp (+29/-161)
launcher/LauncherController.h (+2/-0)
launcher/LauncherControllerPrivate.h (+163/-0)
tests/CMakeLists.txt (+9/-0)
tests/test_edge_barrier_controller.cpp (+48/-1)
tests/test_launcher_controller.cpp (+202/-0)
tests/test_uscreen_mock.h (+85/-0)
unity-shared/UScreen.cpp (+4/-3)
unity-shared/UScreen.h (+5/-2)
To merge this branch: bzr merge lp:~3v1n0/unity/launcher-controller-ensure-new
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) 2012-07-25 Approve on 2012-07-26
jenkins (community) continuous-integration Needs Fixing on 2012-07-26
Review via email: mp+116775@code.launchpad.net

Commit message

LauncherController: Rewritten EnsureLaunchers() added tests, fix a crash caused by invalid barrier subscriptions.

Description of the change

Rewritten the EnsureLaunchers() method LauncherController and added unit tests for it.

As discussed with Tim LauncherControllerTest is now friend of LauncherController to access to the pimpl data, even if I've changed this on my next branch.

To post a comment you must log in.
jenkins (martin-mrazik+qa) wrote :
review: Needs Fixing (continuous-integration)
Sam Spilsbury (smspillaz) wrote :

Looks good.

There are some merge markers in added file 'tests/test_launcher_controller.cpp'.

General comments:

 * If you want to avoid the friend declaration, you can do something like this:
   class TestLauncherExpectationsInterface
   {
       public:
           virtual void ExpectNumControllers (int num) = 0;
           ...
   }

   LauncherControllerPrivate::SetExpectations (TestLauncherExpectationsInterface *expect)
   {
       ...
       expect->ExpectNumControllers (whatever);
   }

   ::testing::NiceMock <MockLauncherExpectations> mock_launcher_expectations;

   EXPECT_CALL (mock_launcher_expectations, ExpectNumControllers (value));

   This method is pretty ugly though, and the friend might be better. Generally speaking, testing implementation details isn't really recommended, but in this case we want to do that.

 * Its a bit unclear as to how UScreen.SetupFakeMultimonitor () causes more launchers to be added to an lc it doesn't know about, unless some singleton knows about lc, and that's pretty confusing.

Marco Trevisan (Treviño) (3v1n0) wrote :

> Looks good.
>
> There are some merge markers in added file
> 'tests/test_launcher_controller.cpp'.

Yeah, fixed...

> General comments:
>
> * If you want to avoid the friend declaration, you can do something like
> [...]
> This method is pretty ugly though, and the friend might be better.

Yes, that's what I generally do, but I didn't want all this even for future testing...

> Generally speaking, testing implementation details isn't really recommended,
> but in this case we want to do that.

Yep, that's the fact.

> * Its a bit unclear as to how UScreen.SetupFakeMultimonitor () causes more
> launchers to be added to an lc it doesn't know about, unless some singleton
> knows about lc, and that's pretty confusing.

As you can see, int SetupFakeMultimonitor implementation, basically I'm adding to it some fake monitors, and then emitting that UScreen has changed, exactly like if I'd have plugged some monitors.

jenkins (martin-mrazik+qa) wrote :
review: Needs Fixing (continuous-integration)
Martin Mrazik (mrazik) wrote :

Sorry for the jenkins failure. I'm looking into this.

Andrea Azzarone (azzar1) wrote :

LGTM

review: Approve
Unity Merger (unity-merger) wrote :

The Jenkins job https://jenkins.qa.ubuntu.com/job/automerge-unity/967/console reported an error when processing this lp:~3v1n0/unity/launcher-controller-ensure-new branch.
Not merging it.

Martin Mrazik (mrazik) wrote :

Now I'm a bit confused. I thought the CI failure is because our jenkins quantal slaves were not 100% up-to-date as I was able to compile the latest trunk on my quantal laptop with staging PPA.
Now it looks like the unity-merger has a similar problem so let me look close into this.

2556. By Marco Trevisan (Treviño) on 2012-07-26

test_launcher_controller: initialize also GeisAdapter

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/EdgeBarrierController.cpp'
2--- launcher/EdgeBarrierController.cpp 2012-07-20 19:26:15 +0000
3+++ launcher/EdgeBarrierController.cpp 2012-07-26 13:13:33 +0000
4@@ -15,6 +15,7 @@
5 * along with this program. If not, see <http://www.gnu.org/licenses/>.
6 *
7 * Authored by: Jason Smith <jason.smith@canonical.com>
8+ * Marco Trevisan <marco.trevisan@canonical.com>
9 */
10
11 #include "EdgeBarrierController.h"
12@@ -157,7 +158,7 @@
13 unsigned int monitor = owner->index;
14 bool process = true;
15
16- if (monitor <= subscribers_.size())
17+ if (monitor < subscribers_.size())
18 {
19 auto subscriber = subscribers_[monitor];
20
21@@ -206,20 +207,32 @@
22
23 void EdgeBarrierController::Subscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor)
24 {
25- if (pimpl->subscribers_.size() <= monitor)
26+ if (monitor >= pimpl->subscribers_.size())
27 pimpl->subscribers_.resize(monitor + 1);
28
29+ auto const& monitors = UScreen::GetDefault()->GetMonitors();
30 pimpl->subscribers_[monitor] = subscriber;
31- pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors());
32+ pimpl->ResizeBarrierList(monitors);
33+ pimpl->SetupBarriers(monitors);
34 }
35
36 void EdgeBarrierController::Unsubscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor)
37 {
38- if (pimpl->subscribers_.size() < monitor || pimpl->subscribers_[monitor] != subscriber)
39+ if (monitor >= pimpl->subscribers_.size() || pimpl->subscribers_[monitor] != subscriber)
40 return;
41
42+ auto const& monitors = UScreen::GetDefault()->GetMonitors();
43 pimpl->subscribers_[monitor] = nullptr;
44- pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors());
45+ pimpl->ResizeBarrierList(monitors);
46+ pimpl->SetupBarriers(monitors);
47+}
48+
49+EdgeBarrierSubscriber* EdgeBarrierController::GetSubscriber(unsigned int monitor)
50+{
51+ if (monitor >= pimpl->subscribers_.size())
52+ return nullptr;
53+
54+ return pimpl->subscribers_[monitor];
55 }
56
57 void EdgeBarrierController::ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
58
59=== modified file 'launcher/EdgeBarrierController.h'
60--- launcher/EdgeBarrierController.h 2012-07-20 18:33:58 +0000
61+++ launcher/EdgeBarrierController.h 2012-07-26 13:13:33 +0000
62@@ -43,6 +43,7 @@
63
64 void Subscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor);
65 void Unsubscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor);
66+ EdgeBarrierSubscriber* GetSubscriber(unsigned int monitor);
67
68 protected:
69 void ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event);
70
71=== modified file 'launcher/LauncherController.cpp'
72--- launcher/LauncherController.cpp 2012-07-25 02:39:32 +0000
73+++ launcher/LauncherController.cpp 2012-07-26 13:13:33 +0000
74@@ -30,23 +30,15 @@
75 #include "BamfLauncherIcon.h"
76 #include "DesktopLauncherIcon.h"
77 #include "DeviceLauncherIcon.h"
78-#include "DeviceLauncherSection.h"
79-#include "EdgeBarrierController.h"
80 #include "FavoriteStore.h"
81 #include "HudLauncherIcon.h"
82-#include "Launcher.h"
83 #include "LauncherController.h"
84-#include "LauncherEntryRemote.h"
85-#include "LauncherEntryRemoteModel.h"
86-#include "AbstractLauncherIcon.h"
87+#include "LauncherControllerPrivate.h"
88 #include "SoftwareCenterLauncherIcon.h"
89-#include "LauncherModel.h"
90-#include "VolumeMonitorWrapper.h"
91 #include "unity-shared/WindowManager.h"
92 #include "TrashLauncherIcon.h"
93 #include "BFBLauncherIcon.h"
94 #include "unity-shared/UScreen.h"
95-#include "unity-shared/UBusWrapper.h"
96 #include "unity-shared/UBusMessages.h"
97 #include "unity-shared/TimeUtil.h"
98
99@@ -93,120 +85,7 @@
100 }
101 }
102
103-class Controller::Impl
104-{
105-public:
106- Impl(Display* display, Controller* parent);
107- ~Impl();
108-
109- void UpdateNumWorkspaces(int workspaces);
110-
111- Launcher* CreateLauncher(int monitor);
112-
113- void Save();
114- void SortAndUpdate();
115-
116- nux::ObjectPtr<Launcher> CurrentLauncher();
117-
118- void OnIconAdded(AbstractLauncherIcon::Ptr icon);
119- void OnIconRemoved(AbstractLauncherIcon::Ptr icon);
120-
121- void OnLauncherAddRequest(char* path, AbstractLauncherIcon::Ptr before);
122- void OnLauncherAddRequestSpecial(std::string const& path, std::string const& aptdaemon_trans_id,
123- std::string const& icon_path, int icon_x, int icon_y, int icon_size);
124- void OnLauncherRemoveRequest(AbstractLauncherIcon::Ptr icon);
125- void OnSCIconAnimationComplete(AbstractLauncherIcon::Ptr icon);
126-
127- void OnLauncherEntryRemoteAdded(LauncherEntryRemote::Ptr const& entry);
128- void OnLauncherEntryRemoteRemoved(LauncherEntryRemote::Ptr const& entry);
129-
130- void OnFavoriteStoreFavoriteAdded(std::string const& entry, std::string const& pos, bool before);
131- void OnFavoriteStoreFavoriteRemoved(std::string const& entry);
132- void OnFavoriteStoreReordered();
133-
134-
135- void InsertExpoAction();
136- void RemoveExpoAction();
137-
138- void InsertDesktopIcon();
139- void RemoveDesktopIcon();
140-
141- void SendHomeActivationRequest();
142-
143- int MonitorWithMouse();
144-
145- void InsertTrash();
146-
147- void RegisterIcon(AbstractLauncherIcon::Ptr icon);
148-
149- AbstractLauncherIcon::Ptr CreateFavorite(const char* file_path);
150-
151- SoftwareCenterLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path);
152-
153- void SetupBamf();
154-
155- void EnsureLaunchers(int primary, std::vector<nux::Geometry> const& monitors);
156-
157- void OnExpoActivated();
158-
159- void OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors);
160-
161- void OnWindowFocusChanged (guint32 xid);
162-
163- void OnViewOpened(BamfMatcher* matcher, BamfView* view);
164-
165- void ReceiveMouseDownOutsideArea(int x, int y, unsigned long button_flags, unsigned long key_flags);
166-
167- void ReceiveLauncherKeyPress(unsigned long eventType,
168- unsigned long keysym,
169- unsigned long state,
170- const char* character,
171- unsigned short keyCount);
172-
173- static void OnBusAcquired(GDBusConnection* connection, const gchar* name, gpointer user_data);
174- static void OnDBusMethodCall(GDBusConnection* connection, const gchar* sender, const gchar* object_path,
175- const gchar* interface_name, const gchar* method_name,
176- GVariant* parameters, GDBusMethodInvocation* invocation,
177- gpointer user_data);
178-
179- static GDBusInterfaceVTable interface_vtable;
180-
181- Controller* parent_;
182- LauncherModel::Ptr model_;
183- nux::ObjectPtr<Launcher> launcher_;
184- nux::ObjectPtr<Launcher> keyboard_launcher_;
185- int sort_priority_;
186- AbstractVolumeMonitorWrapper::Ptr volume_monitor_;
187- DeviceLauncherSection device_section_;
188- LauncherEntryRemoteModel remote_model_;
189- AbstractLauncherIcon::Ptr expo_icon_;
190- AbstractLauncherIcon::Ptr desktop_icon_;
191- int num_workspaces_;
192- bool show_desktop_icon_;
193- Display* display_;
194-
195- bool launcher_open;
196- bool launcher_keynav;
197- bool launcher_grabbed;
198- bool reactivate_keynav;
199- int reactivate_index;
200- bool keynav_restore_window_;
201- int launcher_key_press_time_;
202- unsigned int dbus_owner_;
203-
204- ui::EdgeBarrierController edge_barriers_;
205-
206- LauncherList launchers;
207-
208- glib::Object<BamfMatcher> matcher_;
209- glib::Signal<void, BamfMatcher*, BamfView*> view_opened_signal_;
210- glib::SourceManager sources_;
211- UBusManager ubus;
212-
213- sigc::connection on_expoicon_activate_connection_;
214- sigc::connection launcher_key_press_connection_;
215- sigc::connection launcher_event_outside_connection_;
216-};
217+
218
219 GDBusInterfaceVTable Controller::Impl::interface_vtable =
220 { Controller::Impl::OnDBusMethodCall, NULL, NULL};
221@@ -316,41 +195,35 @@
222 unsigned int num_monitors = monitors.size();
223 unsigned int num_launchers = parent_->multiple_launchers ? num_monitors : 1;
224 unsigned int launchers_size = launchers.size();
225- unsigned int last_monitor = 0;
226-
227- if (num_launchers == 1)
228- {
229- if (launchers_size == 0)
230- {
231- launchers.push_back(nux::ObjectPtr<Launcher>(CreateLauncher(primary)));
232- }
233- else if (!launchers[0].IsValid())
234- {
235- launchers[0] = nux::ObjectPtr<Launcher>(CreateLauncher(primary));
236- }
237-
238- launchers[0]->monitor(primary);
239- launchers[0]->Resize();
240- last_monitor = 1;
241- }
242- else
243- {
244- for (unsigned int i = 0; i < num_monitors; i++, last_monitor++)
245- {
246- if (i >= launchers_size)
247- {
248- launchers.push_back(nux::ObjectPtr<Launcher>(CreateLauncher(i)));
249- }
250-
251- launchers[i]->monitor(i);
252- launchers[i]->Resize();
253- }
254- }
255-
256- for (unsigned int i = last_monitor; i < launchers_size; ++i)
257+ unsigned int last_launcher = 0;
258+
259+ for (unsigned int i = 0; i < num_launchers; i++, last_launcher++)
260+ {
261+ if (i >= launchers_size)
262+ {
263+ launchers.push_back(nux::ObjectPtr<Launcher>(CreateLauncher(i)));
264+ }
265+ else if (!launchers[i])
266+ {
267+ launchers[i] = nux::ObjectPtr<Launcher>(CreateLauncher(i));
268+ }
269+
270+ int monitor = (num_launchers == 1) ? primary : i;
271+
272+ if (launchers[i]->monitor() != monitor)
273+ {
274+ edge_barriers_.Unsubscribe(launchers[i].GetPointer(), launchers[i]->monitor);
275+ }
276+
277+ launchers[i]->monitor(monitor);
278+ launchers[i]->Resize();
279+ edge_barriers_.Subscribe(launchers[i].GetPointer(), launchers[i]->monitor);
280+ }
281+
282+ for (unsigned int i = last_launcher; i < launchers_size; ++i)
283 {
284 auto launcher = launchers[i];
285- if (launcher.IsValid())
286+ if (launcher)
287 {
288 parent_->RemoveChild(launcher.GetPointer());
289 launcher->GetParent()->UnReference();
290@@ -359,11 +232,6 @@
291 }
292
293 launchers.resize(num_launchers);
294-
295- for (size_t i = 0; i < launchers.size(); ++i)
296- {
297- edge_barriers_.Subscribe(launchers[i].GetPointer(), launchers[i]->monitor);
298- }
299 }
300
301 void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors)
302
303=== modified file 'launcher/LauncherController.h'
304--- launcher/LauncherController.h 2012-06-18 02:57:23 +0000
305+++ launcher/LauncherController.h 2012-07-26 13:13:33 +0000
306@@ -35,6 +35,7 @@
307 class AbstractLauncherIcon;
308 class Launcher;
309 class LauncherModel;
310+class TestLauncherController;
311
312 class Controller : public unity::debug::Introspectable, public sigc::trackable
313 {
314@@ -86,6 +87,7 @@
315 void AddProperties(GVariantBuilder* builder);
316
317 private:
318+ friend class TestLauncherController;
319 class Impl;
320 std::unique_ptr<Impl> pimpl;
321 };
322
323=== added file 'launcher/LauncherControllerPrivate.h'
324--- launcher/LauncherControllerPrivate.h 1970-01-01 00:00:00 +0000
325+++ launcher/LauncherControllerPrivate.h 2012-07-26 13:13:33 +0000
326@@ -0,0 +1,163 @@
327+/*
328+ * Copyright 2012 Canonical Ltd.
329+ *
330+ * This program is free software: you can redistribute it and/or modify it
331+ * under the terms of the GNU General Public License version 3, as published
332+ * by the Free Software Foundation.
333+ *
334+ * This program is distributed in the hope that it will be useful, but
335+ * WITHOUT ANY WARRANTY; without even the implied warranties of
336+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
337+ * PURPOSE. See the GNU General Public License for more details.
338+ *
339+ * You should have received a copy of the GNU General Public License
340+ * version 3 along with this program. If not, see
341+ * <http://www.gnu.org/licenses/>
342+ *
343+ * Authored by: Jason Smith <jason.smith@canonical.com>
344+ * Tim Penhey <tim.penhey@canonical.com>
345+ * Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
346+ *
347+ */
348+
349+#ifndef LAUNCHER_CONTROLLER_PRIVATE_H
350+#define LAUNCHER_CONTROLLER_PRIVATE_H
351+
352+#include <Nux/Nux.h>
353+
354+#include "AbstractLauncherIcon.h"
355+#include "DeviceLauncherSection.h"
356+#include "EdgeBarrierController.h"
357+#include "LauncherController.h"
358+#include "Launcher.h"
359+#include "LauncherEntryRemote.h"
360+#include "LauncherEntryRemoteModel.h"
361+#include "LauncherModel.h"
362+#include "SoftwareCenterLauncherIcon.h"
363+#include "unity-shared/UBusWrapper.h"
364+#include "VolumeMonitorWrapper.h"
365+
366+namespace unity
367+{
368+namespace launcher
369+{
370+
371+class Controller::Impl
372+{
373+public:
374+ Impl(Display* display, Controller* parent);
375+ ~Impl();
376+
377+ void UpdateNumWorkspaces(int workspaces);
378+
379+ Launcher* CreateLauncher(int monitor);
380+
381+ void Save();
382+ void SortAndUpdate();
383+
384+ nux::ObjectPtr<Launcher> CurrentLauncher();
385+
386+ void OnIconAdded(AbstractLauncherIcon::Ptr icon);
387+ void OnIconRemoved(AbstractLauncherIcon::Ptr icon);
388+
389+ void OnLauncherAddRequest(char* path, AbstractLauncherIcon::Ptr before);
390+ void OnLauncherAddRequestSpecial(std::string const& path, std::string const& aptdaemon_trans_id,
391+ std::string const& icon_path, int icon_x, int icon_y, int icon_size);
392+ void OnLauncherRemoveRequest(AbstractLauncherIcon::Ptr icon);
393+ void OnSCIconAnimationComplete(AbstractLauncherIcon::Ptr icon);
394+
395+ void OnLauncherEntryRemoteAdded(LauncherEntryRemote::Ptr const& entry);
396+ void OnLauncherEntryRemoteRemoved(LauncherEntryRemote::Ptr const& entry);
397+
398+ void OnFavoriteStoreFavoriteAdded(std::string const& entry, std::string const& pos, bool before);
399+ void OnFavoriteStoreFavoriteRemoved(std::string const& entry);
400+ void OnFavoriteStoreReordered();
401+
402+
403+ void InsertExpoAction();
404+ void RemoveExpoAction();
405+
406+ void InsertDesktopIcon();
407+ void RemoveDesktopIcon();
408+
409+ void SendHomeActivationRequest();
410+
411+ int MonitorWithMouse();
412+
413+ void InsertTrash();
414+
415+ void RegisterIcon(AbstractLauncherIcon::Ptr icon);
416+
417+ AbstractLauncherIcon::Ptr CreateFavorite(const char* file_path);
418+
419+ SoftwareCenterLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path);
420+
421+ void SetupBamf();
422+
423+ void EnsureLaunchers(int primary, std::vector<nux::Geometry> const& monitors);
424+
425+ void OnExpoActivated();
426+
427+ void OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors);
428+
429+ void OnWindowFocusChanged (guint32 xid);
430+
431+ void OnViewOpened(BamfMatcher* matcher, BamfView* view);
432+
433+ void ReceiveMouseDownOutsideArea(int x, int y, unsigned long button_flags, unsigned long key_flags);
434+
435+ void ReceiveLauncherKeyPress(unsigned long eventType,
436+ unsigned long keysym,
437+ unsigned long state,
438+ const char* character,
439+ unsigned short keyCount);
440+
441+ static void OnBusAcquired(GDBusConnection* connection, const gchar* name, gpointer user_data);
442+ static void OnDBusMethodCall(GDBusConnection* connection, const gchar* sender, const gchar* object_path,
443+ const gchar* interface_name, const gchar* method_name,
444+ GVariant* parameters, GDBusMethodInvocation* invocation,
445+ gpointer user_data);
446+
447+ static GDBusInterfaceVTable interface_vtable;
448+
449+ Controller* parent_;
450+ LauncherModel::Ptr model_;
451+ nux::ObjectPtr<Launcher> launcher_;
452+ nux::ObjectPtr<Launcher> keyboard_launcher_;
453+ int sort_priority_;
454+ AbstractVolumeMonitorWrapper::Ptr volume_monitor_;
455+ DeviceLauncherSection device_section_;
456+ LauncherEntryRemoteModel remote_model_;
457+ AbstractLauncherIcon::Ptr expo_icon_;
458+ AbstractLauncherIcon::Ptr desktop_icon_;
459+ int num_workspaces_;
460+ bool show_desktop_icon_;
461+ Display* display_;
462+
463+ bool launcher_open;
464+ bool launcher_keynav;
465+ bool launcher_grabbed;
466+ bool reactivate_keynav;
467+ int reactivate_index;
468+ bool keynav_restore_window_;
469+ int launcher_key_press_time_;
470+ unsigned int dbus_owner_;
471+
472+ ui::EdgeBarrierController edge_barriers_;
473+
474+ LauncherList launchers;
475+
476+ glib::Object<BamfMatcher> matcher_;
477+ glib::Signal<void, BamfMatcher*, BamfView*> view_opened_signal_;
478+ glib::SourceManager sources_;
479+ UBusManager ubus;
480+
481+ sigc::connection on_expoicon_activate_connection_;
482+ sigc::connection launcher_key_press_connection_;
483+ sigc::connection launcher_event_outside_connection_;
484+};
485+
486+} // launcher namespace
487+} // unity namespace
488+
489+#endif
490
491=== modified file 'tests/CMakeLists.txt'
492--- tests/CMakeLists.txt 2012-07-24 23:09:24 +0000
493+++ tests/CMakeLists.txt 2012-07-26 13:13:33 +0000
494@@ -217,6 +217,7 @@
495 test_hud_view.cpp
496 test_icon_loader.cpp
497 test_im_text_entry.cpp
498+ test_launcher_controller.cpp
499 test_keyboard_util.cpp
500 test_resultviewgrid.cpp
501 test_single_monitor_launcher_icon.cpp
502@@ -239,9 +240,11 @@
503 ${CMAKE_SOURCE_DIR}/hud/HudView.cpp
504 ${CMAKE_SOURCE_DIR}/launcher/AbstractLauncherIcon.cpp
505 ${CMAKE_SOURCE_DIR}/launcher/BamfLauncherIcon.cpp
506+ ${CMAKE_SOURCE_DIR}/launcher/BFBLauncherIcon.cpp
507 ${CMAKE_SOURCE_DIR}/launcher/CairoBaseWindow.cpp
508 ${CMAKE_SOURCE_DIR}/launcher/DNDCollectionWindow.cpp
509 ${CMAKE_SOURCE_DIR}/launcher/Decaymulator.cpp
510+ ${CMAKE_SOURCE_DIR}/launcher/DesktopLauncherIcon.cpp
511 ${CMAKE_SOURCE_DIR}/launcher/DeviceLauncherIcon.cpp
512 ${CMAKE_SOURCE_DIR}/launcher/DeviceLauncherSection.cpp
513 ${CMAKE_SOURCE_DIR}/launcher/DevicesSettings.cpp
514@@ -251,9 +254,12 @@
515 ${CMAKE_SOURCE_DIR}/launcher/FavoriteStoreGSettings.cpp
516 ${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp
517 ${CMAKE_SOURCE_DIR}/launcher/GeisAdapter.cpp
518+ ${CMAKE_SOURCE_DIR}/launcher/HudLauncherIcon.cpp
519 ${CMAKE_SOURCE_DIR}/launcher/Launcher.cpp
520+ ${CMAKE_SOURCE_DIR}/launcher/LauncherController.cpp
521 ${CMAKE_SOURCE_DIR}/launcher/LauncherDragWindow.cpp
522 ${CMAKE_SOURCE_DIR}/launcher/LauncherEntryRemote.cpp
523+ ${CMAKE_SOURCE_DIR}/launcher/LauncherEntryRemoteModel.cpp
524 ${CMAKE_SOURCE_DIR}/launcher/LauncherHideMachine.cpp
525 ${CMAKE_SOURCE_DIR}/launcher/LauncherHoverMachine.cpp
526 ${CMAKE_SOURCE_DIR}/launcher/LauncherIcon.cpp
527@@ -271,11 +277,14 @@
528 ${CMAKE_SOURCE_DIR}/launcher/QuicklistView.cpp
529 ${CMAKE_SOURCE_DIR}/launcher/SimpleLauncherIcon.cpp
530 ${CMAKE_SOURCE_DIR}/launcher/SingleMonitorLauncherIcon.cpp
531+ ${CMAKE_SOURCE_DIR}/launcher/SoftwareCenterLauncherIcon.cpp
532 ${CMAKE_SOURCE_DIR}/launcher/SpacerLauncherIcon.cpp
533 ${CMAKE_SOURCE_DIR}/launcher/SwitcherController.cpp
534 ${CMAKE_SOURCE_DIR}/launcher/SwitcherModel.cpp
535 ${CMAKE_SOURCE_DIR}/launcher/SwitcherView.cpp
536 ${CMAKE_SOURCE_DIR}/launcher/Tooltip.cpp
537+ ${CMAKE_SOURCE_DIR}/launcher/TrashLauncherIcon.cpp
538+ ${CMAKE_SOURCE_DIR}/launcher/VolumeMonitorWrapper.cpp
539 ${CMAKE_SOURCE_DIR}/unity-shared/Animator.cpp
540 ${CMAKE_SOURCE_DIR}/unity-shared/BackgroundEffectHelper.cpp
541 ${CMAKE_SOURCE_DIR}/unity-shared/DashStyle.cpp
542
543=== modified file 'tests/test_edge_barrier_controller.cpp'
544--- tests/test_edge_barrier_controller.cpp 2012-07-20 18:34:34 +0000
545+++ tests/test_edge_barrier_controller.cpp 2012-07-26 13:13:33 +0000
546@@ -20,9 +20,9 @@
547
548 #include <gmock/gmock.h>
549 #include "test_utils.h"
550+#include "test_uscreen_mock.h"
551
552 #include "EdgeBarrierController.h"
553-#include "MultiMonitor.h"
554
555 using namespace unity;
556 using namespace unity::ui;
557@@ -53,6 +53,11 @@
558 {
559 EdgeBarrierController::ProcessBarrierEvent(owner, event);
560 }
561+
562+ EdgeBarrierSubscriber* GetSubscriber(unsigned int monitor)
563+ {
564+ return EdgeBarrierController::GetSubscriber(monitor);
565+ }
566 };
567
568 class TestBarrierSubscriber : public EdgeBarrierSubscriber
569@@ -79,6 +84,8 @@
570 bc.options()->edge_resist = true;
571 bc.options()->edge_passed_disabled_ms = 150;
572
573+ uscreen.SetupFakeMultiMonitor();
574+
575 for (int i = 0; i < max_num_monitors; ++i)
576 {
577 // By default we assume that no subscriber handles the events!!!
578@@ -93,12 +100,38 @@
579 }
580
581 TestBarrierSubscriber subscribers_[max_num_monitors];
582+ MockUScreen uscreen;
583 MockEdgeBarrierController bc;
584 };
585
586 TEST_F(TestEdgeBarrierController, Construction)
587 {
588 EXPECT_TRUE(bc.sticky_edges);
589+
590+ for (int i = 0; i < max_num_monitors; ++i)
591+ ASSERT_EQ(bc.GetSubscriber(i), &subscribers_[i]);
592+}
593+
594+TEST_F(TestEdgeBarrierController, Unsubscribe)
595+{
596+ for (int i = 0; i < max_num_monitors; ++i)
597+ {
598+ bc.Unsubscribe(&subscribers_[i], i);
599+ ASSERT_EQ(bc.GetSubscriber(i), nullptr);
600+ }
601+}
602+
603+TEST_F(TestEdgeBarrierController, UnsubscribeInvalid)
604+{
605+ bc.Unsubscribe(&subscribers_[2], 1);
606+ ASSERT_EQ(bc.GetSubscriber(2), &subscribers_[2]);
607+}
608+
609+TEST_F(TestEdgeBarrierController, SubscriberReplace)
610+{
611+ TestBarrierSubscriber handling_subscriber(true);
612+ bc.Subscribe(&handling_subscriber, 0);
613+ EXPECT_EQ(bc.GetSubscriber(0), &handling_subscriber);
614 }
615
616 TEST_F(TestEdgeBarrierController, ProcessHandledEvent)
617@@ -141,6 +174,20 @@
618 bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
619 }
620
621+TEST_F(TestEdgeBarrierController, ProcessUnHandledEventBreakingBarrierOnMaxMonitor)
622+{
623+ int monitor = max_num_monitors;
624+
625+ MockPointerBarrier owner(monitor);
626+ auto breaking_barrier_event = MakeBarrierEvent(0, true);
627+
628+ // This was leading to a crash, see bug #1020075
629+ // you can reproduce this repeating this test multiple times using the
630+ // --gtest_repeat=X command line
631+ EXPECT_CALL(owner, ReleaseBarrier(_));
632+ bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
633+}
634+
635 TEST_F(TestEdgeBarrierController, ProcessUnHandledEventNotBreakingBarrier)
636 {
637 int monitor = 2;
638
639=== added file 'tests/test_launcher_controller.cpp'
640--- tests/test_launcher_controller.cpp 1970-01-01 00:00:00 +0000
641+++ tests/test_launcher_controller.cpp 2012-07-26 13:13:33 +0000
642@@ -0,0 +1,202 @@
643+/*
644+ * Copyright 2012 Canonical Ltd.
645+ *
646+ * This program is free software: you can redistribute it and/or modify it
647+ * under the terms of the GNU General Public License version 3, as published
648+ * by the Free Software Foundation.
649+ *
650+ * This program is distributed in the hope that it will be useful, but
651+ * WITHOUT ANY WARRANTY; without even the implied warranties of
652+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
653+ * PURPOSE. See the GNU General Public License for more details.
654+ *
655+ * You should have received a copy of the GNU General Public License
656+ * version 3 along with this program. If not, see
657+ * <http://www.gnu.org/licenses/>
658+ *
659+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
660+ */
661+
662+#include <gmock/gmock.h>
663+#include "test_uscreen_mock.h"
664+
665+#include "FavoriteStore.h"
666+#include "LauncherController.h"
667+#include "LauncherControllerPrivate.h"
668+#include "PanelStyle.h"
669+#include "UnitySettings.h"
670+
671+using namespace unity::launcher;
672+using namespace testing;
673+
674+namespace unity
675+{
676+
677+class MockFavoriteStore : public FavoriteStore
678+{
679+public:
680+ FavoriteList const& GetFavorites()
681+ {
682+ return fav_list_;
683+ };
684+
685+ void AddFavorite(std::string const& desktop_path, int position) {};
686+ void RemoveFavorite(std::string const& desktop_path) {};
687+ void MoveFavorite(std::string const& desktop_path, int position) {};
688+ void SetFavorites(FavoriteList const& desktop_paths) {};
689+
690+private:
691+ FavoriteList fav_list_;
692+};
693+
694+namespace launcher
695+{
696+class TestLauncherController : public testing::Test
697+{
698+public:
699+ TestLauncherController()
700+ : lc(nux::GetGraphicsDisplay()->GetX11Display())
701+ {}
702+
703+ virtual void SetUp()
704+ {
705+ lc.options = std::make_shared<Options>();
706+ lc.multiple_launchers = true;
707+ }
708+
709+protected:
710+ ui::EdgeBarrierController &GetBarrierController()
711+ {
712+ return lc.pimpl->edge_barriers_;
713+ }
714+
715+ MockUScreen uscreen;
716+ Settings settings;
717+ panel::Style panel_style;
718+ MockFavoriteStore favorite_store;
719+ GeisAdapter geis_adapter;
720+ Controller lc;
721+};
722+}
723+
724+TEST_F(TestLauncherController, Construction)
725+{
726+ EXPECT_NE(lc.options(), nullptr);
727+ EXPECT_TRUE(lc.multiple_launchers());
728+}
729+
730+TEST_F(TestLauncherController, MultimonitorMultipleLaunchers)
731+{
732+ lc.multiple_launchers = true;
733+ uscreen.SetupFakeMultiMonitor();
734+
735+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
736+
737+ for (int i = 0; i < max_num_monitors; ++i)
738+ {
739+ EXPECT_EQ(lc.launchers()[i]->monitor(), i);
740+ }
741+}
742+
743+TEST_F(TestLauncherController, MultimonitorSingleLauncher)
744+{
745+ lc.multiple_launchers = false;
746+ uscreen.SetupFakeMultiMonitor(0, false);
747+
748+ for (int i = 0; i < max_num_monitors; ++i)
749+ {
750+ uscreen.SetPrimary(i);
751+ ASSERT_EQ(lc.launchers().size(), 1);
752+ EXPECT_EQ(lc.launcher().monitor(), i);
753+ }
754+}
755+
756+TEST_F(TestLauncherController, MultimonitorSwitchToMultipleLaunchers)
757+{
758+ lc.multiple_launchers = false;
759+ uscreen.SetupFakeMultiMonitor();
760+
761+ ASSERT_EQ(lc.launchers().size(), 1);
762+
763+ lc.multiple_launchers = true;
764+ EXPECT_EQ(lc.launchers().size(), max_num_monitors);
765+}
766+
767+TEST_F(TestLauncherController, MultimonitorSwitchToSingleLauncher)
768+{
769+ lc.multiple_launchers = true;
770+ int primary = 3;
771+ uscreen.SetupFakeMultiMonitor(primary);
772+
773+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
774+
775+ lc.multiple_launchers = false;
776+ EXPECT_EQ(lc.launchers().size(), 1);
777+ EXPECT_EQ(lc.launcher().monitor(), primary);
778+}
779+
780+TEST_F(TestLauncherController, MultimonitorSwitchToSingleMonitor)
781+{
782+ uscreen.SetupFakeMultiMonitor();
783+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
784+
785+ uscreen.Reset();
786+ EXPECT_EQ(lc.launchers().size(), 1);
787+ EXPECT_EQ(lc.launcher().monitor(), 0);
788+}
789+
790+TEST_F(TestLauncherController, MultimonitorRemoveMiddleMonitor)
791+{
792+ uscreen.SetupFakeMultiMonitor();
793+ ASSERT_EQ(lc.launchers().size(), max_num_monitors);
794+
795+ std::vector<nux::Geometry> &monitors = uscreen.GetMonitors();
796+ monitors.erase(monitors.begin() + monitors.size()/2);
797+ uscreen.changed.emit(uscreen.GetPrimaryMonitor(), uscreen.GetMonitors());
798+ ASSERT_EQ(lc.launchers().size(), max_num_monitors - 1);
799+
800+ for (int i = 0; i < max_num_monitors - 1; ++i)
801+ EXPECT_EQ(lc.launchers()[i]->monitor(), i);
802+}
803+
804+TEST_F(TestLauncherController, SingleMonitorSwitchToMultimonitor)
805+{
806+ ASSERT_EQ(lc.launchers().size(), 1);
807+
808+ uscreen.SetupFakeMultiMonitor();
809+
810+ EXPECT_EQ(lc.launchers().size(), max_num_monitors);
811+}
812+
813+TEST_F(TestLauncherController, MultiMonitorEdgeBarrierSubscriptions)
814+{
815+ uscreen.SetupFakeMultiMonitor();
816+
817+ for (int i = 0; i < max_num_monitors; ++i)
818+ ASSERT_EQ(GetBarrierController().GetSubscriber(i), lc.launchers()[i].GetPointer());
819+}
820+
821+TEST_F(TestLauncherController, SingleMonitorEdgeBarrierSubscriptionsUpdates)
822+{
823+ lc.multiple_launchers = false;
824+ uscreen.SetupFakeMultiMonitor(0, false);
825+
826+ for (int i = 0; i < max_num_monitors; ++i)
827+ {
828+ uscreen.SetPrimary(i);
829+
830+ for (int j = 0; j < max_num_monitors; ++j)
831+ {
832+ if (j == i)
833+ {
834+ ASSERT_EQ(GetBarrierController().GetSubscriber(j), &lc.launcher());
835+ }
836+ else
837+ {
838+ ASSERT_EQ(GetBarrierController().GetSubscriber(j), nullptr);
839+ }
840+ }
841+ }
842+}
843+
844+}
845
846=== added file 'tests/test_uscreen_mock.h'
847--- tests/test_uscreen_mock.h 1970-01-01 00:00:00 +0000
848+++ tests/test_uscreen_mock.h 2012-07-26 13:13:33 +0000
849@@ -0,0 +1,85 @@
850+/*
851+ * Copyright 2012 Canonical Ltd.
852+ *
853+ * This program is free software: you can redistribute it and/or modify it
854+ * under the terms of the GNU General Public License version 3, as published
855+ * by the Free Software Foundation.
856+ *
857+ * This program is distributed in the hope that it will be useful, but
858+ * WITHOUT ANY WARRANTY; without even the implied warranties of
859+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
860+ * PURPOSE. See the GNU General Public License for more details.
861+ *
862+ * You should have received a copy of the GNU General Public License
863+ * version 3 along with this program. If not, see
864+ * <http://www.gnu.org/licenses/>
865+ *
866+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
867+
868+ */
869+
870+#ifndef TEST_USCREEN_MOCK_H
871+#define TEST_USCREEN_MOCK_H
872+
873+#include "MultiMonitor.h"
874+#include "UScreen.h"
875+
876+namespace unity
877+{
878+
879+const unsigned MONITOR_WIDTH = 1024;
880+const unsigned MONITOR_HEIGHT = 768;
881+
882+class MockUScreen : public UScreen
883+{
884+public:
885+ MockUScreen()
886+ {
887+ Reset(false);
888+ }
889+
890+ ~MockUScreen()
891+ {
892+ if (default_screen_ == this)
893+ default_screen_ = nullptr;
894+ }
895+
896+ void Reset(bool emit = true)
897+ {
898+ default_screen_ = this;
899+ primary_ = 0;
900+ monitors_ = {nux::Geometry(0, 0, MONITOR_WIDTH, MONITOR_HEIGHT)};
901+
902+ changed.emit(primary_, monitors_);
903+ }
904+
905+ void SetupFakeMultiMonitor(int primary = 0, bool emit_update = true)
906+ {
907+ SetPrimary(primary, false);
908+ monitors_.clear();
909+
910+ for (int i = 0, total_width = 0; i < max_num_monitors; ++i)
911+ {
912+ monitors_.push_back(nux::Geometry(MONITOR_WIDTH, MONITOR_HEIGHT, total_width, 0));
913+ total_width += MONITOR_WIDTH;
914+
915+ if (emit_update)
916+ changed.emit(GetPrimaryMonitor(), GetMonitors());
917+ }
918+ }
919+
920+ void SetPrimary(int primary, bool emit = true)
921+ {
922+ if (primary_ != primary)
923+ {
924+ primary_ = primary;
925+
926+ if (emit)
927+ changed.emit(primary_, monitors_);
928+ }
929+ }
930+};
931+
932+}
933+
934+#endif
935\ No newline at end of file
936
937=== modified file 'unity-shared/UScreen.cpp'
938--- unity-shared/UScreen.cpp 2012-06-18 02:57:23 +0000
939+++ unity-shared/UScreen.cpp 2012-07-26 13:13:33 +0000
940@@ -24,17 +24,18 @@
941
942 namespace
943 {
944-static UScreen* default_screen_ = nullptr;
945 nux::logging::Logger logger("unity.screen");
946 }
947
948+UScreen* UScreen::default_screen_ = nullptr;
949+
950 UScreen::UScreen()
951- : screen_(gdk_screen_get_default(), glib::AddRef())
952+ : primary_(0)
953+ , screen_(gdk_screen_get_default(), glib::AddRef())
954 , proxy_("org.freedesktop.UPower",
955 "/org/freedesktop/UPower",
956 "org.freedesktop.UPower",
957 G_BUS_TYPE_SYSTEM)
958- , primary_(0)
959 {
960 size_changed_signal_.Connect(screen_, "size-changed", sigc::mem_fun(this, &UScreen::Changed));
961 monitors_changed_signal_.Connect(screen_, "monitors-changed", sigc::mem_fun(this, &UScreen::Changed));
962
963=== modified file 'unity-shared/UScreen.h'
964--- unity-shared/UScreen.h 2012-06-18 02:57:23 +0000
965+++ unity-shared/UScreen.h 2012-07-26 13:13:33 +0000
966@@ -55,14 +55,17 @@
967 void Changed(GdkScreen* screen);
968 void Refresh();
969
970-private:
971+protected:
972+ static UScreen* default_screen_;
973 std::vector<nux::Geometry> monitors_;
974+ int primary_;
975+
976+private:
977 glib::Object<GdkScreen> screen_;
978 glib::DBusProxy proxy_;
979 glib::Signal<void, GdkScreen*> size_changed_signal_;
980 glib::Signal<void, GdkScreen*> monitors_changed_signal_;
981 glib::Source::UniquePtr refresh_idle_;
982- int primary_;
983 };
984
985 } // Namespace