Merge lp:~3v1n0/unity/create-local-desktop-file 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: 3458
Proposed branch: lp:~3v1n0/unity/create-local-desktop-file
Merge into: lp:unity
Diff against target: 602 lines (+195/-92)
11 files modified
launcher/ApplicationLauncherIcon.cpp (+36/-37)
launcher/LauncherDragWindow.cpp (+1/-1)
launcher/SoftwareCenterLauncherIcon.cpp (+0/-1)
tests/mock-application.h (+1/-0)
tests/test_application_launcher_icon.cpp (+118/-39)
tests/test_launcher.cpp (+4/-4)
tests/test_software_center_launcher_icon.cpp (+1/-1)
unity-shared/ApplicationManager.h (+2/-0)
unity-shared/BamfApplicationManager.cpp (+11/-0)
unity-shared/BamfApplicationManager.h (+2/-0)
unity-shared/StandaloneAppManager.cpp (+19/-9)
To merge this branch: bzr merge lp:~3v1n0/unity/create-local-desktop-file
Reviewer Review Type Date Requested Status
Christopher Townsend Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+179016@code.launchpad.net

Commit message

ApplicationLauncherIcon: Create a local desktop file when sticking an app that has not

Also make icon sticky only if both the icon itself and the inner app is sticky as well.

Description of the change

When we try to stick an application that has no desktop file (and no URI, in fact) we use bamf to generate the .desktop file. If/When this happens the application get notified with a desktop-file-updated signal that makes unity to update the icon and save it on favorites.

I sometime noticed that a "default icon" is shown instead of the real one, this seems mostly related to something else or a race... There's one line in bamf that can avoid this, but before reverting that I'd like to see if we can find a better solution.

As always, added and updated new unit tests

To post a comment you must log in.
Revision history for this message
Christopher Townsend (townsend) wrote :

I think this is almost working.

However, I ran into one problem where if I start a local app using ./name_of_exe, then the desktop file uses ./name_of_exe and when clicking the Launcher icon, it can't find ./name_of_exe. Is there any way to expand ./ to the full path?

Also, the .desktop file sticks around in .local/share/applications even after unpinning the icon from the Launcher. Is this intended behavior?

After I unpinned the icon, and then restarted the application using the full path, the already existing .desktop file did not get updated with the new full path. Not sure if the .desktop file is supposed to get updated or not.

Another behavior I noticed is that when I start the application using the Launcher icon (when the paths are correct), if I try quitting the application using Quit in the icon quicklist, the application won't quit.

review: Needs Information
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 :

The last behavior I noted about quiting from the Quicklist seems to only happen the first time I start the app and then try quitting. If I kill the app via the terminal and then open it again via Launcher icon, then Quit works.

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

Well, my comments about the Quicklist Quit may be invalid because for some reason, the new bamfdaemon crashed due to a "BadWindow (invalid Window parameter)" X error. Not really sure what caused this, but after starting the new bamfdaemon again, Quit now works as expected.

The other comments still seem valid.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

> However, I ran into one problem where if I start a local app using
> ./name_of_exe, then the desktop file uses ./name_of_exe and when clicking the
> Launcher icon, it can't find ./name_of_exe. Is there any way to expand ./ to
> the full path?

So, good catch! This lp:~3v1n0/bamf/working-dir-support bamf branch should fix this case by including the working directory path on generated .desktop file.

> Also, the .desktop file sticks around in .local/share/applications even after
> unpinning the icon from the Launcher. Is this intended behavior?

Yes, I thought about removing these .desktop files, but I also think that this is a also a nice way to create .desktop files for applications we only want to show in dash and that don't have a valid launcher (i.e. you stick it and then you unstick it).

> After I unpinned the icon, and then restarted the application using the full
> path, the already existing .desktop file did not get updated with the new full
> path. Not sure if the .desktop file is supposed to get updated or not.

Yeah, that's the wanted behaviour as the .desktop should be generated once and never touched anymore by unity.

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 :

For some reason, the TestLauncher.DragLauncherIconSavesIconOrderIfPositionHasNotChanged test is failing on armhf, which doesn't seem right...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

> For some reason, the
> TestLauncher.DragLauncherIconSavesIconOrderIfPositionHasNotChanged test is
> failing on armhf, which doesn't seem right...

Fixed it...

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

