Merge lp:~3v1n0/unity/desktop-file-updated-support 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: 3455
Proposed branch: lp:~3v1n0/unity/desktop-file-updated-support
Merge into: lp:unity
Diff against target: 1654 lines (+532/-273)
25 files modified
CMakeLists.txt (+1/-1)
debian/control (+1/-1)
launcher/AbstractLauncherIcon.h (+3/-2)
launcher/ApplicationLauncherIcon.cpp (+75/-54)
launcher/ApplicationLauncherIcon.h (+3/-3)
launcher/DesktopLauncherIcon.cpp (+1/-1)
launcher/DesktopLauncherIcon.h (+1/-1)
launcher/ExpoLauncherIcon.cpp (+1/-1)
launcher/ExpoLauncherIcon.h (+1/-1)
launcher/LauncherController.cpp (+8/-3)
launcher/LauncherIcon.cpp (+1/-1)
launcher/LauncherIcon.h (+3/-3)
launcher/MockLauncherIcon.h (+2/-2)
launcher/SoftwareCenterLauncherIcon.cpp (+96/-98)
launcher/SoftwareCenterLauncherIcon.h (+0/-1)
launcher/VolumeLauncherIcon.cpp (+2/-2)
launcher/VolumeLauncherIcon.h (+1/-1)
tests/data/applications/update-manager.desktop (+6/-0)
tests/mock-application.h (+19/-6)
tests/test_application_launcher_icon.cpp (+101/-0)
tests/test_launcher_controller.cpp (+90/-44)
tests/test_software_center_launcher_icon.cpp (+104/-38)
unity-shared/ApplicationManager.h (+1/-1)
unity-shared/BamfApplicationManager.cpp (+8/-6)
unity-shared/BamfApplicationManager.h (+3/-2)
To merge this branch: bzr merge lp:~3v1n0/unity/desktop-file-updated-support
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Christopher Townsend (community) Approve
Review via email: mp+178703@code.launchpad.net

Commit message

BamfApplicationManager: add support for desktop-file-updated signal and use in AppIcon

Now an ApplicationLauncherIcon can have its .desktop file updated and when this happens
it reloads the infos it needs and updates the FavoriteStore accordingly.

Description of the change

Added support to desktop-file-updated signal added to libbamf (this happens on
lp:~3v1n0/bamf/create-local-desktop), in case an icon changes its .desktop.
This needs to update the favorite store or to firstly save the icon there if
it was sticked but not saved.

Added unit tests, updated some of them and increased the libbamf requirements.

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
Christopher Townsend (townsend) wrote :

Merges and compiles cleanly and tests pass. Code looks code.

review: Approve
Revision history for this message
Christopher Townsend (townsend) wrote :

