Merge lp:~3v1n0/unity/application-manager-new into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Christopher Townsend
Approved revision: no longer in the source branch.
Merged at revision: 3975
Proposed branch: lp:~3v1n0/unity/application-manager-new
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/lim-everywhere
Diff against target: 2037 lines (+583/-507)
15 files modified
launcher/ApplicationLauncherIcon.cpp (+11/-11)
launcher/MockLauncherIcon.h (+1/-1)
panel/CMakeLists.txt (+1/-1)
panel/PanelMenuView.cpp (+102/-251)
panel/PanelMenuView.h (+11/-21)
tests/mock-application.h (+15/-7)
tests/test_application_launcher_icon.cpp (+5/-2)
tests/test_panel_menu_view.cpp (+1/-8)
tests/test_switcher_controller.h (+1/-1)
tests/test_switcher_controller_class.cpp (+1/-1)
unity-shared/ApplicationManager.cpp (+19/-0)
unity-shared/ApplicationManager.h (+64/-6)
unity-shared/BamfApplicationManager.cpp (+215/-145)
unity-shared/BamfApplicationManager.h (+36/-18)
unity-shared/StandaloneAppManager.cpp (+100/-34)
To merge this branch: bzr merge lp:~3v1n0/unity/application-manager-new
Reviewer Review Type Date Requested Status
Christopher Townsend Approve
PS Jenkins bot (community) continuous-integration Approve
Stephen M. Webb (community) Needs Fixing
Review via email: mp+248778@code.launchpad.net

Commit message

ApplicationManager: add missing features, keep a copy of views around

Use this in PanelMenuView, getting rid of the BAMF internal at this level.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Stephen M. Webb (bregma) wrote :

One of the commits made after this MP was reviewd and approved cause unit test failures.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