I still see the Quicklist Quit issue, but it's probably not related to this branch. I'll open a new bug about that.

This branch looks good, so +1!

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 2013-08-06 09:53:12 +0000
3+++ launcher/ApplicationLauncherIcon.cpp 2013-08-09 12:10:05 +0000
4@@ -75,16 +75,6 @@
5 , use_custom_bg_color_(false)
6 , bg_color_(nux::color::White)
7 {
8- app->seen = true;
9-
10- tooltip_text = app->title();
11- std::string const& icon = app->icon();
12- icon_name = (icon.empty() ? DEFAULT_ICON : icon);
13-
14- SetQuirk(Quirk::VISIBLE, app->visible());
15- SetQuirk(Quirk::ACTIVE, app->active());
16- SetQuirk(Quirk::RUNNING, app->running());
17-
18 LOG_INFO(logger) << "Created ApplicationLauncherIcon: "
19 << tooltip_text()
20 << ", icon: " << icon_name()
21@@ -95,10 +85,6 @@
22
23 SetApplication(app);
24
25- // Make sure we set the LauncherIcon stick bit too...
26- if (app->sticky())
27- SimpleLauncherIcon::Stick(false); // don't emit the signal
28-
29 WindowManager& wm = WindowManager::Default();
30 wm.window_minimized.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMinimized));
31 wm.window_moved.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMoved));
32@@ -110,28 +96,40 @@
33
34 ApplicationLauncherIcon::~ApplicationLauncherIcon()
35 {
36+ SetApplication(nullptr);
37+}
38+
39+void ApplicationLauncherIcon::SetApplication(ApplicationPtr const& app)
40+{
41+ if (app_ == app)
42+ return;
43+
44 if (app_)
45 {
46 app_->sticky = false;
47 app_->seen = false;
48 }
49-}
50-
51-void ApplicationLauncherIcon::SetApplication(ApplicationPtr const& app)
52-{
53- if (app_ == app)
54- return;
55
56 signals_conn_.Clear();
57
58+ if (!app)
59+ return;
60+
61 app_ = app;
62+ app_->seen = true;
63 SetupApplicationSignalsConnections();
64
65- // It's very likely that application desktop file has been changed, we need to
66- // inform the icon to make sure that it reloads the informations from it.
67+ // Let's update the icon properties to match the new application ones
68 app_->desktop_file.changed.emit(app_->desktop_file());
69 app_->title.changed.emit(app_->title());
70 app_->icon.changed.emit(app_->icon());
71+ app_->visible.changed.emit(app_->visible());
72+ app_->active.changed.emit(app_->active());
73+ app_->running.changed.emit(app_->running());
74+
75+ // Make sure we set the LauncherIcon stick bit too...
76+ if (app_->sticky())
77+ Stick(false); // don't emit the signal
78 }
79
80 void ApplicationLauncherIcon::SetupApplicationSignalsConnections()
81@@ -187,8 +185,7 @@
82 }));
83
84 signals_conn_.Add(app_->visible.changed.connect([this](bool const& visible) {
85- if (!IsSticky())
86- SetQuirk(Quirk::VISIBLE, visible);
87+ SetQuirk(Quirk::VISIBLE, IsSticky() ? true : visible);
88 }));
89
90 signals_conn_.Add(app_->closed.connect([this]() {
91@@ -245,7 +242,8 @@
92 bool ApplicationLauncherIcon::IsSticky() const
93 {
94 if (app_)
95- return app_->sticky();
96+ return app_->sticky() && SimpleLauncherIcon::IsSticky();
97+
98 return false;
99 }
100
101@@ -511,6 +509,7 @@
102 UpdateRemoteUri();
103 UpdateDesktopQuickList();
104 UpdateBackgroundColor();
105+ auto const& new_uri = RemoteUri();
106
107 if (!filename.empty())
108 {
109@@ -547,19 +546,17 @@
110 }
111 });
112
113- if (IsSticky())
114+ if (app_->sticky() && old_uri != new_uri)
115 {
116- position_forgot.emit();
117- position_saved.emit();
118+ UnStick();
119+ Stick();
120 }
121 }
122- else if (IsSticky())
123+ else if (app_->sticky())
124 {
125 UnStick();
126 }
127
128- auto const& new_uri = RemoteUri();
129-
130 if (old_uri != new_uri)
131 uri_changed.emit(new_uri);
132 }
133@@ -846,18 +843,20 @@
134 return;
135
136 app_->sticky = true;
137- SimpleLauncherIcon::Stick(save);
138+
139+ if (RemoteUri().empty())
140+ app_->CreateLocalDesktopFile();
141+ else
142+ SimpleLauncherIcon::Stick(save);
143 }
144
145 void ApplicationLauncherIcon::UnStick()
146 {
147+ if (!IsSticky())
148+ return;
149+
150 SimpleLauncherIcon::UnStick();
151-
152- if (!IsSticky())
153- return;
154-
155 SetQuirk(Quirk::VISIBLE, app_->running());
156-
157 app_->sticky = false;
158
159 if (!app_->running())
160
161=== modified file 'launcher/LauncherDragWindow.cpp'
162--- launcher/LauncherDragWindow.cpp 2013-07-01 21:20:51 +0000
163+++ launcher/LauncherDragWindow.cpp 2013-08-09 12:10:05 +0000
164@@ -115,7 +115,7 @@
165 }
166
167 bool LauncherDragWindow::OnAnimationTimeout()
168-{
169+{
170 nux::Geometry const& geo = GetGeometry();
171
172 int half_size = geo.width / 2;
173
174=== modified file 'launcher/SoftwareCenterLauncherIcon.cpp'
175--- launcher/SoftwareCenterLauncherIcon.cpp 2013-08-05 08:07:09 +0000
176+++ launcher/SoftwareCenterLauncherIcon.cpp 2013-08-09 12:10:05 +0000
177@@ -217,7 +217,6 @@
178 new_app->sticky = IsSticky();
179 SetApplication(new_app);
180 Stick();
181- position_saved.emit();
182
183 _source_manager.AddIdle([this] {
184 ShowTooltip();
185
186=== modified file 'tests/mock-application.h'
187--- tests/mock-application.h 2013-08-01 15:09:26 +0000
188+++ tests/mock-application.h 2013-08-09 12:10:05 +0000
189@@ -163,6 +163,7 @@
190 MOCK_CONST_METHOD1(OwnsWindow, bool(Window));
191 MOCK_CONST_METHOD0(GetSupportedMimeTypes, std::vector<std::string>());
192 MOCK_CONST_METHOD0(GetFocusableWindow, unity::ApplicationWindowPtr());
193+ MOCK_CONST_METHOD0(CreateLocalDesktopFile, bool());
194 MOCK_CONST_METHOD2(Focus, void(bool, int));
195 MOCK_CONST_METHOD0(Quit, void());
196
197
198=== modified file 'tests/test_application_launcher_icon.cpp'
199--- tests/test_application_launcher_icon.cpp 2013-08-06 09:53:30 +0000
200+++ tests/test_application_launcher_icon.cpp 2013-08-09 12:10:05 +0000
201@@ -89,7 +89,7 @@
202 empty_icon = new NiceMock<MockApplicationLauncherIcon>(empty_app);
203 ASSERT_EQ(empty_icon->DesktopFile(), NO_ICON_DESKTOP);
204
205- mock_app = std::make_shared<MockApplication::Nice>("");
206+ mock_app = std::make_shared<MockApplication::Nice>();
207 mock_icon = new NiceMock<MockApplicationLauncherIcon>(mock_app);
208 ASSERT_TRUE(mock_icon->DesktopFile().empty());
209 }
210@@ -185,7 +185,7 @@
211 EXPECT_EQ(mock_icon->icon_name(), DEFAULT_EMPTY_ICON);
212 }
213
214-TEST_F(TestApplicationLauncherIcon, Stick)
215+TEST_F(TestApplicationLauncherIcon, StickDesktopApp)
216 {
217 bool saved = false;
218 usc_icon->position_saved.connect([&saved] {saved = true;});
219@@ -200,55 +200,135 @@
220 EXPECT_FALSE(saved);
221 }
222
223-TEST_F(TestApplicationLauncherIcon, StickAndSave)
224+TEST_F(TestApplicationLauncherIcon, StickDesktopLessApp)
225 {
226 bool saved = false;
227 mock_icon->position_saved.connect([&saved] {saved = true;});
228
229+ mock_icon->Stick(false);
230+ EXPECT_TRUE(mock_app->sticky());
231+ EXPECT_FALSE(mock_icon->IsSticky());
232+ EXPECT_FALSE(mock_icon->IsVisible());
233+ EXPECT_FALSE(saved);
234+
235 mock_icon->Stick(true);
236- EXPECT_TRUE(mock_app->sticky());
237- EXPECT_TRUE(mock_icon->IsSticky());
238- EXPECT_TRUE(mock_icon->IsVisible());
239+ EXPECT_FALSE(saved);
240+}
241+
242+TEST_F(TestApplicationLauncherIcon, StickAndSaveDesktopApp)
243+{
244+ bool saved = false;
245+ usc_icon->position_saved.connect([&saved] {saved = true;});
246+
247+ usc_icon->Stick(true);
248+ EXPECT_TRUE(usc_app->sticky());
249+ EXPECT_TRUE(usc_icon->IsSticky());
250+ EXPECT_TRUE(usc_icon->IsVisible());
251 EXPECT_TRUE(saved);
252 }
253
254-TEST_F(TestApplicationLauncherIcon, StickStickedApplication)
255+TEST_F(TestApplicationLauncherIcon, StickAndSaveDesktopLessApp)
256+{
257+ bool saved = false;
258+ mock_icon->position_saved.connect([&saved] {saved = true;});
259+
260+ mock_icon->Stick(true);
261+ EXPECT_TRUE(mock_app->sticky());
262+ EXPECT_FALSE(mock_icon->IsSticky());
263+ EXPECT_FALSE(mock_icon->IsVisible());
264+ EXPECT_FALSE(saved);
265+}
266+
267+TEST_F(TestApplicationLauncherIcon, StickStickedDesktopApp)
268 {
269 auto app = std::make_shared<MockApplication::Nice>(USC_DESKTOP);
270 app->sticky = true;
271+ app->desktop_file_ = UM_DESKTOP;
272 MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));
273 ASSERT_TRUE(icon->IsSticky());
274 EXPECT_TRUE(icon->LauncherIconIsSticky());
275 }
276
277+TEST_F(TestApplicationLauncherIcon, StickStickedDesktopLessApp)
278+{
279+ auto app = std::make_shared<MockApplication::Nice>();
280+ app->sticky = true;
281+ MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));
282+ ASSERT_FALSE(icon->IsSticky());
283+ EXPECT_FALSE(icon->LauncherIconIsSticky());
284+}
285+
286+TEST_F(TestApplicationLauncherIcon, StickAndSaveDesktopApplication)
287+{
288+ EXPECT_CALL(*usc_app, CreateLocalDesktopFile()).Times(0);
289+ usc_icon->Stick(true);
290+
291+ EXPECT_TRUE(usc_icon->IsSticky());
292+}
293+
294+TEST_F(TestApplicationLauncherIcon, StickAndSaveDesktopLessApplication)
295+{
296+ auto app = std::make_shared<MockApplication::Nice>();
297+ MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));
298+
299+ EXPECT_CALL(*app, CreateLocalDesktopFile());
300+ icon->Stick(true);
301+
302+ EXPECT_TRUE(app->sticky());
303+ EXPECT_FALSE(icon->IsSticky());
304+}
305+
306 TEST_F(TestApplicationLauncherIcon, UnstickNotRunning)
307 {
308 bool forgot = false;
309- mock_app->running_ = false;
310- mock_icon->position_forgot.connect([&forgot] {forgot = true;});
311+ usc_app->running_ = false;
312+ usc_icon->position_forgot.connect([&forgot] {forgot = true;});
313
314- mock_icon->Stick();
315- mock_icon->UnStick();
316- EXPECT_FALSE(mock_app->sticky());
317- EXPECT_FALSE(mock_icon->IsSticky());
318- EXPECT_FALSE(mock_icon->IsVisible());
319+ usc_icon->Stick();
320+ usc_icon->UnStick();
321+ EXPECT_FALSE(usc_app->sticky());
322+ EXPECT_FALSE(usc_icon->IsSticky());
323+ EXPECT_FALSE(usc_icon->IsVisible());
324 EXPECT_TRUE(forgot);
325 }
326
327 TEST_F(TestApplicationLauncherIcon, UnstickRunning)
328 {
329 bool forgot = false;
330- mock_app->running_ = true;
331- mock_icon->position_forgot.connect([&forgot] {forgot = true;});
332+ usc_app->running_ = true;
333+ usc_icon->position_forgot.connect([&forgot] {forgot = true;});
334
335- mock_icon->Stick();
336- mock_icon->UnStick();
337- EXPECT_FALSE(mock_app->sticky());
338- EXPECT_FALSE(mock_icon->IsSticky());
339- EXPECT_TRUE(mock_icon->IsVisible());
340+ usc_icon->Stick();
341+ usc_icon->UnStick();
342+ EXPECT_FALSE(usc_app->sticky());
343+ EXPECT_FALSE(usc_icon->IsSticky());
344+ EXPECT_TRUE(usc_icon->IsVisible());
345 EXPECT_TRUE(forgot);
346 }
347
348+TEST_F(TestApplicationLauncherIcon, VisibleChanged)
349+{
350+ usc_app->visible_ = true;
351+ usc_app->visible.changed(usc_app->visible_);
352+ ASSERT_TRUE(usc_icon->IsVisible());
353+
354+ usc_app->visible_ = false;
355+ usc_app->visible.changed(usc_app->visible_);
356+ EXPECT_FALSE(usc_icon->IsVisible());
357+}
358+
359+TEST_F(TestApplicationLauncherIcon, VisibleChangedSticky)
360+{
361+ usc_icon->Stick();
362+ usc_app->visible_ = true;
363+ usc_app->visible.changed(usc_app->visible_);
364+ ASSERT_TRUE(usc_icon->IsVisible());
365+
366+ usc_app->visible_ = false;
367+ usc_app->visible.changed(usc_app->visible_);
368+ EXPECT_TRUE(usc_icon->IsVisible());
369+}
370+
371 TEST_F(TestApplicationLauncherIcon, UpdateDesktopFile)
372 {
373 usc_app->desktop_file_ = UM_DESKTOP;
374@@ -613,50 +693,49 @@
375
376 TEST_F(TestApplicationLauncherIcon, QuicklistMenuHasLockToLauncher)
377 {
378- mock_app->sticky = false;
379- EXPECT_TRUE(HasMenuItemWithLabel(mock_icon, "Lock to Launcher"));
380- EXPECT_FALSE(HasMenuItemWithLabel(mock_icon, "Unlock from Launcher"));
381+ usc_app->sticky = false;
382+ EXPECT_TRUE(HasMenuItemWithLabel(usc_icon, "Lock to Launcher"));
383+ EXPECT_FALSE(HasMenuItemWithLabel(usc_icon, "Unlock from Launcher"));
384 }
385
386 TEST_F(TestApplicationLauncherIcon, QuicklistMenuItemLockToLauncher)
387 {
388 bool saved = false;
389- mock_app->sticky = false;
390- mock_icon->position_saved.connect([&saved] {saved = true;});
391+ usc_icon->position_saved.connect([&saved] {saved = true;});
392
393- auto const& menu_item = GetMenuItemWithLabel(mock_icon, "Lock to Launcher");
394+ auto const& menu_item = GetMenuItemWithLabel(usc_icon, "Lock to Launcher");
395 ASSERT_NE(menu_item, nullptr);
396
397- EXPECT_CALL(*mock_icon, Stick(true));
398+ EXPECT_CALL(*usc_icon, Stick(true));
399 dbusmenu_menuitem_handle_event(menu_item, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);
400
401 EXPECT_TRUE(saved);
402- EXPECT_TRUE(mock_app->sticky());
403- EXPECT_TRUE(mock_icon->IsSticky());
404+ EXPECT_TRUE(usc_app->sticky());
405+ EXPECT_TRUE(usc_icon->IsSticky());
406 }
407
408 TEST_F(TestApplicationLauncherIcon, QuicklistMenuHasUnLockToLauncher)
409 {
410- mock_app->sticky = true;
411- EXPECT_TRUE(HasMenuItemWithLabel(mock_icon, "Unlock from Launcher"));
412- EXPECT_FALSE(HasMenuItemWithLabel(mock_icon, "Lock to Launcher"));
413+ usc_icon->Stick();
414+ EXPECT_TRUE(HasMenuItemWithLabel(usc_icon, "Unlock from Launcher"));
415+ EXPECT_FALSE(HasMenuItemWithLabel(usc_icon, "Lock to Launcher"));
416 }
417
418 TEST_F(TestApplicationLauncherIcon, QuicklistMenuItemUnLockFromLauncher)
419 {
420 bool forgot = false;
421- mock_icon->position_forgot.connect([&forgot] {forgot = true;});
422- mock_icon->Stick();
423+ usc_icon->position_forgot.connect([&forgot] {forgot = true;});
424+ usc_icon->Stick();
425
426- auto const& menu_item = GetMenuItemWithLabel(mock_icon, "Unlock from Launcher");
427+ auto const& menu_item = GetMenuItemWithLabel(usc_icon, "Unlock from Launcher");
428 ASSERT_NE(menu_item, nullptr);
429
430- EXPECT_CALL(*mock_icon, UnStick());
431+ EXPECT_CALL(*usc_icon, UnStick());
432 dbusmenu_menuitem_handle_event(menu_item, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);
433
434 EXPECT_TRUE(forgot);
435- EXPECT_FALSE(mock_app->sticky());
436- EXPECT_FALSE(mock_icon->IsSticky());
437+ EXPECT_FALSE(usc_app->sticky());
438+ EXPECT_FALSE(usc_icon->IsSticky());
439 }
440
441 TEST_F(TestApplicationLauncherIcon, QuicklistMenuHasNotQuit)
442
443=== modified file 'tests/test_launcher.cpp'
444--- tests/test_launcher.cpp 2013-06-10 16:10:27 +0000
445+++ tests/test_launcher.cpp 2013-08-09 12:10:05 +0000
446@@ -205,7 +205,7 @@
447 .WillRepeatedly(Return(false));
448
449 launcher_->DndStarted("");
450- Utils::WaitForTimeout(1);
451+ Utils::WaitPendingEvents();
452
453 EXPECT_FALSE(first->GetQuirk(launcher::AbstractLauncherIcon::Quirk::DESAT));
454 EXPECT_FALSE(second->GetQuirk(launcher::AbstractLauncherIcon::Quirk::DESAT));
455@@ -330,7 +330,7 @@
456 launcher_->HideDragWindow();
457
458 // Let's wait the drag icon animation to be completed
459- Utils::WaitForTimeout(1);
460+ Utils::WaitPendingEvents();
461 EXPECT_EQ(launcher_->GetDraggedIcon(), nullptr);
462 }
463
464@@ -367,7 +367,7 @@
465 EXPECT_TRUE(model_saved);
466
467 // Let's wait the drag icon animation to be completed
468- Utils::WaitForTimeout(1);
469+ Utils::WaitUntilMSec([this] { return launcher_->GetDraggedIcon(); }, false, 2000);
470 EXPECT_EQ(launcher_->GetDraggedIcon(), nullptr);
471 }
472
473@@ -411,7 +411,7 @@
474 EXPECT_FALSE(model_saved);
475
476 // Let's wait the drag icon animation to be completed
477- Utils::WaitForTimeout(1);
478+ Utils::WaitUntilMSec([this] { return launcher_->GetDraggedIcon(); }, false, 2000);
479 EXPECT_EQ(launcher_->GetDraggedIcon(), nullptr);
480 }
481
482
483=== modified file 'tests/test_software_center_launcher_icon.cpp'
484--- tests/test_software_center_launcher_icon.cpp 2013-08-05 08:02:47 +0000
485+++ tests/test_software_center_launcher_icon.cpp 2013-08-09 12:10:05 +0000
486@@ -158,7 +158,7 @@
487 bool saved = false;
488 usc->sticky = true;
489 icon.position_saved.connect([&saved] {saved = true;});
490- ASSERT_TRUE(icon.IsSticky());
491+ ASSERT_FALSE(icon.IsSticky());
492
493 icon.OnFinished(glib::Variant(g_variant_new("(s)", "exit-success")));
494 ASSERT_TRUE(icon.IsSticky());
495
496=== modified file 'unity-shared/ApplicationManager.h'
497--- unity-shared/ApplicationManager.h 2013-07-31 01:15:14 +0000
498+++ unity-shared/ApplicationManager.h 2013-08-09 12:10:05 +0000
499@@ -89,6 +89,8 @@
500 // Calls quit on all the Windows for this application.
501 virtual void Quit() const = 0;
502
503+ virtual bool CreateLocalDesktopFile() const = 0;
504+
505 nux::ROProperty<std::string> desktop_file;
506 nux::ROProperty<std::string> title;
507 nux::ROProperty<std::string> icon;
508
509=== modified file 'unity-shared/BamfApplicationManager.cpp'
510--- unity-shared/BamfApplicationManager.cpp 2013-07-31 01:15:14 +0000
511+++ unity-shared/BamfApplicationManager.cpp 2013-08-09 12:10:05 +0000
512@@ -454,6 +454,17 @@
513 }
514 }
515
516+bool Application::CreateLocalDesktopFile() const
517+{
518+ if (!desktop_file().empty())
519+ return false;
520+
521+ glib::Object<BamfControl> control(bamf_control_get_default());
522+ bamf_control_create_local_desktop_file(control, bamf_app_);
523+
524+ return true;
525+}
526+
527 bool Application::GetSeen() const
528 {
529 return g_object_get_qdata(glib::object_cast<GObject>(bamf_app_),
530
531=== modified file 'unity-shared/BamfApplicationManager.h'
532--- unity-shared/BamfApplicationManager.h 2013-07-31 01:15:14 +0000
533+++ unity-shared/BamfApplicationManager.h 2013-08-09 12:10:05 +0000
534@@ -124,6 +124,8 @@
535
536 virtual void Quit() const;
537
538+ virtual bool CreateLocalDesktopFile() const;
539+
540 virtual std::string repr() const;
541
542 private: // Property getters and setters
543
544=== modified file 'unity-shared/StandaloneAppManager.cpp'
545--- unity-shared/StandaloneAppManager.cpp 2013-01-17 14:09:35 +0000
546+++ unity-shared/StandaloneAppManager.cpp 2013-08-09 12:10:05 +0000
547@@ -75,28 +75,38 @@
548 return;
549 }
550 std::string app_name = app->title();
551- app->visible.changed.connect([app_name](bool const& value) {
552+ app->title.changed.connect([&app_name](std::string const& value) {
553+ cout << app_name << " changed name to: " << value << endl;
554+ app_name = value;
555+ });
556+ app->icon.changed.connect([&app_name](std::string const& value) {
557+ cout << app_name << " icon changed: " << value << endl;
558+ });
559+ app->desktop_file.changed.connect([&app_name](std::string const& value) {
560+ cout << app_name << " desktop file changed: " << value << endl;
561+ });
562+ app->visible.changed.connect([&app_name](bool value) {
563 cout << app_name << " visibility changed: " << (value ? "yes" : "no") << endl;
564 });
565- app->running.changed.connect([app_name](bool const& value) {
566+ app->running.changed.connect([&app_name](bool value) {
567 cout << app_name << " running changed: " << (value ? "yes" : "no") << endl;
568 });
569- app->active.changed.connect([app_name](bool const& value) {
570+ app->active.changed.connect([&app_name](bool value) {
571 cout << app_name << " active changed: " << (value ? "yes" : "no") << endl;
572 });
573- app->urgent.changed.connect([app_name](bool const& value) {
574+ app->urgent.changed.connect([&app_name](bool value) {
575 cout << app_name << " urgent changed: " << (value ? "yes" : "no") << endl;
576 });
577- app->closed.connect([app_name]() {
578+ app->closed.connect([&app_name]() {
579 cout << app_name << " closed." << endl;
580 });
581- app->window_opened.connect([app_name](ApplicationWindow const& window) {
582+ app->window_opened.connect([&app_name](ApplicationWindow const& window) {
583 cout << "** " << app_name << " window opened: " << window.title() << endl;
584 });
585- app->window_closed.connect([app_name]() {
586+ app->window_closed.connect([&app_name]() {
587 cout << "** " << app_name << " window closed" << endl;
588 });
589- app->window_moved.connect([app_name](ApplicationWindow const& window) {
590+ app->window_moved.connect([&app_name](ApplicationWindow const& window) {
591 cout << "** " << app_name << " window moved: " << window.title() << endl;
592 });
593 app->seen = true;
594@@ -195,7 +205,7 @@
595
596 ApplicationList apps = manager.GetRunningApplications();
597
598- for (auto app : apps)
599+ for (auto const& app : apps)
600 {
601 dump_app(app);
602 connect_events(app);