Merge lp:~laney/unity/xpathselect-v5 into lp:unity

Proposed by Iain Lane
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 3998
Proposed branch: lp:~laney/unity/xpathselect-v5
Merge into: lp:unity
Diff against target: 2309 lines (+508/-512)
45 files modified
dash/DashView.cpp (+34/-0)
dash/DashView.h (+2/-0)
dash/PlacesGroup.cpp (+21/-7)
dash/PlacesGroup.h (+2/-0)
dash/ResultViewGrid.cpp (+6/-6)
debian/changelog (+29/-0)
debian/control (+1/-1)
decorations/DecoratedWindow.cpp (+5/-0)
decorations/DecoratedWindow.h (+1/-0)
decorations/DecorationsForceQuitDialog.cpp (+8/-0)
decorations/DecorationsManager.cpp (+5/-1)
launcher/ApplicationLauncherIcon.cpp (+19/-26)
launcher/ApplicationLauncherIcon.h (+1/-1)
launcher/Launcher.cpp (+7/-1)
panel/PanelMenuView.cpp (+15/-0)
panel/PanelMenuView.h (+1/-0)
shutdown/SessionButton.cpp (+7/-0)
shutdown/SessionButton.h (+1/-0)
shutdown/SessionView.cpp (+1/-1)
tests/autopilot/unity/emulators/__init__.py (+24/-0)
tests/autopilot/unity/emulators/dash.py (+26/-67)
tests/autopilot/unity/emulators/hud.py (+2/-2)
tests/autopilot/unity/emulators/icons.py (+2/-9)
tests/autopilot/unity/emulators/launcher.py (+3/-7)
tests/autopilot/unity/emulators/panel.py (+35/-45)
tests/autopilot/unity/emulators/quicklist.py (+6/-9)
tests/autopilot/unity/emulators/screen.py (+5/-4)
tests/autopilot/unity/emulators/window_manager.py (+3/-2)
tests/autopilot/unity/tests/launcher/test_icon_behavior.py (+1/-1)
tests/autopilot/unity/tests/launcher/test_visual.py (+1/-3)
tests/autopilot/unity/tests/test_dash.py (+59/-200)
tests/autopilot/unity/tests/test_panel.py (+12/-16)
tests/autopilot/unity/tests/test_quicklist.py (+3/-3)
tests/autopilot/unity/tests/test_spread.py (+5/-16)
tests/autopilot/unity/tests/test_switcher.py (+5/-6)
tests/bamf-mock-application.c (+16/-2)
tests/mock-application.h (+3/-4)
tests/test_bamf_application.cpp (+3/-2)
unity-shared/ApplicationManager.h (+3/-2)
unity-shared/BamfApplicationManager.cpp (+82/-38)
unity-shared/BamfApplicationManager.h (+10/-9)
unity-shared/IconTexture.cpp (+3/-1)
unity-shared/PluginAdapter.cpp (+4/-0)
unity-shared/StandaloneAppManager.cpp (+18/-12)
unity-shared/WindowButtons.cpp (+8/-8)
To merge this branch: bzr merge lp:~laney/unity/xpathselect-v5
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Review via email: mp+268939@code.launchpad.net

Commit message