Ok, all good now.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/ApplicationLauncherIcon.cpp'
2--- launcher/ApplicationLauncherIcon.cpp 2015-03-25 14:59:04 +0000
3+++ launcher/ApplicationLauncherIcon.cpp 2015-05-22 16:04:25 +0000
4@@ -156,13 +156,14 @@
5 {
6 // Lambda functions should be fine here because when the application the icon
7 // is only ever removed when the application is closed.
8- signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindow const&) {
9+ signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindowPtr const&) {
10 EnsureWindowState();
11 UpdateIconGeometries(GetCenters());
12 }));
13
14- signals_conn_.Add(app_->window_closed.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState)));
15- signals_conn_.Add(app_->window_moved.connect(sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState))));
16+ auto ensure_windows_cb = sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
17+ signals_conn_.Add(app_->window_closed.connect(ensure_windows_cb));
18+ signals_conn_.Add(app_->window_moved.connect(ensure_windows_cb));
19
20 signals_conn_.Add(app_->urgent.changed.connect([this](bool const& urgent) {
21 LOG_DEBUG(logger) << tooltip_text() << " urgent now " << (urgent ? "true" : "false");
22@@ -235,7 +236,7 @@
23 if (!SimpleLauncherIcon::GetQuirk(Quirk::ACTIVE, monitor))
24 return false;
25
26- if (app_->type() == "webapp")
27+ if (app_->type() == AppType::WEBAPP)
28 return true;
29
30 // Sometimes BAMF is not fast enough to update the active application
31@@ -702,7 +703,7 @@
32 if (window->Focus())
33 return;
34 }
35- else if (app_->type() == "webapp")
36+ else if (app_->type() == AppType::WEBAPP)
37 {
38 // Webapps are again special.
39 OpenInstanceLauncherIcon(arg.timestamp);
40@@ -837,8 +838,6 @@
41 if (windows.size() < 2)
42 return;
43
44- Window active = WindowManager::Default().GetActiveWindow();
45-
46 // add menu items for all open windows
47 for (auto const& w : windows)
48 {
49@@ -862,7 +861,7 @@
50 wm.Raise(xid);
51 });
52
53- if (xid == active)
54+ if (w->active())
55 {
56 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_RADIO);
57 dbusmenu_menuitem_property_set_int(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
58@@ -1113,7 +1112,7 @@
59
60 void ApplicationLauncherIcon::UpdateIconGeometries(std::vector<nux::Point3> const& centers)
61 {
62- if (app_->type() == "webapp")
63+ if (app_->type() == AppType::WEBAPP)
64 return;
65
66 nux::Geometry geo(0, 0, icon_size, icon_size);
67@@ -1189,6 +1188,7 @@
68 auto const& desktop_file = DesktopFile();
69
70 return boost::algorithm::ends_with(desktop_file, "org.gnome.Nautilus.desktop") ||
71+ boost::algorithm::ends_with(desktop_file, "nautilus.desktop") ||
72 boost::algorithm::ends_with(desktop_file, "nautilus-folder-handler.desktop") ||
73 boost::algorithm::ends_with(desktop_file, "nautilus-home.desktop");
74 }
75@@ -1264,14 +1264,14 @@
76
77 bool ApplicationLauncherIcon::AllowDetailViewInSwitcher() const
78 {
79- return app_->type() != "webapp";
80+ return app_->type() != AppType::WEBAPP;
81 }
82
83 uint64_t ApplicationLauncherIcon::SwitcherPriority()
84 {
85 uint64_t result = 0;
86 // Webapps always go at the back.
87- if (app_->type() == "webapp")
88+ if (app_->type() == AppType::WEBAPP)
89 return result;
90
91 for (auto& window : app_->GetWindows())
92
93=== modified file 'launcher/MockLauncherIcon.h'
94--- launcher/MockLauncherIcon.h 2015-03-20 16:23:04 +0000
95+++ launcher/MockLauncherIcon.h 2015-05-22 16:04:25 +0000
96@@ -52,7 +52,7 @@
97 icon.SetGetterFunction([this] { return ""; });
98 }
99
100- virtual std::string type() const { return "mock"; }
101+ virtual WindowType type() const { return WindowType::UNKNOWN; }
102
103 virtual Window window_id() const { return xid_; }
104 virtual int monitor() const { return -1; }
105
106=== modified file 'panel/CMakeLists.txt'
107--- panel/CMakeLists.txt 2014-02-12 07:13:01 +0000
108+++ panel/CMakeLists.txt 2015-05-22 16:04:25 +0000
109@@ -36,4 +36,4 @@
110 #
111 add_executable (panel StandalonePanel.cpp)
112 find_library (COMPIZ_LIB compiz_core ${COMPIZ_LIBDIR})
113-target_link_libraries (panel panel-lib unity-shared unity-shared-standalone ${COMPIZ_LIB})
114+target_link_libraries (panel panel-lib unity-shared unity-shared-standalone unity-shared-bamf ${COMPIZ_LIB})
115
116=== modified file 'panel/PanelMenuView.cpp'
117--- panel/PanelMenuView.cpp 2015-02-19 14:19:44 +0000
118+++ panel/PanelMenuView.cpp 2015-05-22 16:04:25 +0000
119@@ -20,6 +20,7 @@
120
121 #include <Nux/Nux.h>
122 #include <NuxCore/Logger.h>
123+#include <UnityCore/GLibWrapper.h>
124 #include <boost/algorithm/string/erase.hpp>
125
126 #include "PanelMenuView.h"
127@@ -87,13 +88,11 @@
128 , maximized_window(0)
129 , focused(true)
130 , menu_manager_(menus)
131- , matcher_(bamf_matcher_get_default())
132 , is_inside_(false)
133 , is_grabbed_(false)
134 , is_maximized_(false)
135 , is_desktop_focused_(false)
136 , last_active_view_(nullptr)
137- , new_application_(nullptr)
138 , switcher_showing_(false)
139 , spread_showing_(false)
140 , launcher_keynav_(false)
141@@ -105,9 +104,8 @@
142 , always_show_menus_(menu_manager_->always_show_menus())
143 , desktop_name_(get_current_desktop())
144 {
145- BamfWindow* active_win = bamf_matcher_get_active_window(matcher_);
146- if (BAMF_IS_WINDOW(active_win))
147- active_window = bamf_window_get_xid(active_win);
148+ if (ApplicationWindowPtr const& win = ApplicationManager::Default().GetActiveWindow())
149+ active_window = win->window_id();
150
151 SetupWindowButtons();
152 SetupTitlebarGrabArea();
153@@ -117,8 +115,7 @@
154
155 opacity = 0.0f;
156
157- if (Refresh())
158- FullRedraw();
159+ RefreshAndRedraw();
160 }
161
162 PanelMenuView::~PanelMenuView()
163@@ -144,14 +141,11 @@
164
165 void PanelMenuView::SetupPanelMenuViewSignals()
166 {
167- active_win_changed_signal_.Connect(matcher_, "active-window-changed",
168- sigc::mem_fun(this, &PanelMenuView::OnActiveWindowChanged));
169- active_app_changed_signal_.Connect(matcher_, "active-application-changed",
170- sigc::mem_fun(this, &PanelMenuView::OnActiveAppChanged));
171- view_opened_signal_.Connect(matcher_, "view-opened",
172- sigc::mem_fun(this, &PanelMenuView::OnViewOpened));
173- view_closed_signal_.Connect(matcher_, "view-closed",
174- sigc::mem_fun(this, &PanelMenuView::OnViewClosed));
175+ auto& am = ApplicationManager::Default();
176+ am.active_window_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveWindowChanged));
177+ am.active_application_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveAppChanged));
178+ am.application_started.connect(sigc::mem_fun(this, &PanelMenuView::OnApplicationStarted));
179+ am.application_stopped.connect(sigc::mem_fun(this, &PanelMenuView::OnApplicationClosed));
180
181 mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
182 mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
183@@ -232,9 +226,9 @@
184 wm.window_resized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMoved));
185 wm.initiate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadInitiate));
186 wm.terminate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadTerminate));
187- wm.initiate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoInitiate));
188- wm.terminate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate));
189- wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate));
190+ wm.initiate_expo.connect(sigc::mem_fun(this, &PanelMenuView::RefreshAndRedraw));
191+ wm.terminate_expo.connect(sigc::mem_fun(this, &PanelMenuView::RefreshAndRedraw));
192+ wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &PanelMenuView::RefreshAndRedraw));
193 }
194
195 void PanelMenuView::SetupUBusManagerInterests()
196@@ -300,7 +294,7 @@
197 void PanelMenuView::OnLIMChanged(bool lim)
198 {
199 integrated_menus_ = lim;
200- new_application_ = nullptr;
201+ new_application_.reset();
202
203 if (!integrated_menus_)
204 {
205@@ -321,7 +315,7 @@
206 if (!always_show_menus_)
207 CheckMouseInside();
208
209- FullRedraw();
210+ QueueDraw();
211 }
212
213 nux::Area* PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
214@@ -762,41 +756,13 @@
215 std::string PanelMenuView::GetActiveViewName(bool use_appname) const
216 {
217 std::string label;
218- BamfWindow* window;
219-
220- window = bamf_matcher_get_active_window(matcher_);
221-
222- if (BAMF_IS_WINDOW(window))
223+ auto& am = ApplicationManager::Default();
224+
225+ if (ApplicationWindowPtr const& window = am.GetActiveWindow())
226 {
227- BamfView *view = reinterpret_cast<BamfView*>(window);
228- Window window_xid = bamf_window_get_xid(window);
229-
230- if (bamf_window_get_window_type(window) == BAMF_WINDOW_DOCK)
231- {
232- auto panel = const_cast<PanelMenuView*>(this)->GetTopLevelViewWindow();
233- if (static_cast<nux::BaseWindow*>(panel)->GetInputWindowId() == window_xid)
234- return desktop_name_;
235-
236- std::vector<Window> const& our_xids = nux::XInputWindow::NativeHandleList();
237-
238- if (std::find(our_xids.begin(), our_xids.end(), window_xid) != our_xids.end())
239- {
240- /* If the active window is an unity window, we need to fallback to the
241- * top one, anyway we should always avoid to focus unity internal windows */
242- BamfWindow* top_win = GetBamfWindowForXid(GetTopWindow());
243-
244- if (top_win && top_win != window)
245- {
246- window = top_win;
247- }
248- else
249- {
250- return "";
251- }
252- }
253- }
254-
255- if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
256+ Window window_xid = window->window_id();
257+
258+ if (window->type() == WindowType::DESKTOP)
259 {
260 label = desktop_name_;
261 }
262@@ -806,27 +772,16 @@
263 }
264
265 if (WindowManager::Default().IsWindowMaximized(window_xid) && !use_appname)
266- {
267- label = glib::String(bamf_view_get_name(view)).Str();
268- }
269-
270- if (label.empty())
271- {
272- BamfApplication* app;
273- app = bamf_matcher_get_application_for_window(matcher_, window);
274-
275- if (BAMF_IS_APPLICATION(app))
276- {
277- view = reinterpret_cast<BamfView*>(app);
278- label = glib::String(bamf_view_get_name(view)).Str();
279- }
280- }
281-
282- if (label.empty())
283- {
284- view = reinterpret_cast<BamfView*>(window);
285- label = glib::String(bamf_view_get_name(view)).Str();
286- }
287+ label = window->title();
288+
289+ if (label.empty())
290+ {
291+ if (ApplicationPtr const& app = am.GetActiveApplication())
292+ label = app->title();
293+ }
294+
295+ if (label.empty())
296+ label = window->title();
297 }
298
299 return label;
300@@ -835,24 +790,16 @@
301 std::string PanelMenuView::GetMaximizedViewName(bool use_appname) const
302 {
303 Window maximized = maximized_window();
304- BamfWindow* window = nullptr;
305 std::string label;
306
307- window = GetBamfWindowForXid(maximized);
308-
309- if (BAMF_IS_WINDOW(window))
310+ if (ApplicationWindowPtr const& window = ApplicationManager::Default().GetWindowForId(maximized))
311 {
312- BamfView* view = reinterpret_cast<BamfView*>(window);
313- label = glib::String(bamf_view_get_name(view)).Str();
314+ label = window->title();
315
316 if (use_appname || label.empty())
317 {
318- BamfApplication* app = bamf_matcher_get_application_for_window(matcher_, window);
319-
320- if (BAMF_IS_APPLICATION(app))
321- view = reinterpret_cast<BamfView*>(app);
322-
323- label = glib::String(bamf_view_get_name(view)).Str();
324+ if (ApplicationPtr const& app = window->application())
325+ label = app->title();
326 }
327 }
328
329@@ -963,6 +910,12 @@
330 return true;
331 }
332
333+void PanelMenuView::RefreshAndRedraw()
334+{
335+ if (Refresh())
336+ QueueDraw();
337+}
338+
339 void PanelMenuView::OnActiveChanged(PanelIndicatorEntryView* view, bool is_active)
340 {
341 if (is_active)
342@@ -977,8 +930,7 @@
343 }
344 }
345
346- if (Refresh())
347- FullRedraw();
348+ RefreshAndRedraw();
349 }
350
351 void PanelMenuView::OnEntryAdded(indicator::Entry::Ptr const& entry)
352@@ -1012,22 +964,13 @@
353 }
354 }
355
356-void PanelMenuView::OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name)
357-{
358- if (Refresh())
359- FullRedraw();
360-}
361-
362 bool PanelMenuView::OnNewAppShow()
363 {
364- BamfApplication* active_app = bamf_matcher_get_active_application(matcher_);
365- new_application_ = glib::Object<BamfApplication>(active_app, glib::AddRef());
366+ new_application_ = ApplicationManager::Default().GetActiveApplication();
367 QueueDraw();
368
369 if (sources_.GetSource(NEW_APP_HIDE_TIMEOUT))
370- {
371 new_app_menu_shown_ = false;
372- }
373
374 auto cb_func = sigc::mem_fun(this, &PanelMenuView::OnNewAppHide);
375 sources_.AddTimeoutSeconds(menu_manager_->discovery(), cb_func, NEW_APP_HIDE_TIMEOUT);
376@@ -1044,69 +987,51 @@
377 return false;
378 }
379
380-void PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view)
381+void PanelMenuView::OnApplicationStarted(ApplicationPtr const& app)
382 {
383 /* FIXME: here we should also check for if the view is also user_visible
384 * but it seems that BAMF doesn't handle this correctly after some
385 * stress tests (repeated launches). */
386- if (!BAMF_IS_APPLICATION(view) || integrated_menus_)
387+ if (integrated_menus_)
388 return;
389
390- new_apps_.push_front(glib::Object<BamfApplication>(BAMF_APPLICATION(view), glib::AddRef()));
391+ new_apps_.push_front(app);
392 }
393
394-void PanelMenuView::OnApplicationClosed(BamfApplication* app)
395+void PanelMenuView::OnApplicationClosed(ApplicationPtr const& app)
396 {
397- if (BAMF_IS_APPLICATION(app) && !integrated_menus_)
398+ if (app && !integrated_menus_)
399 {
400 if (std::find(new_apps_.begin(), new_apps_.end(), app) != new_apps_.end())
401 {
402- new_apps_.remove(glib::Object<BamfApplication>(app, glib::AddRef()));
403+ new_apps_.remove(app);
404 }
405 else if (new_apps_.empty())
406 {
407- new_application_ = nullptr;
408+ new_application_.reset();
409 }
410 }
411
412 if (app == new_application_)
413 {
414- new_application_ = nullptr;
415- }
416-}
417-
418-void PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view)
419-{
420- if (reinterpret_cast<BamfView*>(view_name_changed_signal_.object()) == view)
421- {
422- view_name_changed_signal_.Disconnect();
423- }
424-
425- if (BAMF_IS_APPLICATION(view))
426- {
427- OnApplicationClosed(reinterpret_cast<BamfApplication*>(view));
428- }
429- else if (reinterpret_cast<BamfApplication*>(view) == new_application_)
430- {
431- new_application_ = nullptr;
432- }
433- else if (BAMF_IS_WINDOW(view))
434- {
435- /* FIXME, this can be removed when window_unmapped WindowManager signal
436- * will emit the proper xid */
437- Window xid = bamf_window_get_xid(reinterpret_cast<BamfWindow*>(view));
438- OnWindowUnmapped(xid);
439- }
440-}
441-
442-void PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher,
443- BamfApplication* old_app,
444- BamfApplication* new_app)
445-{
446- if (BAMF_IS_APPLICATION(new_app))
447- {
448- app_name_changed_signal_.Connect(BAMF_VIEW(new_app), "name-changed",
449- sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
450+ new_application_.reset();
451+ }
452+}
453+
454+void PanelMenuView::OnWindowClosed(ApplicationWindowPtr const& win)
455+{
456+ /* FIXME, this can be removed when window_unmapped WindowManager signal
457+ * will emit the proper xid */
458+ OnWindowUnmapped(win->window_id());
459+}
460+
461+void PanelMenuView::OnActiveAppChanged(ApplicationPtr const& new_app)
462+{
463+ if (new_app)
464+ {
465+ app_name_changed_conn_ = new_app->title.changed.connect([this] (std::string const&t) {
466+ RefreshAndRedraw();
467+ });
468
469 if (integrated_menus_ || always_show_menus_)
470 return;
471@@ -1140,7 +1065,7 @@
472 }
473 }
474
475-void PanelMenuView::OnActiveWindowChanged(BamfMatcher *matcher, BamfView* old_view, BamfView* new_view)
476+void PanelMenuView::OnActiveWindowChanged(ApplicationWindowPtr const& new_win)
477 {
478 show_now_activated_ = false;
479 is_maximized_ = false;
480@@ -1149,13 +1074,12 @@
481
482 sources_.Remove(WINDOW_MOVED_TIMEOUT);
483
484- if (BAMF_IS_WINDOW(new_view))
485+ if (new_win)
486 {
487- BamfWindow* window = reinterpret_cast<BamfWindow*>(new_view);
488- active_xid = bamf_window_get_xid(window);
489- is_maximized_ = (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED);
490+ active_xid = new_win->window_id();
491+ is_maximized_ = new_win->maximized();
492
493- if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
494+ if (new_win->type() == WindowType::DESKTOP)
495 {
496 is_desktop_focused_ = !maximized_window();
497 we_control_active_ = true;
498@@ -1173,14 +1097,13 @@
499 }
500
501 // register callback for new view
502- view_name_changed_signal_.Connect(new_view, "name-changed",
503- sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
504+ win_name_changed_conn_ = new_win->title.changed.connect([this] (std::string const& t) {
505+ RefreshAndRedraw();
506+ });
507 }
508
509 active_window = active_xid;
510-
511- if (Refresh())
512- FullRedraw();
513+ RefreshAndRedraw();
514 }
515
516 void PanelMenuView::OnSpreadInitiate()
517@@ -1195,18 +1118,6 @@
518 QueueDraw();
519 }
520
521-void PanelMenuView::OnExpoInitiate()
522-{
523- if (Refresh())
524- QueueDraw();
525-}
526-
527-void PanelMenuView::OnExpoTerminate()
528-{
529- if (Refresh())
530- QueueDraw();
531-}
532-
533 void PanelMenuView::OnWindowMinimized(Window xid)
534 {
535 maximized_wins_.erase(std::remove(maximized_wins_.begin(), maximized_wins_.end(), xid), maximized_wins_.end());
536@@ -1214,13 +1125,11 @@
537
538 if (xid == active_window())
539 {
540- if (Refresh())
541- QueueDraw();
542+ RefreshAndRedraw();
543 }
544 else if (integrated_menus_ && window_buttons_->controlled_window == xid)
545 {
546- if (Refresh())
547- QueueDraw();
548+ RefreshAndRedraw();
549 }
550 }
551
552@@ -1234,8 +1143,7 @@
553 UpdateMaximizedWindow();
554 }
555
556- if (Refresh())
557- QueueDraw();
558+ RefreshAndRedraw();
559 }
560 else
561 {
562@@ -1247,8 +1155,7 @@
563
564 if (integrated_menus_ && IsWindowUnderOurControl(xid))
565 {
566- if (Refresh())
567- QueueDraw();
568+ RefreshAndRedraw();
569 }
570 }
571 }
572@@ -1262,13 +1169,11 @@
573
574 if (xid == active_window())
575 {
576- if (Refresh())
577- QueueDraw();
578+ RefreshAndRedraw();
579 }
580 else if (integrated_menus_ && window_buttons_->controlled_window == xid)
581 {
582- if (Refresh())
583- QueueDraw();
584+ RefreshAndRedraw();
585 }
586 }
587
588@@ -1281,8 +1186,7 @@
589 maximized_wins_.push_front(xid);
590 UpdateMaximizedWindow();
591
592- if (Refresh())
593- QueueDraw();
594+ RefreshAndRedraw();
595 }
596 else
597 {
598@@ -1303,8 +1207,7 @@
599 CheckMouseInside();
600 is_maximized_ = true;
601
602- if (Refresh())
603- FullRedraw();
604+ RefreshAndRedraw();
605 }
606 else
607 {
608@@ -1313,8 +1216,7 @@
609
610 if (integrated_menus_ && IsWindowUnderOurControl(xid))
611 {
612- if (Refresh())
613- QueueDraw();
614+ RefreshAndRedraw();
615 }
616 }
617 }
618@@ -1328,14 +1230,11 @@
619 {
620 is_maximized_ = false;
621 is_grabbed_ = false;
622-
623- if (Refresh())
624- FullRedraw();
625+ RefreshAndRedraw();
626 }
627 else if (integrated_menus_ && window_buttons_->controlled_window == xid)
628 {
629- if (Refresh())
630- QueueDraw();
631+ RefreshAndRedraw();
632 }
633 }
634
635@@ -1350,8 +1249,7 @@
636 if (HasVisibleMenus())
637 on_indicator_updated.emit();
638
639- if (Refresh())
640- QueueDraw();
641+ RefreshAndRedraw();
642 }
643
644 return false;
645@@ -1436,55 +1334,20 @@
646 Window PanelMenuView::GetTopWindow() const
647 {
648 Window window_xid = 0;
649- GList* windows = bamf_matcher_get_window_stack_for_monitor(matcher_, monitor_);
650
651- for (GList* l = windows; l; l = l->next)
652+ for (auto const& win : ApplicationManager::Default().GetWindowsForMonitor(monitor_))
653 {
654- if (!BAMF_IS_WINDOW(l->data))
655- continue;
656-
657- Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data));
658- bool visible = bamf_view_is_user_visible(static_cast<BamfView*>(l->data));
659-
660- if (visible && IsValidWindow(xid))
661+ Window xid = win->window_id();
662+
663+ if (win->visible() && IsValidWindow(xid))
664 {
665 window_xid = xid;
666 }
667 }
668
669- g_list_free(windows);
670-
671 return window_xid;
672 }
673
674-BamfWindow* PanelMenuView::GetBamfWindowForXid(Window xid) const
675-{
676- BamfWindow* window = nullptr;
677-
678- if (xid != 0)
679- {
680- GList* windows = bamf_matcher_get_windows(matcher_);
681-
682- for (GList* l = windows; l; l = l->next)
683- {
684- if (!BAMF_IS_WINDOW(l->data))
685- continue;
686-
687- auto win = static_cast<BamfWindow*>(l->data);
688-
689- if (bamf_window_get_xid(win) == xid)
690- {
691- window = win;
692- break;
693- }
694- }
695-
696- g_list_free(windows);
697- }
698-
699- return window;
700-}
701-
702 void PanelMenuView::ActivateIntegratedMenus(nux::Point const& click)
703 {
704 if (!layout_->GetAbsoluteGeometry().IsInside(click))
705@@ -1679,8 +1542,7 @@
706
707 is_inside_ = true;
708 is_grabbed_ = true;
709- if (Refresh())
710- FullRedraw();
711+ RefreshAndRedraw();
712
713 /* Ungrab the pointer and start the X move, to make the decorator handle it */
714 titlebar_grab_area_->SetGrabbed(false);
715@@ -1700,8 +1562,7 @@
716 if (!is_inside_)
717 is_grabbed_ = false;
718
719- if (Refresh())
720- FullRedraw();
721+ RefreshAndRedraw();
722 }
723
724 // Introspectable
725@@ -1763,8 +1624,7 @@
726 show_now_activated_ = false;
727 }
728
729- if (Refresh())
730- QueueDraw();
731+ RefreshAndRedraw();
732 }
733
734 void PanelMenuView::OnLauncherKeyNavStarted(GVariant* data)
735@@ -1785,9 +1645,7 @@
736
737 launcher_keynav_ = false;
738 CheckMouseInside();
739-
740- if (Refresh())
741- QueueDraw();
742+ RefreshAndRedraw();
743 }
744
745 void PanelMenuView::OnLauncherSelectionChanged(GVariant* data)
746@@ -1854,23 +1712,17 @@
747
748 maximized_wins_.clear();
749 monitor_geo_ = UScreen::GetDefault()->GetMonitorGeometry(monitor_);
750- GList* windows = bamf_matcher_get_window_stack_for_monitor(matcher_, monitor_);
751
752- for (GList* l = windows; l; l = l->next)
753+ for (auto const& win : ApplicationManager::Default().GetWindowsForMonitor(monitor_))
754 {
755- if (!BAMF_IS_WINDOW(l->data))
756- continue;
757-
758- auto window = static_cast<BamfWindow*>(l->data);
759- auto view = static_cast<BamfView*>(l->data);
760- auto xid = bamf_window_get_xid(window);
761-
762- if (bamf_view_is_active(view))
763+ auto xid = win->window_id();
764+
765+ if (win->active())
766 active_window = xid;
767
768- if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED)
769+ if (win->maximized())
770 {
771- if (xid == active_window())
772+ if (win->active())
773 maximized_wins_.push_front(xid);
774 else
775 maximized_wins_.push_back(xid);
776@@ -1881,7 +1733,6 @@
777 UpdateMaximizedWindow();
778
779 OnStyleChanged();
780- g_list_free(windows);
781 }
782
783 bool PanelMenuView::HasMenus() const
784
785=== modified file 'panel/PanelMenuView.h'
786--- panel/PanelMenuView.h 2015-02-04 09:54:49 +0000
787+++ panel/PanelMenuView.h 2015-05-22 16:04:25 +0000
788@@ -22,12 +22,11 @@
789 #define PANEL_MENU_VIEW_H
790
791 #include <NuxCore/Animation.h>
792-#include <UnityCore/GLibWrapper.h>
793 #include <UnityCore/GLibSignal.h>
794-#include <libbamf/libbamf.h>
795
796 #include "PanelIndicatorsView.h"
797 #include "PanelTitlebarGrabAreaView.h"
798+#include "unity-shared/ApplicationManager.h"
799 #include "unity-shared/MenuManager.h"
800 #include "unity-shared/StaticCairoText.h"
801 #include "unity-shared/WindowButtons.h"
802@@ -88,20 +87,17 @@
803
804 void OnActiveChanged(PanelIndicatorEntryView* view, bool is_active);
805 void OnEntryViewAdded(PanelIndicatorEntryView* view);
806- void OnViewOpened(BamfMatcher* matcher, BamfView* view);
807- void OnViewClosed(BamfMatcher* matcher, BamfView* view);
808- void OnApplicationClosed(BamfApplication* app);
809- void OnActiveWindowChanged(BamfMatcher* matcher, BamfView* old_view, BamfView* new_view);
810- void OnActiveAppChanged(BamfMatcher* matcher, BamfApplication* old_app, BamfApplication* new_app);
811- void OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name);
812+ void OnApplicationStarted(ApplicationPtr const&);
813+ void OnApplicationClosed(ApplicationPtr const&);
814+ void OnWindowClosed(ApplicationWindowPtr const&);
815+ void OnActiveWindowChanged(ApplicationWindowPtr const&);
816+ void OnActiveAppChanged(ApplicationPtr const&);
817 void OnStyleChanged();
818 void OnLIMChanged(bool);
819 void OnAlwaysShowMenusChanged(bool);
820
821 void OnSpreadInitiate();
822 void OnSpreadTerminate();
823- void OnExpoInitiate();
824- void OnExpoTerminate();
825 void OnWindowMinimized(Window xid);
826 void OnWindowUnminimized(Window xid);
827 void OnWindowUnmapped(Window xid);
828@@ -122,6 +118,7 @@
829 void FullRedraw();
830 std::string GetCurrentTitle() const;
831 bool Refresh(bool force = false);
832+ void RefreshAndRedraw();
833
834 void UpdateTitleTexture(nux::Geometry const&, std::string const& label);
835 void UpdateLastGeometry(nux::Geometry const& geo);
836@@ -131,8 +128,6 @@
837 void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
838 void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
839
840- BamfWindow* GetBamfWindowForXid(Window xid) const;
841-
842 void OnSwitcherShown(GVariant* data);
843 void OnLauncherKeyNavStarted(GVariant* data);
844 void OnLauncherKeyNavEnded(GVariant* data);
845@@ -164,7 +159,6 @@
846 void ActivateIntegratedMenus(nux::Point const&);
847
848 menu::Manager::Ptr menu_manager_;
849- glib::Object<BamfMatcher> matcher_;
850
851 nux::TextureLayer* title_layer_;
852 nux::ObjectPtr<WindowButtons> window_buttons_;
853@@ -179,8 +173,8 @@
854
855 PanelIndicatorEntryView* last_active_view_;
856 std::deque<Window> maximized_wins_;
857- glib::Object<BamfApplication> new_application_;
858- std::list<glib::Object<BamfApplication>> new_apps_;
859+ ApplicationPtr new_application_;
860+ std::list<ApplicationPtr> new_apps_;
861 std::string panel_title_;
862 nux::Geometry last_geo_;
863 nux::Geometry title_geo_;
864@@ -198,12 +192,8 @@
865 nux::Geometry monitor_geo_;
866 const std::string desktop_name_;
867
868- glib::Signal<void, BamfMatcher*, BamfView*> view_opened_signal_;
869- glib::Signal<void, BamfMatcher*, BamfView*> view_closed_signal_;
870- glib::Signal<void, BamfMatcher*, BamfView*, BamfView*> active_win_changed_signal_;
871- glib::Signal<void, BamfMatcher*, BamfApplication*, BamfApplication*> active_app_changed_signal_;
872- glib::Signal<void, BamfView*, gchar*, gchar*> view_name_changed_signal_;
873- glib::Signal<void, BamfView*, gchar*, gchar*> app_name_changed_signal_;
874+ connection::Wrapper app_name_changed_conn_;
875+ connection::Wrapper win_name_changed_conn_;
876
877 UBusManager ubus_manager_;
878 glib::SourceManager sources_;
879
880=== modified file 'tests/mock-application.h'
881--- tests/mock-application.h 2015-02-03 09:46:48 +0000
882+++ tests/mock-application.h 2015-05-22 16:04:25 +0000
883@@ -40,8 +40,8 @@
884 MockApplicationWindow(Window xid)
885 : xid_(xid)
886 , monitor_(0)
887+ , type_(unity::WindowType::MOCK)
888 , title_("MockApplicationWindow "+std::to_string(xid_))
889- , type_("window")
890 , visible_(true)
891 , active_(false)
892 , urgent_(false)
893@@ -61,26 +61,28 @@
894
895 Window xid_;
896 int monitor_;
897+ unity::WindowType type_;
898 std::string title_;
899 std::string icon_;
900- std::string type_;
901
902 bool visible_;
903 bool active_;
904 bool urgent_;
905
906- MOCK_CONST_METHOD0(type, std::string());
907+ MOCK_CONST_METHOD0(type, unity::WindowType());
908 MOCK_CONST_METHOD0(window_id, Window());
909 MOCK_CONST_METHOD0(monitor, int());
910 MOCK_CONST_METHOD0(application, unity::ApplicationPtr());
911 MOCK_CONST_METHOD0(Focus, bool());
912 MOCK_CONST_METHOD0(Quit, void());
913
914- virtual bool LocalFocus() const
915+ bool LocalFocus()
916 {
917 auto& wm = unity::WindowManager::Default();
918 wm.Raise(xid_);
919 wm.Activate(xid_);
920+ active_ = true;
921+ active.changed.emit(active_);
922 return true;
923 }
924
925@@ -124,7 +126,7 @@
926 , active_(false)
927 , running_(false)
928 , urgent_(false)
929- , type_("mock")
930+ , type_(unity::AppType::MOCK)
931 {
932 seen.SetSetterFunction(sigc::mem_fun(this, &MockApplication::SetSeen));
933 sticky.SetSetterFunction(sigc::mem_fun(this, &MockApplication::SetSticky));
934@@ -159,10 +161,10 @@
935 bool running_;
936 bool urgent_;
937 unity::WindowList windows_;
938- std::string type_;
939+ unity::AppType type_;
940 std::vector<std::pair<unity::ApplicationEventType, unity::ApplicationSubjectPtr>> actions_log_;
941
942- MOCK_CONST_METHOD0(type, std::string());
943+ MOCK_CONST_METHOD0(type, unity::AppType());
944 MOCK_CONST_METHOD0(repr, std::string());
945 MOCK_CONST_METHOD0(desktop_id, std::string());
946 MOCK_CONST_METHOD0(GetWindows, unity::WindowList());
947@@ -306,6 +308,9 @@
948 ON_CALL(*this, GetActiveWindow()).WillByDefault(Invoke([this] { return unity::ApplicationWindowPtr(); } ));
949 ON_CALL(*this, GetRunningApplications()).WillByDefault(Invoke([this] { return unity::ApplicationList(); } ));
950 ON_CALL(*this, GetApplicationForWindow(_)).WillByDefault(Invoke([this] (Window) { return unity::ApplicationPtr(); } ));
951+ ON_CALL(*this, GetActiveApplication()).WillByDefault(Invoke([this] { return unity::ApplicationPtr(); } ));
952+ ON_CALL(*this, GetWindowsForMonitor(_)).WillByDefault(Invoke([this] (Window) { return unity::WindowList(); } ));
953+ ON_CALL(*this, GetWindowForId(_)).WillByDefault(Invoke([this] (int) { return unity::ApplicationWindowPtr(); } ));
954 }
955
956 static void StartApp(std::string const& desktop_file)
957@@ -322,6 +327,9 @@
958 MOCK_CONST_METHOD1(GetApplicationForDesktopFile, unity::ApplicationPtr(std::string const&));
959 MOCK_CONST_METHOD0(GetRunningApplications, unity::ApplicationList());
960 MOCK_CONST_METHOD1(GetApplicationForWindow, unity::ApplicationPtr(Window));
961+ MOCK_CONST_METHOD0(GetActiveApplication, unity::ApplicationPtr());
962+ MOCK_CONST_METHOD1(GetWindowsForMonitor, unity::WindowList(int));
963+ MOCK_CONST_METHOD1(GetWindowForId, unity::ApplicationWindowPtr(Window));
964
965 unity::ApplicationPtr LocalGetApplicationForDesktopFile(std::string const& desktop_file)
966 {
967
968=== modified file 'tests/test_application_launcher_icon.cpp'
969--- tests/test_application_launcher_icon.cpp 2015-03-30 15:48:38 +0000
970+++ tests/test_application_launcher_icon.cpp 2015-05-22 16:04:25 +0000
971@@ -775,7 +775,10 @@
972 mock_app->windows_ = { win1, win2 };
973 WM->AddStandaloneWindow(wm_win1);
974 WM->AddStandaloneWindow(wm_win2);
975+
976+ win2->Focus();
977 ASSERT_TRUE(wm_win2->active());
978+ ASSERT_TRUE(win2->active());
979
980 auto const& menus = mock_icon->Menus();
981 auto const& menu1 = GetMenuItemWithLabel(menus, win1->title());
982@@ -1121,10 +1124,10 @@
983
984 TEST_F(TestApplicationLauncherIcon, AllowDetailViewInSwitcher)
985 {
986- mock_app->type_ = "mock";
987+ mock_app->type_ = AppType::NORMAL;
988 EXPECT_TRUE(mock_icon->AllowDetailViewInSwitcher());
989
990- mock_app->type_ = "webapp";
991+ mock_app->type_ = AppType::WEBAPP;
992 EXPECT_FALSE(mock_icon->AllowDetailViewInSwitcher());
993 }
994
995
996=== modified file 'tests/test_panel_menu_view.cpp'
997--- tests/test_panel_menu_view.cpp 2015-03-13 13:49:16 +0000
998+++ tests/test_panel_menu_view.cpp 2015-05-22 16:04:25 +0000
999@@ -45,13 +45,7 @@
1000 {
1001 MockPanelMenuView(menu::Manager::Ptr const& menu_manager)
1002 : PanelMenuView(menu_manager)
1003- {
1004- view_opened_signal_.Disconnect();
1005- active_win_changed_signal_.Disconnect();
1006- active_app_changed_signal_.Disconnect();
1007- view_closed_signal_.Disconnect();
1008- maximized_wins_.clear();
1009- }
1010+ {}
1011
1012 MOCK_METHOD0(QueueDraw, void());
1013 MOCK_CONST_METHOD1(GetActiveViewName, std::string(bool));
1014@@ -81,7 +75,6 @@
1015 panel_win->ComputeContentSize();
1016
1017 menu_view.SetMonitor(monitor);
1018- menu_view.maximized_wins_.clear();
1019
1020 return panel_win;
1021 }
1022
1023=== modified file 'tests/test_switcher_controller.h'
1024--- tests/test_switcher_controller.h 2014-03-21 04:40:12 +0000
1025+++ tests/test_switcher_controller.h 2015-05-22 16:04:25 +0000
1026@@ -54,7 +54,7 @@
1027 FakeApplicationWindow(Window xid, uint64_t active_number = 0);
1028 ~FakeApplicationWindow();
1029
1030- virtual std::string type() const;
1031+ virtual WindowType type() const;
1032
1033 virtual Window window_id() const;
1034 virtual int monitor() const;
1035
1036=== modified file 'tests/test_switcher_controller_class.cpp'
1037--- tests/test_switcher_controller_class.cpp 2013-10-14 17:36:51 +0000
1038+++ tests/test_switcher_controller_class.cpp 2015-05-22 16:04:25 +0000
1039@@ -41,7 +41,7 @@
1040 testwrapper::StandaloneWM::Get()->Close(xid_);
1041 }
1042
1043-std::string FakeApplicationWindow::type() const { return "mock"; }
1044+WindowType FakeApplicationWindow::type() const { return WindowType::MOCK; }
1045
1046 Window FakeApplicationWindow::window_id() const { return xid_; }
1047 int FakeApplicationWindow::monitor() const { return -1; }
1048
1049=== modified file 'unity-shared/ApplicationManager.cpp'
1050--- unity-shared/ApplicationManager.cpp 2012-11-29 09:25:50 +0000
1051+++ unity-shared/ApplicationManager.cpp 2015-05-22 16:04:25 +0000
1052@@ -33,6 +33,25 @@
1053 return *instance;
1054 }
1055
1056+bool operator==(ApplicationPtr const& lhs, ApplicationPtr const& rhs)
1057+{
1058+ return (lhs.get() == rhs.get() || (lhs && rhs && *lhs == *rhs));
1059+}
1060+
1061+bool operator!=(ApplicationPtr const& lhs, ApplicationPtr const& rhs)
1062+{
1063+ return !(lhs == rhs);
1064+}
1065+
1066+bool operator==(ApplicationWindowPtr const& lhs, ApplicationWindowPtr const& rhs)
1067+{
1068+ return (lhs.get() == rhs.get() || (lhs && rhs && *lhs == *rhs));
1069+}
1070+
1071+bool operator!=(ApplicationWindowPtr const& lhs, ApplicationWindowPtr const& rhs)
1072+{
1073+ return !(lhs == rhs);
1074+}
1075
1076 // This method is needed to create an unresolved external for the
1077 // WindowManager::Default method. This is because it is highly likely that
1078
1079=== modified file 'unity-shared/ApplicationManager.h'
1080--- unity-shared/ApplicationManager.h 2013-09-11 09:11:30 +0000
1081+++ unity-shared/ApplicationManager.h 2015-05-22 16:04:25 +0000
1082@@ -50,13 +50,35 @@
1083 LEAVE
1084 };
1085
1086+enum class AppType
1087+{
1088+ NORMAL,
1089+ WEBAPP,
1090+ MOCK,
1091+ UNKNOWN
1092+};
1093+
1094+enum class WindowType
1095+{
1096+ NORMAL,
1097+ DESKTOP,
1098+ DOCK,
1099+ DIALOG,
1100+ TOOLBAR,
1101+ MENU,
1102+ UTILITY,
1103+ SPLASHSCREEN,
1104+ TAB,
1105+ MOCK,
1106+ UNKNOWN
1107+};
1108+
1109 class ApplicationWindow
1110 {
1111 public:
1112 virtual ~ApplicationWindow() = default;
1113
1114- virtual std::string type() const = 0; // 'window' or 'tab'
1115-
1116+ virtual WindowType type() const = 0;
1117 virtual Window window_id() const = 0;
1118 virtual int monitor() const = 0;
1119
1120@@ -69,20 +91,32 @@
1121 // Closes the window, or the browser tab if a webapp.
1122 virtual void Quit() const = 0;
1123
1124+ virtual bool operator==(ApplicationWindow const& other) const
1125+ {
1126+ return (window_id() == other.window_id());
1127+ }
1128+
1129+ virtual bool operator!=(ApplicationWindow const& other) const
1130+ {
1131+ return !(operator==(other));
1132+ }
1133+
1134 nux::ROProperty<std::string> title;
1135 nux::ROProperty<std::string> icon;
1136
1137 nux::ROProperty<bool> visible;
1138 nux::ROProperty<bool> active;
1139 nux::ROProperty<bool> urgent;
1140+ nux::ROProperty<bool> maximized;
1141 };
1142
1143+
1144 class Application
1145 {
1146 public:
1147 virtual ~Application() = default;
1148
1149- virtual std::string type() const = 0;
1150+ virtual AppType type() const = 0;
1151
1152 // A string representation of the object.
1153 virtual std::string repr() const = 0;
1154@@ -102,6 +136,17 @@
1155 virtual void LogEvent(ApplicationEventType, ApplicationSubjectPtr const&) const = 0;
1156
1157 virtual std::string desktop_id() const = 0;
1158+
1159+ virtual bool operator==(Application const& other) const
1160+ {
1161+ return (!desktop_id().empty() && (desktop_id() == other.desktop_id()));
1162+ }
1163+
1164+ virtual bool operator!=(Application const& other) const
1165+ {
1166+ return !(operator==(other));
1167+ }
1168+
1169 nux::ROProperty<std::string> desktop_file;
1170 nux::ROProperty<std::string> title;
1171 nux::ROProperty<std::string> icon;
1172@@ -117,11 +162,12 @@
1173
1174 sigc::signal<void> closed;
1175
1176- sigc::signal<void, ApplicationWindow const&> window_opened;
1177- sigc::signal<void, ApplicationWindow const&> window_moved;
1178- sigc::signal<void> window_closed;
1179+ sigc::signal<void, ApplicationWindowPtr const&> window_opened;
1180+ sigc::signal<void, ApplicationWindowPtr const&> window_moved;
1181+ sigc::signal<void, ApplicationWindowPtr const&> window_closed;
1182 };
1183
1184+
1185 class ApplicationSubject
1186 {
1187 public:
1188@@ -165,16 +211,28 @@
1189 static ApplicationManager& Default();
1190
1191 virtual ApplicationPtr GetUnityApplication() const = 0;
1192+ virtual ApplicationPtr GetActiveApplication() const = 0;
1193 virtual ApplicationWindowPtr GetActiveWindow() const = 0;
1194 virtual ApplicationPtr GetApplicationForDesktopFile(std::string const& desktop_file) const = 0;
1195 virtual ApplicationList GetRunningApplications() const = 0;
1196+ virtual WindowList GetWindowsForMonitor(int monitor = -1) const = 0;
1197 virtual ApplicationPtr GetApplicationForWindow(Window xid) const = 0;
1198+ virtual ApplicationWindowPtr GetWindowForId(Window xid) const = 0;
1199
1200 sigc::signal<void, ApplicationPtr const&> application_started;
1201+ sigc::signal<void, ApplicationPtr const&> application_stopped;
1202 sigc::signal<void, ApplicationPtr const&> active_application_changed;
1203+ sigc::signal<void, ApplicationWindowPtr const&> window_opened;
1204+ sigc::signal<void, ApplicationWindowPtr const&> window_closed;
1205 sigc::signal<void, ApplicationWindowPtr const&> active_window_changed;
1206 };
1207
1208+
1209+bool operator==(ApplicationPtr const&, ApplicationPtr const&);
1210+bool operator!=(ApplicationPtr const&, ApplicationPtr const&);
1211+bool operator==(ApplicationWindowPtr const&, ApplicationWindowPtr const&);
1212+bool operator!=(ApplicationWindowPtr const&, ApplicationWindowPtr const&);
1213+
1214 }
1215
1216 #endif // UNITYSHARED_APPLICATION_MANAGER_H
1217
1218=== modified file 'unity-shared/BamfApplicationManager.cpp'
1219--- unity-shared/BamfApplicationManager.cpp 2013-10-03 22:39:01 +0000
1220+++ unity-shared/BamfApplicationManager.cpp 2015-05-22 16:04:25 +0000
1221@@ -34,7 +34,47 @@
1222 namespace
1223 {
1224 const char* UNSEEN_QUARK = "unity-unseen";
1225-}
1226+
1227+namespace pool
1228+{
1229+// We keep a cache on views here, it would be nice to clean these on BAMF reload
1230+std::unordered_map<BamfView*, ApplicationPtr> apps_;
1231+std::unordered_map<BamfView*, ApplicationWindowPtr> wins_;
1232+
1233+ApplicationPtr EnsureApplication(ApplicationManager const& manager, BamfView* view)
1234+{
1235+ if (!BAMF_IS_APPLICATION(view))
1236+ return nullptr;
1237+
1238+ auto it = apps_.find(view);
1239+
1240+ if (it != apps_.end())
1241+ return it->second;
1242+
1243+ glib::Object<BamfApplication> bamfapp(reinterpret_cast<BamfApplication*>(view), glib::AddRef());
1244+ auto const& app = std::make_shared<Application>(manager, bamfapp);
1245+ apps_.insert({view, app});
1246+ return app;
1247+}
1248+
1249+ApplicationWindowPtr EnsureWindow(ApplicationManager const& manager, BamfView* view)
1250+{
1251+ if (!BAMF_IS_WINDOW(view))
1252+ return nullptr;
1253+
1254+ auto it = wins_.find(view);
1255+
1256+ if (it != wins_.end())
1257+ return it->second;
1258+
1259+ glib::Object<BamfWindow> bamfwin(reinterpret_cast<BamfWindow*>(view), glib::AddRef());
1260+ auto const& win = std::make_shared<AppWindow>(manager, bamfwin);
1261+ wins_.insert({view, win});
1262+ return win;
1263+}
1264+
1265+} // pool namespace
1266+} // anonymous namespace
1267
1268
1269 // Due to the way glib handles object inheritance, we need to cast between pointer types.
1270@@ -54,11 +94,6 @@
1271 return glib::String(bamf_view_get_icon(bamf_view_)).Str();
1272 }
1273
1274-std::string View::type() const
1275-{
1276- return glib::gchar_to_string(bamf_view_get_view_type(bamf_view_));
1277-}
1278-
1279 bool View::GetVisible() const
1280 {
1281 return bamf_view_is_user_visible(bamf_view_);
1282@@ -80,11 +115,6 @@
1283 }
1284
1285
1286-std::string WindowBase::type() const
1287-{
1288- return View::type();
1289-}
1290-
1291 WindowBase::WindowBase(ApplicationManager const& manager,
1292 glib::Object<BamfView> const& window)
1293 : View(manager, window)
1294@@ -122,13 +152,10 @@
1295 Window xid = window_id();
1296 if (xid)
1297 {
1298- std::vector<Window> windows = { xid };
1299- // TODO: we should simplify the use case of focusing one window.
1300- // Somewhat outside the scope of these changes however.
1301- WindowManager::Default().FocusWindowGroup(
1302- windows,
1303- WindowManager::FocusVisibility::ForceUnminimizeInvisible,
1304- monitor(),true);
1305+ auto& wm = WindowManager::Default();
1306+ wm.UnMinimize(xid);
1307+ wm.Raise(xid);
1308+ wm.Activate(xid);
1309 return true;
1310 }
1311 return false;
1312@@ -136,14 +163,25 @@
1313
1314
1315 AppWindow::AppWindow(ApplicationManager const& manager, glib::Object<BamfWindow> const& window)
1316- : WindowBase(manager, glib::object_cast<BamfView>(window))
1317- , bamf_window_(window)
1318+ : AppWindow(manager, glib::object_cast<BamfView>(window))
1319 {}
1320
1321 AppWindow::AppWindow(ApplicationManager const& manager, glib::Object<BamfView> const& window)
1322 : WindowBase(manager, window)
1323 , bamf_window_(glib::object_cast<BamfWindow>(window))
1324-{}
1325+{
1326+ maximized.SetGetterFunction(std::bind(&AppWindow::GetMaximized, this));
1327+ signals_.Add<void, BamfWindow*, gint, gint>(bamf_window_, "maximized-changed",
1328+ [this] (BamfWindow*, gint old_state, gint state) {
1329+ if ((old_state == BAMF_WINDOW_MAXIMIZED) != (state == BAMF_WINDOW_MAXIMIZED))
1330+ this->maximized.changed.emit(state == BAMF_WINDOW_MAXIMIZED);
1331+ });
1332+}
1333+
1334+bool AppWindow::GetMaximized() const
1335+{
1336+ return bamf_window_maximized(bamf_window_) == BAMF_WINDOW_MAXIMIZED;
1337+}
1338
1339 Window AppWindow::window_id() const
1340 {
1341@@ -155,6 +193,31 @@
1342 return bamf_window_get_monitor(bamf_window_);
1343 }
1344
1345+WindowType AppWindow::type() const
1346+{
1347+ switch (bamf_window_get_window_type(bamf_window_))
1348+ {
1349+ case BAMF_WINDOW_NORMAL:
1350+ return WindowType::NORMAL;
1351+ case BAMF_WINDOW_DESKTOP:
1352+ return WindowType::DESKTOP;
1353+ case BAMF_WINDOW_DOCK:
1354+ return WindowType::DOCK;
1355+ case BAMF_WINDOW_DIALOG:
1356+ return WindowType::DIALOG;
1357+ case BAMF_WINDOW_TOOLBAR:
1358+ return WindowType::TOOLBAR;
1359+ case BAMF_WINDOW_MENU:
1360+ return WindowType::MENU;
1361+ case BAMF_WINDOW_UTILITY:
1362+ return WindowType::UTILITY;
1363+ case BAMF_WINDOW_SPLASHSCREEN:
1364+ return WindowType::SPLASHSCREEN;
1365+ default:
1366+ return WindowType::UNKNOWN;
1367+ }
1368+}
1369+
1370 ApplicationPtr AppWindow::application() const
1371 {
1372 // Moderately evil, but better than changing the method to non-const.
1373@@ -183,6 +246,11 @@
1374 return bamf_tab_get_xid(bamf_tab_);
1375 }
1376
1377+WindowType Tab::type() const
1378+{
1379+ return WindowType::TAB;
1380+}
1381+
1382 int Tab::monitor() const
1383 {
1384 // TODO, we could find the real window for the window_id, and get the monitor for that.
1385@@ -208,37 +276,14 @@
1386 bamf_tab_close(bamf_tab_);
1387 }
1388
1389-// Being brutal with this function.
1390-ApplicationWindowPtr create_window(ApplicationManager const& manager, glib::Object<BamfView> const& view)
1391-{
1392- if (view.IsType(BAMF_TYPE_WINDOW))
1393- {
1394- return std::make_shared<AppWindow>(manager, view);
1395- }
1396- else if (view.IsType(BAMF_TYPE_TAB))
1397- {
1398- return std::make_shared<Tab>(manager, view);
1399- }
1400- // We don't handle applications here.
1401- return nullptr;
1402-}
1403-
1404 Application::Application(ApplicationManager const& manager, glib::Object<BamfView> const& app)
1405- : View(manager, app)
1406- , bamf_app_(glib::object_cast<BamfApplication>(app))
1407-{
1408- HookUpEvents();
1409-}
1410+ : Application(manager, glib::object_cast<BamfApplication>(app))
1411+{}
1412
1413 Application::Application(ApplicationManager const& manager, glib::Object<BamfApplication> const& app)
1414 : View(manager, glib::object_cast<BamfView>(app))
1415 , bamf_app_(app)
1416 {
1417- HookUpEvents();
1418-}
1419-
1420-void Application::HookUpEvents()
1421-{
1422 // Hook up the property set/get functions
1423 using namespace std::placeholders;
1424 desktop_file.SetGetterFunction(std::bind(&Application::GetDesktopFile, this));
1425@@ -292,24 +337,21 @@
1426 signals_.Add<void, BamfView*, BamfView*>(bamf_view_, "child-added",
1427 [this] (BamfView*, BamfView* child) {
1428 // Ownership is not passed on signals
1429- glib::Object<BamfView> view(child, glib::AddRef());
1430- ApplicationWindowPtr const& win = create_window(this->manager_, view);
1431- if (win)
1432- this->window_opened.emit(*win);
1433+ if (ApplicationWindowPtr const& win = pool::EnsureWindow(manager_, child))
1434+ this->window_opened.emit(win);
1435 });
1436
1437 signals_.Add<void, BamfView*, BamfView*>(bamf_view_, "child-removed",
1438 [this] (BamfView*, BamfView* child) {
1439- this->window_closed.emit();
1440+ if (ApplicationWindowPtr const& win = pool::EnsureWindow(manager_, child))
1441+ this->window_closed.emit(win);
1442 });
1443
1444 signals_.Add<void, BamfView*, BamfView*>(bamf_view_, "child-moved",
1445 [this] (BamfView*, BamfView* child) {
1446 // Ownership is not passed on signals
1447- glib::Object<BamfView> view(child, glib::AddRef());
1448- ApplicationWindowPtr const& win = create_window(this->manager_, view);
1449- if (win)
1450- this->window_moved.emit(*win);
1451+ if (ApplicationWindowPtr const& win = pool::EnsureWindow(manager_, child))
1452+ this->window_moved.emit(win);
1453 });
1454 }
1455
1456@@ -318,16 +360,21 @@
1457 return glib::gchar_to_string(bamf_application_get_desktop_file(bamf_app_));
1458 }
1459
1460-std::string Application::type() const
1461+AppType Application::type() const
1462 {
1463 // Can't determine the type of a non-running app.
1464- std::string result = "unknown";
1465 if (running())
1466 {
1467- const gchar* type = bamf_application_get_application_type(bamf_app_);
1468- if (type) result = type;
1469+ auto type = glib::gchar_to_string(bamf_application_get_application_type(bamf_app_));
1470+
1471+ if (type == "system")
1472+ return AppType::NORMAL;
1473+
1474+ if (type == "webapp")
1475+ return AppType::WEBAPP;
1476 }
1477- return result;
1478+
1479+ return AppType::UNKNOWN;
1480 }
1481
1482 std::string Application::repr() const
1483@@ -347,9 +394,7 @@
1484 std::shared_ptr<GList> children(bamf_view_get_children(bamf_view_), g_list_free);
1485 for (GList* l = children.get(); l; l = l->next)
1486 {
1487- glib::Object<BamfView> view(BAMF_VIEW(l->data), glib::AddRef());
1488- ApplicationWindowPtr const& window(create_window(manager_, view));
1489- if (window)
1490+ if (ApplicationWindowPtr const& window = pool::EnsureWindow(manager_, static_cast<BamfView*>(l->data)))
1491 result.push_back(window);
1492 }
1493 return result;
1494@@ -389,9 +434,7 @@
1495
1496 ApplicationWindowPtr Application::GetFocusableWindow() const
1497 {
1498- glib::Object<BamfView> view(bamf_application_get_focusable_child(bamf_app_),
1499- glib::AddRef());
1500- return create_window(manager_, view);
1501+ return pool::EnsureWindow(manager_, bamf_application_get_focusable_child(bamf_app_));
1502 }
1503
1504 void Application::Focus(bool show_only_visible, int monitor) const
1505@@ -507,29 +550,19 @@
1506 LOG_TRACE(logger) << "Create BAMF Application Manager";
1507 signals_.Add<void, BamfMatcher*, BamfView*> (matcher_, "view-opened",
1508 sigc::mem_fun(this, &Manager::OnViewOpened));
1509+ signals_.Add<void, BamfMatcher*, BamfView*> (matcher_, "view-closed",
1510+ sigc::mem_fun(this, &Manager::OnViewClosed));
1511
1512 signals_.Add<void, BamfMatcher*, BamfView*, BamfView*>(matcher_, "active-window-changed",
1513 [this](BamfMatcher*, BamfView* /* from */, BamfView* to) {
1514- // Ownership is not passed on signals
1515- glib::Object<BamfView> view(to, glib::AddRef());
1516- ApplicationWindowPtr const& win = create_window(*this, view);
1517- if (win)
1518+ if (ApplicationWindowPtr const& win = pool::EnsureWindow(*this, to))
1519 this->active_window_changed.emit(win);
1520 });
1521
1522 signals_.Add<void, BamfMatcher*, BamfApplication*, BamfApplication*> (matcher_, "active-application-changed",
1523 [this](BamfMatcher*, BamfApplication* /* from */, BamfApplication* to) {
1524- if (to)
1525- {
1526- // Ownership is not passed on signals
1527- glib::Object<BamfApplication> bamf_app(to, glib::AddRef());
1528- auto app = std::make_shared<Application>(*this, bamf_app);
1529- this->active_application_changed.emit(app);
1530- }
1531- else
1532- {
1533- this->active_application_changed.emit(nullptr);
1534- }
1535+ auto const& app = pool::EnsureApplication(*this, reinterpret_cast<BamfView*>(to));
1536+ this->active_application_changed.emit(app);
1537 });
1538 }
1539
1540@@ -546,81 +579,79 @@
1541 {
1542 auto *app_ptr = bamf_matcher_get_application_for_xid(matcher_, xid);
1543
1544- if (BAMF_IS_APPLICATION(app_ptr))
1545- {
1546- glib::Object<BamfApplication> app(app_ptr, glib::AddRef());
1547- return std::make_shared<Application>(*this, app);
1548- }
1549+ if (ApplicationPtr const& app = pool::EnsureApplication(*this, reinterpret_cast<BamfView*>(app_ptr)))
1550+ return app;
1551 }
1552
1553 return GetApplicationForDesktopFile(DesktopUtilities::GetDesktopPathById("compiz.desktop"));
1554 }
1555
1556+ApplicationPtr Manager::GetActiveApplication() const
1557+{
1558+ auto *app_ptr = bamf_matcher_get_active_application(matcher_);
1559+ return pool::EnsureApplication(*this, reinterpret_cast<BamfView*>(app_ptr));
1560+}
1561+
1562 ApplicationWindowPtr Manager::GetActiveWindow() const
1563 {
1564- // No transfer of ownership for bamf_matcher_get_active_window.
1565- BamfWindow* active_win = bamf_matcher_get_active_window(matcher_);
1566-
1567- if (!active_win)
1568- return nullptr;
1569+ if (BamfWindow* active_win = bamf_matcher_get_active_window(matcher_))
1570+ {
1571+ if (bamf_window_get_window_type(active_win) != BAMF_WINDOW_DOCK)
1572+ return pool::EnsureWindow(*this, reinterpret_cast<BamfView*>(active_win));
1573+ }
1574
1575 // If the active window is a dock type, then we want the first visible, non-dock type.
1576- if (bamf_window_get_window_type(active_win) == BAMF_WINDOW_DOCK)
1577+ LOG_DEBUG(logger) << "Is a dock, looking at the window stack.";
1578+
1579+ auto const& wins = GetWindowsForMonitor();
1580+ WindowManager& wm = WindowManager::Default();
1581+
1582+ for (auto it = wins.rbegin(); it != wins.rend(); ++it)
1583 {
1584- LOG_DEBUG(logger) << "Is a dock, looking at the window stack.";
1585-
1586- std::shared_ptr<GList> windows(bamf_matcher_get_window_stack_for_monitor(matcher_, -1), g_list_free);
1587- WindowManager& wm = WindowManager::Default();
1588- active_win = nullptr;
1589-
1590- for (GList *l = windows.get(); l; l = l->next)
1591+ auto const& win = *it;
1592+ auto xid = win->window_id();
1593+
1594+ if (win->visible() &&
1595+ win->type() != WindowType::DOCK &&
1596+ wm.IsWindowOnCurrentDesktop(xid) &&
1597+ wm.IsWindowVisible(xid))
1598 {
1599- if (!BAMF_IS_WINDOW(l->data))
1600- {
1601- LOG_DEBUG(logger) << "Window stack returned something not a window, WTF?";
1602- continue;
1603- }
1604-
1605- auto win = static_cast<BamfWindow*>(l->data);
1606- auto view = static_cast<BamfView*>(l->data);
1607- auto xid = bamf_window_get_xid(win);
1608-
1609- if (bamf_view_is_user_visible(view) &&
1610- bamf_window_get_window_type(win) != BAMF_WINDOW_DOCK &&
1611- wm.IsWindowOnCurrentDesktop(xid) &&
1612- wm.IsWindowVisible(xid))
1613- {
1614- active_win = win;
1615- }
1616+ return win;
1617 }
1618 }
1619
1620- if (active_win)
1621- {
1622- glib::Object<BamfWindow> win(active_win, glib::AddRef());
1623- return std::make_shared<AppWindow>(*this, win);
1624- }
1625-
1626 return nullptr;
1627 }
1628
1629 ApplicationPtr Manager::GetApplicationForDesktopFile(std::string const& desktop_file) const
1630 {
1631- glib::Object<BamfApplication> app(bamf_matcher_get_application_for_desktop_file(
1632- matcher_, desktop_file.c_str(), TRUE), glib::AddRef());
1633-
1634- if (app)
1635- return std::make_shared<Application>(*this, app);
1636-
1637- return nullptr;
1638+ auto* app = bamf_matcher_get_application_for_desktop_file(matcher_, desktop_file.c_str(), TRUE);
1639+ return pool::EnsureApplication(*this, reinterpret_cast<BamfView*>(app));
1640 }
1641
1642 ApplicationPtr Manager::GetApplicationForWindow(Window xid) const
1643 {
1644- glib::Object<BamfApplication> app(bamf_matcher_get_application_for_xid(matcher_, xid),
1645- glib::AddRef());
1646- if (app)
1647- return std::make_shared<Application>(*this, app);
1648+ auto* app = bamf_matcher_get_application_for_xid(matcher_, xid);
1649+ return pool::EnsureApplication(*this, reinterpret_cast<BamfView*>(app));
1650+}
1651+
1652+ApplicationWindowPtr Manager::GetWindowForId(Window xid) const
1653+{
1654+ if (xid == 0)
1655+ return nullptr;
1656+
1657+ std::shared_ptr<GList> windows(bamf_matcher_get_windows(matcher_), g_list_free);
1658+
1659+ for (GList* l = windows.get(); l; l = l->next)
1660+ {
1661+ if (!BAMF_IS_WINDOW(l->data))
1662+ continue;
1663+
1664+ auto win = static_cast<BamfWindow*>(l->data);
1665+
1666+ if (bamf_window_get_xid(win) == xid)
1667+ return pool::EnsureWindow(*this, static_cast<BamfView*>(l->data));
1668+ }
1669
1670 return nullptr;
1671 }
1672@@ -638,26 +669,65 @@
1673 continue;
1674 }
1675
1676- glib::Object<BamfApplication> bamf_app(static_cast<BamfApplication*>(l->data), glib::AddRef());
1677- auto app = std::make_shared<Application>(*this, bamf_app);
1678- result.push_back(app);
1679- LOG_DEBUG(logger) << "Running app: " << app->title();
1680+ result.push_back(pool::EnsureApplication(*this, static_cast<BamfView*>(l->data)));
1681 }
1682 return result;
1683 }
1684
1685+WindowList Manager::GetWindowsForMonitor(int monitor) const
1686+{
1687+ WindowList wins;
1688+ std::shared_ptr<GList> windows(bamf_matcher_get_window_stack_for_monitor(matcher_, monitor), g_list_free);
1689+
1690+ for (GList *l = windows.get(); l; l = l->next)
1691+ {
1692+ if (!BAMF_IS_WINDOW(l->data))
1693+ {
1694+ LOG_DEBUG(logger) << "Window stack returned something not a window, WTF?";
1695+ continue;
1696+ }
1697+
1698+ auto bamf_win = static_cast<BamfWindow*>(l->data);
1699+
1700+ if (bamf_window_get_window_type(bamf_win) != BAMF_WINDOW_DOCK)
1701+ wins.push_back(pool::EnsureWindow(*this, static_cast<BamfView*>(l->data)));
1702+ }
1703+
1704+ return wins;
1705+}
1706
1707 void Manager::OnViewOpened(BamfMatcher* matcher, BamfView* view)
1708 {
1709 LOG_TRACE_BLOCK(logger);
1710- if (!BAMF_IS_APPLICATION(view))
1711- {
1712- LOG_DEBUG(logger) << "view is not an app";
1713- return;
1714- }
1715-
1716- glib::Object<BamfView> app(view, glib::AddRef());
1717- application_started.emit(std::make_shared<Application>(*this, app));
1718+ if (BAMF_IS_APPLICATION(view))
1719+ {
1720+ if (ApplicationPtr const& app = pool::EnsureApplication(*this, view))
1721+ application_started.emit(app);
1722+ }
1723+ else if (BAMF_IS_WINDOW(view))
1724+ {
1725+ if (ApplicationWindowPtr const& win = pool::EnsureWindow(*this, view))
1726+ window_opened.emit(win);
1727+ }
1728+}
1729+
1730+void Manager::OnViewClosed(BamfMatcher* matcher, BamfView* view)
1731+{
1732+ LOG_TRACE_BLOCK(logger);
1733+ if (BAMF_IS_APPLICATION(view))
1734+ {
1735+ if (ApplicationPtr const& app = pool::EnsureApplication(*this, view))
1736+ application_stopped.emit(app);
1737+
1738+ pool::apps_.erase(view);
1739+ }
1740+ else if (BAMF_IS_WINDOW(view))
1741+ {
1742+ if (ApplicationWindowPtr const& win = pool::EnsureWindow(*this, view))
1743+ window_closed.emit(win);
1744+
1745+ pool::wins_.erase(view);
1746+ }
1747 }
1748
1749 } // namespace bamf
1750
1751=== modified file 'unity-shared/BamfApplicationManager.h'
1752--- unity-shared/BamfApplicationManager.h 2013-09-04 19:38:19 +0000
1753+++ unity-shared/BamfApplicationManager.h 2015-05-22 16:04:25 +0000
1754@@ -20,6 +20,7 @@
1755 #ifndef UNITYSHARED_BAMF_APPLICATION_MANAGER_H
1756 #define UNITYSHARED_BAMF_APPLICATION_MANAGER_H
1757
1758+#include <unordered_map>
1759 #include <libbamf/libbamf.h>
1760 #include <UnityCore/GLibWrapper.h>
1761 #include <UnityCore/GLibSignal.h>
1762@@ -39,7 +40,6 @@
1763
1764 std::string GetTitle() const;
1765 std::string GetIcon() const;
1766- std::string type() const;
1767
1768 bool GetVisible() const;
1769 bool GetActive() const;
1770@@ -59,11 +59,15 @@
1771 glib::Object<BamfView> const& window);
1772
1773 public:
1774- virtual std::string type() const; // 'window' or 'tab'
1775-
1776- virtual bool Focus() const;
1777-
1778-private:
1779+ bool Focus() const override;
1780+
1781+ bool operator==(unity::ApplicationWindow const& other) const override
1782+ {
1783+ return static_cast<WindowBase const*>(this)->bamf_view_ == static_cast<WindowBase const&>(other).bamf_view_;
1784+ }
1785+ bool operator!=(unity::ApplicationWindow const& other) const override { return !(operator==(other)); }
1786+
1787+protected:
1788 glib::SignalManager signals_;
1789 };
1790
1791@@ -76,10 +80,12 @@
1792 AppWindow(ApplicationManager const& manager,
1793 glib::Object<BamfView> const& window);
1794
1795- virtual Window window_id() const;
1796- virtual int monitor() const;
1797- virtual ApplicationPtr application() const;
1798- virtual void Quit() const;
1799+ WindowType type() const override;
1800+ Window window_id() const override;
1801+ int monitor() const override;
1802+ ApplicationPtr application() const override;
1803+ void Quit() const override;
1804+ bool GetMaximized() const;
1805
1806 private:
1807 glib::Object<BamfWindow> bamf_window_;
1808@@ -93,11 +99,12 @@
1809 Tab(ApplicationManager const& manager,
1810 glib::Object<BamfView> const& tab);
1811
1812- virtual Window window_id() const;
1813- virtual int monitor() const;
1814- virtual ApplicationPtr application() const;
1815- virtual bool Focus() const;
1816- virtual void Quit() const;
1817+ WindowType type() const override;
1818+ Window window_id() const override;
1819+ int monitor() const override;
1820+ ApplicationPtr application() const override;
1821+ bool Focus() const override;
1822+ void Quit() const override;
1823
1824 private:
1825 glib::Object<BamfTab> bamf_tab_;
1826@@ -112,7 +119,7 @@
1827 Application(ApplicationManager const& manager,
1828 glib::Object<BamfView> const& app);
1829
1830- virtual std::string type() const;
1831+ virtual AppType type() const;
1832
1833 virtual WindowList GetWindows() const;
1834 virtual bool OwnsWindow(Window window_id) const;
1835@@ -128,9 +135,13 @@
1836
1837 virtual std::string repr() const;
1838
1839+ bool operator==(unity::Application const& other) const override
1840+ {
1841+ return static_cast<Application const*>(this)->bamf_app_ == static_cast<Application const&>(other).bamf_app_;
1842+ }
1843+ bool operator!=(unity::Application const& other) const override { return !(operator==(other)); }
1844+
1845 private: // Property getters and setters
1846- void HookUpEvents();
1847-
1848 std::string GetDesktopFile() const;
1849
1850 bool GetSeen() const;
1851@@ -152,13 +163,20 @@
1852 ~Manager();
1853
1854 ApplicationPtr GetUnityApplication() const override;
1855+ ApplicationPtr GetActiveApplication() const override;
1856 ApplicationWindowPtr GetActiveWindow() const override;
1857 ApplicationPtr GetApplicationForDesktopFile(std::string const& desktop_file) const override;
1858 ApplicationList GetRunningApplications() const override;
1859+ WindowList GetWindowsForMonitor(int monitor = -1) const override;
1860 ApplicationPtr GetApplicationForWindow(Window xid) const override;
1861+ ApplicationWindowPtr GetWindowForId(Window xid) const override;
1862+
1863+ ApplicationPtr EnsureApplication(BamfView*) const;
1864+ ApplicationWindowPtr EnsureWindow(BamfView*) const;
1865
1866 private:
1867 void OnViewOpened(BamfMatcher* matcher, BamfView* view);
1868+ void OnViewClosed(BamfMatcher* matcher, BamfView* view);
1869
1870 private:
1871 glib::Object<BamfMatcher> matcher_;
1872
1873=== modified file 'unity-shared/StandaloneAppManager.cpp'
1874--- unity-shared/StandaloneAppManager.cpp 2014-07-30 00:49:35 +0000
1875+++ unity-shared/StandaloneAppManager.cpp 2015-05-22 16:04:25 +0000
1876@@ -33,6 +33,54 @@
1877
1878 GMainLoop *loop;
1879
1880+std::ostream& operator<<(std::ostream &os, AppType at)
1881+{
1882+ switch (at)
1883+ {
1884+ case AppType::NORMAL:
1885+ return os << "NORMAL";
1886+ case AppType::WEBAPP:
1887+ return os << "WEBAPP";
1888+ case AppType::MOCK:
1889+ return os << "MOCK";
1890+ case AppType::UNKNOWN:
1891+ return os << "UNKNOWN";
1892+ }
1893+
1894+ return os;
1895+}
1896+
1897+std::ostream& operator<<(std::ostream &os, WindowType wt)
1898+{
1899+ switch (wt)
1900+ {
1901+ case WindowType::NORMAL:
1902+ return os << "NORMAL";
1903+ case WindowType::DESKTOP:
1904+ return os << "DESKTOP";
1905+ case WindowType::DOCK:
1906+ return os << "DOCK";
1907+ case WindowType::DIALOG:
1908+ return os << "DIALOG";
1909+ case WindowType::TOOLBAR:
1910+ return os << "TOOLBAR";
1911+ case WindowType::MENU:
1912+ return os << "MENU";
1913+ case WindowType::UTILITY:
1914+ return os << "UTILITY";
1915+ case WindowType::SPLASHSCREEN:
1916+ return os << "SPLASHSCREEN";
1917+ case WindowType::TAB:
1918+ return os << "TAB";
1919+ case WindowType::MOCK:
1920+ return os << "MOCK";
1921+ case WindowType::UNKNOWN:
1922+ return os << "UNKNOWN";
1923+ }
1924+
1925+ return os;
1926+}
1927+
1928 void dump_app(ApplicationPtr const& app, std::string const& prefix = "")
1929 {
1930 if (app)
1931@@ -55,6 +103,7 @@
1932 std::cout << " Window: " << win->title()
1933 << ", window_id: " << win->window_id()
1934 << ", monitor: " << win->monitor()
1935+ << ", maximized: " << win->maximized()
1936 << ", type: " << win->type()
1937 << endl;
1938 }
1939@@ -65,6 +114,8 @@
1940 }
1941 }
1942
1943+std::vector<std::string> names;
1944+
1945 void connect_events(ApplicationPtr const& app)
1946 {
1947 if (app->seen())
1948@@ -72,42 +123,57 @@
1949 cout << "Already seen " << app->title() << ", skipping event connection.\n";
1950 return;
1951 }
1952- std::string app_name = app->title();
1953- app->title.changed.connect([&app_name](std::string const& value) {
1954- cout << app_name << " changed name to: " << value << endl;
1955- app_name = value;
1956- });
1957- app->icon.changed.connect([&app_name](std::string const& value) {
1958- cout << app_name << " icon changed: " << value << endl;
1959- });
1960- app->desktop_file.changed.connect([&app_name](std::string const& value) {
1961- cout << app_name << " desktop file changed: " << value << endl;
1962- });
1963- app->visible.changed.connect([&app_name](bool value) {
1964- cout << app_name << " visibility changed: " << (value ? "yes" : "no") << endl;
1965- });
1966- app->running.changed.connect([&app_name](bool value) {
1967- cout << app_name << " running changed: " << (value ? "yes" : "no") << endl;
1968- });
1969- app->active.changed.connect([&app_name](bool value) {
1970- cout << app_name << " active changed: " << (value ? "yes" : "no") << endl;
1971- });
1972- app->urgent.changed.connect([&app_name](bool value) {
1973- cout << app_name << " urgent changed: " << (value ? "yes" : "no") << endl;
1974- });
1975- app->closed.connect([&app_name]() {
1976- cout << app_name << " closed." << endl;
1977- });
1978- app->window_opened.connect([&app_name](ApplicationWindow const& window) {
1979- cout << "** " << app_name << " window opened: " << window.title() << endl;
1980- });
1981- app->window_closed.connect([&app_name]() {
1982- cout << "** " << app_name << " window closed" << endl;
1983- });
1984- app->window_moved.connect([&app_name](ApplicationWindow const& window) {
1985- cout << "** " << app_name << " window moved: " << window.title() << endl;
1986+
1987+ auto idx = names.empty() ? 0 : names.size()-1;
1988+ names.push_back(app->title());
1989+ app->title.changed.connect([idx](std::string const& value) {
1990+ cout << names[idx] << " changed name to: " << value << endl;
1991+ names[idx] = value;
1992+ });
1993+ app->icon.changed.connect([idx](std::string const& value) {
1994+ cout << names[idx] << " icon changed: " << value << endl;
1995+ });
1996+ app->desktop_file.changed.connect([idx](std::string const& value) {
1997+ cout << names[idx] << " desktop file changed: " << value << endl;
1998+ });
1999+ app->visible.changed.connect([idx](bool value) {
2000+ cout << names[idx] << " visibility changed: " << (value ? "yes" : "no") << endl;
2001+ });
2002+ app->running.changed.connect([idx](bool value) {
2003+ cout << names[idx] << " running changed: " << (value ? "yes" : "no") << endl;
2004+ });
2005+ app->active.changed.connect([idx](bool value) {
2006+ cout << names[idx] << " active changed: " << (value ? "yes" : "no") << endl;
2007+ });
2008+ app->urgent.changed.connect([idx](bool value) {
2009+ cout << names[idx] << " urgent changed: " << (value ? "yes" : "no") << endl;
2010+ });
2011+ app->closed.connect([idx]() {
2012+ cout << names[idx] << " closed." << endl;
2013+ });
2014+ app->window_opened.connect([idx](ApplicationWindowPtr const& window) {
2015+ cout << "** " << names[idx] << " window opened: " << window->title() << endl;
2016+ });
2017+ app->window_closed.connect([idx](ApplicationWindowPtr const& window) {
2018+ cout << "** " << names[idx] << " window closed: " << window->title() << endl;
2019+ });
2020+ app->window_moved.connect([idx](ApplicationWindowPtr const& window) {
2021+ cout << "** " << names[idx] << " window moved: " << window->title() << endl;
2022 });
2023 app->seen = true;
2024+
2025+ for (auto win : app->GetWindows())
2026+ {
2027+ win->title.changed.connect([win] (std::string const& t) {
2028+ std::cout << "Window "<< win->window_id()<< " title changed to "<< t << endl;
2029+ });
2030+ win->maximized.changed.connect([win] (bool m) {
2031+ std::cout << "Window "<< win->window_id()<< " maximized changed to "<< m << endl;
2032+ });
2033+ win->active.changed.connect([win] (bool a) {
2034+ std::cout << "Window "<< win->window_id()<< " active changed to "<< a << endl;
2035+ });
2036+ }
2037 }
2038
2039