Err, I meant to say "code looks good" in my last comment. Need more coffee...

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-07-24 18:40:42 +0000
3+++ CMakeLists.txt 2013-08-06 10:06:28 +0000
4@@ -226,7 +226,7 @@
5 gtk+-3.0>=3.1
6 indicator3-0.4>=0.4.90
7 json-glib-1.0
8- libbamf3>=0.4.0
9+ libbamf3>=0.5.0
10 libnotify
11 libstartup-notification-1.0
12 nux-4.0>=4.0.1
13
14=== modified file 'debian/control'
15--- debian/control 2013-07-21 14:53:37 +0000
16+++ debian/control 2013-08-06 10:06:28 +0000
17@@ -13,7 +13,7 @@
18 gsettings-desktop-schemas-dev,
19 intltool (>= 0.35.0),
20 libatk1.0-dev,
21- libbamf3-dev (>= 0.5.0+13.10.20130626),
22+ libbamf3-dev (>= 0.5.0+13.10.20130731),
23 libboost-dev,
24 libboost-serialization-dev,
25 libcairo2-dev,
26
27=== modified file 'launcher/AbstractLauncherIcon.h'
28--- launcher/AbstractLauncherIcon.h 2013-07-29 16:59:04 +0000
29+++ launcher/AbstractLauncherIcon.h 2013-08-06 10:06:28 +0000
30@@ -195,7 +195,7 @@
31
32 virtual IconType GetIconType() const = 0;
33
34- virtual std::string RemoteUri() = 0;
35+ virtual std::string RemoteUri() const = 0;
36
37 virtual MenuItemsVector Menus() = 0;
38
39@@ -212,7 +212,7 @@
40 virtual void InsertEntryRemote(LauncherEntryRemote::Ptr const& remote) = 0;
41 virtual void RemoveEntryRemote(LauncherEntryRemote::Ptr const& remote) = 0;
42
43- virtual std::string DesktopFile() = 0;
44+ virtual std::string DesktopFile() const = 0;
45
46 virtual bool IsSticky() const = 0;
47
48@@ -247,6 +247,7 @@
49 sigc::signal<void> visibility_changed;
50 sigc::signal<void> position_saved;
51 sigc::signal<void> position_forgot;
52+ sigc::signal<void, std::string const&> uri_changed;
53
54 connection::Wrapper on_icon_removed_connection;
55 };
56
57=== modified file 'launcher/ApplicationLauncherIcon.cpp'
58--- launcher/ApplicationLauncherIcon.cpp 2013-07-29 17:17:43 +0000
59+++ launcher/ApplicationLauncherIcon.cpp 2013-08-06 10:06:28 +0000
60@@ -84,9 +84,6 @@
61 SetQuirk(Quirk::VISIBLE, app->visible());
62 SetQuirk(Quirk::ACTIVE, app->active());
63 SetQuirk(Quirk::RUNNING, app->running());
64- // Make sure we set the LauncherIcon stick bit too...
65- if (app->sticky())
66- SimpleLauncherIcon::Stick(false); // don't emit the signal
67
68 LOG_INFO(logger) << "Created ApplicationLauncherIcon: "
69 << tooltip_text()
70@@ -98,6 +95,10 @@
71
72 SetApplication(app);
73
74+ // Make sure we set the LauncherIcon stick bit too...
75+ if (app->sticky())
76+ SimpleLauncherIcon::Stick(false); // don't emit the signal
77+
78 WindowManager& wm = WindowManager::Default();
79 wm.window_minimized.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMinimized));
80 wm.window_moved.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMoved));
81@@ -105,12 +106,6 @@
82 wm.terminate_expo.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
83
84 EnsureWindowState();
85- UpdateMenus();
86- UpdateDesktopFile();
87- UpdateBackgroundColor();
88-
89- // hack
90- SetProgress(0.0f);
91 }
92
93 ApplicationLauncherIcon::~ApplicationLauncherIcon()
94@@ -127,9 +122,16 @@
95 if (app_ == app)
96 return;
97
98+ signals_conn_.Clear();
99+
100 app_ = app;
101- signals_conn_.Clear();
102 SetupApplicationSignalsConnections();
103+
104+ // It's very likely that application desktop file has been changed, we need to
105+ // inform the icon to make sure that it reloads the informations from it.
106+ app_->desktop_file.changed.emit(app_->desktop_file());
107+ app_->title.changed.emit(app_->title());
108+ app_->icon.changed.emit(app_->icon());
109 }
110
111 void ApplicationLauncherIcon::SetupApplicationSignalsConnections()
112@@ -138,7 +140,6 @@
113 // is only ever removed when the application is closed.
114 signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindow const&) {
115 EnsureWindowState();
116- UpdateMenus();
117 UpdateIconGeometries(GetCenters());
118 }));
119
120@@ -155,6 +156,11 @@
121 SetQuirk(Quirk::ACTIVE, active);
122 }));
123
124+ signals_conn_.Add(app_->desktop_file.changed.connect([this](std::string const& desktop_file) {
125+ LOG_DEBUG(logger) << tooltip_text() << " desktop_file now " << desktop_file;
126+ UpdateDesktopFile();
127+ }));
128+
129 signals_conn_.Add(app_->title.changed.connect([this](std::string const& name) {
130 LOG_DEBUG(logger) << tooltip_text() << " name now " << name;
131 if (_menu_items.size() == MenuItemType::SIZE)
132@@ -217,13 +223,7 @@
133 // Sometimes BAMF is not fast enough to update the active application
134 // while quickly switching between apps, so we double check that the
135 // real active window is part of the selection (see bug #1111620)
136- Window active = WindowManager::Default().GetActiveWindow();
137-
138- for (auto& window : app_->GetWindows())
139- if (window->window_id() == active)
140- return true;
141-
142- return false;
143+ return app_->OwnsWindow(WindowManager::Default().GetActiveWindow());
144 }
145
146 return SimpleLauncherIcon::GetQuirk(quirk);
147@@ -301,7 +301,7 @@
148 bool any_on_monitor = (arg.monitor < 0);
149 int active_monitor = arg.monitor;
150
151- for (auto& window : app_->GetWindows())
152+ for (auto const& window : app_->GetWindows())
153 {
154 Window xid = window->window_id();
155
156@@ -504,17 +504,20 @@
157 {
158 std::string const& filename = app_->desktop_file();
159
160- if (!filename.empty() && _desktop_file != filename)
161+ if (_desktop_file_monitor)
162+ _gsignals.Disconnect(_desktop_file_monitor, "changed");
163+
164+ auto old_uri = RemoteUri();
165+ UpdateRemoteUri();
166+ UpdateDesktopQuickList();
167+ UpdateBackgroundColor();
168+
169+ if (!filename.empty())
170 {
171- _desktop_file = filename;
172-
173 // add a file watch to the desktop file so that if/when the app is removed
174 // we can remove ourself from the launcher and when it's changed
175 // we can update the quicklist.
176- if (_desktop_file_monitor)
177- _gsignals.Disconnect(_desktop_file_monitor, "changed");
178-
179- glib::Object<GFile> desktop_file(g_file_new_for_path(_desktop_file.c_str()));
180+ glib::Object<GFile> desktop_file(g_file_new_for_path(filename.c_str()));
181 _desktop_file_monitor = g_file_monitor_file(desktop_file, G_FILE_MONITOR_NONE,
182 nullptr, nullptr);
183 g_file_monitor_set_rate_limit(_desktop_file_monitor, 2000);
184@@ -543,13 +546,27 @@
185 break;
186 }
187 });
188- }
189+
190+ if (IsSticky())
191+ {
192+ position_forgot.emit();
193+ position_saved.emit();
194+ }
195+ }
196+ else if (IsSticky())
197+ {
198+ UnStick();
199+ }
200+
201+ auto const& new_uri = RemoteUri();
202+
203+ if (old_uri != new_uri)
204+ uri_changed.emit(new_uri);
205 }
206
207-std::string ApplicationLauncherIcon::DesktopFile()
208+std::string ApplicationLauncherIcon::DesktopFile() const
209 {
210- UpdateDesktopFile();
211- return _desktop_file;
212+ return app_->desktop_file();
213 }
214
215 void ApplicationLauncherIcon::AddProperties(GVariantBuilder* builder)
216@@ -687,17 +704,19 @@
217 {
218 std::string const& desktop_file = DesktopFile();
219
220- if (desktop_file.empty())
221- return;
222-
223 if (_menu_desktop_shortcuts)
224 {
225 for (GList *l = dbusmenu_menuitem_get_children(_menu_desktop_shortcuts); l; l = l->next)
226 {
227 _gsignals.Disconnect(l->data, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED);
228 }
229+
230+ _menu_desktop_shortcuts = nullptr;
231 }
232
233+ if (desktop_file.empty())
234+ return;
235+
236 _menu_desktop_shortcuts = dbusmenu_menuitem_new();
237 dbusmenu_menuitem_set_root(_menu_desktop_shortcuts, TRUE);
238
239@@ -709,8 +728,8 @@
240 // any or they're filtered for the environment we're in
241 const gchar** nicks = indicator_desktop_shortcuts_get_nicks(_desktop_shortcuts);
242
243- int index = 0;
244- while (nicks[index])
245+
246+ for (int index = 0; nicks[index]; ++index)
247 {
248 // Build a dbusmenu item for each nick that is the desktop
249 // file that is built from it's name and includes a callback
250@@ -721,7 +740,7 @@
251 dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name);
252 dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
253 dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
254- std::string nick(nicks[index]);
255+ auto nick = glib::gchar_to_string(nicks[index]);
256
257 _gsignals.Add<void, DbusmenuMenuitem*, gint>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
258 [this, nick] (DbusmenuMenuitem* item, unsigned timestamp) {
259@@ -733,7 +752,6 @@
260 });
261
262 dbusmenu_menuitem_child_append(_menu_desktop_shortcuts, item);
263- index++;
264 }
265 }
266
267@@ -751,7 +769,9 @@
268
269 if (last_use_custom_bg_color != use_custom_bg_color_ ||
270 last_bg_color != bg_color_)
271+ {
272 EmitNeedsRedraw();
273+ }
274 }
275
276 void ApplicationLauncherIcon::EnsureMenuItemsWindowsReady()
277@@ -764,17 +784,19 @@
278 // We only add quicklist menu-items for windows if we have more than one window
279 if (windows.size() < 2)
280 return;
281-
282+
283 Window active = WindowManager::Default().GetActiveWindow();
284
285 // add menu items for all open windows
286 for (auto const& w : windows)
287 {
288- if (w->title().empty())
289+ auto const& title = w->title();
290+
291+ if (title.empty())
292 continue;
293
294 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
295- dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, w->title().c_str());
296+ dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, title.c_str());
297 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
298 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
299 dbusmenu_menuitem_property_set_bool(menu_item, QuicklistMenuItem::MARKUP_ACCEL_DISABLED_PROPERTY, true);
300@@ -787,7 +809,7 @@
301 wm.Activate(xid);
302 wm.Raise(xid);
303 });
304-
305+
306 if (xid == active)
307 {
308 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_RADIO);
309@@ -798,7 +820,7 @@
310 }
311 }
312
313-void ApplicationLauncherIcon::UpdateMenus()
314+void ApplicationLauncherIcon::EnsureMenuItemsStaticQuicklist()
315 {
316 // make a client for desktop file actions
317 if (!_menu_desktop_shortcuts.IsType(DBUSMENU_TYPE_MENUITEM))
318@@ -901,7 +923,7 @@
319 bool separator_needed = false;
320
321 EnsureMenuItemsDefaultReady();
322- UpdateMenus();
323+ EnsureMenuItemsStaticQuicklist();
324
325 for (auto const& menus : {GetRemoteMenus(), _menu_desktop_shortcuts})
326 {
327@@ -1041,21 +1063,20 @@
328
329 void ApplicationLauncherIcon::UpdateRemoteUri()
330 {
331- std::string const& desktop_id = GetDesktopID();
332+ std::string const& desktop_id = GetDesktopID();
333
334- if (!desktop_id.empty())
335- {
336- _remote_uri = FavoriteStore::URI_PREFIX_APP + desktop_id;
337- }
338+ if (!desktop_id.empty())
339+ {
340+ _remote_uri = FavoriteStore::URI_PREFIX_APP + desktop_id;
341+ }
342+ else
343+ {
344+ _remote_uri.clear();
345+ }
346 }
347
348-std::string ApplicationLauncherIcon::GetRemoteUri()
349+std::string ApplicationLauncherIcon::GetRemoteUri() const
350 {
351- if (_remote_uri.empty())
352- {
353- UpdateRemoteUri();
354- }
355-
356 return _remote_uri;
357 }
358
359
360=== modified file 'launcher/ApplicationLauncherIcon.h'
361--- launcher/ApplicationLauncherIcon.h 2013-07-03 23:45:17 +0000
362+++ launcher/ApplicationLauncherIcon.h 2013-08-06 10:06:28 +0000
363@@ -45,7 +45,7 @@
364
365 virtual void ActivateLauncherIcon(ActionArg arg);
366
367- std::string DesktopFile();
368+ std::string DesktopFile() const;
369
370 bool IsSticky() const;
371 bool IsActive() const;
372@@ -92,7 +92,7 @@
373 MenuItemsVector GetMenus();
374 std::set<std::string> ValidateUrisForLaunch(DndData const& dnd_data);
375
376- std::string GetRemoteUri();
377+ std::string GetRemoteUri() const;
378
379 bool HandlesSpread() { return true; }
380 std::string GetName() const;
381@@ -115,8 +115,8 @@
382 void EnsureWindowState();
383 void EnsureMenuItemsWindowsReady();
384 void EnsureMenuItemsDefaultReady();
385+ void EnsureMenuItemsStaticQuicklist();
386 void UpdateBackgroundColor();
387- void UpdateMenus();
388 void UpdateDesktopQuickList();
389
390 void OpenInstanceWithUris(std::set<std::string> const& uris, Time timestamp);
391
392=== modified file 'launcher/DesktopLauncherIcon.cpp'
393--- launcher/DesktopLauncherIcon.cpp 2012-10-18 11:45:32 +0000
394+++ launcher/DesktopLauncherIcon.cpp 2013-08-06 10:06:28 +0000
395@@ -51,7 +51,7 @@
396 return "DesktopLauncherIcon";
397 }
398
399-std::string DesktopLauncherIcon::GetRemoteUri()
400+std::string DesktopLauncherIcon::GetRemoteUri() const
401 {
402 return FavoriteStore::URI_PREFIX_UNITY + "desktop-icon";
403 }
404
405=== modified file 'launcher/DesktopLauncherIcon.h'
406--- launcher/DesktopLauncherIcon.h 2012-08-17 10:54:33 +0000
407+++ launcher/DesktopLauncherIcon.h 2013-08-06 10:06:28 +0000
408@@ -38,7 +38,7 @@
409 protected:
410 void ActivateLauncherIcon(ActionArg arg);
411 std::string GetName() const;
412- std::string GetRemoteUri();
413+ std::string GetRemoteUri() const;
414
415 private:
416 bool show_in_switcher_;
417
418=== modified file 'launcher/ExpoLauncherIcon.cpp'
419--- launcher/ExpoLauncherIcon.cpp 2013-07-01 21:20:51 +0000
420+++ launcher/ExpoLauncherIcon.cpp 2013-08-06 10:06:28 +0000
421@@ -106,7 +106,7 @@
422 return "ExpoLauncherIcon";
423 }
424
425-std::string ExpoLauncherIcon::GetRemoteUri()
426+std::string ExpoLauncherIcon::GetRemoteUri() const
427 {
428 return FavoriteStore::URI_PREFIX_UNITY + "expo-icon";
429 }
430
431=== modified file 'launcher/ExpoLauncherIcon.h'
432--- launcher/ExpoLauncherIcon.h 2013-07-01 21:20:51 +0000
433+++ launcher/ExpoLauncherIcon.h 2013-08-06 10:06:28 +0000
434@@ -37,7 +37,7 @@
435 protected:
436 void ActivateLauncherIcon(ActionArg arg);
437 std::string GetName() const;
438- std::string GetRemoteUri();
439+ std::string GetRemoteUri() const;
440
441 private:
442 void OnViewportLayoutChanged(int hsize, int vsize);
443
444=== modified file 'launcher/LauncherController.cpp'
445--- launcher/LauncherController.cpp 2013-07-01 21:20:51 +0000
446+++ launcher/LauncherController.cpp 2013-08-06 10:06:28 +0000
447@@ -533,7 +533,7 @@
448 }
449 else
450 {
451- result->SetQuirk(AbstractLauncherIcon::Quirk::VISIBLE, true);
452+ result->SetQuirk(AbstractLauncherIcon::Quirk::VISIBLE, true);
453 }
454 }
455 }
456@@ -760,8 +760,13 @@
457 ResetIconPriorities();
458 });
459
460- icon->position_forgot.connect([this, icon_uri] {
461- FavoriteStore::Instance().RemoveFavorite(icon_uri);
462+ auto uri_ptr = std::make_shared<std::string>(icon_uri);
463+ icon->position_forgot.connect([this, uri_ptr] {
464+ FavoriteStore::Instance().RemoveFavorite(*uri_ptr);
465+ });
466+
467+ icon->uri_changed.connect([this, uri_ptr] (std::string const& new_uri) {
468+ *uri_ptr = new_uri;
469 });
470
471 if (icon->GetIconType() == AbstractLauncherIcon::IconType::APPLICATION)
472
473=== modified file 'launcher/LauncherIcon.cpp'
474--- launcher/LauncherIcon.cpp 2013-07-29 17:17:43 +0000
475+++ launcher/LauncherIcon.cpp 2013-08-06 10:06:28 +0000
476@@ -77,7 +77,7 @@
477 , _sticky(false)
478 , _remote_urgent(false)
479 , _present_urgency(0)
480- , _progress(0)
481+ , _progress(0.0f)
482 , _sort_priority(DefaultPriority(type))
483 , _last_monitor(0)
484 , _background_color(nux::color::White)
485
486=== modified file 'launcher/LauncherIcon.h'
487--- launcher/LauncherIcon.h 2013-07-29 16:58:49 +0000
488+++ launcher/LauncherIcon.h 2013-08-06 10:06:28 +0000
489@@ -139,7 +139,7 @@
490
491 virtual nux::Color GlowColor();
492
493- std::string RemoteUri()
494+ std::string RemoteUri() const
495 {
496 return GetRemoteUri();
497 }
498@@ -180,7 +180,7 @@
499 OnDndLeave();
500 }
501
502- virtual std::string DesktopFile() { return std::string(""); }
503+ virtual std::string DesktopFile() const { return std::string(); }
504
505 virtual bool IsSticky() const { return _sticky; }
506
507@@ -231,7 +231,7 @@
508
509 virtual void OnCenterStabilized(std::vector<nux::Point3> center) {}
510
511- virtual std::string GetRemoteUri()
512+ virtual std::string GetRemoteUri() const
513 {
514 return "";
515 }
516
517=== modified file 'launcher/MockLauncherIcon.h'
518--- launcher/MockLauncherIcon.h 2013-06-26 17:24:06 +0000
519+++ launcher/MockLauncherIcon.h 2013-08-06 10:06:28 +0000
520@@ -265,7 +265,7 @@
521 return nux::Color(0xFFAAAAAA);
522 }
523
524- std::string RemoteUri()
525+ std::string RemoteUri() const
526 {
527 return remote_uri_;
528 }
529@@ -309,7 +309,7 @@
530
531 void SendDndLeave() {}
532
533- std::string DesktopFile() { return std::string(""); }
534+ std::string DesktopFile() const { return std::string(""); }
535
536 bool IsSticky() const { return false; }
537
538
539=== modified file 'launcher/SoftwareCenterLauncherIcon.cpp'
540--- launcher/SoftwareCenterLauncherIcon.cpp 2013-07-23 15:23:34 +0000
541+++ launcher/SoftwareCenterLauncherIcon.cpp 2013-08-06 10:06:28 +0000
542@@ -39,8 +39,8 @@
543
544 namespace
545 {
546-#define SOURCE_SHOW_TOOLTIP "ShowTooltip"
547-#define SOURCE_HIDE_TOOLTIP "HideTooltip"
548+const std::string SOURCE_SHOW_TOOLTIP = "ShowTooltip";
549+const std::string SOURCE_HIDE_TOOLTIP = "HideTooltip";
550 const int INSTALL_TIP_DURATION = 1500;
551 }
552
553@@ -58,7 +58,6 @@
554 , finished_(true)
555 , needs_urgent_(false)
556 , aptdaemon_trans_id_(aptdaemon_trans_id)
557- , app_title_(app->title())
558 {
559 SetQuirk(Quirk::VISIBLE, false);
560 aptdaemon_trans_.Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged));
561@@ -79,10 +78,10 @@
562
563 // FIXME: this needs testing, if there is no useful coordinates
564 // then do not animate
565- if(start_x <= 0 && start_y <= 0)
566+ if (start_x <= 0 && start_y <= 0)
567 {
568- SetQuirk(Quirk::VISIBLE, true);
569- return;
570+ SetQuirk(Quirk::VISIBLE, true);
571+ return;
572 }
573
574 icon_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(
575@@ -138,103 +137,102 @@
576
577 std::string SoftwareCenterLauncherIcon::GetActualDesktopFileAfterInstall()
578 {
579- // Fixup the _desktop_file because the one we get from software-center
580- // is not the final one, e.g. the s-c-agent does send a temp one and
581- // app-install-data points to the "wrong" one in /usr/share/app-install
582- //
583- // So:
584- // - if there is a desktop file already and it startswith
585- // /usr/share/app-install/desktop, then transform to
586- // /usr/share/application
587- // - if there is a desktop file with prefix /tmp/software-center-agent:
588- // transform to /usr/share/application
589- // (its using "/tmp/software-center-agent:$random:$pkgname.desktop")
590- // maybe:
591- // - and search in /var/lib/apt/lists/$pkgname.list
592- // for a desktop file that roughly matches what we want
593- std::string filename = _desktop_file;
594-
595- // take /usr/share/app-install/desktop/foo:subdir__bar.desktop
596- // and tranform it
597- if (_desktop_file.find("/share/app-install/desktop/") != std::string::npos)
598- {
599- filename = filename.substr(filename.rfind(":") + 1,
600- filename.length() - filename.rfind(":"));
601- // the app-install-data package encodes subdirs in a funny way, once
602- // that is fixed, this code can be dropped
603- if (filename.find("__") != std::string::npos)
604- {
605- int pos = filename.find("__");
606- filename = filename.replace(pos, 2, "-");
607- }
608- filename = DesktopUtilities::GetDesktopPathById(filename);
609- return filename;
610- }
611- else if (_desktop_file.find("/tmp/software-center-agent:") == 0)
612- {
613- // by convention the software-center-agent uses
614- // /usr/share/applications/$pkgname.desktop
615- // or
616- // /usr/share/applications/extras-$pkgname.desktop
617- std::string desktopf = filename.substr(filename.rfind(":") + 1,
618- filename.length() - filename.rfind(":"));
619- filename = DesktopUtilities::GetDesktopPathById(desktopf);
620- if (filename.size() > 0)
621- return filename;
622- // now try extras-$pkgname.desktop
623- filename = DesktopUtilities::GetDesktopPathById(std::string("extras-") + desktopf);
624- if (filename.size() > 0)
625- return filename;
626-
627- // FIXME: test if there is a file now and if not, search
628- // /var/lib/dpkg/info/$pkgname.list for a desktop file
629- }
630-
631- return _desktop_file;
632+ // Fixup the _desktop_file because the one we get from software-center
633+ // is not the final one, e.g. the s-c-agent does send a temp one and
634+ // app-install-data points to the "wrong" one in /usr/share/app-install
635+ //
636+ // So:
637+ // - if there is a desktop file already and it startswith
638+ // /usr/share/app-install/desktop, then transform to
639+ // /usr/share/application
640+ // - if there is a desktop file with prefix /tmp/software-center-agent:
641+ // transform to /usr/share/application
642+ // (its using "/tmp/software-center-agent:$random:$pkgname.desktop")
643+ // maybe:
644+ // - and search in /var/lib/apt/lists/$pkgname.list
645+ // for a desktop file that roughly matches what we want
646+ auto const& desktop_file = DesktopFile();
647+
648+ // take /usr/share/app-install/desktop/foo:subdir__bar.desktop
649+ // and tranform it
650+ if (desktop_file.find("/share/app-install/desktop/") != std::string::npos)
651+ {
652+ auto colon_pos = desktop_file.rfind(":");
653+ auto filename = desktop_file.substr(colon_pos + 1, desktop_file.length() - colon_pos);
654+ // the app-install-data package encodes subdirs in a funny way, once
655+ // that is fixed, this code can be dropped
656+ if (filename.find("__") != std::string::npos)
657+ {
658+ int pos = filename.find("__");
659+ filename = filename.replace(pos, 2, "-");
660+ }
661+ filename = DesktopUtilities::GetDesktopPathById(filename);
662+ return filename;
663+ }
664+ else if (desktop_file.find("/tmp/software-center-agent:") == 0)
665+ {
666+ // by convention the software-center-agent uses
667+ // /usr/share/applications/$pkgname.desktop
668+ // or
669+ // /usr/share/applications/extras-$pkgname.desktop
670+ auto colon_pos = desktop_file.rfind(":");
671+ auto desktopf = desktop_file.substr(colon_pos + 1, desktop_file.length() - colon_pos);
672+
673+ auto filename = DesktopUtilities::GetDesktopPathById(desktopf);
674+
675+ if (!filename.empty())
676+ return filename;
677+
678+ // now try extras-$pkgname.desktop
679+ filename = DesktopUtilities::GetDesktopPathById("extras-" + desktopf);
680+ if (!filename.empty())
681+ return filename;
682+
683+ // FIXME: test if there is a file now and if not, search
684+ // /var/lib/dpkg/info/$pkgname.list for a desktop file
685+ }
686+
687+ return desktop_file;
688 }
689
690 void SoftwareCenterLauncherIcon::OnFinished(GVariant *params)
691 {
692- glib::String exit_state;
693- g_variant_get_child(params, 0, "s", &exit_state);
694-
695- if (exit_state.Str() == "exit-success")
696- {
697- tooltip_text = app_title_;
698- SetQuirk(Quirk::PROGRESS, false);
699- SetQuirk(Quirk::URGENT, true);
700- SetProgress(0.0f);
701- finished_ = true;
702- needs_urgent_ = true;
703-
704- // find and update to the real desktop file
705- std::string new_desktop_path = GetActualDesktopFileAfterInstall();
706-
707- // exchange the temp Application with the real one
708- SetApplication(ApplicationManager::Default().GetApplicationForDesktopFile(new_desktop_path));
709-
710- UpdateDesktopFile();
711- UpdateRemoteUri();
712-
713- Stick();
714- position_saved.emit();
715-
716- _source_manager.AddIdle([this]()
717- {
718- ShowTooltip();
719- _source_manager.AddTimeout(INSTALL_TIP_DURATION, [this]()
720- {
721- HideTooltip();
722- return false;
723- }, SOURCE_HIDE_TOOLTIP);
724+ glib::String exit_state;
725+ g_variant_get_child(params, 0, "s", &exit_state);
726+
727+ if (exit_state.Str() == "exit-success")
728+ {
729+ SetQuirk(Quirk::PROGRESS, false);
730+ SetQuirk(Quirk::URGENT, true);
731+ SetProgress(0.0f);
732+ finished_ = true;
733+ needs_urgent_ = true;
734+
735+ // find and update to the real desktop file
736+ std::string const& new_desktop_path = GetActualDesktopFileAfterInstall();
737+
738+ // exchange the temp Application with the real one
739+ auto& app_manager = ApplicationManager::Default();
740+ auto const& new_app = app_manager.GetApplicationForDesktopFile(new_desktop_path);
741+ new_app->sticky = IsSticky();
742+ SetApplication(new_app);
743+ Stick();
744+ position_saved.emit();
745+
746+ _source_manager.AddIdle([this] {
747+ ShowTooltip();
748+ _source_manager.AddTimeout(INSTALL_TIP_DURATION, [this] {
749+ HideTooltip();
750 return false;
751- }, SOURCE_SHOW_TOOLTIP);
752- }
753- else
754- {
755- // failure condition, remove icon again
756- UnStick();
757- }
758+ }, SOURCE_HIDE_TOOLTIP);
759+ return false;
760+ }, SOURCE_SHOW_TOOLTIP);
761+ }
762+ else
763+ {
764+ // failure condition, remove icon again
765+ UnStick();
766+ }
767 };
768
769 void SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params)
770
771=== modified file 'launcher/SoftwareCenterLauncherIcon.h'
772--- launcher/SoftwareCenterLauncherIcon.h 2013-07-17 18:35:09 +0000
773+++ launcher/SoftwareCenterLauncherIcon.h 2013-08-06 10:06:28 +0000
774@@ -63,7 +63,6 @@
775 bool finished_;
776 bool needs_urgent_;
777 std::string aptdaemon_trans_id_;
778- std::string app_title_;
779 };
780
781 }
782
783=== modified file 'launcher/VolumeLauncherIcon.cpp'
784--- launcher/VolumeLauncherIcon.cpp 2013-07-01 17:07:00 +0000
785+++ launcher/VolumeLauncherIcon.cpp 2013-08-06 10:06:28 +0000
786@@ -264,7 +264,7 @@
787 menu.push_back(menu_item);
788 }
789
790- std::string GetRemoteUri()
791+ std::string GetRemoteUri() const
792 {
793 auto const& identifier = volume_->GetIdentifier();
794
795@@ -334,7 +334,7 @@
796 return pimpl_->GetMenus();
797 }
798
799-std::string VolumeLauncherIcon::GetRemoteUri()
800+std::string VolumeLauncherIcon::GetRemoteUri() const
801 {
802 return pimpl_->GetRemoteUri();
803 }
804
805=== modified file 'launcher/VolumeLauncherIcon.h'
806--- launcher/VolumeLauncherIcon.h 2012-11-27 01:09:26 +0000
807+++ launcher/VolumeLauncherIcon.h 2013-08-06 10:06:28 +0000
808@@ -48,7 +48,7 @@
809 void Stick(bool save = true);
810 void UnStick();
811 MenuItemsVector GetMenus();
812- std::string GetRemoteUri();
813+ std::string GetRemoteUri() const;
814
815 protected:
816 virtual void ActivateLauncherIcon(ActionArg arg);
817
818=== modified file 'tests/data/applications/update-manager.desktop'
819--- tests/data/applications/update-manager.desktop 2013-03-25 18:22:32 +0000
820+++ tests/data/applications/update-manager.desktop 2013-08-06 10:06:28 +0000
821@@ -8,3 +8,9 @@
822 Type=Application
823 Categories=System;Settings;
824 X-Ubuntu-Gettext-Domain=update-manager
825+Actions=UpdateAction;
826+
827+[Desktop Action UpdateAction]
828+Name=Update Action
829+Exec=/bin/true
830+OnlyShowIn=Unity
831\ No newline at end of file
832
833=== modified file 'tests/mock-application.h'
834--- tests/mock-application.h 2013-06-28 09:41:06 +0000
835+++ tests/mock-application.h 2013-08-06 10:06:28 +0000
836@@ -22,6 +22,8 @@
837
838 #include <map>
839 #include <gmock/gmock.h>
840+#include <gio/gdesktopappinfo.h>
841+#include <UnityCore/GLibWrapper.h>
842
843 #include "unity-shared/ApplicationManager.h"
844 #include "unity-shared/WindowManager.h"
845@@ -32,6 +34,7 @@
846 {
847 struct MockApplicationWindow : unity::ApplicationWindow
848 {
849+ typedef std::shared_ptr<MockApplicationWindow> Ptr;
850 typedef NiceMock<MockApplicationWindow> Nice;
851
852 MockApplicationWindow(Window xid)
853@@ -102,16 +105,17 @@
854
855 struct MockApplication : unity::Application
856 {
857+ typedef std::shared_ptr<MockApplication> Ptr;
858 typedef NiceMock<MockApplication> Nice;
859
860 MockApplication()
861 : MockApplication("")
862 {}
863
864- MockApplication(std::string const& desktop_file,
865+ MockApplication(std::string const& desktop_file_path,
866 std::string const& icon_name = "",
867 std::string const& title_str = "")
868- : desktop_file_(desktop_file)
869+ : desktop_file_(desktop_file_path)
870 , icon_(icon_name)
871 , title_(title_str)
872 , seen_(false)
873@@ -131,10 +135,10 @@
874 active.SetGetterFunction([this] { return active_; });
875 running.SetGetterFunction([this] { return running_; });
876 urgent.SetGetterFunction([this] { return urgent_; });
877+ desktop_file.SetGetterFunction([this] { return desktop_file_; });
878 title.SetGetterFunction([this] { return title_; });
879 icon.SetGetterFunction([this] { return icon_; });
880
881- ON_CALL(*this, desktop_file()).WillByDefault(Invoke([this] { return desktop_file_; }));
882 ON_CALL(*this, type()).WillByDefault(Invoke([this] { return type_; }));
883 ON_CALL(*this, repr()).WillByDefault(Invoke([this] { return "MockApplication"; }));
884 ON_CALL(*this, GetWindows()).WillByDefault(Invoke([this] { return windows_; }));
885@@ -153,7 +157,6 @@
886 unity::WindowList windows_;
887 std::string type_;
888
889- MOCK_CONST_METHOD0(desktop_file, std::string());
890 MOCK_CONST_METHOD0(type, std::string());
891 MOCK_CONST_METHOD0(repr, std::string());
892 MOCK_CONST_METHOD0(GetWindows, unity::WindowList());
893@@ -173,7 +176,7 @@
894 void SetRunState(bool state) {
895 running_ = state;
896 running.changed.emit(state);
897- }
898+ }
899
900 bool SetSeen(bool const& param) {
901 if (param != seen_) {
902@@ -249,7 +252,17 @@
903 AppMap::iterator iter = app_map_.find(desktop_file);
904 if (iter == app_map_.end())
905 {
906- auto app = std::make_shared<NiceMock<MockApplication>>(desktop_file);
907+ std::string title;
908+ std::string icon;
909+ std::shared_ptr<GKeyFile> key_file(g_key_file_new(), g_key_file_free);
910+
911+ if (g_key_file_load_from_file(key_file.get(), desktop_file.c_str(), G_KEY_FILE_NONE, nullptr))
912+ {
913+ title = unity::glib::String(g_key_file_get_string(key_file.get(), G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, nullptr)).Str();
914+ icon = unity::glib::String(g_key_file_get_string(key_file.get(), G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, nullptr)).Str();
915+ }
916+
917+ auto app = std::make_shared<MockApplication::Nice>(desktop_file, icon, title);
918 app_map_.insert(AppMap::value_type(desktop_file, app));
919 return app;
920 }
921
922=== modified file 'tests/test_application_launcher_icon.cpp'
923--- tests/test_application_launcher_icon.cpp 2013-06-28 13:58:07 +0000
924+++ tests/test_application_launcher_icon.cpp 2013-08-06 10:06:28 +0000
925@@ -40,6 +40,7 @@
926 {
927 const std::string DEFAULT_EMPTY_ICON = "application-default-icon";
928 const std::string USC_DESKTOP = BUILDDIR"/tests/data/applications/ubuntu-software-center.desktop";
929+const std::string UM_DESKTOP = BUILDDIR"/tests/data/applications/update-manager.desktop";
930 const std::string NO_ICON_DESKTOP = BUILDDIR"/tests/data/applications/no-icon.desktop";
931
932 struct MockApplicationLauncherIcon : ApplicationLauncherIcon
933@@ -61,6 +62,8 @@
934 MOCK_METHOD0(UnStick, void());
935 MOCK_CONST_METHOD0(GetRemoteMenus, glib::Object<DbusmenuMenuitem>());
936
937+ bool LauncherIconIsSticky() const { return LauncherIcon::IsSticky(); }
938+
939 using ApplicationLauncherIcon::IsFileManager;
940 };
941
942@@ -209,6 +212,15 @@
943 EXPECT_TRUE(saved);
944 }
945
946+TEST_F(TestApplicationLauncherIcon, StickStickedApplication)
947+{
948+ auto app = std::make_shared<MockApplication::Nice>(USC_DESKTOP);
949+ app->sticky = true;
950+ MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));
951+ ASSERT_TRUE(icon->IsSticky());
952+ EXPECT_TRUE(icon->LauncherIconIsSticky());
953+}
954+
955 TEST_F(TestApplicationLauncherIcon, UnstickNotRunning)
956 {
957 bool forgot = false;
958@@ -237,6 +249,95 @@
959 EXPECT_TRUE(forgot);
960 }
961
962+TEST_F(TestApplicationLauncherIcon, UpdateDesktopFile)
963+{
964+ usc_app->desktop_file_ = UM_DESKTOP;
965+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
966+
967+ EXPECT_EQ(UM_DESKTOP, usc_icon->DesktopFile());
968+}
969+
970+TEST_F(TestApplicationLauncherIcon, UpdateDesktopFileRemoteUri)
971+{
972+ usc_app->desktop_file_ = UM_DESKTOP;
973+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
974+
975+ EXPECT_EQ(FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(UM_DESKTOP), usc_icon->RemoteUri());
976+}
977+
978+TEST_F(TestApplicationLauncherIcon, UpdateDesktopStaticQuicklistEmpty)
979+{
980+ usc_app->desktop_file_ = NO_ICON_DESKTOP;
981+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
982+
983+ EXPECT_FALSE(HasMenuItemWithLabel(usc_icon, "Test Action"));
984+}
985+
986+TEST_F(TestApplicationLauncherIcon, UpdateDesktopStaticQuicklist)
987+{
988+ usc_app->desktop_file_ = UM_DESKTOP;
989+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
990+
991+ EXPECT_FALSE(HasMenuItemWithLabel(usc_icon, "Test Action"));
992+ EXPECT_TRUE(HasMenuItemWithLabel(usc_icon, "Update Action"));
993+}
994+
995+TEST_F(TestApplicationLauncherIcon, UpdateDesktopReSavesIconPosition)
996+{
997+ mock_icon->Stick(true);
998+
999+ bool saved = false;
1000+ mock_icon->position_saved.connect([&saved] {saved = true;});
1001+ mock_app->desktop_file_ = UM_DESKTOP;
1002+ mock_app->desktop_file.changed.emit(usc_app->desktop_file_);
1003+
1004+ EXPECT_TRUE(mock_app->sticky());
1005+ EXPECT_TRUE(mock_icon->IsSticky());
1006+ EXPECT_TRUE(saved);
1007+}
1008+
1009+TEST_F(TestApplicationLauncherIcon, UpdateDesktopEmptyForgetsIconPosition)
1010+{
1011+ usc_icon->Stick(true);
1012+
1013+ bool forgot = false;
1014+ usc_icon->position_forgot.connect([&forgot] {forgot = true;});
1015+ usc_app->desktop_file_ = "";
1016+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
1017+
1018+ EXPECT_FALSE(mock_app->sticky());
1019+ EXPECT_FALSE(mock_icon->IsSticky());
1020+ EXPECT_TRUE(forgot);
1021+}
1022+
1023+TEST_F(TestApplicationLauncherIcon, UpdateDesktopUpdatesIconUri)
1024+{
1025+ bool updated = false;
1026+ usc_icon->uri_changed.connect([this, &updated] (std::string const& new_uri) {
1027+ updated = true;
1028+ EXPECT_EQ(usc_icon->RemoteUri(), new_uri);
1029+ });
1030+
1031+ usc_app->desktop_file_ = "";
1032+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
1033+ EXPECT_TRUE(updated);
1034+
1035+ updated = false;
1036+ usc_app->desktop_file_ = UM_DESKTOP;
1037+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
1038+ EXPECT_TRUE(updated);
1039+}
1040+
1041+
1042+TEST_F(TestApplicationLauncherIcon, UpdateDesktopDoesntUpdatesIconUri)
1043+{
1044+ bool updated = false;
1045+ usc_icon->uri_changed.connect([&updated] (std::string const& new_uri) { updated = true; });
1046+ usc_app->desktop_file.changed.emit(usc_app->desktop_file_);
1047+
1048+ EXPECT_FALSE(updated);
1049+}
1050+
1051 TEST_F(TestApplicationLauncherIcon, RemoteUri)
1052 {
1053 EXPECT_EQ(usc_icon->RemoteUri(), FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(USC_DESKTOP));
1054
1055=== modified file 'tests/test_launcher_controller.cpp'
1056--- tests/test_launcher_controller.cpp 2013-07-29 17:17:43 +0000
1057+++ tests/test_launcher_controller.cpp 2013-08-06 10:06:28 +0000
1058@@ -133,49 +133,43 @@
1059 FavoriteList fav_list_;
1060 };
1061
1062-struct MockApplicationLauncherIcon : public ApplicationLauncherIcon
1063+struct MockApplicationLauncherIcon : ApplicationLauncherIcon
1064 {
1065- typedef nux::ObjectPtr<MockApplicationLauncherIcon> Ptr;
1066+ typedef NiceMock<MockApplicationLauncherIcon> Nice;
1067+ typedef nux::ObjectPtr<MockApplicationLauncherIcon::Nice> Ptr;
1068 typedef bool Fake;
1069
1070 MockApplicationLauncherIcon(Fake = true, std::string const& remote_uri = "")
1071- : ApplicationLauncherIcon(std::make_shared<MockApplication::Nice>())
1072- , remote_uri_(remote_uri)
1073+ : MockApplicationLauncherIcon(std::make_shared<MockApplication::Nice>())
1074 {
1075- InitMock();
1076 SetQuirk(Quirk::VISIBLE, true);
1077+
1078+ if (!remote_uri.empty())
1079+ {
1080+ ON_CALL(*this, GetRemoteUri()).WillByDefault(Invoke([this, remote_uri] {
1081+ return FavoriteStore::URI_PREFIX_APP + remote_uri;
1082+ }));
1083+ }
1084 }
1085
1086 explicit MockApplicationLauncherIcon(ApplicationPtr const& app)
1087 : ApplicationLauncherIcon(app)
1088 {
1089- InitMock();
1090+ ON_CALL(*this, Stick(_)).WillByDefault(Invoke([this] (bool save) { ApplicationLauncherIcon::Stick(save); }));
1091+ ON_CALL(*this, UnStick()).WillByDefault(Invoke([this] { ApplicationLauncherIcon::UnStick(); }));
1092+ ON_CALL(*this, GetRemoteUri()).WillByDefault(Invoke([this] { return ReallyGetRemoteUri(); }));
1093 }
1094
1095 MockApplicationLauncherIcon(std::string const& desktop_file)
1096- : ApplicationLauncherIcon(std::make_shared<MockApplication::Nice>(desktop_file))
1097- {
1098- InitMock();
1099- }
1100-
1101- void InitMock()
1102- {
1103- ON_CALL(*this, Stick(_)).WillByDefault(Invoke([this] (bool save) { ApplicationLauncherIcon::Stick(save); }));
1104- }
1105-
1106- std::string GetRemoteUri()
1107- {
1108- if (remote_uri_.empty())
1109- return ApplicationLauncherIcon::GetRemoteUri();
1110- else
1111- return FavoriteStore::URI_PREFIX_APP + remote_uri_;
1112- }
1113-
1114+ : MockApplicationLauncherIcon(std::make_shared<MockApplication::Nice>(desktop_file))
1115+ {}
1116+
1117+ std::string ReallyGetRemoteUri() const { return ApplicationLauncherIcon::GetRemoteUri(); }
1118+
1119+ MOCK_CONST_METHOD0(GetRemoteUri, std::string());
1120 MOCK_METHOD1(Stick, void(bool));
1121 MOCK_METHOD0(UnStick, void());
1122 MOCK_METHOD0(Quit, void());
1123-
1124- std::string remote_uri_;
1125 };
1126
1127 struct MockVolumeLauncherIcon : public VolumeLauncherIcon
1128@@ -482,7 +476,7 @@
1129 TEST_F(TestLauncherController, OnlyUnstickIconOnFavoriteRemoval)
1130 {
1131 const std::string desktop = app::BZR_HANDLE_PATCH;
1132- MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon(desktop));
1133+ MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon::Nice(desktop));
1134 lc.Impl()->model_->AddIcon(bamf_icon);
1135
1136 EXPECT_CALL(*bamf_icon, UnStick());
1137@@ -720,7 +714,7 @@
1138
1139 TEST_F(TestLauncherController, RegisteredIconSavesPosition)
1140 {
1141- MockApplicationLauncherIcon::Ptr app_icon(new NiceMock<MockApplicationLauncherIcon>(true, "normal-icon.desktop"));
1142+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(true, "normal-icon.desktop"));
1143 lc.Impl()->RegisterIcon(app_icon);
1144 ASSERT_FALSE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1145
1146@@ -729,6 +723,23 @@
1147 EXPECT_TRUE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1148 }
1149
1150+TEST_F(TestLauncherController, RegisteredIconWithNoDesktopSavesPositionOnDesktopUpdated)
1151+{
1152+ auto app = std::make_shared<MockApplication::Nice>();
1153+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(app));
1154+ lc.Impl()->RegisterIcon(app_icon);
1155+ app_icon->Stick(true);
1156+
1157+ ASSERT_TRUE(app_icon->RemoteUri().empty());
1158+ ASSERT_FALSE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1159+
1160+ app->desktop_file_ = "brand-new-desktop-file.desktop";
1161+ app->desktop_file.changed.emit(app->desktop_file_);
1162+
1163+ EXPECT_FALSE(app_icon->RemoteUri().empty());
1164+ EXPECT_TRUE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1165+}
1166+
1167 TEST_F(TestLauncherController, RegisteredIconForgetsPosition)
1168 {
1169 auto const& fav = lc.Impl()->GetIconByUri(favorite_store.GetFavorites().front());
1170@@ -738,6 +749,41 @@
1171 EXPECT_FALSE(favorite_store.IsFavorite(fav->RemoteUri()));
1172 }
1173
1174+TEST_F(TestLauncherController, RegisteredIconWithNoDesktopForgetsPositionOnDesktopUpdated)
1175+{
1176+ auto app = std::make_shared<MockApplication::Nice>();
1177+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(app));
1178+ lc.Impl()->RegisterIcon(app_icon);
1179+ app_icon->Stick(true);
1180+
1181+ app->desktop_file_ = "brand-new-desktop-file.desktop";
1182+ app->desktop_file.changed.emit(app->desktop_file_);
1183+ ASSERT_TRUE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1184+
1185+ app_icon->UnStick();
1186+ EXPECT_FALSE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1187+}
1188+
1189+TEST_F(TestLauncherController, RegisteredIconUpdatesPositionOnDesktopUpdated)
1190+{
1191+ auto app = std::make_shared<MockApplication::Nice>("awesome-app.desktop");
1192+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(app));
1193+ lc.Impl()->RegisterIcon(app_icon);
1194+ auto old_uri = app_icon->RemoteUri();
1195+ app_icon->Stick(true);
1196+ ASSERT_TRUE(favorite_store.IsFavorite(old_uri));
1197+
1198+ app->desktop_file_ = "even_more_awesome_app.desktop";
1199+ app->desktop_file.changed.emit(app->desktop_file_);
1200+ ASSERT_NE(app_icon->RemoteUri(), old_uri);
1201+
1202+ EXPECT_FALSE(favorite_store.IsFavorite(old_uri));
1203+ ASSERT_TRUE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1204+
1205+ app_icon->UnStick();
1206+ EXPECT_FALSE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1207+}
1208+
1209 TEST_F(TestLauncherController, GetIconByUriDesktop)
1210 {
1211 lc.Impl()->RegisterIcon(lc.Impl()->desktop_icon_);
1212@@ -1126,7 +1172,7 @@
1213 std::string desktop = app::BZR_HANDLE_PATCH;
1214 std::string icon_uri = FavoriteStore::URI_PREFIX_FILE + desktop;
1215
1216- MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon(desktop));
1217+ MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon::Nice(desktop));
1218 lc.Impl()->RegisterIcon(bamf_icon, std::numeric_limits<int>::max());
1219
1220 auto app_icons = model->GetSublist<ApplicationLauncherIcon>();
1221@@ -1178,7 +1224,7 @@
1222
1223 TEST_F(TestLauncherController, LauncherRemoveRequestApplicationUnStickAndQuit)
1224 {
1225- MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon());
1226+ MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon::Nice());
1227
1228 EXPECT_CALL(*bamf_icon, UnStick());
1229 EXPECT_CALL(*bamf_icon, Quit());
1230@@ -1233,7 +1279,7 @@
1231 std::string desktop = app::BZR_HANDLE_PATCH;
1232 std::string icon_uri = FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(desktop);
1233
1234- MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon(desktop));
1235+ MockApplicationLauncherIcon::Ptr bamf_icon(new MockApplicationLauncherIcon::Nice(desktop));
1236 lc.Impl()->RegisterIcon(bamf_icon, std::numeric_limits<int>::max());
1237 ASSERT_TRUE(lc.Impl()->GetIconByUri(icon_uri).IsValid());
1238
1239@@ -1252,11 +1298,11 @@
1240 lc.DisconnectSignals();
1241 int priority = 0;
1242
1243- MockApplicationLauncherIcon::Ptr sticky_app(new NiceMock<MockApplicationLauncherIcon>(true, "sticky-app"));
1244+ MockApplicationLauncherIcon::Ptr sticky_app(new MockApplicationLauncherIcon::Nice(true, "sticky-app"));
1245 sticky_app->Stick(false);
1246 lc.Impl()->RegisterIcon(sticky_app, ++priority);
1247
1248- MockApplicationLauncherIcon::Ptr invisible_app(new NiceMock<MockApplicationLauncherIcon>(true, "invisible-app"));
1249+ MockApplicationLauncherIcon::Ptr invisible_app(new MockApplicationLauncherIcon::Nice(true, "invisible-app"));
1250 invisible_app->SetQuirk(AbstractLauncherIcon::Quirk::VISIBLE, false);
1251 lc.Impl()->RegisterIcon(invisible_app, ++priority);
1252
1253@@ -1267,7 +1313,7 @@
1254 MockVolumeLauncherIcon::Ptr device(new MockVolumeLauncherIcon());
1255 lc.Impl()->RegisterIcon(device, ++priority);
1256
1257- MockApplicationLauncherIcon::Ptr running_app(new MockApplicationLauncherIcon(true, "running-app"));
1258+ MockApplicationLauncherIcon::Ptr running_app(new MockApplicationLauncherIcon::Nice(true, "running-app"));
1259 lc.Impl()->RegisterIcon(running_app, ++priority);
1260
1261 lc.Impl()->SaveIconsOrder();
1262@@ -1287,7 +1333,7 @@
1263 lc.ClearModel();
1264 int priority = 0;
1265
1266- MockApplicationLauncherIcon::Ptr sticky_app(new NiceMock<MockApplicationLauncherIcon>(true, "sticky-app"));
1267+ MockApplicationLauncherIcon::Ptr sticky_app(new MockApplicationLauncherIcon::Nice(true, "sticky-app"));
1268 sticky_app->Stick(false);
1269 lc.Impl()->RegisterIcon(sticky_app, ++priority);
1270
1271@@ -1316,7 +1362,7 @@
1272 FavoriteStore::URI_PREFIX_APP + "bar.desktop", places::APPS_URI,
1273 FavoriteStore::URI_PREFIX_APP + "foobar.desktop"});
1274
1275- MockApplicationLauncherIcon::Ptr sticky_app(new NiceMock<MockApplicationLauncherIcon>(true, "sticky-app"));
1276+ MockApplicationLauncherIcon::Ptr sticky_app(new MockApplicationLauncherIcon::Nice(true, "sticky-app"));
1277 sticky_app->Stick(false);
1278 lc.Impl()->RegisterIcon(sticky_app, ++priority);
1279
1280@@ -1341,7 +1387,7 @@
1281 lc.ClearModel();
1282 int priority = 0;
1283
1284- MockApplicationLauncherIcon::Ptr sticky_app(new NiceMock<MockApplicationLauncherIcon>(true, "sticky-app"));
1285+ MockApplicationLauncherIcon::Ptr sticky_app(new MockApplicationLauncherIcon::Nice(true, "sticky-app"));
1286 sticky_app->Stick(false);
1287 lc.Impl()->RegisterIcon(sticky_app, ++priority);
1288
1289@@ -1370,7 +1416,7 @@
1290
1291 for (int i = 0; i < 15; ++i)
1292 {
1293- MockApplicationLauncherIcon::Ptr app(new MockApplicationLauncherIcon());
1294+ MockApplicationLauncherIcon::Ptr app(new MockApplicationLauncherIcon::Nice());
1295 app->SetQuirk(AbstractLauncherIcon::Quirk::VISIBLE, (i % 5) != 0);
1296 lc.Impl()->RegisterIcon(app, 0);
1297 }
1298@@ -1439,7 +1485,7 @@
1299 std::string desktop = app::BZR_HANDLE_PATCH;
1300 std::string icon_uri = FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(desktop);
1301
1302- MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon(desktop));
1303+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(desktop));
1304 lc.Impl()->RegisterIcon(app_icon, std::numeric_limits<int>::max());
1305
1306 EXPECT_CALL(*app_icon, Stick(false));
1307@@ -1453,7 +1499,7 @@
1308 std::string desktop = app::BZR_HANDLE_PATCH;
1309 std::string icon_uri = FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(desktop);
1310
1311- MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon(desktop));
1312+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(desktop));
1313 lc.Impl()->RegisterIcon(app_icon, std::numeric_limits<int>::max());
1314
1315 auto app_icons = model->GetSublist<ApplicationLauncherIcon>();
1316@@ -1473,7 +1519,7 @@
1317 std::string desktop = app::BZR_HANDLE_PATCH;
1318 std::string icon_uri = FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(desktop);
1319
1320- MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon(desktop));
1321+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(desktop));
1322 lc.Impl()->RegisterIcon(app_icon, std::numeric_limits<int>::max());
1323
1324 auto const& app_icons = model->GetSublist<ApplicationLauncherIcon>();
1325@@ -1516,7 +1562,7 @@
1326
1327 TEST_F(TestLauncherController, OnFavoriteStoreFavoriteRemovedApplication)
1328 {
1329- MockApplicationLauncherIcon::Ptr app_icon(new NiceMock<MockApplicationLauncherIcon>(true, "sticky-icon"));
1330+ MockApplicationLauncherIcon::Ptr app_icon(new MockApplicationLauncherIcon::Nice(true, "sticky-icon"));
1331 lc.Impl()->RegisterIcon(app_icon);
1332 app_icon->Stick(false);
1333
1334@@ -1695,7 +1741,7 @@
1335 {
1336 const char * desktop_file = "normal-icon.desktop";
1337 MockApplicationLauncherIcon::Ptr
1338- app_icon(new NiceMock<MockApplicationLauncherIcon>(true, desktop_file));
1339+ app_icon(new MockApplicationLauncherIcon::Nice(true, desktop_file));
1340 lc.Impl()->RegisterIcon(app_icon);
1341 ASSERT_FALSE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1342
1343@@ -1710,7 +1756,7 @@
1344 {
1345 const char * desktop_file = "normal-icon.desktop";
1346 MockApplicationLauncherIcon::Ptr
1347- app_icon(new NiceMock<MockApplicationLauncherIcon>(true, desktop_file));
1348+ app_icon(new MockApplicationLauncherIcon::Nice(true, desktop_file));
1349 lc.Impl()->RegisterIcon(app_icon);
1350 ASSERT_FALSE(favorite_store.IsFavorite(app_icon->RemoteUri()));
1351 app_icon->Stick(true);
1352
1353=== modified file 'tests/test_software_center_launcher_icon.cpp'
1354--- tests/test_software_center_launcher_icon.cpp 2013-07-23 15:23:34 +0000
1355+++ tests/test_software_center_launcher_icon.cpp 2013-08-06 10:06:28 +0000
1356@@ -23,8 +23,10 @@
1357
1358 #include <config.h>
1359 #include <gmock/gmock.h>
1360+#include <UnityCore/Variant.h>
1361
1362 #include "mock-application.h"
1363+#include "FavoriteStore.h"
1364 #include "SoftwareCenterLauncherIcon.h"
1365 #include "Launcher.h"
1366 #include "PanelStyle.h"
1367@@ -46,28 +48,26 @@
1368 class MockSoftwareCenterLauncherIcon : public SoftwareCenterLauncherIcon
1369 {
1370 public:
1371- MockSoftwareCenterLauncherIcon(ApplicationPtr const& app,
1372- std::string const& aptdaemon_trans_id,
1373- std::string const& icon_path)
1374- : SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path)
1375- {}
1376+ MockSoftwareCenterLauncherIcon(ApplicationPtr const& app,
1377+ std::string const& aptdaemon_trans_id,
1378+ std::string const& icon_path)
1379+ : SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path)
1380+ {}
1381
1382- using SoftwareCenterLauncherIcon::GetActualDesktopFileAfterInstall;
1383- using SoftwareCenterLauncherIcon::_desktop_file;
1384- using SoftwareCenterLauncherIcon::GetRemoteUri;
1385- using SoftwareCenterLauncherIcon::OnFinished;
1386- using SoftwareCenterLauncherIcon::OnPropertyChanged;
1387+ using SoftwareCenterLauncherIcon::GetActualDesktopFileAfterInstall;
1388+ using SoftwareCenterLauncherIcon::GetRemoteUri;
1389+ using SoftwareCenterLauncherIcon::OnFinished;
1390+ using SoftwareCenterLauncherIcon::OnPropertyChanged;
1391 };
1392
1393 struct TestSoftwareCenterLauncherIcon : testing::Test
1394 {
1395-public:
1396 TestSoftwareCenterLauncherIcon()
1397- : usc(std::make_shared<MockApplication::Nice>(USC_APP_INSTALL_DESKTOP, "softwarecenter"))
1398+ : usc(std::make_shared<MockApplication::Nice>(USC_APP_INSTALL_DESKTOP, "softwarecenter", "Ubuntu Software Center"))
1399 , icon(usc, "/com/canonical/unity/test/object/path", "")
1400 {}
1401
1402- ApplicationPtr usc;
1403+ MockApplication::Ptr usc;
1404 MockSoftwareCenterLauncherIcon icon;
1405 };
1406
1407@@ -80,42 +80,103 @@
1408
1409 TEST_F(TestSoftwareCenterLauncherIcon, DesktopFileTransformTrivial)
1410 {
1411- // no transformation needed
1412- icon._desktop_file = USC_DESKTOP;
1413+ // no transformation needed
1414+ usc->desktop_file_ = USC_DESKTOP;
1415 EXPECT_EQ(icon.GetActualDesktopFileAfterInstall(), USC_DESKTOP);
1416 }
1417
1418 TEST_F(TestSoftwareCenterLauncherIcon, DesktopFileTransformAppInstall)
1419 {
1420- // ensure that tranformation from app-install data desktop files works
1421- icon._desktop_file = "/usr/share/app-install/desktop/pkgname:kde4__afile.desktop";
1422- EXPECT_EQ(icon.GetActualDesktopFileAfterInstall(),
1423- BUILDDIR"/tests/data/applications/kde4/afile.desktop");
1424+ // ensure that tranformation from app-install data desktop files works
1425+ usc->desktop_file_ = "/usr/share/app-install/desktop/pkgname:kde4__afile.desktop";
1426+ EXPECT_EQ(icon.GetActualDesktopFileAfterInstall(),
1427+ LOCAL_DATA_DIR+"/applications/kde4/afile.desktop");
1428 }
1429
1430 TEST_F(TestSoftwareCenterLauncherIcon, DesktopFileTransformSCAgent)
1431 {
1432- // now simualte data coming from the sc-agent
1433- icon._desktop_file = "/tmp/software-center-agent:VP2W9M:ubuntu-software-center.desktop";
1434- EXPECT_EQ(icon.GetActualDesktopFileAfterInstall(), USC_DESKTOP);
1435+ // now simualte data coming from the sc-agent
1436+ usc->desktop_file_ = "/tmp/software-center-agent:VP2W9M:ubuntu-software-center.desktop";
1437+ EXPECT_EQ(icon.GetActualDesktopFileAfterInstall(), USC_DESKTOP);
1438 }
1439
1440 // simulate a OnFinished signal from a /usr/share/app-install location
1441 // and ensure that the remote uri is updated from temp location to
1442 // the real location
1443-TEST_F(TestSoftwareCenterLauncherIcon, OnFinished)
1444-{
1445- // now simulate that the install was successful
1446- GVariant *params = g_variant_new("(s)", "exit-success");
1447- icon.OnFinished(params);
1448-
1449- // and verify that both the desktop file and the remote uri gets updated
1450-
1451- EXPECT_EQ(icon._desktop_file, USC_DESKTOP);
1452- EXPECT_EQ(icon.GetRemoteUri(), "application://ubuntu-software-center.desktop");
1453- EXPECT_TRUE(usc->closed.empty());
1454-
1455- g_variant_unref(params);
1456+TEST_F(TestSoftwareCenterLauncherIcon, OnFinishedReplacesDesktopFile)
1457+{
1458+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1459+
1460+ EXPECT_EQ(USC_DESKTOP, icon.DesktopFile());
1461+}
1462+
1463+TEST_F(TestSoftwareCenterLauncherIcon, OnFinishedUpdatesRemoteURI)
1464+{
1465+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1466+
1467+ ASSERT_EQ(USC_DESKTOP, icon.DesktopFile());
1468+ EXPECT_EQ(FavoriteStore::URI_PREFIX_APP + "ubuntu-software-center.desktop", icon.GetRemoteUri());
1469+}
1470+
1471+TEST_F(TestSoftwareCenterLauncherIcon, DisconnectsOldAppSignals)
1472+{
1473+ ASSERT_FALSE(usc->closed.empty());
1474+
1475+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1476+
1477+ EXPECT_TRUE(usc->closed.empty());
1478+ EXPECT_TRUE(usc->window_opened.empty());
1479+ EXPECT_TRUE(usc->window_moved.empty());
1480+ EXPECT_TRUE(usc->window_closed.empty());
1481+ EXPECT_TRUE(usc->visible.changed.empty());
1482+ EXPECT_TRUE(usc->active.changed.empty());
1483+ EXPECT_TRUE(usc->running.changed.empty());
1484+ EXPECT_TRUE(usc->urgent.changed.empty());
1485+ EXPECT_TRUE(usc->desktop_file.changed.empty());
1486+ EXPECT_TRUE(usc->title.changed.empty());
1487+ EXPECT_TRUE(usc->icon.changed.empty());
1488+}
1489+
1490+TEST_F(TestSoftwareCenterLauncherIcon, OnFinishedSticksIcon)
1491+{
1492+ ASSERT_FALSE(icon.IsSticky());
1493+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1494+ EXPECT_TRUE(icon.IsSticky());
1495+}
1496+
1497+TEST_F(TestSoftwareCenterLauncherIcon, OnFinishedSavesIconPosition)
1498+{
1499+ bool saved = false;
1500+ icon.position_saved.connect([&saved] {saved = true;});
1501+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1502+ ASSERT_TRUE(icon.IsSticky());
1503+ EXPECT_TRUE(saved);
1504+}
1505+
1506+TEST_F(TestSoftwareCenterLauncherIcon, OnFinishedKeepsStickyStatus)
1507+{
1508+ bool saved = false;
1509+ usc->sticky = true;
1510+ icon.position_saved.connect([&saved] {saved = true;});
1511+ ASSERT_TRUE(icon.IsSticky());
1512+
1513+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1514+ ASSERT_TRUE(icon.IsSticky());
1515+ EXPECT_TRUE(saved);
1516+}
1517+
1518+TEST_F(TestSoftwareCenterLauncherIcon, OnFinishedUpdatesTooltip)
1519+{
1520+ icon.tooltip_text = "FooText";
1521+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1522+ EXPECT_EQ("Ubuntu Software Center", icon.tooltip_text());
1523+}
1524+
1525+TEST_F(TestSoftwareCenterLauncherIcon, OnFinishedUpdatesIcon)
1526+{
1527+ icon.icon_name = "foo-icon";
1528+ icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
1529+ EXPECT_EQ("softwarecenter", icon.icon_name());
1530 }
1531
1532 TEST_F(TestSoftwareCenterLauncherIcon, Animate)
1533@@ -135,16 +196,21 @@
1534 EXPECT_TRUE(icon.IsVisible());
1535 }
1536
1537-TEST_F(TestSoftwareCenterLauncherIcon, TooltipInstalling)
1538+struct InstallProgress : TestSoftwareCenterLauncherIcon, testing::WithParamInterface<int> {};
1539+INSTANTIATE_TEST_CASE_P(TestSoftwareCenterLauncherIcon, InstallProgress, testing::Range<int>(0, 99, 10));
1540+
1541+TEST_P(/*TestSoftwareCenterLauncherIcon*/InstallProgress, InstallEmblems)
1542 {
1543 ASSERT_EQ(icon.tooltip_text(), "Waiting to install");
1544
1545- GVariant *progress = g_variant_new("i", 10);
1546+ GVariant *progress = g_variant_new("i", GetParam());
1547 GVariant *params = g_variant_new("(sv)", "Progress", progress);
1548
1549 icon.OnPropertyChanged(params);
1550
1551- EXPECT_EQ(icon.tooltip_text(), "Installing…");
1552+ EXPECT_EQ("Installing…", icon.tooltip_text());
1553+ EXPECT_TRUE(icon.GetQuirk(AbstractLauncherIcon::Quirk::PROGRESS));
1554+ EXPECT_FLOAT_EQ(GetParam()/100.0f, icon.GetProgress());
1555
1556 g_variant_unref(params);
1557 }
1558
1559=== modified file 'unity-shared/ApplicationManager.h'
1560--- unity-shared/ApplicationManager.h 2013-06-26 16:51:30 +0000
1561+++ unity-shared/ApplicationManager.h 2013-08-06 10:06:28 +0000
1562@@ -74,7 +74,6 @@
1563 public:
1564 virtual ~Application() {}
1565
1566- virtual std::string desktop_file() const = 0;
1567 virtual std::string type() const = 0;
1568
1569 // A string representation of the object.
1570@@ -90,6 +89,7 @@
1571 // Calls quit on all the Windows for this application.
1572 virtual void Quit() const = 0;
1573
1574+ nux::ROProperty<std::string> desktop_file;
1575 nux::ROProperty<std::string> title;
1576 nux::ROProperty<std::string> icon;
1577
1578
1579=== modified file 'unity-shared/BamfApplicationManager.cpp'
1580--- unity-shared/BamfApplicationManager.cpp 2013-06-27 11:36:51 +0000
1581+++ unity-shared/BamfApplicationManager.cpp 2013-08-06 10:06:28 +0000
1582@@ -55,8 +55,7 @@
1583
1584 std::string View::type() const
1585 {
1586- const gchar* t = bamf_view_get_view_type(bamf_view_);
1587- return (t ? t : "");
1588+ return glib::gchar_to_string(bamf_view_get_view_type(bamf_view_));
1589 }
1590
1591 bool View::GetVisible() const
1592@@ -241,6 +240,7 @@
1593 {
1594 // Hook up the property set/get functions
1595 using namespace std::placeholders;
1596+ desktop_file.SetGetterFunction(std::bind(&Application::GetDesktopFile, this));
1597 title.SetGetterFunction(std::bind(&View::GetTitle, this));
1598 icon.SetGetterFunction(std::bind(&View::GetIcon, this));
1599 seen.SetGetterFunction(std::bind(&Application::GetSeen, this));
1600@@ -252,7 +252,10 @@
1601 running.SetGetterFunction(std::bind(&View::GetRunning, this));
1602 urgent.SetGetterFunction(std::bind(&View::GetUrgent, this));
1603
1604- // Use signals_.Add....
1605+ signals_.Add<void, BamfApplication*, const char*>(bamf_app_, "desktop-file-updated",
1606+ [this] (BamfApplication*, const char* new_desktop_file) {
1607+ this->desktop_file.changed.emit(glib::gchar_to_string(new_desktop_file));
1608+ });
1609 signals_.Add<void, BamfView*, const char*, const char*>(bamf_view_, "name-changed",
1610 [this] (BamfView*, const char*, const char* new_name) {
1611 this->title.changed.emit(glib::gchar_to_string(new_name));
1612@@ -309,10 +312,9 @@
1613 });
1614 }
1615
1616-std::string Application::desktop_file() const
1617+std::string Application::GetDesktopFile() const
1618 {
1619- const gchar* file = bamf_application_get_desktop_file(bamf_app_);
1620- return file ? file : "";
1621+ return glib::gchar_to_string(bamf_application_get_desktop_file(bamf_app_));
1622 }
1623
1624 std::string Application::type() const
1625
1626=== modified file 'unity-shared/BamfApplicationManager.h'
1627--- unity-shared/BamfApplicationManager.h 2013-06-27 11:11:19 +0000
1628+++ unity-shared/BamfApplicationManager.h 2013-08-06 10:06:28 +0000
1629@@ -112,7 +112,6 @@
1630 Application(ApplicationManager const& manager,
1631 glib::Object<BamfView> const& app);
1632
1633- virtual std::string desktop_file() const;
1634 virtual std::string type() const;
1635
1636 virtual WindowList GetWindows() const;
1637@@ -130,6 +129,8 @@
1638 private: // Property getters and setters
1639 void HookUpEvents();
1640
1641+ std::string GetDesktopFile() const;
1642+
1643 bool GetSeen() const;
1644 bool SetSeen(bool const& param);
1645
1646@@ -137,7 +138,7 @@
1647 bool SetSticky(bool const& param);
1648
1649 private:
1650- glib::Object< ::BamfApplication> bamf_app_;
1651+ glib::Object<::BamfApplication> bamf_app_;
1652 glib::SignalManager signals_;
1653 std::string type_;
1654 };