Depend on v5-renamed xpathselect package

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dash/DashView.cpp'
2--- dash/DashView.cpp 2015-05-22 13:21:01 +0000
3+++ dash/DashView.cpp 2015-08-24 17:01:53 +0000
4@@ -1547,6 +1547,32 @@
5 ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
6 }
7
8+nux::Area* DashView::SkipUnexpandableHeaderKeyNav()
9+{
10+ PlacesGroup::Ptr prev_view;
11+ auto category_views = active_scope_view_->GetOrderedCategoryViews();
12+
13+ for (auto category : category_views)
14+ {
15+ if (category->GetLayout() != nullptr)
16+ {
17+ auto header = category->GetHeaderFocusableView();
18+ if (header && header->HasKeyFocus() && !category->IsExpandable())
19+ {
20+ if (prev_view)
21+ return prev_view->GetChildView();
22+ else
23+ return search_bar_->text_entry();
24+ }
25+
26+ if (category->IsVisible())
27+ prev_view = category;
28+ }
29+ }
30+
31+ return nullptr;
32+}
33+
34 nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
35 unsigned long x11_key_code,
36 unsigned long special_keys_state)
37@@ -1698,6 +1724,14 @@
38 }
39 }
40
41+ if (direction == KEY_NAV_UP)
42+ {
43+ if (auto skip_view = SkipUnexpandableHeaderKeyNav())
44+ {
45+ return skip_view;
46+ }
47+ }
48+
49 bool search_key = false;
50
51 if (direction == KEY_NAV_NONE)
52
53=== modified file 'dash/DashView.h'
54--- dash/DashView.h 2015-04-24 12:59:57 +0000
55+++ dash/DashView.h 2015-08-24 17:01:53 +0000
56@@ -137,6 +137,8 @@
57
58 nux::Area* KeyNavIteration(nux::KeyNavDirection direction);
59
60+ nux::Area* SkipUnexpandableHeaderKeyNav();
61+
62 UBusManager ubus_manager_;
63 Scopes::Ptr scopes_;
64 ScopeViews scope_views_;
65
66=== modified file 'dash/PlacesGroup.cpp'
67--- dash/PlacesGroup.cpp 2014-07-10 16:39:12 +0000
68+++ dash/PlacesGroup.cpp 2015-08-24 17:01:53 +0000
69@@ -212,7 +212,12 @@
70 if(direction == nux::KEY_NAV_UP)
71 nux::GetWindowCompositor().SetKeyFocusArea(_child_view, direction);
72 else
73- nux::GetWindowCompositor().SetKeyFocusArea(GetHeaderFocusableView(), direction);
74+ {
75+ if (IsExpandable())
76+ nux::GetWindowCompositor().SetKeyFocusArea(GetHeaderFocusableView(), direction);
77+ else
78+ nux::GetWindowCompositor().SetKeyFocusArea(_child_view, direction);
79+ }
80 });
81
82 UpdatePlacesGroupSize();
83@@ -343,15 +348,18 @@
84 UpdateResultViewPadding();
85 _group_layout->AddLayout(_child_layout, 1);
86
87- view->results_per_row.changed.connect([this] (int results_per_row)
88- {
89- _n_visible_items_in_unexpand_mode = results_per_row;
90- RefreshLabel();
91- });
92+ UpdateVisibleItems(view->results_per_row());
93+ view->results_per_row.changed.connect(sigc::mem_fun(this, &PlacesGroup::UpdateVisibleItems));
94
95 QueueDraw();
96 }
97
98+void PlacesGroup::UpdateVisibleItems(int visible_items)
99+{
100+ _n_visible_items_in_unexpand_mode = visible_items;
101+ RefreshLabel();
102+}
103+
104 dash::ResultView*
105 PlacesGroup::GetChildView()
106 {
107@@ -567,6 +575,12 @@
108 }
109
110 bool
111+PlacesGroup::IsExpandable() const
112+{
113+ return (_n_visible_items_in_unexpand_mode < _n_total_items);
114+}
115+
116+bool
117 PlacesGroup::GetExpanded() const
118 {
119 return _is_expanded;
120@@ -649,7 +663,7 @@
121
122 bool PlacesGroup::ShouldBeHighlighted() const
123 {
124- return HeaderHasKeyFocus();
125+ return (HeaderHasKeyFocus() && IsExpandable());
126 }
127
128 void PlacesGroup::SetResultsPreviewAnimationValue(float preview_animation)
129
130=== modified file 'dash/PlacesGroup.h'
131--- dash/PlacesGroup.h 2014-03-20 04:05:39 +0000
132+++ dash/PlacesGroup.h 2015-08-24 17:01:53 +0000
133@@ -77,6 +77,7 @@
134
135 void SetCounts(unsigned n_total_items);
136
137+ virtual bool IsExpandable() const;
138 virtual void SetExpanded(bool is_expanded);
139 virtual bool GetExpanded() const;
140
141@@ -127,6 +128,7 @@
142 void UpdatePlacesGroupSize();
143 void UpdateResultViewPadding();
144 void UpdateScale(double scale);
145+ void UpdateVisibleItems(int visible_items);
146
147 private:
148 std::string _category_id;
149
150=== modified file 'dash/ResultViewGrid.cpp'
151--- dash/ResultViewGrid.cpp 2015-05-22 13:20:52 +0000
152+++ dash/ResultViewGrid.cpp 2015-08-24 17:01:53 +0000
153@@ -85,11 +85,11 @@
154 EnableDoubleClick(true);
155 SetAcceptKeyNavFocusOnMouseDown(false);
156
157- auto needredraw_lambda = [this](int value) { NeedRedraw(); };
158- horizontal_spacing.changed.connect(needredraw_lambda);
159- vertical_spacing.changed.connect(needredraw_lambda);
160- padding.changed.connect(needredraw_lambda);
161- selected_index_.changed.connect(needredraw_lambda);
162+ auto queue_draw_cb = sigc::hide(sigc::mem_fun(this, &ResultViewGrid::QueueDraw));
163+ horizontal_spacing.changed.connect(queue_draw_cb);
164+ vertical_spacing.changed.connect(queue_draw_cb);
165+ padding.changed.connect(queue_draw_cb);
166+ selected_index_.changed.connect(queue_draw_cb);
167 expanded.changed.connect([this](bool value) { if (value) all_results_preloaded_ = false; });
168 results_per_row.changed.connect([this](int value) { if (value > 0) all_results_preloaded_ = false; });
169 scale.changed.connect(sigc::mem_fun(this, &ResultViewGrid::UpdateScale));
170@@ -119,7 +119,7 @@
171 NeedRedraw();
172 });
173
174- WindowManager::Default().average_color.changed.connect(sigc::hide(sigc::mem_fun(this, &View::QueueDraw)));
175+ WindowManager::Default().average_color.changed.connect(queue_draw_cb);
176
177 ubus_.RegisterInterest(UBUS_DASH_SIZE_CHANGED, [this] (GVariant* data) {
178 // on dash size changed, we update our stored values, this sucks
179
180=== modified file 'debian/changelog'
181--- debian/changelog 2015-08-03 12:35:24 +0000
182+++ debian/changelog 2015-08-24 17:01:53 +0000
183@@ -1,3 +1,32 @@
184+unity (7.3.2+15.10.20150819-0ubuntu1) wily; urgency=medium
185+
186+ [ Andrea Azzarone andrea.azzarone@canonical.com ]
187+ * Do not handle events coming from viewports not actually containing
188+ the window. (LP: #1449654)
189+
190+ [ Chris Townsend ]
191+ * Also use the Compiz show() method when forcing an unmapped window to
192+ be visible when clicking on it's active Launcher icon. (LP: #989588)
193+ * When using keyboard navigation in the Dash, skip category headers
194+ that are not expandable. Also, do not highlight the category header
195+ when the mouse cursor is over it. (LP: #1045933)
196+
197+ [ Marco Trevisan (Treviño) ]
198+ * ApplicationManager: rely on windows monitor property changes for
199+ updating Pips (LP: #1027191)
200+ * Autopilot: modernize some tests, use stronger methods to ensure
201+ false positive
202+ * DecorationsForceQuitDialog: override the background of the window
203+ with transparent color (LP: #1470292)
204+ * Launcher: Always unfold an active icon (LP: #1472339)
205+ * PanelMenuView: ensure that we connect to window signals as soon as
206+ the AppManager knows it (LP: #1472326)
207+ * PlacesGroup: connect to view changes using a function instead of a
208+ lambda (LP: #1470298)
209+ * SessionButton: set button opacity to 75% when pressed (LP: #1301655)
210+
211+ -- CI Train Bot <ci-train-bot@canonical.com> Wed, 19 Aug 2015 14:45:18 +0000
212+
213 unity (7.3.2+15.10.20150803.1-0ubuntu1) wily; urgency=medium
214
215 [ Andrea Azzarone andrea.azzarone@canonical.com ]
216
217=== modified file 'debian/control'
218--- debian/control 2015-04-05 22:07:47 +0000
219+++ debian/control 2015-08-24 17:01:53 +0000
220@@ -192,7 +192,7 @@
221 python-testtools,
222 python-xdg,
223 python-xlib,
224- libxpathselect1.4 (>= 1.4),
225+ libxpathselect1.4v5 (>= 1.4),
226 mesa-utils,
227 Description: Autopiloted tests for Unity
228 Unity is tested automatically through autopilot, a framework which enables
229
230=== modified file 'decorations/DecoratedWindow.cpp'
231--- decorations/DecoratedWindow.cpp 2015-02-03 10:28:30 +0000
232+++ decorations/DecoratedWindow.cpp 2015-08-24 17:01:53 +0000
233@@ -842,6 +842,11 @@
234 , impl_(new Impl(this, cwin))
235 {}
236
237+CompWindow* Window::GetCompWindow()
238+{
239+ return impl_->win_;
240+}
241+
242 void Window::Update()
243 {
244 impl_->Update();
245
246=== modified file 'decorations/DecoratedWindow.h'
247--- decorations/DecoratedWindow.h 2014-03-03 19:07:56 +0000
248+++ decorations/DecoratedWindow.h 2015-08-24 17:01:53 +0000
249@@ -45,6 +45,7 @@
250 nux::Property<bool> scaled;
251 nux::ROProperty<double> dpi_scale;
252
253+ CompWindow* GetCompWindow();
254 void Update();
255 void Undecorate();
256 void UpdateDecorationPosition();
257
258=== modified file 'decorations/DecorationsForceQuitDialog.cpp'
259--- decorations/DecorationsForceQuitDialog.cpp 2015-06-12 12:15:40 +0000
260+++ decorations/DecorationsForceQuitDialog.cpp 2015-08-24 17:01:53 +0000
261@@ -169,6 +169,14 @@
262 gtk_widget_set_visual(GTK_WIDGET(self), gdk_screen_get_rgba_visual(screen));
263 gtk_widget_realize(GTK_WIDGET(self));
264
265+ glib::Object<GtkCssProvider> style(gtk_css_provider_new());
266+ gtk_css_provider_load_from_data(style, R"(
267+ * { background-color: transparent; }
268+ )", -1, nullptr);
269+
270+ auto* style_ctx = gtk_widget_get_style_context(GTK_WIDGET(self));
271+ gtk_style_context_add_provider(style_ctx, glib::object_cast<GtkStyleProvider>(style), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
272+
273 gtk_container_add(GTK_CONTAINER(self), sheet_style_dialog_new(main_dialog, parent_xid, parent_pid));
274
275 gtk_window_set_modal(self, TRUE);
276
277=== modified file 'decorations/DecorationsManager.cpp'
278--- decorations/DecorationsManager.cpp 2015-02-03 08:38:19 +0000
279+++ decorations/DecorationsManager.cpp 2015-08-24 17:01:53 +0000
280@@ -172,7 +172,7 @@
281 {
282 auto const& win = GetWindowByXid(xid);
283
284- if (win && !win->impl_->win_->hasUnmapReference())
285+ if (win && !win->GetCompWindow()->hasUnmapReference())
286 {
287 win->Update();
288 return true;
289@@ -306,6 +306,10 @@
290 return false;
291
292 auto const& win = GetWindowByFrame(event->xany.window);
293+ CompWindow* comp_window = win ? win->GetCompWindow() : nullptr;
294+
295+ if (comp_window && comp_window->defaultViewport() != screen->vp())
296+ return false;
297
298 // ButtonRelease events might happen also outside the frame window, in this
299 // case we must unset the mouse owner, wherever the event happens.
300
301=== modified file 'launcher/ApplicationLauncherIcon.cpp'
302--- launcher/ApplicationLauncherIcon.cpp 2015-04-22 23:43:16 +0000
303+++ launcher/ApplicationLauncherIcon.cpp 2015-08-24 17:01:53 +0000
304@@ -48,7 +48,6 @@
305 namespace
306 {
307 // We use the "bamf-" prefix since the manager is protected, to avoid name clash
308-const std::string WINDOW_MOVE_TIMEOUT = "bamf-window-move";
309 const std::string ICON_REMOVE_TIMEOUT = "bamf-icon-remove";
310 const std::string ICON_DND_OVER_TIMEOUT = "bamf-icon-dnd-over";
311 const std::string DEFAULT_ICON = "application-default-icon";
312@@ -87,12 +86,11 @@
313
314 WindowManager& wm = WindowManager::Default();
315 wm.window_minimized.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMinimized));
316- wm.window_moved.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMoved));
317 wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
318 wm.terminate_expo.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
319- UScreen::GetDefault()->changed.connect(sigc::hide(sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState))));
320+ UScreen::GetDefault()->changed.connect(sigc::hide(sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowsLocation))));
321
322- EnsureWindowState();
323+ EnsureWindowsLocation();
324 }
325
326 ApplicationLauncherIcon::~ApplicationLauncherIcon()
327@@ -156,14 +154,16 @@
328 {
329 // Lambda functions should be fine here because when the application the icon
330 // is only ever removed when the application is closed.
331- signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindowPtr const&) {
332- EnsureWindowState();
333- UpdateIconGeometries(GetCenters());
334+ signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindowPtr const& win) {
335+ signals_conn_.Add(win->monitor.changed.connect([this] (int) { EnsureWindowsLocation(); }));
336+ EnsureWindowsLocation();
337 }));
338
339- auto ensure_windows_cb = sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
340- signals_conn_.Add(app_->window_closed.connect(ensure_windows_cb));
341- signals_conn_.Add(app_->window_moved.connect(ensure_windows_cb));
342+ auto ensure_win_location_cb = sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowsLocation));
343+ signals_conn_.Add(app_->window_closed.connect(ensure_win_location_cb));
344+
345+ for (auto& win : app_->GetWindows())
346+ signals_conn_.Add(win->monitor.changed.connect(ensure_win_location_cb));
347
348 signals_conn_.Add(app_->urgent.changed.connect([this](bool const& urgent) {
349 LOG_DEBUG(logger) << tooltip_text() << " urgent now " << (urgent ? "true" : "false");
350@@ -535,19 +535,6 @@
351 }
352 }
353
354-void ApplicationLauncherIcon::OnWindowMoved(guint32 moved_win)
355-{
356- if (!app_->OwnsWindow(moved_win))
357- return;
358-
359- _source_manager.AddTimeout(250, [this] {
360- EnsureWindowState();
361- UpdateIconGeometries(GetCenters());
362-
363- return false;
364- }, WINDOW_MOVE_TIMEOUT);
365-}
366-
367 void ApplicationLauncherIcon::UpdateDesktopFile()
368 {
369 std::string const& filename = app_->desktop_file();
370@@ -738,8 +725,8 @@
371 // If monitor is -1 (or negative), show on all monitors.
372 if (monitor < 0)
373 {
374- for (unsigned j; j < monitors::MAX; j++)
375- ++number_of_windows_on_monitor[j];
376+ for (unsigned j; j < monitors::MAX; ++j)
377+ ++number_of_windows_on_monitor[j];
378 }
379 else
380 {
381@@ -748,12 +735,18 @@
382 }
383 }
384
385- for (unsigned i = 0; i < monitors::MAX; i++)
386+ for (unsigned i = 0; i < monitors::MAX; ++i)
387 SetNumberOfWindowsVisibleOnMonitor(number_of_windows_on_monitor[i], i);
388
389 WindowsChanged.emit();
390 }
391
392+void ApplicationLauncherIcon::EnsureWindowsLocation()
393+{
394+ EnsureWindowState();
395+ UpdateIconGeometries(GetCenters());
396+}
397+
398 void ApplicationLauncherIcon::UpdateDesktopQuickList()
399 {
400 std::string const& desktop_file = DesktopFile();
401
402=== modified file 'launcher/ApplicationLauncherIcon.h'
403--- launcher/ApplicationLauncherIcon.h 2014-06-07 16:27:16 +0000
404+++ launcher/ApplicationLauncherIcon.h 2015-08-24 17:01:53 +0000
405@@ -116,6 +116,7 @@
406 void UnsetApplication();
407 void SetupApplicationSignalsConnections();
408 void EnsureWindowState();
409+ void EnsureWindowsLocation();
410 void EnsureMenuItemsWindowsReady();
411 void EnsureMenuItemsDefaultReady();
412 void EnsureMenuItemsStaticQuicklist();
413@@ -127,7 +128,6 @@
414 bool Spread(bool current_desktop, int state, bool force);
415
416 void OnWindowMinimized(guint32 xid);
417- void OnWindowMoved(guint32 xid);
418
419 WindowList GetWindows(WindowFilterMask filter = 0, int monitor = -1);
420 const std::set<std::string> GetSupportedTypes();
421
422=== modified file 'launcher/Launcher.cpp'
423--- launcher/Launcher.cpp 2015-05-21 16:30:26 +0000
424+++ launcher/Launcher.cpp 2015-08-24 17:01:53 +0000
425@@ -677,7 +677,9 @@
426 // goes for 0.0f when fully unfolded, to 1.0f folded
427 float folding_progress = CLAMP((center.y + c_icon_size - folding_threshold) / (float) c_icon_size, 0.0f, 1.0f);
428 float unfold_progress = icon->GetQuirkProgress(AbstractLauncherIcon::Quirk::UNFOLDED, monitor());
429+ float active_progress = icon->GetQuirkProgress(AbstractLauncherIcon::Quirk::ACTIVE, monitor());
430
431+ unfold_progress = CLAMP(unfold_progress + active_progress, 0.0f, 1.0f);
432 folding_progress *= 1.0f - unfold_progress;
433
434 float half_size = (folded_size / 2.0f) + (c_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress);
435@@ -779,9 +781,12 @@
436 sum += height;
437
438 // magic constant must some day be explained, for now suffice to say this constant prevents the bottom from "marching";
439- float magic_constant = 1.3f;
440+ const float magic_constant = 1.3f;
441
442 float unfold_progress = (*it)->GetQuirkProgress(AbstractLauncherIcon::Quirk::UNFOLDED, monitor());
443+ float active_progress = (*it)->GetQuirkProgress(AbstractLauncherIcon::Quirk::ACTIVE, monitor());
444+
445+ unfold_progress = CLAMP(unfold_progress + active_progress, 0.0f, 1.0f);
446 folding_threshold -= CLAMP(sum - launcher_height, 0.0f, height * magic_constant) * (folding_constant + (1.0f - folding_constant) * unfold_progress);
447 }
448
449@@ -1597,6 +1602,7 @@
450 {
451 icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::VISIBLE, ANIM_DURATION_SHORT, monitor());
452 icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::RUNNING, ANIM_DURATION_SHORT, monitor());
453+ icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::ACTIVE, ANIM_DURATION_SHORT, monitor());
454 icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::STARTING, (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2), monitor());
455 icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::PULSE_ONCE, (ANIM_DURATION_LONG * PULSE_BLINK_LAMBDA * 2), monitor());
456 icon->SetQuirkDuration(AbstractLauncherIcon::Quirk::PRESENTED, ANIM_DURATION, monitor());
457
458=== modified file 'panel/PanelMenuView.cpp'
459--- panel/PanelMenuView.cpp 2015-04-20 18:42:25 +0000
460+++ panel/PanelMenuView.cpp 2015-08-24 17:01:53 +0000
461@@ -146,6 +146,8 @@
462 am.active_application_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveAppChanged));
463 am.application_started.connect(sigc::mem_fun(this, &PanelMenuView::OnApplicationStarted));
464 am.application_stopped.connect(sigc::mem_fun(this, &PanelMenuView::OnApplicationClosed));
465+ am.window_opened.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowOpened));
466+ am.window_closed.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowClosed));
467
468 mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
469 mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
470@@ -1028,6 +1030,19 @@
471 }
472 }
473
474+void PanelMenuView::OnWindowOpened(ApplicationWindowPtr const& win)
475+{
476+ if (win->window_id() == window_buttons_->controlled_window() &&
477+ win->title.changed.empty())
478+ {
479+ /* This is a not so nice workaround that we need to include here, since
480+ * BAMF might be late in informing us about a new window, and thus we
481+ * can't connect to it's signals (as not available in the App Manager). */
482+ window_buttons_->controlled_window = 0;
483+ UpdateTargetWindowItems();
484+ }
485+}
486+
487 void PanelMenuView::OnWindowClosed(ApplicationWindowPtr const& win)
488 {
489 /* FIXME, this can be removed when window_unmapped WindowManager signal
490
491=== modified file 'panel/PanelMenuView.h'
492--- panel/PanelMenuView.h 2015-04-20 17:58:31 +0000
493+++ panel/PanelMenuView.h 2015-08-24 17:01:53 +0000
494@@ -89,6 +89,7 @@
495 void OnEntryViewAdded(PanelIndicatorEntryView* view);
496 void OnApplicationStarted(ApplicationPtr const&);
497 void OnApplicationClosed(ApplicationPtr const&);
498+ void OnWindowOpened(ApplicationWindowPtr const&);
499 void OnWindowClosed(ApplicationWindowPtr const&);
500 void OnActiveWindowChanged(ApplicationWindowPtr const&);
501 void OnActiveAppChanged(ApplicationPtr const&);
502
503=== modified file 'shutdown/SessionButton.cpp'
504--- shutdown/SessionButton.cpp 2014-05-08 04:04:18 +0000
505+++ shutdown/SessionButton.cpp 2015-08-24 17:01:53 +0000
506@@ -40,6 +40,7 @@
507 : nux::View(NUX_FILE_LINE_PARAM)
508 , scale(1.0)
509 , highlighted(false)
510+ , pressed(false)
511 , action([this] { return action_; })
512 , label([this] { return label_view_->GetText(); })
513 , action_(action)
514@@ -107,6 +108,8 @@
515 mouse_enter.connect([this] (int, int, unsigned long, unsigned long) { highlighted = true; });
516 mouse_leave.connect([this] (int, int, unsigned long, unsigned long) { highlighted = false; });
517 mouse_click.connect([this] (int, int, unsigned long, unsigned long) { activated.emit(); });
518+ mouse_down.connect([this] (int, int, unsigned long, unsigned long) { pressed = true; });
519+ mouse_up.connect([this] (int, int, unsigned long, unsigned long) { pressed = false; });
520
521 begin_key_focus.connect([this] { highlighted = true; });
522 end_key_focus.connect([this] { highlighted = false; });
523@@ -116,6 +119,10 @@
524 image_view_->SetTexture(value ? highlight_tex_ : normal_tex_);
525 label_view_->SetTextColor(value ? nux::color::White : nux::color::Transparent);
526 });
527+
528+ pressed.changed.connect([this] (bool value) {
529+ image_view_->SetOpacity(value ? 0.75 : 1.0);
530+ });
531 }
532
533 void Button::UpdateTextures(std::string const& texture_prefix)
534
535=== modified file 'shutdown/SessionButton.h'
536--- shutdown/SessionButton.h 2014-05-05 18:42:45 +0000
537+++ shutdown/SessionButton.h 2015-08-24 17:01:53 +0000
538@@ -52,6 +52,7 @@
539
540 nux::Property<double> scale;
541 nux::Property<bool> highlighted;
542+ nux::Property<bool> pressed;
543 nux::ROProperty<Action> action;
544 nux::ROProperty<std::string> label;
545
546
547=== modified file 'shutdown/SessionView.cpp'
548--- shutdown/SessionView.cpp 2014-06-18 15:08:33 +0000
549+++ shutdown/SessionView.cpp 2015-08-24 17:01:53 +0000
550@@ -236,7 +236,7 @@
551 {
552 if (mode() == Mode::FULL)
553 {
554- if (manager_->CanLock())
555+ if (manager_->CanLock() && !manager_->is_locked())
556 {
557 auto* button = new Button(Button::Action::LOCK, NUX_TRACKER_LOCATION);
558 button->activated.connect(sigc::mem_fun(manager_.get(), &Manager::LockScreen));
559
560=== modified file 'tests/autopilot/unity/emulators/__init__.py'
561--- tests/autopilot/unity/emulators/__init__.py 2013-10-03 02:47:42 +0000
562+++ tests/autopilot/unity/emulators/__init__.py 2015-08-24 17:01:53 +0000
563@@ -28,6 +28,30 @@
564
565 _Backend = DBusAddress.SessionBus(DBUS_SERVICE, DBUS_OBJECT)
566
567+ def _repr_string(self, obj_details=""):
568+ geostr = ""
569+ if hasattr(self, 'globalRect'):
570+ geostr = " geo=[{r.x}x{r.y} {r.width}x{r.height}]".format(r=self.globalRect)
571+
572+ obj_details.strip()
573+ obj_details = " "+obj_details if len(obj_details) else ""
574+
575+ return "<{cls} {addr} id={id}{geo}{details}>".format(cls=self.__class__.__name__,
576+ addr=hex(id(self)),
577+ id=self.id,
578+ geo=geostr,
579+ details=obj_details)
580+
581+ def __repr__(self):
582+ with self.no_automatic_refreshing():
583+ return self._repr_string()
584+
585+ def __eq__(self, other):
586+ return isinstance(other, self.__class__) and self.id == other.id
587+
588+ def __ne__(self, other):
589+ return not self.__eq__(other)
590+
591
592 def ensure_unity_is_running(timeout=300):
593 """Poll the unity debug interface, and return when it's ready for use.
594
595=== modified file 'tests/autopilot/unity/emulators/dash.py'
596--- tests/autopilot/unity/emulators/dash.py 2015-04-10 16:22:23 +0000
597+++ tests/autopilot/unity/emulators/dash.py 2015-08-24 17:01:53 +0000
598@@ -158,7 +158,7 @@
599
600 @property
601 def geometry(self):
602- return (self.view.x, self.view.y, self.view.width, self.view.height)
603+ return self.view.globalRect
604
605
606 class DashView(UnityIntrospectionObject):
607@@ -225,10 +225,12 @@
608 class ScopeView(UnityIntrospectionObject):
609 """A Scope View."""
610
611- def get_groups(self):
612+ def get_categories(self, only_visible=False):
613 """Get a list of all groups within this scopeview. May return an empty list."""
614- groups = self.get_children_by_type(PlacesGroup)
615- return groups
616+ if only_visible:
617+ return self.get_children_by_type(PlacesGroup, is_visible=True)
618+
619+ return self.get_children_by_type(PlacesGroup)
620
621 def get_focused_category(self):
622 """Return a PlacesGroup instance for the category whose header has keyboard focus.
623@@ -236,30 +238,22 @@
624 Returns None if no category headers have keyboard focus.
625
626 """
627- categories = self.get_children_by_type(PlacesGroup)
628- matches = [m for m in categories if m.header_has_keyfocus]
629- if matches:
630- return matches[0]
631- return None
632+ matches = self.get_children_by_type(PlacesGroup, header_has_keyfocus=True)
633+ return matches[0] if matches else None
634
635 def get_category_by_name(self, category_name):
636 """Return a PlacesGroup instance with the given name, or None."""
637- categories = self.get_children_by_type(PlacesGroup)
638- matches = [m for m in categories if m.name == category_name]
639- if matches:
640- return matches[0]
641- return None
642+ matches = self.get_children_by_type(PlacesGroup, name=category_name)
643+ return matches[0] if matches else None
644
645 def get_num_visible_categories(self):
646 """Get the number of visible categories in this scope."""
647- return len([c for c in self.get_children_by_type(PlacesGroup) if c.is_visible])
648+ return len(self.get_categories(only_visible=True))
649
650 def get_filterbar(self):
651 """Get the filter bar for the current scope, or None if it doesn't have one."""
652 bars = self.get_children_by_type(FilterBar)
653- if bars:
654- return bars[0]
655- return None
656+ return bars[0] if bars else None
657
658
659 class PlacesGroup(UnityIntrospectionObject):
660@@ -279,26 +273,16 @@
661 """A single result in the dash."""
662
663 def activate(self, double_click=True):
664- tx = self.x + (self.width / 2)
665- ty = self.y + (self.height / 2)
666 m = Mouse.create()
667- m.move(tx, ty)
668- m.click(1)
669+ m.click_object(self, button=1)
670 if double_click:
671- m.click(1)
672+ m.click_object(self, button=1)
673
674 def preview(self, button=1):
675- tx = self.x + (self.width / 2)
676- ty = self.y + (self.height / 2)
677- m = Mouse.create()
678- m.move(tx, ty)
679- m.click(button)
680+ Mouse.create().click_object(self, button)
681
682 def preview_key(self):
683- tx = self.x + (self.width / 2)
684- ty = self.y + (self.height / 2)
685- m = Mouse.create()
686- m.move(tx, ty)
687+ Mouse.create().move_to_object(self)
688
689 k = Keyboard.create()
690 k.press_and_release('Menu')
691@@ -313,11 +297,8 @@
692
693 def get_focused_filter(self):
694 """Returns the id of the focused filter widget."""
695- filters = self.get_children_by_type(FilterExpanderLabel)
696- for filter_label in filters:
697- if filter_label.expander_has_focus:
698- return filter_label
699- return None
700+ filters = self.get_children_by_type(FilterExpanderLabel, expander_has_focus=True)
701+ return filters[0] if filters else None
702
703 @property
704 def expanded(self):
705@@ -366,21 +347,13 @@
706 def ensure_expanded(self):
707 """Expand the filter expander label, if it's not already"""
708 if not self.expanded:
709- tx = self.x + self.width / 2
710- ty = self.y + self.height / 2
711- m = Mouse.create()
712- m.move(tx, ty)
713- m.click()
714+ Mouse.create().click_object(self)
715 self.expanded.wait_for(True)
716
717 def ensure_collapsed(self):
718 """Collapse the filter expander label, if it's not already"""
719 if self.expanded:
720- tx = self.x + self.width / 2
721- ty = self.y + self.height / 2
722- m = Mouse.create()
723- m.move(tx, ty)
724- m.click()
725+ Mouse.create().click_object(self)
726 self.expanded.wait_for(False)
727
728
729@@ -402,21 +375,14 @@
730
731 def get_action_by_id(self, action_id):
732 """Returns the action given it's action hint."""
733- actions = self.get_children_by_type(ActionButton)
734- for action in actions:
735- if action.action == action_id:
736- return action
737- return None
738+ actions = self.get_children_by_type(ActionButton, action=action_id)
739+ return actions[0] if actions else None
740
741 def execute_action_by_id(self, action_id):
742 """Executes an action given by the id."""
743 action = self.get_action_by_id(action_id)
744 if action:
745- tx = action.x + (action.width / 2)
746- ty = action.y + (action.height / 2)
747- m = Mouse.create()
748- m.move(tx, ty)
749- m.click()
750+ Mouse.create().click_object(action)
751
752 @property
753 def cover_art(self):
754@@ -495,12 +461,8 @@
755
756 def navigate_left(self, count=1):
757 """Navigate preview left"""
758- navigator = self.get_left_navigator()
759-
760- tx = navigator.button_x + (navigator.button_width / 2)
761- ty = navigator.button_y + (navigator.button_height / 2)
762 m = Mouse.create()
763- m.move(tx, ty)
764+ m.move_to_object(self.get_left_navigator().button_geo)
765
766 old_preview_initiate_count = self.preview_initiate_count
767
768@@ -512,12 +474,8 @@
769
770 def navigate_right(self, count=1):
771 """Navigate preview right"""
772- navigator = self.get_right_navigator()
773-
774- tx = navigator.button_x + (navigator.button_width / 2)
775- ty = navigator.button_y + (navigator.button_height / 2)
776 m = Mouse.create()
777- m.move(tx, ty)
778+ m.move_to_object(self.get_right_navigator().button_geo)
779
780 old_preview_initiate_count = self.preview_initiate_count
781
782@@ -607,3 +565,4 @@
783
784 class StaticCairoText(UnityIntrospectionObject):
785 """Text boxes in the preview"""
786+
787
788=== modified file 'tests/autopilot/unity/emulators/hud.py'
789--- tests/autopilot/unity/emulators/hud.py 2013-10-03 01:33:53 +0000
790+++ tests/autopilot/unity/emulators/hud.py 2015-08-24 17:01:53 +0000
791@@ -105,7 +105,7 @@
792
793 @property
794 def geometry(self):
795- return (self.x, self.y, self.width, self.height)
796+ return self.globalRect
797
798 @property
799 def selected_button(self):
800@@ -156,7 +156,7 @@
801
802 @property
803 def geometry(self):
804- return (self.x, self.y, self.width, self.height)
805+ return self.globalRect
806
807
808 class HudButton(UnityIntrospectionObject):
809
810=== modified file 'tests/autopilot/unity/emulators/icons.py'
811--- tests/autopilot/unity/emulators/icons.py 2013-11-14 01:56:41 +0000
812+++ tests/autopilot/unity/emulators/icons.py 2015-08-24 17:01:53 +0000
813@@ -58,10 +58,6 @@
814
815 return self.xids.contains(xid)
816
817- def __repr__(self):
818- with self.no_automatic_refreshing():
819- return "<%s id=%d>" % (self.__class__.__name__, self.id)
820-
821
822 class BFBLauncherIcon(SimpleLauncherIcon):
823 """Represents the BFB button in the launcher."""
824@@ -80,10 +76,7 @@
825
826 def __repr__(self):
827 with self.no_automatic_refreshing():
828- return "<%s %s id=%d>" % (
829- self.__class__.__name__,
830- self.desktop_id,
831- self.id)
832+ return self._repr_string("{0.desktop_id}".format(self))
833
834 class TrashLauncherIcon(SimpleLauncherIcon):
835 """Represents the trash launcher icon."""
836@@ -110,7 +103,7 @@
837
838 @property
839 def geometry(self):
840- return (self.x, self.y, self.width, self.height)
841+ return self.globalRect
842
843
844 class LauncherEntry(UnityIntrospectionObject):
845
846=== modified file 'tests/autopilot/unity/emulators/launcher.py'
847--- tests/autopilot/unity/emulators/launcher.py 2014-01-23 15:51:46 +0000
848+++ tests/autopilot/unity/emulators/launcher.py 2015-08-24 17:01:53 +0000
849@@ -118,12 +118,8 @@
850 def move_mouse_over_launcher(self):
851 """Move the mouse over this launcher."""
852 move_mouse_to_screen(self.monitor)
853- (x, y, w, h) = self.geometry
854- target_x = x + w / 2
855- target_y = y + h / 2
856-
857 logger.debug("Moving mouse to center of launcher.")
858- self._mouse.move(target_x, target_y)
859+ self._mouse.move_to_object(self)
860
861 def move_mouse_to_icon(self, icon, autoscroll_offset=0):
862 """Move the mouse to a specific icon."""
863@@ -438,8 +434,8 @@
864
865 @property
866 def geometry(self):
867- """Returns a tuple of (x,y,w,h) for the current launcher."""
868- return (self.x, self.y, self.width, self.height)
869+ """Returns a Rectangle (x,y,w,h) for the current launcher."""
870+ return self.globalRect
871
872
873 class LauncherModel(UnityIntrospectionObject):
874
875=== modified file 'tests/autopilot/unity/emulators/panel.py'
876--- tests/autopilot/unity/emulators/panel.py 2015-02-18 00:49:47 +0000
877+++ tests/autopilot/unity/emulators/panel.py 2015-08-24 17:01:53 +0000
878@@ -14,6 +14,7 @@
879
880 from autopilot.input import Mouse
881 from autopilot.keybindings import KeybindingsHelper
882+from autopilot.introspection.types import Rectangle
883
884 from unity.emulators import UnityIntrospectionObject
885 logger = logging.getLogger(__name__)
886@@ -107,30 +108,18 @@
887
888 def move_mouse_over_grab_area(self):
889 """Move the mouse over the grab area for this panel."""
890- (x, y, w, h) = self.grab_area.geometry
891- target_x = x + w / 2
892- target_y = y + h / 2
893-
894 logger.debug("Moving mouse to center of grab area.")
895- self._mouse.move(target_x, target_y)
896+ self._mouse.move_to_object(self.grab_area)
897
898 def move_mouse_over_window_buttons(self):
899 """Move the mouse over the center of the window buttons area for this panel."""
900- (x, y, w, h) = self.window_buttons.geometry
901- target_x = x + w / 2
902- target_y = y + h / 2
903-
904 logger.debug("Moving mouse to center of the window buttons.")
905- self._mouse.move(target_x, target_y)
906+ self._mouse.move_to_object(self.window_buttons)
907
908 def move_mouse_over_indicators(self):
909 """Move the mouse over the center of the indicators area for this panel."""
910- (x, y, w, h) = self.indicators.geometry
911- target_x = x + w / 2
912- target_y = y + h / 2
913-
914 logger.debug("Moving mouse to center of the indicators area.")
915- self._mouse.move(target_x, target_y)
916+ self._mouse.move_to_object(self.indicators)
917
918 def get_indicator_entries(self, visible_only=True, include_hidden_menus=False):
919 """Returns a list of entries for this panel including both menus and indicators"""
920@@ -192,8 +181,8 @@
921
922 @property
923 def geometry(self):
924- """Returns a tuple of (x,y,w,h) for the current panel."""
925- return (self.x, self.y, self.width, self.height)
926+ """Returns a Rectangle (x,y,w,h) for the current panel."""
927+ return self.globalRect
928
929
930 class MenuView(UnityIntrospectionObject):
931@@ -215,8 +204,8 @@
932
933 @property
934 def geometry(self):
935- """Returns a tuple of (x,y,w,h) for the current menu view."""
936- return (self.x, self.y, self.width, self.height)
937+ """Returns a Rectangle (x,y,w,h) for the current menu view."""
938+ return self.globalRect
939
940
941 class WindowButtons(UnityIntrospectionObject):
942@@ -256,8 +245,8 @@
943
944 @property
945 def geometry(self):
946- """Returns a tuple of (x,y,w,h) for the current panel."""
947- return (self.x, self.y, self.width, self.height)
948+ """Returns a Rectangle (x,y,w,h) for the current panel."""
949+ return self.globalRect
950
951
952 class WindowButton(UnityIntrospectionObject):
953@@ -268,20 +257,25 @@
954 self._mouse = Mouse.create()
955
956 def mouse_move_to(self):
957- target_x = self.x + self.width / 2
958- target_y = self.y + self.height / 2
959- self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
960+ self._mouse.move_to_object(self)
961
962 def mouse_click(self):
963- self.mouse_move_to()
964- sleep(.2)
965- self._mouse.click(press_duration=.1)
966+ # Ignore buttons that are placed at 0x0, as they're invisible yet
967+ if not self.x and not self.y and not self.visible:
968+ return
969+
970+ self._mouse.click_object(self)
971 sleep(.01)
972
973 @property
974 def geometry(self):
975- """Returns a tuple of (x,y,w,h) for the window button."""
976- return (self.x, self.y, self.width, self.height)
977+ """Returns a Rectangle (x,y,w,h) for the window button."""
978+ return self.globalRect
979+
980+ def __repr__(self):
981+ with self.no_automatic_refreshing():
982+ details = "type={0.type} state={0.visual_state} sensitive={0.sensitive}".format(self)
983+ return self._repr_string(details)
984
985
986 class GrabArea(UnityIntrospectionObject):
987@@ -289,8 +283,8 @@
988
989 @property
990 def geometry(self):
991- """Returns a tuple of (x,y,w,h) for the grab area."""
992- return (self.x, self.y, self.width, self.height)
993+ """Returns a Rectangle (x,y,w,h) for the grab area."""
994+ return self.globalRect
995
996
997 class Indicators(UnityIntrospectionObject):
998@@ -314,8 +308,8 @@
999
1000 @property
1001 def geometry(self):
1002- """Returns a tuple of (x,y,w,h) for the indicators area."""
1003- return (self.x, self.y, self.width, self.height)
1004+ """Returns a Rectangle (x,y,w,h) for the indicators area."""
1005+ return self.globalRect
1006
1007
1008 class IndicatorEntry(UnityIntrospectionObject):
1009@@ -326,30 +320,26 @@
1010 self._mouse = Mouse.create()
1011
1012 def mouse_move_to(self):
1013- target_x = self.x + self.width / 2
1014- target_y = self.y + self.height / 2
1015- self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
1016+ self._mouse.move_to_object(self)
1017
1018 def mouse_click(self, button=1):
1019- self.mouse_move_to()
1020- sleep(.2)
1021- assert(self.visible)
1022- self._mouse.click(press_duration=.1)
1023+ self._mouse.click_object(self, button=button)
1024 sleep(.01)
1025
1026 @property
1027 def geometry(self):
1028- """Returns a tuple of (x,y,w,h) for the indicator entry."""
1029- return (self.x, self.y, self.width, self.height)
1030+ """Returns a Rectangle (x,y,w,h) for the indicator entry."""
1031+ return self.globalRect
1032
1033 @property
1034 def menu_geometry(self):
1035- """Returns a tuple of (x,y,w,h) for the opened menu geometry."""
1036- return (self.menu_x, self.menu_y, self.menu_width, self.menu_height)
1037+ """Returns a Rectangle (x,y,w,h) for the opened menu geometry."""
1038+ return Rectangle(self.menu_x, self.menu_y, self.menu_width, self.menu_height)
1039
1040 def __repr__(self):
1041 with self.no_automatic_refreshing():
1042- return "<IndicatorEntry 0x%x (%s)>" % (id(self), self.label)
1043+ details = "label={0.label}".format(self)
1044+ return self._repr_string(details)
1045
1046
1047 class Tray(UnityIntrospectionObject):
1048
1049=== modified file 'tests/autopilot/unity/emulators/quicklist.py'
1050--- tests/autopilot/unity/emulators/quicklist.py 2013-05-10 05:16:07 +0000
1051+++ tests/autopilot/unity/emulators/quicklist.py 2015-08-24 17:01:53 +0000
1052@@ -66,8 +66,8 @@
1053
1054 @property
1055 def geometry(self):
1056- """Returns a tuple of (x,y,w,h) for the quicklist."""
1057- return (self.x, self.y, self.width, self.height)
1058+ """Returns a Rectangle (x,y,w,h) for the quicklist."""
1059+ return self.globalRect
1060
1061
1062 class QuicklistMenuItem(UnityIntrospectionObject):
1063@@ -79,20 +79,17 @@
1064
1065 @property
1066 def geometry(self):
1067- """Returns a tuple of (x,y,w,h) for the quicklist item."""
1068- return (self.x, self.y, self.width, self.height)
1069+ """Returns a Rectangle (x,y,w,h) for the quicklist item."""
1070+ return self.globalRect
1071
1072 def mouse_move_to(self):
1073 assert(self.visible)
1074 logger.debug("Moving mouse over quicklist item %r", self)
1075- target_x = self.x + self.width / 2
1076- target_y = self.y + self.height / 2
1077- self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
1078+ self._mouse.move_to_object(self)
1079
1080 def mouse_click(self, button=1):
1081 logger.debug("Clicking on quicklist item %r", self)
1082- self.mouse_move_to()
1083- self._mouse.click()
1084+ self._mouse.click_object(self)
1085
1086
1087 class QuicklistMenuItemLabel(QuicklistMenuItem):
1088
1089=== modified file 'tests/autopilot/unity/emulators/screen.py'
1090--- tests/autopilot/unity/emulators/screen.py 2014-02-20 21:37:37 +0000
1091+++ tests/autopilot/unity/emulators/screen.py 2015-08-24 17:01:53 +0000
1092@@ -13,6 +13,7 @@
1093 from unity.emulators import UnityIntrospectionObject
1094 from testtools.matchers import GreaterThan
1095
1096+from autopilot.introspection.types import Rectangle
1097 from unity.emulators.dash import SearchBar
1098
1099 logger = logging.getLogger(__name__)
1100@@ -54,15 +55,15 @@
1101
1102 @property
1103 def geometry(self):
1104- """Returns a tuple of (x,y,w,h) for the current window."""
1105- return (self.x, self.y, self.width, self.height)
1106+ """Returns a Rectangle (x,y,w,h) for the current window."""
1107+ return self.globalRect
1108
1109 @property
1110 def scale_close_geometry(self):
1111- """Returns a tuple of (x,y,w,h) for the scale close button."""
1112+ """Returns a Rectangle (x,y,w,h) for the scale close button."""
1113 self.scaled_close_width.wait_for(GreaterThan(0))
1114 self.scaled_close_height.wait_for(GreaterThan(0))
1115- return (self.scaled_close_x, self.scaled_close_y, self.scaled_close_width, self.scaled_close_height)
1116+ return Rectangle(self.scaled_close_x, self.scaled_close_y, self.scaled_close_width, self.scaled_close_height)
1117
1118
1119 class SpreadFilter(UnityIntrospectionObject):
1120
1121=== modified file 'tests/autopilot/unity/emulators/window_manager.py'
1122--- tests/autopilot/unity/emulators/window_manager.py 2013-10-02 23:33:55 +0000
1123+++ tests/autopilot/unity/emulators/window_manager.py 2015-08-24 17:01:53 +0000
1124@@ -10,6 +10,7 @@
1125 from __future__ import absolute_import
1126
1127 import logging
1128+from autopilot.introspection.types import Rectangle
1129 from autopilot.keybindings import KeybindingsHelper
1130
1131 from unity.emulators import UnityIntrospectionObject
1132@@ -22,8 +23,8 @@
1133
1134 @property
1135 def screen_geometry(self):
1136- """Returns a tuple of (x,y,w,h) for the screen."""
1137- return (self.x, self.y, self.width, self.height)
1138+ """Returns a Rectangle (x,y,w,h) for the screen."""
1139+ return self.globalRect
1140
1141 def initiate_spread(self):
1142 self.keybinding("spread/start")
1143
1144=== modified file 'tests/autopilot/unity/tests/launcher/test_icon_behavior.py'
1145--- tests/autopilot/unity/tests/launcher/test_icon_behavior.py 2015-03-25 14:59:04 +0000
1146+++ tests/autopilot/unity/tests/launcher/test_icon_behavior.py 2015-08-24 17:01:53 +0000
1147@@ -384,7 +384,7 @@
1148 self.drag_type)
1149 moved_icon = self.unity.launcher.model.\
1150 get_launcher_icons_for_monitor(self.launcher_monitor)[1]
1151- self.assertThat(moved_icon.id, Equals(calc_icon.id))
1152+ self.assertThat(moved_icon, Equals(calc_icon))
1153
1154 def test_can_drag_icon_below_window_switcher(self):
1155 """Application icons must be dragable to below the workspace switcher icon."""
1156
1157=== modified file 'tests/autopilot/unity/tests/launcher/test_visual.py'
1158--- tests/autopilot/unity/tests/launcher/test_visual.py 2013-12-11 19:12:58 +0000
1159+++ tests/autopilot/unity/tests/launcher/test_visual.py 2015-08-24 17:01:53 +0000
1160@@ -71,14 +71,12 @@
1161
1162 def test_mouse_over_with_dash_open_desaturates_icons(self):
1163 """Moving mouse over launcher with dash open must saturate icons."""
1164- launcher_instance = self.get_launcher()
1165 self.unity.dash.ensure_visible()
1166 current_monitor = self.unity.dash.monitor
1167
1168 self.addCleanup(self.unity.dash.ensure_hidden)
1169 sleep(.5)
1170- x,y,w,h = launcher_instance.geometry
1171- self.mouse.move(x + w/2, y + h/2)
1172+ self.mouse.move_to_object(self.get_launcher())
1173 sleep(.5)
1174 for icon in self.unity.launcher.model.get_launcher_icons():
1175 self.assertFalse(icon.monitors_desaturated[current_monitor])
1176
1177=== modified file 'tests/autopilot/unity/tests/test_dash.py'
1178--- tests/autopilot/unity/tests/test_dash.py 2015-02-19 19:23:39 +0000
1179+++ tests/autopilot/unity/tests/test_dash.py 2015-08-24 17:01:53 +0000
1180@@ -400,10 +400,11 @@
1181
1182 # Test that tab cycles through the categories.
1183 # + 1 is the filter bar
1184- for i in range(scope.get_num_visible_categories()):
1185+ for category in scope.get_categories(only_visible=True):
1186 self.keyboard.press_and_release('Tab')
1187- category = scope.get_focused_category()
1188- self.assertIsNot(category, None)
1189+ selected = scope.get_focused_category()
1190+ expected = category if category.expand_label_is_visible else None
1191+ self.assertEqual(selected, expected)
1192
1193 def test_tab_with_filter_bar(self):
1194 """ This test makes sure that Tab works well with the filter bara."""
1195@@ -544,10 +545,7 @@
1196
1197 self.unity.dash.ensure_visible()
1198
1199- self.mouse.move(self.unity.dash.searchbar.x + self.unity.dash.searchbar.width / 2,
1200- self.unity.dash.searchbar.y + self.unity.dash.searchbar.height / 2)
1201-
1202- self.mouse.click(button=2)
1203+ self.mouse.click_object(self.unity.dash.searchbar, button=2)
1204
1205 self.assertThat(self.unity.dash.search_string, Eventually(Equals('ThirdButtonPaste')))
1206
1207@@ -691,7 +689,7 @@
1208
1209 self.unity.dash.ensure_visible()
1210
1211- self.assertThat(self.unity.dash.geometry[0], Eventually(Equals(launcher.geometry[0] + launcher.geometry[2] - 1)))
1212+ self.assertThat(self.unity.dash.view.x, Eventually(Equals(launcher.geometry.x + launcher.geometry.width - 1)))
1213
1214
1215 def test_see_more_result_alignment(self):
1216@@ -701,11 +699,9 @@
1217 self.unity.dash.reveal_application_scope()
1218
1219 scope = self.unity.dash.get_current_scope()
1220- self.assertThat(lambda: len(scope.get_groups()), Eventually(GreaterThan(0), timeout=20))
1221-
1222- groups = scope.get_groups()
1223-
1224- for group in groups:
1225+ self.assertThat(lambda: len(scope.get_categories()), Eventually(GreaterThan(0), timeout=20))
1226+
1227+ for group in scope.get_categories():
1228 if (group.is_visible and group.expand_label_is_visible):
1229 expand_label_y = group.expand_label_y + group.expand_label_baseline
1230 name_label_y = group.name_label_y + group.name_label_baseline
1231@@ -725,10 +721,7 @@
1232 the rectangle outside of the icon.
1233 """
1234 app_icon = self.scopebar.get_icon_by_name(u'applications.scope')
1235-
1236- self.mouse.move(app_icon.x + (app_icon.width / 2),
1237- app_icon.y + (app_icon.height / 2))
1238- self.mouse.click()
1239+ self.mouse.click_object(app_icon)
1240
1241 self.assertThat(self.scopebar.active_scope, Eventually(Equals('applications.scope')))
1242
1243@@ -1119,10 +1112,7 @@
1244 cover_art = self.get_current_preview().cover_art[0]
1245
1246 # click the cover-art (this will set focus)
1247- tx = cover_art.x + (cover_art.width / 2)
1248- ty = cover_art.y + (cover_art.height / 2)
1249- self.mouse.move(tx, ty)
1250- self.mouse.click()
1251+ self.mouse.click_object(cover_art)
1252
1253 self.keyboard.press_and_release("Escape")
1254
1255@@ -1138,13 +1128,21 @@
1256 class PreviewClickCancelTests(DashTestCase):
1257 """Tests that the preview closes when left, middle, and right clicking in the preview"""
1258
1259+ scenarios = [('Left button', {'clicked_button': 1}),
1260+ ('Middle button', {'clicked_button': 2}),
1261+ ('Right button', {'clicked_button': 3})]
1262+
1263 def setUp(self):
1264 super(PreviewClickCancelTests, self).setUp()
1265 gettext.install("unity-scope-applications")
1266- scope = self.unity.dash.reveal_application_scope()
1267+ scope = self.unity.dash.reveal_application_scope(clear_search=False)
1268 self.addCleanup(self.unity.dash.ensure_hidden)
1269 # Only testing an application preview for this test.
1270- self.keyboard.type("Software Updater")
1271+
1272+ search_string = "Software Updater"
1273+ if self.unity.dash.search_string != search_string:
1274+ self.unity.dash.clear_search()
1275+ self.keyboard.type(search_string)
1276
1277 # wait for "Installed" category
1278 category = self.wait_for_category(scope, _("Installed"))
1279@@ -1159,183 +1157,43 @@
1280
1281 self.preview_container = self.unity.dash.view.get_preview_container()
1282
1283- def test_left_click_on_preview_icon_cancel_preview(self):
1284- """Left click on preview icon must close preview."""
1285- icon = self.get_current_preview().icon[0]
1286- self.assertThat(icon, NotEquals(None))
1287-
1288- tx = icon.x + icon.width
1289- ty = icon.y + (icon.height / 2)
1290- self.mouse.move(tx, ty)
1291- self.mouse.click(button=1)
1292-
1293- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1294-
1295- def test_middle_click_on_preview_icon_cancel_preview(self):
1296- """Middle click on preview icon must close preview."""
1297- icon = self.get_current_preview().icon[0]
1298- self.assertThat(icon, NotEquals(None))
1299-
1300- tx = icon.x + icon.width
1301- ty = icon.y + (icon.height / 2)
1302- self.mouse.move(tx, ty)
1303- self.mouse.click(button=2)
1304-
1305- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1306-
1307- def test_right_click_on_preview_icon_cancel_preview(self):
1308- """Right click on preview icon must close preview."""
1309- icon = self.get_current_preview().icon[0]
1310- self.assertThat(icon, NotEquals(None))
1311-
1312- tx = icon.x + icon.width
1313- ty = icon.y + (icon.height / 2)
1314- self.mouse.move(tx, ty)
1315- self.mouse.click(button=3)
1316-
1317- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1318-
1319- def test_left_click_on_preview_image_cancel_preview(self):
1320- """Left click on preview image must cancel the preview."""
1321- cover_art = self.get_current_preview().cover_art[0]
1322- self.assertThat(cover_art, NotEquals(None))
1323-
1324- tx = cover_art.x + (cover_art.width / 2)
1325- ty = cover_art.y + (cover_art.height / 2)
1326- self.mouse.move(tx, ty)
1327- self.mouse.click(button=1)
1328-
1329- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1330-
1331- def test_middle_click_on_preview_image_cancel_preview(self):
1332- """Middle click on preview image must cancel the preview."""
1333- cover_art = self.get_current_preview().cover_art[0]
1334- self.assertThat(cover_art, NotEquals(None))
1335-
1336- tx = cover_art.x + (cover_art.width / 2)
1337- ty = cover_art.y + (cover_art.height / 2)
1338- self.mouse.move(tx, ty)
1339- self.mouse.click(button=2)
1340-
1341- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1342-
1343- def test_right_click_on_preview_image_cancel_preview(self):
1344- """Right click on preview image must cancel the preview."""
1345- cover_art = self.get_current_preview().cover_art[0]
1346- self.assertThat(cover_art, NotEquals(None))
1347-
1348- tx = cover_art.x + (cover_art.width / 2)
1349- ty = cover_art.y + (cover_art.height / 2)
1350- self.mouse.move(tx, ty)
1351- self.mouse.click(button=3)
1352-
1353- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1354-
1355- def test_left_click_on_preview_text_cancel_preview(self):
1356- """Left click on some preview text must cancel the preview."""
1357- text = self.get_current_preview().text_boxes[0]
1358- self.assertThat(text, NotEquals(None))
1359-
1360- tx = text.x + (text.width / 2)
1361- ty = text.y + (text.height / 2)
1362- self.mouse.move(tx, ty)
1363- self.mouse.click(button=1)
1364-
1365- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1366-
1367- def test_middle_click_on_preview_text_cancel_preview(self):
1368- """Middle click on some preview text must cancel the preview."""
1369- text = self.get_current_preview().text_boxes[0]
1370- self.assertThat(text, NotEquals(None))
1371-
1372- tx = text.x + (text.width / 2)
1373- ty = text.y + (text.height / 2)
1374- self.mouse.move(tx, ty)
1375- self.mouse.click(button=2)
1376-
1377- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1378-
1379- def test_right_click_on_preview_text_cancel_preview(self):
1380- """Right click on some preview text must cancel the preview."""
1381- text = self.get_current_preview().text_boxes[0]
1382- self.assertThat(text, NotEquals(None))
1383-
1384- tx = text.x + (text.width / 2)
1385- ty = text.y + (text.height / 2)
1386- self.mouse.move(tx, ty)
1387- self.mouse.click(button=3)
1388-
1389- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1390-
1391- def test_left_click_on_preview_ratings_widget_cancel_preview(self):
1392- """Left click on the ratings widget must cancel the preview."""
1393- ratings_widget = self.get_current_preview().ratings_widget[0]
1394- self.assertThat(ratings_widget, NotEquals(None))
1395-
1396- tx = ratings_widget.x + (ratings_widget.width / 2)
1397- ty = ratings_widget.y + (ratings_widget.height / 2)
1398- self.mouse.move(tx, ty)
1399- self.mouse.click(button=1)
1400-
1401- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1402-
1403- def test_middle_click_on_preview_ratings_widget_cancel_preview(self):
1404- """Middle click on the ratings widget must cancel the preview."""
1405- ratings_widget = self.get_current_preview().ratings_widget[0]
1406- self.assertThat(ratings_widget, NotEquals(None))
1407-
1408- tx = ratings_widget.x + (ratings_widget.width / 2)
1409- ty = ratings_widget.y + (ratings_widget.height / 2)
1410- self.mouse.move(tx, ty)
1411- self.mouse.click(button=2)
1412-
1413- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1414-
1415- def test_right_click_on_preview_ratings_widget_cancel_preview(self):
1416- """Right click on the ratings widget must cancel the preview."""
1417- ratings_widget = self.get_current_preview().ratings_widget[0]
1418- self.assertThat(ratings_widget, NotEquals(None))
1419-
1420- tx = ratings_widget.x + (ratings_widget.width / 2)
1421- ty = ratings_widget.y + (ratings_widget.height / 2)
1422- self.mouse.move(tx, ty)
1423- self.mouse.click(button=3)
1424-
1425- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1426-
1427- def test_left_click_on_preview_info_hint_cancel_preview(self):
1428- """Left click on the info hint must cancel the preview."""
1429- info_hint = self.get_current_preview().info_hint_widget[0]
1430- self.assertThat(info_hint, NotEquals(None))
1431-
1432- tx = info_hint.x + (info_hint.width / 2)
1433- ty = info_hint.y + (info_hint.height / 8)
1434- self.mouse.move(tx, ty)
1435- self.mouse.click(button=1)
1436-
1437- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1438-
1439- def test_middle_click_on_preview_info_hint_cancel_preview(self):
1440- """Middle click on the info hint must cancel the preview."""
1441- info_hint = self.get_current_preview().info_hint_widget[0]
1442- self.assertThat(info_hint, NotEquals(None))
1443-
1444- tx = info_hint.x + (info_hint.width / 2)
1445- ty = info_hint.y + (info_hint.height / 8)
1446- self.mouse.move(tx, ty)
1447- self.mouse.click(button=2)
1448-
1449- self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1450-
1451- def test_right_click_on_preview_info_hint_cancel_preview(self):
1452- """Right click on the info hint must cancel the preview."""
1453- info_hint = self.get_current_preview().info_hint_widget[0]
1454- self.assertThat(info_hint, NotEquals(None))
1455-
1456- tx = info_hint.x + (info_hint.width / 2)
1457- ty = info_hint.y + (info_hint.height / 8)
1458- self.mouse.move(tx, ty)
1459- self.mouse.click(button=3)
1460+ def test_click_on_preview_icon_cancel_preview(self):
1461+ """Clicking with any button on preview icon must close preview."""
1462+ icon = self.get_current_preview().icon[0]
1463+ self.assertThat(icon, NotEquals(None))
1464+
1465+ self.mouse.click_object(icon, button=self.clicked_button)
1466+ self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1467+
1468+ def test_click_on_preview_image_cancel_preview(self):
1469+ """Clicking with any button on preview image must cancel the preview."""
1470+ cover_art = self.get_current_preview().cover_art[0]
1471+ self.assertThat(cover_art, NotEquals(None))
1472+
1473+ self.mouse.click_object(cover_art, button=self.clicked_button)
1474+ self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1475+
1476+ def test_click_on_preview_text_cancel_preview(self):
1477+ """Clicking with any button on some preview text must cancel the preview."""
1478+ text = self.get_current_preview().text_boxes[0]
1479+ self.assertThat(text, NotEquals(None))
1480+ self.mouse.click_object(text, button=self.clicked_button)
1481+
1482+ self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1483+
1484+ def test_click_on_preview_ratings_widget_cancel_preview(self):
1485+ """Clicking with any button on the ratings widget must cancel the preview."""
1486+ ratings_widget = self.get_current_preview().ratings_widget[0]
1487+ self.assertThat(ratings_widget, NotEquals(None))
1488+ self.mouse.click_object(ratings_widget, button=self.clicked_button)
1489+
1490+ self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1491+
1492+ def test_click_on_preview_info_hint_cancel_preview(self):
1493+ """Clicking with any button on the info hint must cancel the preview."""
1494+ info_hint = self.get_current_preview().info_hint_widget[0]
1495+ self.assertThat(info_hint, NotEquals(None))
1496+ self.mouse.click_object(info_hint, button=self.clicked_button)
1497
1498 self.assertThat(self.unity.dash.preview_displaying, Eventually(Equals(False)))
1499
1500@@ -1401,3 +1259,4 @@
1501 self.addCleanup(self.unity.dash.ensure_hidden)
1502
1503 self.assertThat(self.unity.dash.visible, Eventually(Equals(True)))
1504+
1505
1506=== modified file 'tests/autopilot/unity/tests/test_panel.py'
1507--- tests/autopilot/unity/tests/test_panel.py 2015-02-19 14:41:09 +0000
1508+++ tests/autopilot/unity/tests/test_panel.py 2015-08-24 17:01:53 +0000
1509@@ -78,8 +78,7 @@
1510 self.keybinding("window/restore")
1511 self.addCleanup(self.keybinding, "window/maximize")
1512
1513- sleep(.25)
1514- self.assertProperty(win, is_maximized=maximized)
1515+ self.assertThat(lambda: win.is_maximized, Eventually(Equals(maximized)))
1516
1517 def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True):
1518 """Opens a new instance of the requested application, ensuring that only
1519@@ -93,8 +92,8 @@
1520 app = app_win.application
1521
1522 app_win.set_focus()
1523- self.assertTrue(app.is_active)
1524- self.assertTrue(app_win.is_focused)
1525+ self.assertThat(lambda: app.is_active, Eventually(Equals(True)))
1526+ self.assertThat(lambda: app_win.is_focused, Eventually(Equals(True)))
1527 self.assertThat(app.desktop_file, Equals(app_win.application.desktop_file))
1528
1529 if move_to_monitor:
1530@@ -431,7 +430,6 @@
1531 self.addCleanup(self.unity.hud.ensure_hidden)
1532
1533 self.panel.window_buttons.maximize.mouse_click()
1534-
1535 self.assertThat(self.unity.hud.visible, Eventually(Equals(True)))
1536
1537 def test_hud_maximize_button_does_not_change_dash_form_factor(self):
1538@@ -986,7 +984,7 @@
1539
1540 def open_app_and_get_menu_entry(self):
1541 """Open the test app and wait for the menu entry to appear."""
1542- self.open_new_application_window("Remmina" if self.lim else "Calculator",
1543+ self.open_new_application_window("Text Editor" if self.lim else "Calculator",
1544 maximized=self.lim)
1545
1546 refresh_fn = lambda: len(self.panel.menus.get_entries())
1547@@ -1043,7 +1041,8 @@
1548 self.assertThat(menu_entry.active, Eventually(Equals(True)))
1549
1550 self.open_new_application_window("Text Editor")
1551- self.assertThat(self.unity.panels.get_active_indicator, Eventually(Equals(None)))
1552+ get_active_indicator_fn = lambda: self.unity.panels.get_active_indicator()
1553+ self.assertThat(get_active_indicator_fn, Eventually(Equals(None)))
1554
1555 def test_indicator_opens_when_dash_is_open(self):
1556 """When the dash is open and a click is on an indicator the dash
1557@@ -1068,8 +1067,9 @@
1558 This method will wait until the active indicator has been set.
1559
1560 """
1561- self.assertThat(self.panel.get_active_indicator, Eventually(NotEquals(None)))
1562- return self.panel.get_active_indicator()
1563+ get_active_indicator_fn = lambda: self.panel.get_active_indicator()
1564+ self.assertThat(get_active_indicator_fn, Eventually(NotEquals(None)))
1565+ return get_active_indicator_fn()
1566
1567 def test_panel_first_menu_show_works(self):
1568 """Pressing the open-menus keybinding must open the first indicator."""
1569@@ -1185,9 +1185,7 @@
1570 self.assertProperty(text_win, is_focused=False)
1571 self.assertProperty(calc_win, is_focused=True)
1572
1573- self.move_mouse_over_grab_area()
1574- self.mouse.click()
1575-
1576+ self.mouse.click_object(self.panel.grab_area, button=1)
1577 self.assertProperty(text_win, is_focused=True)
1578
1579 def test_lower_the_maximized_window_works(self):
1580@@ -1198,8 +1196,7 @@
1581 self.assertProperty(text_win, is_focused=True)
1582 self.assertProperty(calc_win, is_focused=False)
1583
1584- self.move_mouse_over_grab_area()
1585- self.mouse.click(2)
1586+ self.mouse.click_object(self.panel.grab_area, button=2)
1587
1588 self.assertProperty(calc_win, is_focused=True)
1589
1590@@ -1209,8 +1206,7 @@
1591 self.addCleanup(self.unity.hud.ensure_hidden)
1592
1593 self.keyboard.type("Hello")
1594- self.move_mouse_over_grab_area()
1595- self.mouse.click()
1596+ self.mouse.click_object(self.panel.grab_area)
1597 self.keyboard.type("World")
1598
1599 self.assertThat(self.unity.hud.search_string, Eventually(Equals("HelloWorld")))
1600
1601=== modified file 'tests/autopilot/unity/tests/test_quicklist.py'
1602--- tests/autopilot/unity/tests/test_quicklist.py 2015-03-25 14:59:04 +0000
1603+++ tests/autopilot/unity/tests/test_quicklist.py 2015-08-24 17:01:53 +0000
1604@@ -269,7 +269,7 @@
1605 def assertCorrectItemSelected(self, item):
1606 """Ensure the item considers itself selected and that quicklist agrees."""
1607 self.assertThat(item.selected, Eventually(Equals(True)))
1608- self.assertThat(self.quicklist.selected_item.id, Equals(item.id))
1609+ self.assertThat(self.quicklist.selected_item, Equals(item))
1610
1611 def test_keynav_selects_first_item_when_unselected(self):
1612 """Home key MUST select the first selectable item in a quicklist."""
1613@@ -402,11 +402,11 @@
1614
1615 # Moving the mouse horizontally doesn't change the selection
1616 self.mouse.move(mouse_item.x + mouse_item.width - 10, mouse_item.y + mouse_item.height / 2)
1617- self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
1618+ self.assertThat(self.quicklist.selected_item, Equals(key_item))
1619
1620 # Moving the mouse outside doesn't change the selection
1621 self.mouse.move(mouse_item.x + mouse_item.width + 50, mouse_item.y + mouse_item.height / 2)
1622- self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
1623+ self.assertThat(self.quicklist.selected_item, Equals(key_item))
1624
1625 # Moving the mouse to another entry, changes the selection
1626 mouse_item = self.quicklist.selectable_items[-2]
1627
1628=== modified file 'tests/autopilot/unity/tests/test_spread.py'
1629--- tests/autopilot/unity/tests/test_spread.py 2015-03-24 22:35:27 +0000
1630+++ tests/autopilot/unity/tests/test_spread.py 2015-08-24 17:01:53 +0000
1631@@ -114,11 +114,7 @@
1632 target_xid = not_focused.x_id
1633 [target_win] = [w for w in self.unity.screen.scaled_windows if w.xid == target_xid]
1634
1635- (x, y, w, h) = target_win.geometry
1636- self.mouse.move(x + w / 2, y + h / 2)
1637- sleep(.5)
1638- self.mouse.click()
1639-
1640+ self.mouse.click_object(target_win, button=1)
1641 self.assertThat(lambda: not_focused.is_focused, Eventually(Equals(True)))
1642
1643 def test_scaled_window_closes_on_middle_click(self):
1644@@ -129,10 +125,8 @@
1645 target_xid = win.x_id
1646 [target_win] = [w for w in self.unity.screen.scaled_windows if w.xid == target_xid]
1647
1648- (x, y, w, h) = target_win.geometry
1649- self.mouse.move(x + w / 2, y + h / 2)
1650- sleep(.5)
1651- self.mouse.click(button=2)
1652+ sleep(1)
1653+ self.mouse.click_object(target_win, button=2)
1654
1655 self.assertWindowIsScaledEquals(target_xid, False)
1656 self.assertWindowIsClosed(target_xid)
1657@@ -146,13 +140,8 @@
1658 [target_win] = [w for w in self.unity.screen.scaled_windows if w.xid == target_xid]
1659
1660 # Make sure mouse is over the test window
1661- (x1, y1, w1, h1) = target_win.geometry
1662- self.mouse.move(x1 + w1 / 2, y1 + h1 / 2)
1663-
1664- (x, y, w, h) = target_win.scale_close_geometry
1665- self.mouse.move(x + w / 2, y + h / 2)
1666- sleep(.5)
1667- self.mouse.click()
1668+ self.mouse.move_to_object(target_win)
1669+ self.mouse.click_object(target_win.scale_close_geometry)
1670
1671 self.assertWindowIsScaledEquals(target_xid, False)
1672 self.assertWindowIsClosed(target_xid)
1673
1674=== modified file 'tests/autopilot/unity/tests/test_switcher.py'
1675--- tests/autopilot/unity/tests/test_switcher.py 2014-01-29 20:33:47 +0000
1676+++ tests/autopilot/unity/tests/test_switcher.py 2015-08-24 17:01:53 +0000
1677@@ -629,6 +629,7 @@
1678 def setUp(self):
1679 super(SwitcherDetailsMouseTests, self).setUp()
1680 self.set_timeout_setting(False)
1681+ self.mouse.move(0, 0, animate=False)
1682
1683 def test_mouse_highlights_switcher_icons(self):
1684 """ Tests that the mouse can hightlight all the switcher icons. """
1685@@ -653,7 +654,7 @@
1686 index = 0;
1687 for cords in icon_cords:
1688 self.mouse.move(cords[0], cords[1])
1689- self.assertThat(index, Equals(self.unity.switcher.selection_index))
1690+ self.assertThat(self.unity.switcher.selection_index, Eventually(Equals(index)))
1691 index += 1
1692
1693 def test_mouse_clicks_activate_icon(self):
1694@@ -691,7 +692,7 @@
1695
1696 mouse_index = self.unity.switcher.selection_index - 1
1697
1698- self.unity.switcher.view.move_over_icon(mouse_index);
1699+ self.unity.switcher.view.move_over_icon(mouse_index)
1700 # Assert we are over the icon we want to hover over.
1701 self.assertThat(self.unity.switcher.view.last_icon_selected, Eventually(Equals(mouse_index)))
1702
1703@@ -724,11 +725,9 @@
1704 self.unity.switcher.initiate(SwitcherMode.DETAIL)
1705 self.addCleanup(self.unity.switcher.terminate)
1706
1707- index = 0;
1708- for icon in self.unity.switcher.view.detail_icons:
1709+ for index in range(len(self.unity.switcher.view.detail_icons)):
1710 self.unity.switcher.view.move_over_detail_icon(index)
1711- self.assertThat(index, Equals(self.unity.switcher.detail_selection_index))
1712- index += 1
1713+ self.assertThat(self.unity.switcher.detail_selection_index, Eventually(Equals(index)))
1714
1715 def test_mouse_click_will_activate_detail_icon(self):
1716 """
1717
1718=== modified file 'tests/bamf-mock-application.c'
1719--- tests/bamf-mock-application.c 2012-11-06 18:19:09 +0000
1720+++ tests/bamf-mock-application.c 2015-08-24 17:01:53 +0000
1721@@ -99,10 +99,24 @@
1722 void
1723 bamf_mock_application_set_children (BamfMockApplication * self, GList * children)
1724 {
1725+ GList *l;
1726+
1727 g_return_if_fail (BAMF_IS_MOCK_APPLICATION (self));
1728
1729- g_list_free (self->priv->children);
1730- self->priv->children = g_list_copy (children);
1731+ for (l = self->priv->children; l;)
1732+ {
1733+ GList *next = l->next;
1734+ BamfView *view = l->data;
1735+ self->priv->children = g_list_delete_link (self->priv->children, l);
1736+ g_signal_emit_by_name (G_OBJECT (self), "child-removed", view);
1737+ l = next;
1738+ }
1739+
1740+ for (l = g_list_last (children); l; l = l->prev)
1741+ {
1742+ self->priv->children = g_list_prepend (self->priv->children, l->data);
1743+ g_signal_emit_by_name (G_OBJECT (self), "child-added", l->data);
1744+ }
1745 }
1746
1747 static void
1748
1749=== modified file 'tests/mock-application.h'
1750--- tests/mock-application.h 2015-05-22 16:03:30 +0000
1751+++ tests/mock-application.h 2015-08-24 17:01:53 +0000
1752@@ -46,6 +46,7 @@
1753 , active_(false)
1754 , urgent_(false)
1755 {
1756+ monitor.SetGetterFunction([this] { return monitor_; });
1757 visible.SetGetterFunction([this] { return visible_; });
1758 active.SetGetterFunction([this] { return active_; });
1759 urgent.SetGetterFunction([this] { return urgent_; });
1760@@ -54,7 +55,6 @@
1761
1762 ON_CALL(*this, type()).WillByDefault(Invoke([this] { return type_; }));
1763 ON_CALL(*this, window_id()).WillByDefault(Invoke([this] { return xid_; }));
1764- ON_CALL(*this, monitor()).WillByDefault(Invoke([this] { return monitor_; }));
1765 ON_CALL(*this, Focus()).WillByDefault(Invoke([this] { return LocalFocus(); }));
1766 ON_CALL(*this, application()).WillByDefault(Return(unity::ApplicationPtr()));
1767 }
1768@@ -71,7 +71,6 @@
1769
1770 MOCK_CONST_METHOD0(type, unity::WindowType());
1771 MOCK_CONST_METHOD0(window_id, Window());
1772- MOCK_CONST_METHOD0(monitor, int());
1773 MOCK_CONST_METHOD0(application, unity::ApplicationPtr());
1774 MOCK_CONST_METHOD0(Focus, bool());
1775 MOCK_CONST_METHOD0(Quit, void());
1776@@ -144,7 +143,7 @@
1777 ON_CALL(*this, type()).WillByDefault(Invoke([this] { return type_; }));
1778 ON_CALL(*this, desktop_id()).WillByDefault(Invoke([this] { return desktop_file_; }));
1779 ON_CALL(*this, repr()).WillByDefault(Return("MockApplication"));
1780- ON_CALL(*this, GetWindows()).WillByDefault(Invoke([this] { return windows_; }));
1781+ ON_CALL(*this, GetWindows()).WillByDefault(Invoke([this] () -> unity::WindowList const& { return windows_; }));
1782 ON_CALL(*this, GetSupportedMimeTypes()).WillByDefault(Return(std::vector<std::string>()));
1783 ON_CALL(*this, GetFocusableWindow()).WillByDefault(Return(unity::ApplicationWindowPtr()));
1784 ON_CALL(*this, OwnsWindow(_)).WillByDefault(Invoke(this, &MockApplication::LocalOwnsWindow));
1785@@ -167,7 +166,7 @@
1786 MOCK_CONST_METHOD0(type, unity::AppType());
1787 MOCK_CONST_METHOD0(repr, std::string());
1788 MOCK_CONST_METHOD0(desktop_id, std::string());
1789- MOCK_CONST_METHOD0(GetWindows, unity::WindowList());
1790+ MOCK_CONST_METHOD0(GetWindows, unity::WindowList const&());
1791 MOCK_CONST_METHOD1(OwnsWindow, bool(Window));
1792 MOCK_CONST_METHOD0(GetSupportedMimeTypes, std::vector<std::string>());
1793 MOCK_CONST_METHOD0(GetFocusableWindow, unity::ApplicationWindowPtr());
1794
1795=== modified file 'tests/test_bamf_application.cpp'
1796--- tests/test_bamf_application.cpp 2013-10-14 17:36:51 +0000
1797+++ tests/test_bamf_application.cpp 2015-08-24 17:01:53 +0000
1798@@ -56,6 +56,8 @@
1799
1800 TEST_F(TestBamfApplication, GetWindows)
1801 {
1802+ ASSERT_EQ(application_.GetWindows().size(), 0);
1803+
1804 GList* children = nullptr;
1805 for (int i = 0; i<5; ++i)
1806 {
1807@@ -71,8 +73,7 @@
1808 AddFakeWindowToWM(3, true);
1809 AddFakeWindowToWM(4, false);
1810
1811- auto windows = application_.GetWindows();
1812- ASSERT_EQ(windows.size(), 5);
1813+ EXPECT_EQ(application_.GetWindows().size(), 5);
1814
1815 g_list_free_full(children, g_object_unref);
1816 }
1817
1818=== modified file 'unity-shared/ApplicationManager.h'
1819--- unity-shared/ApplicationManager.h 2015-02-09 16:47:24 +0000
1820+++ unity-shared/ApplicationManager.h 2015-08-24 17:01:53 +0000
1821@@ -80,7 +80,6 @@
1822
1823 virtual WindowType type() const = 0;
1824 virtual Window window_id() const = 0;
1825- virtual int monitor() const = 0;
1826
1827 // It is possible for this to be null, especially in situations where
1828 // the application is starting up or shutting down.
1829@@ -101,6 +100,8 @@
1830 return !(operator==(other));
1831 }
1832
1833+ nux::ROProperty<int> monitor;
1834+
1835 nux::ROProperty<std::string> title;
1836 nux::ROProperty<std::string> icon;
1837
1838@@ -121,7 +122,7 @@
1839 // A string representation of the object.
1840 virtual std::string repr() const = 0;
1841
1842- virtual WindowList GetWindows() const = 0;
1843+ virtual WindowList const& GetWindows() const = 0;
1844 virtual bool OwnsWindow(Window window_id) const = 0;
1845
1846 virtual std::vector<std::string> GetSupportedMimeTypes() const = 0;
1847
1848=== modified file 'unity-shared/BamfApplicationManager.cpp'
1849--- unity-shared/BamfApplicationManager.cpp 2015-04-21 19:57:00 +0000
1850+++ unity-shared/BamfApplicationManager.cpp 2015-08-24 17:01:53 +0000
1851@@ -145,6 +145,10 @@
1852 [this] (BamfView*, gboolean urgent) {
1853 this->urgent.changed.emit(urgent);
1854 });
1855+ signals_.Add<void, BamfView*>(bamf_view_, "closed",
1856+ [this] (BamfView* view) {
1857+ pool::wins_.erase(view);
1858+ });
1859 }
1860
1861 bool WindowBase::Focus() const
1862@@ -170,7 +174,13 @@
1863 : WindowBase(manager, window)
1864 , bamf_window_(glib::object_cast<BamfWindow>(window))
1865 {
1866+ monitor.SetGetterFunction(std::bind(&AppWindow::GetMonitor, this));
1867 maximized.SetGetterFunction(std::bind(&AppWindow::GetMaximized, this));
1868+
1869+ signals_.Add<void, BamfWindow*, gint, gint>(bamf_window_, "monitor-changed",
1870+ [this] (BamfWindow*, gint, gint monitor) {
1871+ this->monitor.changed.emit(monitor);
1872+ });
1873 signals_.Add<void, BamfWindow*, gint, gint>(bamf_window_, "maximized-changed",
1874 [this] (BamfWindow*, gint old_state, gint state) {
1875 if ((old_state == BAMF_WINDOW_MAXIMIZED) != (state == BAMF_WINDOW_MAXIMIZED))
1876@@ -178,6 +188,11 @@
1877 });
1878 }
1879
1880+int AppWindow::GetMonitor() const
1881+{
1882+ return bamf_window_get_monitor(bamf_window_);
1883+}
1884+
1885 bool AppWindow::GetMaximized() const
1886 {
1887 return bamf_window_maximized(bamf_window_) == BAMF_WINDOW_MAXIMIZED;
1888@@ -188,11 +203,6 @@
1889 return bamf_window_get_xid(bamf_window_);
1890 }
1891
1892-int AppWindow::monitor() const
1893-{
1894- return bamf_window_get_monitor(bamf_window_);
1895-}
1896-
1897 WindowType AppWindow::type() const
1898 {
1899 switch (bamf_window_get_window_type(bamf_window_))
1900@@ -231,14 +241,15 @@
1901 WindowManager::Default().Close(window_id());
1902 }
1903
1904-Tab::Tab(ApplicationManager const& manager, glib::Object<BamfView> const& tab)
1905- : WindowBase(manager, tab)
1906- , bamf_tab_(glib::object_cast<BamfTab>(tab))
1907-{}
1908-
1909 Tab::Tab(ApplicationManager const& manager, glib::Object<BamfTab> const& tab)
1910 : WindowBase(manager, glib::object_cast<BamfView>(tab))
1911 , bamf_tab_(tab)
1912+{
1913+ monitor.SetGetterFunction([] { return -1; });
1914+}
1915+
1916+Tab::Tab(ApplicationManager const& manager, glib::Object<BamfView> const& tab)
1917+ : Tab(manager_, glib::object_cast<BamfTab>(tab))
1918 {}
1919
1920 Window Tab::window_id() const
1921@@ -251,12 +262,6 @@
1922 return WindowType::TAB;
1923 }
1924
1925-int Tab::monitor() const
1926-{
1927- // TODO, we could find the real window for the window_id, and get the monitor for that.
1928- return -1;
1929-}
1930-
1931 ApplicationPtr Tab::application() const
1932 {
1933 // TODO, we could find the real window for the window_id, and return the application for that.
1934@@ -323,6 +328,7 @@
1935 signals_.Add<void, BamfView*, gboolean>(bamf_view_, "running-changed",
1936 [this] (BamfView*, gboolean running) {
1937 LOG_TRACE(logger) << "running " << visible;
1938+ UpdateWindows();
1939 this->running.changed.emit(running);
1940 });
1941 signals_.Add<void, BamfView*, gboolean>(bamf_view_, "urgent-changed",
1942@@ -330,21 +336,34 @@
1943 this->urgent.changed.emit(urgent);
1944 });
1945 signals_.Add<void, BamfView*>(bamf_view_, "closed",
1946- [this] (BamfView*) {
1947+ [this] (BamfView* view) {
1948+ UpdateWindows();
1949 this->closed.emit();
1950+
1951+ if (!sticky())
1952+ pool::apps_.erase(view);
1953 });
1954
1955 signals_.Add<void, BamfView*, BamfView*>(bamf_view_, "child-added",
1956 [this] (BamfView*, BamfView* child) {
1957 // Ownership is not passed on signals
1958 if (ApplicationWindowPtr const& win = pool::EnsureWindow(manager_, child))
1959- this->window_opened.emit(win);
1960+ {
1961+ if (std::find(windows_.begin(), windows_.end(), win) == windows_.end())
1962+ {
1963+ windows_.push_back(win);
1964+ this->window_opened.emit(win);
1965+ }
1966+ }
1967 });
1968
1969 signals_.Add<void, BamfView*, BamfView*>(bamf_view_, "child-removed",
1970 [this] (BamfView*, BamfView* child) {
1971 if (ApplicationWindowPtr const& win = pool::EnsureWindow(manager_, child))
1972+ {
1973+ windows_.erase(std::remove(windows_.begin(), windows_.end(), win), windows_.end());
1974 this->window_closed.emit(win);
1975+ }
1976 });
1977
1978 signals_.Add<void, BamfView*, BamfView*>(bamf_view_, "child-moved",
1979@@ -353,6 +372,8 @@
1980 if (ApplicationWindowPtr const& win = pool::EnsureWindow(manager_, child))
1981 this->window_moved.emit(win);
1982 });
1983+
1984+ UpdateWindows();
1985 }
1986
1987 std::string Application::GetDesktopFile() const
1988@@ -384,20 +405,38 @@
1989 return sout.str();
1990 }
1991
1992-WindowList Application::GetWindows() const
1993-{
1994- WindowList result;
1995-
1996- if (!bamf_app_)
1997- return result;
1998+WindowList const& Application::GetWindows() const
1999+{
2000+ return windows_;
2001+}
2002+
2003+void Application::UpdateWindows()
2004+{
2005+ if (!bamf_app_ || !running() || bamf_view_is_closed(bamf_view_))
2006+ {
2007+ for (auto it = windows_.begin(); it != windows_.end();)
2008+ {
2009+ window_closed.emit(*it);
2010+ it = windows_.erase(it);
2011+ }
2012+
2013+ return;
2014+ }
2015+
2016+ bool was_empty = windows_.empty();
2017
2018 std::shared_ptr<GList> children(bamf_view_get_children(bamf_view_), g_list_free);
2019 for (GList* l = children.get(); l; l = l->next)
2020 {
2021 if (ApplicationWindowPtr const& window = pool::EnsureWindow(manager_, static_cast<BamfView*>(l->data)))
2022- result.push_back(window);
2023+ {
2024+ if (was_empty || std::find(windows_.begin(), windows_.end(), window) == windows_.end())
2025+ {
2026+ windows_.push_back(window);
2027+ window_opened.emit(window);
2028+ }
2029+ }
2030 }
2031- return result;
2032 }
2033
2034 bool Application::OwnsWindow(Window window_id) const
2035@@ -405,15 +444,13 @@
2036 if (!window_id)
2037 return false;
2038
2039- bool owns = false;
2040- std::shared_ptr<GList> children(bamf_view_get_children(bamf_view_), g_list_free);
2041- for (GList* l = children.get(); l && !owns; l = l->next)
2042+ for (auto const& win : windows_)
2043 {
2044- owns = BAMF_IS_WINDOW(l->data) &&
2045- bamf_window_get_xid(static_cast<BamfWindow*>(l->data)) == window_id;
2046+ if (win->window_id() == window_id)
2047+ return true;
2048 }
2049
2050- return owns;
2051+ return false;
2052 }
2053
2054 std::vector<std::string> Application::GetSupportedMimeTypes() const
2055@@ -515,7 +552,7 @@
2056 g_quark_from_string(UNSEEN_QUARK));
2057 }
2058
2059-bool Application::SetSeen(bool const& param)
2060+bool Application::SetSeen(bool param)
2061 {
2062 bool is_seen = GetSeen();
2063 if (param == is_seen)
2064@@ -533,12 +570,15 @@
2065 return bamf_view_is_sticky(bamf_view_);
2066 }
2067
2068-bool Application::SetSticky(bool const& param)
2069+bool Application::SetSticky(bool param)
2070 {
2071 bool is_sticky = GetSticky();
2072 if (param == is_sticky)
2073 return false; // unchanged
2074
2075+ if (!param && bamf_view_is_closed(bamf_view_))
2076+ pool::apps_.erase(bamf_view_);
2077+
2078 bamf_view_set_sticky(bamf_view_, param);
2079 return true; // value updated
2080 }
2081@@ -640,6 +680,12 @@
2082 if (xid == 0)
2083 return nullptr;
2084
2085+ for (auto const& win_pair : pool::wins_)
2086+ {
2087+ if (win_pair.second->window_id() == xid)
2088+ return win_pair.second;
2089+ }
2090+
2091 // TODO: use bamf_matcher_get_window_for_xid
2092 auto* app = bamf_matcher_get_application_for_xid(matcher_, xid);
2093
2094@@ -724,16 +770,14 @@
2095 {
2096 if (ApplicationPtr const& app = pool::EnsureApplication(*this, view))
2097 application_stopped.emit(app);
2098-
2099- pool::apps_.erase(view);
2100 }
2101 else if (BAMF_IS_WINDOW(view))
2102 {
2103 if (ApplicationWindowPtr const& win = pool::EnsureWindow(*this, view))
2104 window_closed.emit(win);
2105-
2106- pool::wins_.erase(view);
2107 }
2108+
2109+ /* No removal here, it's done inside views, as 'closed' signal arrives later */
2110 }
2111
2112 } // namespace bamf
2113
2114=== modified file 'unity-shared/BamfApplicationManager.h'
2115--- unity-shared/BamfApplicationManager.h 2015-02-05 14:35:07 +0000
2116+++ unity-shared/BamfApplicationManager.h 2015-08-24 17:01:53 +0000
2117@@ -49,6 +49,7 @@
2118 protected:
2119 ApplicationManager const& manager_;
2120 glib::Object<BamfView> bamf_view_;
2121+ glib::SignalManager signals_;
2122 };
2123
2124
2125@@ -66,9 +67,6 @@
2126 return static_cast<WindowBase const*>(this)->bamf_view_ == static_cast<WindowBase const&>(other).bamf_view_;
2127 }
2128 bool operator!=(unity::ApplicationWindow const& other) const override { return !(operator==(other)); }
2129-
2130-protected:
2131- glib::SignalManager signals_;
2132 };
2133
2134 // NOTE: Can't use Window as a type as there is a #define for Window to some integer value.
2135@@ -82,12 +80,13 @@
2136
2137 WindowType type() const override;
2138 Window window_id() const override;
2139- int monitor() const override;
2140 ApplicationPtr application() const override;
2141 void Quit() const override;
2142+
2143+private:
2144+ int GetMonitor() const;
2145 bool GetMaximized() const;
2146
2147-private:
2148 glib::Object<BamfWindow> bamf_window_;
2149 };
2150
2151@@ -101,7 +100,6 @@
2152
2153 WindowType type() const override;
2154 Window window_id() const override;
2155- int monitor() const override;
2156 ApplicationPtr application() const override;
2157 bool Focus() const override;
2158 void Quit() const override;
2159@@ -121,7 +119,7 @@
2160
2161 virtual AppType type() const;
2162
2163- virtual WindowList GetWindows() const;
2164+ virtual WindowList const& GetWindows() const;
2165 virtual bool OwnsWindow(Window window_id) const;
2166
2167 virtual std::vector<std::string> GetSupportedMimeTypes() const;
2168@@ -145,13 +143,16 @@
2169 std::string GetDesktopFile() const;
2170
2171 bool GetSeen() const;
2172- bool SetSeen(bool const& param);
2173+ bool SetSeen(bool param);
2174
2175 bool GetSticky() const;
2176- bool SetSticky(bool const& param);
2177+ bool SetSticky(bool param);
2178+
2179+ void UpdateWindows();
2180
2181 private:
2182 glib::Object<::BamfApplication> bamf_app_;
2183+ WindowList windows_;
2184 glib::SignalManager signals_;
2185 std::string type_;
2186 };
2187
2188=== modified file 'unity-shared/IconTexture.cpp'
2189--- unity-shared/IconTexture.cpp 2014-07-28 16:28:38 +0000
2190+++ unity-shared/IconTexture.cpp 2015-08-24 17:01:53 +0000
2191@@ -281,8 +281,10 @@
2192
2193 void IconTexture::SetOpacity(float opacity)
2194 {
2195+ if (_opacity == opacity)
2196+ return;
2197+
2198 _opacity = opacity;
2199-
2200 QueueDraw();
2201 }
2202
2203
2204=== modified file 'unity-shared/PluginAdapter.cpp'
2205--- unity-shared/PluginAdapter.cpp 2015-04-09 14:42:07 +0000
2206+++ unity-shared/PluginAdapter.cpp 2015-08-24 17:01:53 +0000
2207@@ -781,7 +781,10 @@
2208 {
2209 CompWindow* window = m_Screen->findWindow(window_id);
2210 if (window && (window->actions() & CompWindowActionMinimizeMask))
2211+ {
2212 window->unminimize();
2213+ window->show();
2214+ }
2215 }
2216
2217 void PluginAdapter::Shade(Window window_id)
2218@@ -962,6 +965,7 @@
2219 if (forced_unminimize)
2220 {
2221 top_window->unminimize();
2222+ top_window->show();
2223 }
2224
2225 top_window->raise();
2226
2227=== modified file 'unity-shared/StandaloneAppManager.cpp'
2228--- unity-shared/StandaloneAppManager.cpp 2015-02-09 19:39:39 +0000
2229+++ unity-shared/StandaloneAppManager.cpp 2015-08-24 17:01:53 +0000
2230@@ -81,6 +81,22 @@
2231 return os;
2232 }
2233
2234+void connect_window_events(ApplicationWindowPtr const& win)
2235+{
2236+ win->title.changed.connect([win] (std::string const& t) {
2237+ std::cout << "Window "<< win->window_id()<< " title changed to "<< t << endl;
2238+ });
2239+ win->maximized.changed.connect([win] (bool m) {
2240+ std::cout << "Window "<< win->window_id()<< " maximized changed to "<< m << endl;
2241+ });
2242+ win->monitor.changed.connect([win] (int m) {
2243+ std::cout << "Window "<< win->window_id()<< " monitor changed to "<< m << endl;
2244+ });
2245+ win->active.changed.connect([win] (bool a) {
2246+ std::cout << "Window "<< win->window_id()<< " active changed to "<< a << endl;
2247+ });
2248+}
2249+
2250 void dump_app(ApplicationPtr const& app, std::string const& prefix = "")
2251 {
2252 if (app)
2253@@ -153,6 +169,7 @@
2254 });
2255 app->window_opened.connect([idx](ApplicationWindowPtr const& window) {
2256 cout << "** " << names[idx] << " window opened: " << window->title() << endl;
2257+ connect_window_events(window);
2258 });
2259 app->window_closed.connect([idx](ApplicationWindowPtr const& window) {
2260 cout << "** " << names[idx] << " window closed: " << window->title() << endl;
2261@@ -163,21 +180,10 @@
2262 app->seen = true;
2263
2264 for (auto win : app->GetWindows())
2265- {
2266- win->title.changed.connect([win] (std::string const& t) {
2267- std::cout << "Window "<< win->window_id()<< " title changed to "<< t << endl;
2268- });
2269- win->maximized.changed.connect([win] (bool m) {
2270- std::cout << "Window "<< win->window_id()<< " maximized changed to "<< m << endl;
2271- });
2272- win->active.changed.connect([win] (bool a) {
2273- std::cout << "Window "<< win->window_id()<< " active changed to "<< a << endl;
2274- });
2275- }
2276+ connect_window_events(win);
2277 }
2278
2279
2280-
2281 nux::logging::Level glog_level_to_nux(GLogLevelFlags log_level)
2282 {
2283 // For some weird reason, ERROR is more critical than CRITICAL in gnome.
2284
2285=== modified file 'unity-shared/WindowButtons.cpp'
2286--- unity-shared/WindowButtons.cpp 2015-06-03 12:10:00 +0000
2287+++ unity-shared/WindowButtons.cpp 2015-08-24 17:01:53 +0000
2288@@ -234,14 +234,14 @@
2289 }
2290
2291 introspection.add(GetAbsoluteGeometry())
2292- .add("type", type_name)
2293- .add("visible", IsVisible() && Parent()->opacity() != 0.0f)
2294- .add("sensitive", Parent()->GetInputEventSensitivity())
2295- .add("enabled", enabled())
2296- .add("visual_state", state_name)
2297- .add("opacity", Parent()->opacity())
2298- .add("focused", Parent()->focused())
2299- .add("overlay_mode", overlay_mode());
2300+ .add("type", type_name)
2301+ .add("visible", IsVisible() && Parent()->opacity() != 0.0f)
2302+ .add("sensitive", Parent()->GetInputEventSensitivity())
2303+ .add("enabled", enabled())
2304+ .add("visual_state", state_name)
2305+ .add("opacity", Parent()->opacity())
2306+ .add("focused", Parent()->focused())
2307+ .add("overlay_mode", overlay_mode());
2308 }
2309 } // Internal Namespace
2310