Merge lp:~3v1n0/unity/hud-lock-out-monitors-tests into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Superseded
Proposed branch: lp:~3v1n0/unity/hud-lock-out-monitors-tests
Merge into: lp:unity
Diff against target: 799 lines (+295/-92)
13 files modified
manual-tests/Hud.txt (+1/-4)
plugins/unityshell/src/BamfLauncherIcon.cpp (+2/-1)
plugins/unityshell/src/HudController.cpp (+40/-35)
plugins/unityshell/src/HudController.h (+6/-9)
plugins/unityshell/src/HudView.cpp (+10/-8)
plugins/unityshell/src/HudView.h (+2/-8)
plugins/unityshell/src/LauncherIcon.cpp (+14/-12)
plugins/unityshell/src/unityshell.cpp (+3/-2)
tests/autopilot/autopilot/emulators/X11.py (+12/-1)
tests/autopilot/autopilot/emulators/unity/hud.py (+23/-0)
tests/autopilot/autopilot/emulators/unity/icons.py (+8/-0)
tests/autopilot/autopilot/emulators/unity/launcher.py (+18/-4)
tests/autopilot/autopilot/tests/test_hud.py (+156/-8)
To merge this branch: bzr merge lp:~3v1n0/unity/hud-lock-out-monitors-tests
Reviewer Review Type Date Requested Status
Thomi Richards (community) Needs Fixing
Gord Allott (community) Approve
Review via email: mp+98634@code.launchpad.net

This proposal has been superseded by a proposal from 2012-03-25.

Description of the change

Added tests for multimonitor in HUD and to check the lock-out

To post a comment you must log in.
Revision history for this message
Gord Allott (gordallott) wrote :

+1, seems good here

review: Approve
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote :

Hi,

44 + def is_rect_on_monitor(self, monitor_number, x, y, w, h):
45 + (m_x, m_y, m_w, m_h) = self.get_monitor_geometry(monitor_number)
46 + return (x >= m_x and x + w <= m_x + m_w and y >= m_y and y + h <= m_y + m_h)
47 +

Instead of passing x,y,w & h as separate parameters, just pass 'rect', and make sure it's a tuple in the function:
def is_rect_on_monitor(self, monitor_number, rect):
    """Returns True if `rect` is _entirely_ on the specified monitor, with no overlap"""
    if type(rect) is not tuple:
        raise TypeError("rect must be a tuple.")

...if you want you can also check that monitor_number is a valid integer, and that the tuple values are all ints.

This:

59 + def get_geometry(self):
60 + return (self.x, self.y, self.width, self.height)
61 +

should be a property, like this:

58 + @property
59 + def geometry(self):
60 + return (self.x, self.y, self.width, self.height)
61 +

this:

84 + screen_geometry = ScreenGeometry()
85 + num_monitors = screen_geometry.get_num_monitors()
86 +
87 + if num_monitors == 1:
88 + scenarios = [
89 + ('Single Monitor, Launcher never hide', {'hud_monitor': 0, 'launcher_hide_mode': 0}),
90 + ('Single Monitor, Launcher autohide', {'hud_monitor': 0, 'launcher_hide_mode': 1}),
91 + ]
92 + else:
93 + scenarios = []
94 + for i in range(num_monitors):
95 + scenarios.append(('Monitor %d, Launcher never hide' % (i), {'hud_monitor': i, 'launcher_hide_mode': 0}))
96 + scenarios.append(('Monitor %d, Launcher autohide' % (i), {'hud_monitor': i, 'launcher_hide_mode': 1}))

is kind of ugly. A better way to do it is how we do it in the launcher tests - use a function to generate the scenarios.

The first two changes I mentioned mean that you can rewrite this:

112 + (x, y, w, h) = self.hud.get_geometry()
113 + self.assertTrue(self.screen_geometry.is_rect_on_monitor(self.hud_monitor, x, y, w, h))

like this:

self.assertTrue(self.screen_geometry.is_rect_on_monitor(self.hud_monitor, self.hud.geometry)

The new test:

131 + def test_hud_dont_change_launcher_status(self):

...needs a docstring.

Finally, please use matchers for everything except simple true/false tests, so this:

139 + self.assertEqual(launcher_shows_pre, launcher_shows_post)

becomes:

self.assertThat(launcher_shows_pre, Equals(launcher_shows_post))

Cheers,

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'manual-tests/Hud.txt'
2--- manual-tests/Hud.txt 2012-03-21 14:44:41 +0000
3+++ manual-tests/Hud.txt 2012-03-25 18:15:22 +0000
4@@ -64,10 +64,7 @@
5 #. Tap Alt
6
7 Outcome
8- The Launcher should stick be locked out.
9- The Launcher icons should be desaturated.
10- The top most Launcher icon should be an icon related the the focused window
11- The BFB should not be present
12+ The top most Launcher icon should be an icon related to the focused window
13
14
15 Hud Sending Undo
16
17=== modified file 'plugins/unityshell/src/BamfLauncherIcon.cpp'
18--- plugins/unityshell/src/BamfLauncherIcon.cpp 2012-03-22 15:14:49 +0000
19+++ plugins/unityshell/src/BamfLauncherIcon.cpp 2012-03-25 18:15:22 +0000
20@@ -473,7 +473,8 @@
21 g_list_free(children);
22
23 variant::BuilderWrapper(builder)
24- .add("desktop-file", DesktopFile())
25+ .add("desktop_file", DesktopFile())
26+ .add("desktop_id", glib::String(g_path_get_basename(DesktopFile().c_str())).Str())
27 .add("xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i))
28 .add("sticky", IsSticky());
29 }
30
31=== modified file 'plugins/unityshell/src/HudController.cpp'
32--- plugins/unityshell/src/HudController.cpp 2012-03-21 15:30:49 +0000
33+++ plugins/unityshell/src/HudController.cpp 2012-03-25 18:15:22 +0000
34@@ -40,6 +40,8 @@
35
36 Controller::Controller()
37 : launcher_width(65)
38+ , launcher_locked_out(false)
39+ , multiple_launchers(true)
40 , hud_service_("com.canonical.hud", "/com/canonical/hud")
41 , window_(nullptr)
42 , visible_(false)
43@@ -47,12 +49,11 @@
44 , timeline_id_(0)
45 , last_opacity_(0.0f)
46 , start_time_(0)
47- , launcher_is_locked_out_(false)
48 , view_(nullptr)
49 , monitor_index_(0)
50 {
51 LOG_DEBUG(logger) << "hud startup";
52- SetupRelayoutCallbacks();
53+ UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(); });
54
55 ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud));
56
57@@ -65,13 +66,13 @@
58 gint32 overlay_monitor = 0;
59 g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor);
60
61- if (g_strcmp0(overlay_identity, "hud"))
62+ if (overlay_identity.Str() != "hud")
63 {
64 HideHud(true);
65 }
66 });
67
68- launcher_width.changed.connect([this] (int new_width) { Relayout(); });
69+ launcher_width.changed.connect([&] (int new_width) { Relayout(); });
70
71 PluginAdapter::Default()->compiz_screen_ungrabbed.connect(sigc::mem_fun(this, &Controller::OnScreenUngrabbed));
72
73@@ -120,14 +121,24 @@
74 AddChild(view_);
75 }
76
77-void Controller::SetupRelayoutCallbacks()
78-{
79- GdkScreen* screen = gdk_screen_get_default();
80-
81- sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen,
82- "monitors-changed", sigc::mem_fun(this, &Controller::Relayout)));
83- sig_manager_.Add(new glib::Signal<void, GdkScreen*>(screen,
84- "size-changed", sigc::mem_fun(this, &Controller::Relayout)));
85+int Controller::GetTargetMonitor()
86+{
87+ return UScreen::GetDefault()->GetMonitorWithMouse();
88+}
89+
90+bool Controller::IsLockedToLauncher(int monitor)
91+{
92+ if (launcher_locked_out)
93+ {
94+ int primary_monitor = UScreen::GetDefault()->GetPrimaryMonitor();
95+
96+ if (multiple_launchers || (!multiple_launchers && primary_monitor == monitor))
97+ {
98+ return true;
99+ }
100+ }
101+
102+ return false;
103 }
104
105 void Controller::EnsureHud()
106@@ -158,26 +169,27 @@
107
108 nux::Geometry Controller::GetIdealWindowGeometry()
109 {
110- UScreen *uscreen = UScreen::GetDefault();
111- int primary_monitor = uscreen->GetMonitorWithMouse();
112- auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor);
113+ int target_monitor = GetTargetMonitor();
114+ auto monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(target_monitor);
115
116- // We want to cover as much of the screen as possible to grab any mouse events outside
117+ // We want to cover as much of the screen as possible to grab any mouse events outside447
118 // of our window
119 panel::Style &panel_style = panel::Style::Instance();
120 nux::Geometry geo(monitor_geo.x,
121- monitor_geo.y + panel_style.panel_height,
122- monitor_geo.width,
123- monitor_geo.height - panel_style.panel_height);
124- if (launcher_is_locked_out_)
125+ monitor_geo.y + panel_style.panel_height,
126+ monitor_geo.width,
127+ monitor_geo.height - panel_style.panel_height);
128+
129+ if (IsLockedToLauncher(target_monitor))
130 {
131 geo.x += launcher_width;
132 geo.width -= launcher_width;
133 }
134+
135 return geo;
136 }
137
138-void Controller::Relayout(GdkScreen*screen)
139+void Controller::Relayout()
140 {
141 EnsureHud();
142 nux::Geometry content_geo = view_->GetGeometry();
143@@ -190,7 +202,7 @@
144 }
145
146 void Controller::OnMouseDownOutsideWindow(int x, int y,
147- unsigned long bflags, unsigned long kflags)
148+ unsigned long bflags, unsigned long kflags)
149 {
150 LOG_DEBUG(logger) << "OnMouseDownOutsideWindow called";
151 HideHud();
152@@ -234,16 +246,6 @@
153 return visible_;
154 }
155
156-void Controller::SetLauncherIsLockedOut(bool launcher_is_locked_out)
157-{
158- launcher_is_locked_out_ = launcher_is_locked_out;
159- if (launcher_is_locked_out_)
160- view_->SetHideIcon(IconHideState::HIDE);
161- else
162- view_->SetHideIcon(IconHideState::SHOW);
163- Relayout();
164-}
165-
166 void Controller::ShowHud()
167 {
168 PluginAdapter* adaptor = PluginAdapter::Default();
169@@ -259,6 +261,8 @@
170 return;
171 }
172
173+ monitor_index_ = GetTargetMonitor();
174+ view_->ShowEmbeddedIcon(!IsLockedToLauncher(monitor_index_));
175 view_->AboutToShow();
176
177 // we first want to grab the currently active window, luckly we can just ask the jason interface(bamf)
178@@ -289,7 +293,6 @@
179 // hide the launcher
180 GVariant* message_data = g_variant_new("(b)", TRUE);
181 ubus.SendMessage(UBUS_LAUNCHER_LOCK_HIDE, message_data);
182- monitor_index_ = UScreen::GetDefault()->GetMonitorWithMouse();
183 GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "hud", FALSE, monitor_index_);
184 ubus.SendMessage(UBUS_OVERLAY_SHOWN, info);
185
186@@ -410,7 +413,6 @@
187 ubus.SendMessage(UBUS_HUD_ICON_CHANGED, g_variant_new_string(query->icon_name.c_str()));
188 }
189
190-
191 void Controller::OnQueriesFinished(Hud::Queries queries)
192 {
193 view_->SetQueries(queries);
194@@ -438,7 +440,10 @@
195 void Controller::AddProperties(GVariantBuilder* builder)
196 {
197 variant::BuilderWrapper(builder)
198- .add("visible", visible_);
199+ .add(window_ ? window_->GetGeometry() : nux::Geometry())
200+ .add("visible", visible_)
201+ .add("hud_monitor", monitor_index_)
202+ .add("locked_to_launcher", IsLockedToLauncher(monitor_index_));
203 }
204
205
206
207=== modified file 'plugins/unityshell/src/HudController.h'
208--- plugins/unityshell/src/HudController.h 2012-03-21 15:30:49 +0000
209+++ plugins/unityshell/src/HudController.h 2012-03-25 18:15:22 +0000
210@@ -22,7 +22,6 @@
211 #include <memory>
212
213 #include <gdk/gdk.h>
214-#include <UnityCore/GLibSignal.h>
215 #include <UnityCore/Hud.h>
216
217 #include <NuxCore/Property.h>
218@@ -49,12 +48,13 @@
219 nux::BaseWindow* window() const;
220
221 nux::Property<int> launcher_width;
222+ nux::Property<bool> launcher_locked_out;
223+ nux::Property<bool> multiple_launchers;
224
225 void ShowHideHud();
226 void ShowHud();
227 void HideHud(bool restore_focus = true);
228 bool IsVisible();
229- void SetLauncherIsLockedOut(bool launcher_is_locked_out);
230
231 protected:
232 std::string GetName() const;
233@@ -64,11 +64,13 @@
234 void EnsureHud();
235 void SetupWindow();
236 void SetupHudView();
237- void SetupRelayoutCallbacks();
238 void RegisterUBusInterests();
239
240+ int GetTargetMonitor();
241+ bool IsLockedToLauncher(int monitor);
242+
243 nux::Geometry GetIdealWindowGeometry();
244- void Relayout(GdkScreen*screen=NULL);
245+ void Relayout();
246
247 void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);
248 void OnScreenUngrabbed();
249@@ -81,8 +83,6 @@
250 void OnQueryActivated(Query::Ptr query);
251 void OnQuerySelected(Query::Ptr query);
252
253-
254-private:
255 void StartShowHideTimeline();
256 static gboolean OnViewShowHideFrame(Controller* self);
257
258@@ -93,7 +93,6 @@
259 private:
260 UBusManager ubus;
261 Hud hud_service_;
262- glib::SignalManager sig_manager_;
263 nux::BaseWindow* window_;
264 bool visible_;
265 bool need_show_;
266@@ -101,8 +100,6 @@
267 guint timeline_id_;
268 float last_opacity_;
269 gint64 start_time_;
270-
271- bool launcher_is_locked_out_;
272
273 View* view_;
274 guint ensure_id_;
275
276=== modified file 'plugins/unityshell/src/HudView.cpp'
277--- plugins/unityshell/src/HudView.cpp 2012-03-21 15:07:29 +0000
278+++ plugins/unityshell/src/HudView.cpp 2012-03-25 18:15:22 +0000
279@@ -64,7 +64,7 @@
280 , current_height_(0)
281 , timeline_need_more_draw_(false)
282 , selected_button_(0)
283- , icon_state_(IconHideState::SHOW)
284+ , show_embedded_icon_(true)
285 , activated_signal_sent_(false)
286 {
287 renderer_.SetOwner(this);
288@@ -276,16 +276,16 @@
289 QueueDraw();
290 }
291
292-void View::SetHideIcon(IconHideState hide_icon)
293+void View::ShowEmbeddedIcon(bool show)
294 {
295 LOG_DEBUG(logger) << "Hide icon called";
296- if (hide_icon == icon_state_)
297+ if (show == show_embedded_icon_)
298 return;
299
300- icon_state_ = hide_icon;
301+ show_embedded_icon_ = show;
302
303- if (icon_state_ == IconHideState::HIDE)
304- layout_->RemoveChildObject(dynamic_cast<nux::Area*>(icon_layout_.GetPointer()));
305+ if (!show)
306+ layout_->RemoveChildObject(static_cast<nux::Area*>(icon_layout_.GetPointer()));
307 else
308 layout_->AddLayout(icon_layout_.GetPointer(), 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_MATCHCONTENT, 100.0f, nux::LayoutPosition::NUX_LAYOUT_BEGIN);
309
310@@ -303,7 +303,7 @@
311 width = 1024;
312 height = 276;
313
314- if (icon_state_ == IconHideState::HIDE)
315+ if (!show_embedded_icon_)
316 {
317 width -= icon_layout_->GetGeometry().width;
318 }
319@@ -491,8 +491,10 @@
320 {
321 unsigned num_buttons = buttons_.size();
322 variant::BuilderWrapper(builder)
323+ .add(GetGeometry())
324 .add("selected_button", selected_button_)
325- .add("num_buttons", num_buttons);
326+ .add("num_buttons", num_buttons)
327+ .add("show_embedded_icon", show_embedded_icon_);
328 }
329
330 bool View::InspectKeyEvent(unsigned int eventType,
331
332=== modified file 'plugins/unityshell/src/HudView.h'
333--- plugins/unityshell/src/HudView.h 2012-03-21 14:44:41 +0000
334+++ plugins/unityshell/src/HudView.h 2012-03-25 18:15:22 +0000
335@@ -44,12 +44,6 @@
336 namespace hud
337 {
338
339-enum IconHideState
340-{
341- HIDE,
342- SHOW
343-};
344-
345 class View : public nux::View, public unity::debug::Introspectable
346 {
347 NUX_DECLARE_OBJECT_TYPE(HudView, nux::View);
348@@ -65,7 +59,7 @@
349
350 void SetQueries(Hud::Queries queries);
351 void SetIcon(std::string icon_name);
352- void SetHideIcon(IconHideState hide_icon);
353+ void ShowEmbeddedIcon(bool show);
354
355 void AboutToShow();
356 void AboutToHide();
357@@ -126,7 +120,7 @@
358 int current_height_;
359 bool timeline_need_more_draw_;
360 int selected_button_;
361- IconHideState icon_state_;
362+ bool show_embedded_icon_;
363 bool activated_signal_sent_;
364 };
365
366
367=== modified file 'plugins/unityshell/src/LauncherIcon.cpp'
368--- plugins/unityshell/src/LauncherIcon.cpp 2012-03-21 12:31:11 +0000
369+++ plugins/unityshell/src/LauncherIcon.cpp 2012-03-25 18:15:22 +0000
370@@ -185,18 +185,20 @@
371 LauncherIcon::AddProperties(GVariantBuilder* builder)
372 {
373 unity::variant::BuilderWrapper(builder)
374- .add("x", _center[0].x)
375- .add("y", _center[0].y)
376- .add("z", _center[0].z)
377- .add("related-windows", (int)Windows().size())
378- .add("icon-type", _icon_type)
379- .add("tooltip-text", tooltip_text())
380- .add("sort-priority", _sort_priority)
381- .add("quirk-active", GetQuirk(QUIRK_ACTIVE))
382- .add("quirk-visible", GetQuirk(QUIRK_VISIBLE))
383- .add("quirk-urgent", GetQuirk(QUIRK_URGENT))
384- .add("quirk-running", GetQuirk(QUIRK_RUNNING))
385- .add("quirk-presented", GetQuirk(QUIRK_PRESENTED));
386+ .add("center_x", _center[0].x)
387+ .add("center_y", _center[0].y)
388+ .add("center_z", _center[0].z)
389+ .add("related_windows", static_cast<unsigned int>(Windows().size()))
390+ .add("icon_type", _icon_type)
391+ .add("tooltip_text", tooltip_text())
392+ .add("sort_priority", _sort_priority)
393+ .add("active", GetQuirk(QUIRK_ACTIVE))
394+ .add("visible", GetQuirk(QUIRK_VISIBLE))
395+ .add("urgent", GetQuirk(QUIRK_URGENT))
396+ .add("running", GetQuirk(QUIRK_RUNNING))
397+ .add("starting", GetQuirk(QUIRK_STARTING))
398+ .add("desaturated", GetQuirk(QUIRK_DESAT))
399+ .add("presented", GetQuirk(QUIRK_PRESENTED));
400 }
401
402 void
403
404=== modified file 'plugins/unityshell/src/unityshell.cpp'
405--- plugins/unityshell/src/unityshell.cpp 2012-03-22 19:33:10 +0000
406+++ plugins/unityshell/src/unityshell.cpp 2012-03-25 18:15:22 +0000
407@@ -2520,6 +2520,7 @@
408 case UnityshellOptions::NumLaunchers:
409 launcher_controller_->multiple_launchers = optionGetNumLaunchers() == 0;
410 dash_controller_->use_primary = !launcher_controller_->multiple_launchers();
411+ hud_controller_->multiple_launchers = launcher_controller_->multiple_launchers();
412 break;
413 case UnityshellOptions::LauncherCaptureMouse:
414 launcher_options->edge_resist = optionGetLauncherCaptureMouse();
415@@ -2540,7 +2541,7 @@
416 case UnityshellOptions::LauncherHideMode:
417 {
418 launcher_options->hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode();
419- hud_controller_->SetLauncherIsLockedOut(launcher_options->hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER);
420+ hud_controller_->launcher_locked_out = (launcher_options->hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER);
421 break;
422 }
423 case UnityshellOptions::BacklightMode:
424@@ -2775,7 +2776,7 @@
425 /* Setup Hud */
426 hud_controller_.reset(new hud::Controller());
427 auto hide_mode = (unity::launcher::LauncherHideMode) optionGetLauncherHideMode();
428- hud_controller_->SetLauncherIsLockedOut(hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER);
429+ hud_controller_->launcher_locked_out = (hide_mode == unity::launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER);
430 AddChild(hud_controller_.get());
431 LOG_INFO(logger) << "initLauncher-hud " << timer.ElapsedSeconds() << "s";
432
433
434=== modified file 'tests/autopilot/autopilot/emulators/X11.py'
435--- tests/autopilot/autopilot/emulators/X11.py 2012-03-21 12:31:11 +0000
436+++ tests/autopilot/autopilot/emulators/X11.py 2012-03-25 18:15:22 +0000
437@@ -339,10 +339,21 @@
438 Returns a tuple containing (x,y,width,height).
439
440 """
441- if monitor_number >= self.get_num_monitors():
442+ if monitor_number < 0 or monitor_number >= self.get_num_monitors():
443 raise ValueError('Specified monitor number is out of range.')
444 return tuple(self._default_screen.get_monitor_geometry(monitor_number))
445
446+ def is_rect_on_monitor(self, monitor_number, rect):
447+ """Returns True if `rect` is _entirely_ on the specified monitor, with no overlap"""
448+
449+ if type(rect) is not tuple or len(rect) != 4:
450+ raise TypeError("rect must be a tuple of 4 int elements.")
451+
452+ (x, y, w, h) = self.get_monitor_geometry(monitor_number)
453+
454+ (m_x, m_y, m_w, m_h) = self.get_monitor_geometry(monitor_number)
455+ return (x >= m_x and x + w <= m_x + m_w and y >= m_y and y + h <= m_y + m_h)
456+
457 def move_mouse_to_monitor(self, monitor_number):
458 """Move the mouse to the center of the specified monitor."""
459 geo = self.get_monitor_geometry(monitor_number)
460
461=== modified file 'tests/autopilot/autopilot/emulators/unity/hud.py'
462--- tests/autopilot/autopilot/emulators/unity/hud.py 2012-03-04 23:12:19 +0000
463+++ tests/autopilot/autopilot/emulators/unity/hud.py 2012-03-25 18:15:22 +0000
464@@ -35,11 +35,18 @@
465 """Tap the 'Alt' key to toggle the hud visibility."""
466 self.keybinding("hud/reveal", tap_delay)
467
468+ def get_geometry(self):
469+ return (self.x, self.y, self.width, self.height)
470+
471 def _get_view(self):
472 views = self.get_children_by_type(HudView)
473 return views[0] if views else None
474
475 @property
476+ def geometry(self):
477+ return (self.x, self.y, self.width, self.height)
478+
479+ @property
480 def selected_button(self):
481 view = self._get_view()
482 if view:
483@@ -54,3 +61,19 @@
484 return view.num_buttons
485 else:
486 return 0
487+
488+ @property
489+ def is_locked_to_launcher(self):
490+ return bool(self.locked_to_launcher)
491+
492+ @property
493+ def monitor(self):
494+ return int(self.hud_monitor)
495+
496+ @property
497+ def show_embedded_icon(self):
498+ view = self._get_view()
499+ if view:
500+ return bool(view.show_embedded_icon)
501+ else:
502+ return False
503
504=== modified file 'tests/autopilot/autopilot/emulators/unity/icons.py'
505--- tests/autopilot/autopilot/emulators/unity/icons.py 2012-03-04 23:12:19 +0000
506+++ tests/autopilot/autopilot/emulators/unity/icons.py 2012-03-25 18:15:22 +0000
507@@ -19,6 +19,10 @@
508
509 """
510
511+ @property
512+ def center_geometry(self):
513+ return (self.center_x, self.center_y, self.center_z)
514+
515 def get_quicklist(self):
516 """Get the quicklist for this launcher icon.
517
518@@ -34,6 +38,10 @@
519 """Represents the BFB button in the launcher."""
520
521
522+class HudLauncherIcon(SimpleLauncherIcon):
523+ """Represents the HUD button in the launcher."""
524+
525+
526 class BamfLauncherIcon(SimpleLauncherIcon):
527 """Represents a launcher icon with BAMF integration."""
528
529
530=== modified file 'tests/autopilot/autopilot/emulators/unity/launcher.py'
531--- tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-15 20:03:08 +0000
532+++ tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-25 18:15:22 +0000
533@@ -196,8 +196,8 @@
534 logger.debug("Clicking launcher icon %r on monitor %d with mouse button %d",
535 icon, self.monitor, button)
536 self.mouse_reveal_launcher()
537- target_x = icon.x + self.x
538- target_y = icon.y + (self.icon_size / 2)
539+ target_x = icon.center_x + self.x
540+ target_y = icon.center_y
541 self._mouse.move(target_x, target_y )
542 self._mouse.click(button)
543 self.move_mouse_to_right_of_launcher()
544@@ -257,7 +257,7 @@
545 def get_launcher_icons(self, visible_only=True):
546 """Get a list of launcher icons in this launcher."""
547 if visible_only:
548- return self.get_children_by_type(SimpleLauncherIcon, quirk_visible=True)
549+ return self.get_children_by_type(SimpleLauncherIcon, visible=True)
550 else:
551 return self.get_children_by_type(SimpleLauncherIcon)
552
553@@ -277,7 +277,21 @@
554 Returns None if there is no such launcher icon.
555 """
556 icons = self.get_children_by_type(SimpleLauncherIcon, desktop_file=desktop_file)
557- return icons or None
558+ if len(icons):
559+ return icons[0]
560+
561+ return None
562+
563+ def get_icon_by_desktop_id(self, desktop_id):
564+ """Gets a launcher icon with the specified desktop id.
565+
566+ Returns None if there is no such launcher icon.
567+ """
568+ icons = self.get_children_by_type(SimpleLauncherIcon, desktop_id=desktop_id)
569+ if len(icons):
570+ return icons[0]
571+
572+ return None
573
574 def num_launcher_icons(self):
575 """Get the number of icons in the launcher model."""
576
577=== modified file 'tests/autopilot/autopilot/tests/test_hud.py'
578--- tests/autopilot/autopilot/tests/test_hud.py 2012-03-21 14:44:41 +0000
579+++ tests/autopilot/autopilot/tests/test_hud.py 2012-03-25 18:15:22 +0000
580@@ -6,23 +6,55 @@
581 # under the terms of the GNU General Public License version 3, as published
582 # by the Free Software Foundation.
583
584-from testtools.matchers import Equals, LessThan
585+from testtools.matchers import Equals, LessThan, GreaterThan
586 from time import sleep
587
588+from autopilot.emulators.X11 import ScreenGeometry
589 from autopilot.emulators.unity.hud import HudController
590+from autopilot.emulators.unity.icons import BFBLauncherIcon, HudLauncherIcon
591 from autopilot.tests import AutopilotTestCase
592 from os import remove
593
594+def _make_scenarios():
595+ screen_geometry = ScreenGeometry()
596+ num_monitors = screen_geometry.get_num_monitors()
597+
598+ scenarios = []
599+
600+ if num_monitors == 1:
601+ scenarios = [
602+ ('Single Monitor, Launcher never hide', {'hud_monitor': 0, 'launcher_hide_mode': 0, 'launcher_primary_only': False}),
603+ ('Single Monitor, Launcher autohide', {'hud_monitor': 0, 'launcher_hide_mode': 1, 'launcher_primary_only': False}),
604+ ]
605+ else:
606+ for i in range(num_monitors):
607+ scenario_setting = {'hud_monitor': i, 'launcher_hide_mode': 0, 'launcher_primary_only': False}
608+ scenarios.append(('Monitor %d, Launcher never hide, on all monitors' % (i), scenario_setting))
609+
610+ scenario_setting = {'hud_monitor': i, 'launcher_hide_mode': 0, 'launcher_primary_only': True}
611+ scenarios.append(('Monitor %d, Launcher never hide, only on primary monitor' % (i), scenario_setting))
612+
613+ scenario_setting = {'hud_monitor': i, 'launcher_hide_mode': 1, 'launcher_primary_only': True}
614+ scenarios.append(('Monitor %d, Launcher autohide, on all monitors' % (i), scenario_setting))
615+
616+ scenario_setting = {'hud_monitor': i, 'launcher_hide_mode': 1, 'launcher_primary_only': True}
617+ scenarios.append(('Monitor %d, Launcher autohide, only on primary monitor' % (i), scenario_setting))
618+
619+ return scenarios
620+
621 class HudTests(AutopilotTestCase):
622
623- scenarios = [
624- ('Launcher never hide', {'launcher_hide_mode': 0}),
625- ('Launcher autohide', {'launcher_hide_mode': 1}),
626- ]
627+ screen_geo = ScreenGeometry()
628+ scenarios = _make_scenarios()
629
630 def setUp(self):
631 super(HudTests, self).setUp()
632 self.set_unity_option('launcher_hide_mode', self.launcher_hide_mode)
633+ self.set_unity_option('num_launchers', int(self.launcher_primary_only))
634+ self.hud_monitor_is_primary = (self.screen_geo.get_primary_monitor() == self.hud_monitor)
635+ self.hud_locked = (self.launcher_hide_mode == 0 and (not self.launcher_primary_only or self.hud_monitor_is_primary))
636+ self.screen_geo.move_mouse_to_monitor(self.hud_monitor)
637+
638 sleep(0.5)
639 self.hud = self.get_hud_controller()
640
641@@ -35,10 +67,15 @@
642 self.assertEqual(1, len(controllers))
643 return controllers[0]
644
645+ def get_hud_launcher_icon(self):
646+ icons = HudLauncherIcon.get_all_instances()
647+ self.assertEqual(1, len(icons))
648+ return icons[0]
649+
650 def get_num_active_launcher_icons(self):
651 num_active = 0
652 for icon in self.launcher.model.get_launcher_icons():
653- if icon.quirk_active and icon.quirk_visible:
654+ if icon.active and icon.visible:
655 num_active += 1
656 return num_active
657
658@@ -51,8 +88,32 @@
659 sleep(1)
660 if self.hud.visible:
661 break
662+
663 self.assertTrue(self.hud.visible, "HUD did not appear.")
664
665+ def test_hud_is_on_right_monitor(self):
666+ """Tests if the hud is shown and fits the monitor where it should be"""
667+ self.reveal_hud()
668+ self.assertThat(self.hud_monitor, Equals(self.hud.monitor))
669+ self.assertTrue(self.screen_geo.is_rect_on_monitor(self.hud.monitor, self.hud.geometry))
670+
671+ def test_hud_geometries(self):
672+ """Tests the HUD geometries for the given monitor and status"""
673+ self.reveal_hud()
674+ monitor_geo = self.screen_geo.get_monitor_geometry(self.hud_monitor)
675+ monitor_x = monitor_geo[0]
676+ monitor_w = monitor_geo[2]
677+ hud_x = self.hud.geometry[0]
678+ hud_w = self.hud.geometry[2]
679+
680+ if self.hud_locked:
681+ self.assertThat(hud_x, GreaterThan(monitor_x))
682+ self.assertThat(hud_x, LessThan(monitor_x + monitor_w))
683+ self.assertThat(hud_w, Equals(monitor_x + monitor_w - hud_x))
684+ else:
685+ self.assertThat(hud_x, Equals(monitor_x))
686+ self.assertThat(hud_w, Equals(monitor_w))
687+
688 def test_no_initial_values(self):
689 self.reveal_hud()
690 self.assertThat(self.hud.num_buttons, Equals(0))
691@@ -126,6 +187,11 @@
692 apps as active.
693
694 """
695+ launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor)
696+
697+ if not launcher:
698+ self.skipTest("The monitor %d has not a launcher" % self.hud_monitor)
699+
700 # We need an app to switch to:
701 self.start_app('Character Map')
702 # We need an application to play with - I'll use the calculator.
703@@ -144,8 +210,8 @@
704 sleep(0.5)
705
706 # click application icons for running apps in the launcher:
707- icon = self.launcher.model.get_icon_by_tooltip_text("Character Map")
708- self.launcher.get_launcher_for_monitor(0).click_launcher_icon(icon)
709+ icon = self.launcher.model.get_icon_by_desktop_id("gucharmap.desktop")
710+ launcher.click_launcher_icon(icon)
711
712 # see how many apps are marked as being active:
713 num_active = self.get_num_active_launcher_icons()
714@@ -211,3 +277,85 @@
715 contents = open("/tmp/autopilot_gedit_undo_test_temp_file.txt").read().strip('\n')
716 self.assertEqual("0 ", contents)
717
718+ def test_hud_does_not_change_launcher_status(self):
719+ """Tests if the HUD reveal keeps the launcher in the status it was"""
720+
721+ launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor)
722+
723+ if not launcher:
724+ self.skipTest("The monitor %d has not a launcher" % self.hud_monitor)
725+
726+ launcher_shows_pre = launcher.is_showing()
727+ sleep(.25)
728+
729+ self.reveal_hud()
730+ sleep(1)
731+
732+ launcher_shows_post = launcher.is_showing()
733+ self.assertThat(launcher_shows_pre, Equals(launcher_shows_post))
734+
735+ def test_hud_is_locked_to_launcher(self):
736+ """Tests if the HUD is locked to launcher as we expect or not"""
737+ self.reveal_hud()
738+ sleep(.25)
739+
740+ self.assertThat(self.hud.is_locked_to_launcher, Equals(self.hud_locked))
741+
742+ def test_hud_icon_is_shown(self):
743+ """Tests that the correct HUD icon is shown"""
744+ self.reveal_hud()
745+ sleep(.5)
746+
747+ hud_icon = self.get_hud_launcher_icon()
748+
749+ # FIXME this should check self.hud.is_locked_to_launcher
750+ # but the HUD icon is currently shared between launchers.
751+ if self.launcher_hide_mode == 0:
752+ self.assertTrue(hud_icon.visible)
753+ self.assertFalse(hud_icon.desaturated)
754+
755+ # FIXME remove this once the issue above has been resolved
756+ if self.hud.is_locked_to_launcher:
757+ self.assertFalse(self.hud.show_embedded_icon)
758+ else:
759+ self.assertTrue(self.hud.show_embedded_icon)
760+ self.assertFalse(hud_icon.visible)
761+
762+ def test_hud_launcher_icon_hides_bfb(self):
763+ """Tests that the BFB icon is hidden when the HUD launcher icon is shown"""
764+ if not self.hud.is_locked_to_launcher:
765+ self.skipTest("This test needs a locked launcher")
766+
767+ hud_icon = self.get_hud_launcher_icon()
768+
769+ icons = BFBLauncherIcon.get_all_instances()
770+ self.assertEqual(1, len(icons))
771+ bfb_icon = icons[0]
772+
773+ self.assertTrue(bfb_icon.visible)
774+ self.assertFalse(hud_icon.visible)
775+ sleep(.25)
776+
777+ self.reveal_hud()
778+ sleep(.5)
779+
780+ self.assertTrue(hud_icon.visible)
781+ self.assertFalse(bfb_icon.visible)
782+
783+ def test_hud_desaturates_launcher_icons(self):
784+ """Tests that the launcher icons are desaturates when HUD is open"""
785+ if not self.hud.is_locked_to_launcher:
786+ self.skipTest("This test needs a locked launcher")
787+
788+ self.reveal_hud()
789+ sleep(.5)
790+
791+ hud_icon = self.get_hud_launcher_icon()
792+ desaturated = True
793+
794+ for icon in self.launcher.model.get_launcher_icons():
795+ if (not isinstance(icon, HudLauncherIcon) and not icon.desaturated):
796+ desaturated = False
797+ break
798+
799+ self.assertTrue(desaturated)