Merge lp:~thomir-deactivatedaccount/unity/sc-integration-phase2 into lp:unity

Proposed by Tim Penhey
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 2183
Proposed branch: lp:~thomir-deactivatedaccount/unity/sc-integration-phase2
Merge into: lp:unity
Diff against target: 554 lines (+225/-42)
10 files modified
plugins/unityshell/src/BamfLauncherIcon.h (+1/-1)
plugins/unityshell/src/Launcher.cpp (+7/-1)
plugins/unityshell/src/Launcher.h (+7/-3)
plugins/unityshell/src/LauncherController.cpp (+32/-20)
plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp (+93/-5)
plugins/unityshell/src/SoftwareCenterLauncherIcon.h (+23/-3)
tests/autopilot/autopilot/emulators/X11.py (+8/-6)
tests/autopilot/autopilot/emulators/unity/icons.py (+3/-0)
tests/autopilot/autopilot/emulators/unity/launcher.py (+14/-1)
tests/autopilot/autopilot/tests/test_launcher.py (+37/-2)
To merge this branch: bzr merge lp:~thomir-deactivatedaccount/unity/sc-integration-phase2
Reviewer Review Type Date Requested Status
Tim Penhey (community) Approve
Marco Trevisan (Treviño) Needs Fixing
Thomi Richards Pending
Alex Launi Pending
Matthew Paul Thomas design Pending
Review via email: mp+97784@code.launchpad.net

This proposal supersedes a proposal from 2012-03-04.

Commit message

Add animation of icon moving to the launcher, and the wiggle when installation is complete.

Description of the change

This is the second phase of Software Center integration with the Unity launcher. The first phase included progress bars on the icon, as well as a "Waiting to install" tooltip. The second phase includes an icon moving animation from Software Center to the launcher, and also icon Activate() changes. The software center design spec for the whole feature is:

https://wiki.ubuntu.com/SoftwareCenter#Learning_how_to_launch_an_application

The first phase landed around Unity 5.2.0, but got broken right before the release of 5.2.0 (bug #932280). The fix to it lies in this branch: https://code.launchpad.net/~bilalakhtar/unity/fix-sc-launcher-integration/+merge/93908 . The fix has been waiting for review for more than 10 days now, can someone ensure that it gets in for Unity 5.6.0? Since that branch merely contains a fix (all strings have been in since before 5.2.0) so neither that branch nor this branch needs a UIFe.

Note that this branch contains the code from the above merge request too, so if someone were to merge this branch into lp:unity, there would be no need to merge lp:~bilalakhtar/unity/fix-sc-launcher-integration. The reason why I've made two different branches is because I'd like to give the lp:~bilalakhtar/unity/fix-sc-launcher-integration a higher priority (5.6.0) while this could get in to either 5.6.0 (unlikely) or 5.8.0.

The implementation is very stable, with unit tests and all.

Here's a YouTube video of this branch in action:
http://www.youtube.com/watch?v=6peOjOrcURA

To post a comment you must log in.
Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

Bug request for the whole issue was bug #761851, but it got marked Fix Released after phase 1. Not sure if I should mark it Triaged again, or not.

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote : Posted in a previous version of this proposal

This branche introduces a change in behavior (flying icon). It clearly needs an UIFe and a FFe.
Also, we saw that the previous code was broken without anyone noticing. This shows that you need tests for you code. Can you please first ensure that lp:~bilalakhtar/unity/fix-sc-launcher-integration gets autopilot tests for it not regressing again?

Revision history for this message
Matthew Paul Thomas (mpt) wrote : Posted in a previous version of this proposal

Nice work! There are many details to tweak: the origin point is too high, the destination point looks to be on top of another launcher element rather than in a gap, the initial icon size is too small, and (as "krnekhelesh" pointed out on YouTube) the animation should happen after authentication rather than before. But this is a definite improvement, thank you.

review: Approve (design)
Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

@didrocks: When is Unity 5.6.0 coming out? Tomorrow, right?

I won't be able to add autopilot tests until today evening and that would mean a merge of lp:~bilalakhtar/unity/fix-sc-launcher-integration AFTER 5.6.0 (since by then everyone would have gone off to sleep). If that's the case, then can you merge that branch right now and I'll add tests today evening?

But if I'm wrong about the release date of 5.6.0 then don't merge that branch until I've added tests.

@mpt: Thanks for the review! Since you've approved already I'll ensure this gets in before I work on those tweaks.

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote : Posted in a previous version of this proposal

Hey Bilal, there are two things:
5.6 is coming out tomorrow morning if the last regression is fixed. We don't merge anything for a week already as we are in freeze. So this would mean your branch will be merged for 5.8 (once you unfreeze).

Oh, and we don't let entering trunk code without test, so yeah, it's a pre-requisite to push to the other branch some tests.

For that one, you will need to have a Feature freeze exception acked and a UI Freeze exception acked as well before meriging in trunk (in addition to test and from a review from some dx guys, I'm not doing the review. ;)).

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

64 + sigc::signal<void, std::string const&, AbstractLauncherIcon::Ptr, std::string const&, std::string const&,
65 + gint32, gint32, gint32> launcher_addrequest_special;

You can just use int at this level, so we are more C++ conformant.

139 + ((SoftwareCenterLauncherIcon*)result.GetPointer())->Animate(launcher_, icon_x, icon_y, icon_size);

Don't use C-style casts.

184 + finished = true;
185 + finished_just_now = true;

Set them using the constructor initializer list.

201 +void SoftwareCenterLauncherIcon::AddSelfToLauncher()
202 +{
203 + _launcher->icon_animation_complete.emit(self_abstract);
204 +}

306 + void AddSelfToLauncher();

322 + AbstractLauncherIcon::Ptr self_abstract;

I don't really think you need those, please don't do that. You already handling an AbstractLauncherIcon.

244 + target_x = (int)current_bamf_icon->GetCenter(launcher->monitor).x;

Again, use static_cast

256 + g_timeout_add(30, &SoftwareCenterLauncherIcon::OnDragWindowAnimComplete, this);

Maybe it can be a little more lazy.
Anyway I'd focus on fixing the problem at the source, instead of using this workaround.

308 + static gboolean OnDragWindowAnimComplete(gpointer data);

Put in private fields.

310 + void Animate(nux::ObjectPtr<Launcher> launcher, gint32 icon_x, gint32 icon_y, gint32 icon_size);

You can also just use Animate(nux::ObjectPtr<Launcher> const& launcher ... And move to pure int's.

312 + void ActivateLauncherIcon(ActionArg arg);

Put it in protected field.

323 + bool finished;
324 + bool finished_just_now;

Add the _ as prefix for private variables. (Actually it would be betteer use a suffixed _, as defined by our coding standards, but in that case you need to update all the members).

For testing, I think you can also emulate something without autopilot by making your LauncherSpecial request to be caused by a fake dbus server you write on tests.

review: Needs Fixing
Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

I've made all the changes that were possible as per Marco's review, except for the tests (which I'm adding now) and I also left some other ones which would break the code if I did change (I've left code comments at those spots).

Revision history for this message
Gary Lasker (gary-lasker) wrote : Posted in a previous version of this proposal

Hi Bilal! I just want to say thank you for this. It's beautiful!! :D

I am very much looking forward to seeing this in Precise!!!

Thanks everybody,
Gary

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

189 + _finished = true;
190 + _finished_just_now = true;

You don't need them anymore.

329 + AbstractLauncherIcon::Ptr self_abstract;

Are you sure you need to save that on the class? I guess you can just Reference your icon before that it gets unreferenced...

+ if (((int)current_bamf_icon->GetCenter(launcher->monitor).x) != 0 &&
248 + ((int)current_bamf_icon->GetCenter(launcher->monitor).y) != 0)

Those are still C-style casts :)

139 + static_cast<SoftwareCenterLauncherIcon*>(result.GetPointer())->Animate(launcher_, icon_x, icon_y, icon_size);

Do this only if you're sure that this won't happen for another kind of icon... Otherwise use, at least, the dynamic_cast.

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

Branch is ready again, please review :)

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

> 189 + _finished = true;
> 190 + _finished_just_now = true;
>
> You don't need them anymore.

Those lines are part of the Finished function, so they're very much needed for the Activate function to work.

>
> 329 + AbstractLauncherIcon::Ptr self_abstract;
>
> Are you sure you need to save that on the class? I guess you can just
> Reference your icon before that it gets unreferenced...
>

That's the problem. I did try that, but it didn't work. Got a segfault (totally strange). Storing it's own reference in a variable worked, though.

> + if (((int)current_bamf_icon->GetCenter(launcher->monitor).x) != 0 &&
> 248 + ((int)current_bamf_icon->GetCenter(launcher->monitor).y) !=
> 0)
>
> Those are still C-style casts :)

Fixed in latest commit.

>
> 139 + static_cast<SoftwareCenterLauncherIcon*>(result.GetPointer())->Anim
> ate(launcher_, icon_x, icon_y, icon_size);
>
> Do this only if you're sure that this won't happen for another kind of icon...
> Otherwise use, at least, the dynamic_cast.

Yes, it won't happen, because I'm using a special function to create the result variable. That function is hard-coded to create only a SoftwareCenterLauncherIcon and nothing else. So a static cast is safe here.

Thanks for the review anyway, it would be great if you reviewed again!

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

> Those lines are part of the Finished function, so they're very much needed for
> the Activate function to work.

Oh, yes sure. I didn't notice they were inside the lambda, sorry.

> > 329 + AbstractLauncherIcon::Ptr self_abstract;
> >
> > Are you sure you need to save that on the class? I guess you can just
> > Reference your icon before that it gets unreferenced...
> >
>
> That's the problem. I did try that, but it didn't work. Got a segfault
> (totally strange). Storing it's own reference in a variable worked, though.

I want to look to this further and do some experiments with it... I think we should find a cleaner solution.

357 +class SoftwareCenterLauncherIcon(SimpleLauncherIcon):
358 + """Represents a launcher icon of a Software Center app."""

Also on tests SoftwareCenterLauncherIcon should extend BamfLauncherIcon.
This would also avoid the change on line 378

About the autoplito tests, I think that maybe you should define functions to add icons to the launcher in the emulator, also once you've finished them ask a review by Thomi for the tests.

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

I myself have given up on the AbstractLauncherIcon::Ptr thing after multiple hits and misses. I think it's okay in it's current form, an extra line or two but not too ugly.

Other than that, do you think the code (other than the tests) is good? Could you approve the code then? Of course I'd need to file a UIFe and FFe request before it can get merged, but in the meantime you can approve/reject it.

Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote : Posted in a previous version of this proposal

Hi,

There's a problem with the autopilot test (Exception on cleanup), which I will look at and fix on Monday. However, more concerning is that running the autopilot test causes unity / compiz to crash frequently (maybe 50% of the time). I will attempt to look into this as well, and let you know what the issue is.

@Marco - you mentioned above that it might be a good idea to add methods to the Launcher emulator for adding and removing icons - we already have this, but we can't use it in this instance, since this isn't a regular application icon.

review: Needs Fixing
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote : Posted in a previous version of this proposal
Download full text (6.2 KiB)

Hi,

Upon further investigation, the crash is inside the software center launcher icon. I get a segfault about 50% of the time when running the autopilot test. Here's the stack trace:

#0 0x00007fffe4f02ca2 in unity::launcher::SoftwareCenterLauncherIcon::Animate (this=0x0, launcher=..., icon_x=100, icon_y=100, icon_size=32)
    at /home/thomi/code/canonical/unity/sc-integration-phase2/plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp:92
#1 0x00007fffe509ecd7 in unity::launcher::Controller::Impl::OnLauncherAddRequestSpecial (this=0x903c90, path=..., before=..., aptdaemon_trans_id=..., icon_path=...,
    icon_x=100, icon_y=100, icon_size=32) at /home/thomi/code/canonical/unity/sc-integration-phase2/plugins/unityshell/src/LauncherController.cpp:406
#2 0x00007fffe50aa989 in sigc::bound_mem_functor7<void, unity::launcher::Controller::Impl, std::string const&, nux::ObjectPtr<unity::launcher::AbstractLauncherIcon>, std::string const&, std::string const&, int, int, int>::operator() (this=0xd24498, _A_a1=..., _A_a2=..., _A_a3=..., _A_a4=..., _A_a5=@0x7fffffffe0f0: 100,
    _A_a6=@0x7fffffffe0f4: 100, _A_a7=@0x7fffffffe0f8: 32) at /usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:2277
#3 0x00007fffe50a9d5f in sigc::adaptor_functor<sigc::bound_mem_functor7<void, unity::launcher::Controller::Impl, std::string const&, nux::ObjectPtr<unity::launcher::AbstractLauncherIcon>, std::string const&, std::string const&, int, int, int> >::operator()<std::string const&, nux::ObjectPtr<unity::launcher::AbstractLauncherIcon> const&, std::string const&, std::string const&, int const&, int const&, int const&> (this=0xd24490, _A_arg1=..., _A_arg2=..., _A_arg3=..., _A_arg4=...,
    _A_arg5=@0x7fffffffe0f0: 100, _A_arg6=@0x7fffffffe0f4: 100, _A_arg7=@0x7fffffffe0f8: 32) at /usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:213
#4 0x00007fffe50a89b2 in sigc::internal::slot_call7<sigc::bound_mem_functor7<void, unity::launcher::Controller::Impl, std::string const&, nux::ObjectPtr<unity::launcher::AbstractLauncherIcon>, std::string const&, std::string const&, int, int, int>, void, std::string const&, nux::ObjectPtr<unity::launcher::AbstractLauncherIcon>, std::string const&, std::string const&, int, int, int>::call_it (rep=0xd24460, a_1=..., a_2=..., a_3=..., a_4=..., a_5=@0x7fffffffe0f0: 100, a_6=@0x7fffffffe0f4: 100,
    a_7=@0x7fffffffe0f8: 32) at /usr/include/sigc++-2.0/sigc++/functors/slot.h:383
#5 0x00007fffe508b1e9 in sigc::internal::signal_emit7<void, std::string const&, nux::ObjectPtr<unity::launcher::AbstractLauncherIcon>, std::string const&, std::string const&, int, int, int, sigc::nil>::emit (impl=0xd24410, _A_a1=..., _A_a2=..., _A_a3=..., _A_a4=..., _A_a5=@0x7fffffffe0f0: 100, _A_a6=@0x7fffffffe0f4: 100,
    _A_a7=@0x7fffffffe0f8: 32) at /usr/include/sigc++-2.0/sigc++/signal.h:2567
#6 0x00007fffe508995d in sigc::signal7<void, std::string const&, nux::ObjectPtr<unity::launcher::AbstractLauncherIcon>, std::string const&, std::string const&, int, int, int, sigc::nil>::emit (this=0xca1690, _A_a1=..., _A_a2=..., _A_a3=..., _A_a4=..., _A_a5=@0x7fffffffe0f0: 100, _A_a6=@0x7fffffffe0f4: 100, _A_a7=@0x7fffffffe0f8: 32)
    at /usr/include/sigc++-2.0/sigc++/s...

Read more...

review: Needs Fixing
Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

Thomi:

I've fixed the crash, pull the branch and you won't have the problem again :)

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

Also, Marco: Can you review the code? Everything's final now, Thomi will be reviewing the tests. The code is final and works perfectly now.

Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

I don't like how the test skips if the software center is already pinned. You should have your setup ensure that the launcher is not pinned, so that the test can execute.

review: Needs Fixing (test)
Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

Thanks for the review Alex, now it unlocks the icon before proceeding. That fixes the issue. Can you review the tests again now?

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote : Posted in a previous version of this proposal

Note that it will need a Feature Freeze and UI Freeze exception acked. Can you please proceed it?

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

I thought that was after the code review? Anyway, I'll do that now.

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote : Posted in a previous version of this proposal

that's to be done in parallel in fact as you need to get the release team approval before the code is merged.

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

I've filed bug #955147 , and subscribed ubuntu-release to it. That bug contains everything needed for the exception requests. I've also posted to the docs and translators mailing lists and linked the postings there.

Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

The dbus code should be moved into the launcher emulator. Secondly, the assertion that there are more icons may not be true. Consider the case where some applications crash unexpectedly. I would just check for the waiting to install tooltip. That's the real sign that everything worked.

I don't think this test needs to go in its own class. It will be just fine in LauncherTests. I also feel like this test might need some clean up routine to return the desktop to its original state. Does the AddLauncherItemFromPosition call pin the launcher, or is it transient?

review: Needs Fixing
Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

emulate_software_center_dbus_call is sort of a bad name, this might get used somewhere else so just wrap the launcher function and call it add_launcher_itom_from_position.

instead of importing dbus and doing bus.SessionBus just do:
   from autopilot.emulators.dbus_handler import session_bus
session_bus is your bus object.

define the desktop file in a variable instead of reusing the string over and over.

sleep should not be the first thing you do in your test, also not the last!

You need to check that the icon isn't None when you get it after the dbus call. If the call failed, then the test will crash. So assert that it is not None
self.assertThat(icon, Not(Is(None)))

Instead of asserting that icon_text == "blah", Equals(True) do this
self.assertThat(icon[0].tooltip_text, Equals("Waiting to install"))

cleanup should go like this,
add an anonymous function to your test
def cleanup():
    if icon is not None:
        launcher_instance.unlock_from_launcher(icon[0])
then
icon = self.launcher.model.get_icon_by_desktop_file(DESKTOP_FILE_PATH)
if icon is not None:
    launcher_instance.unlock_from_launcher(icon[0])
    sleep(1)
else:
    self.addCleanup(cleanup)

review: Needs Fixing
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

Also, make sure to cover in your test this change (it should be implicit, I guess): https://code.launchpad.net/~bilalakhtar/unity/fix-sc-launcher-integration/+merge/93908 so we can merge all together (if we get the exception, otherwise you need to backport the tests to only that branch).

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote : Posted in a previous version of this proposal

  Hi Marco,

That change is already covered. In fact, the whole test function evolves
around that.

There would be no way to make it implicit without going through the whole
procedure,since all functions are interconnected.

I'll make the rest if the changes soon.

------------------------------
*From:* "Marco Trevisan (Treviño)" <mail@3v1n0.net>
*To:* "Bilal Akhtar" <email address hidden>
*Sent:* 14 March, 2012 1:44 PM
*Subject:* Re: [Merge] lp:~bilalakhtar/unity/sc-integration-phase2 into
lp:unity

Also, make sure to cover in your test this change (it should be implicit, I
guess):
https://code.launchpad.net/~bilalakhtar/unity/fix-sc-launcher-integration/+merge/93908so
we can merge all together (if we get the exception, otherwise you need
to backport the tests to only that branch).
--
https://code.launchpad.net/~bilalakhtar/unity/sc-integration-phase2/+merge/95795
You are the owner of lp:~bilalakhtar/unity/sc-integration-phase2.

Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

Tests now look good Bilal

review: Approve (testing)
Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

I missed this yesterday, please move def cleanup() to be the first thing in test_software_center_add_icon

review: Needs Fixing
Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

Aced

review: Approve
Revision history for this message
Tim Penhey (thumper) wrote :

There were a number of C++ fixes needed. Quicker to just take over at this point to make sure we get this landed. Thanks Bilal for all your work on this.

Revision history for this message
Tim Penhey (thumper) wrote :

Code is good, has AP test.

review: Approve
Revision history for this message
Alex Launi (alexlauni) wrote :

Can you update the autopilot test to move the cleanup routine to the beginning of the test method.

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

 + //TODO: don't iterate through them and pick the last one, just use back() to get the last one.
375 + for (auto current_bamf_icon : bamf_icons)
376 + {

Wouldn't be better to use a reverse iterator at this point, until the back()?

31 + _drag_window->SetAnimationTarget((int)(_drag_icon->GetCenter(monitor).x),
32 (int)(_drag_icon->GetCenter(monitor).y));

There are still some C casts, move them away when finding them :)

157 + void OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon::Ptr before, std::string const& aptdaemon_trans_id, std::string const& icon_path,
158 + int icon_x, int icon_y, int icon_size);

Use one line, or split it to fit the classic 80th coulumn ;)

428 SetProgress(progress/100.0f);
429 + g_variant_unref(property_value);

glib::Variant here could be more friendly ;)

Revision history for this message
Bilal Akhtar (bilalakhtar) wrote :

Thanks for the review Marco, I think we'll go ahead with how it is right now, since I don't want any more delays (so that we don't miss the 5.8 release for this change) and I'll make all those changes you suggested coupled with a few tweaks in the design as suggested by MPT in his review on the previous merge request, into a phase 3 branch. The only blocker for this branch is the freeze exception.

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

For me code it's fine... In the case you get an exception.

review: Approve
Revision history for this message
Bilal Akhtar (bilalakhtar) wrote :

Freeze exception just got the approval, on the linked bug.

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

Tested again, this crashes to me on anther machine.
Here you are the log: http://paste.ubuntu.com/893381/

Please merge with this the branch lp:~3v1n0/unity/favorite-store-crash-fix

review: Needs Fixing
Revision history for this message
Bilal Akhtar (bilalakhtar) wrote :

That's a completely unrelated branch, right? That's a problem with trunk, not this branch.

Revision history for this message
Tim Penhey (thumper) :
review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

No commit message specified.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/BamfLauncherIcon.h'
2--- plugins/unityshell/src/BamfLauncherIcon.h 2012-03-22 15:14:49 +0000
3+++ plugins/unityshell/src/BamfLauncherIcon.h 2012-03-28 22:26:18 +0000
4@@ -43,7 +43,7 @@
5 BamfLauncherIcon(BamfApplication* app);
6 virtual ~BamfLauncherIcon();
7
8- void ActivateLauncherIcon(ActionArg arg);
9+ virtual void ActivateLauncherIcon(ActionArg arg);
10
11 std::string DesktopFile();
12
13
14=== modified file 'plugins/unityshell/src/Launcher.cpp'
15--- plugins/unityshell/src/Launcher.cpp 2012-03-27 17:27:27 +0000
16+++ plugins/unityshell/src/Launcher.cpp 2012-03-28 22:26:18 +0000
17@@ -1769,6 +1769,11 @@
18 Resize();
19 }
20
21+int Launcher::GetIconSize() const
22+{
23+ return _icon_size;
24+}
25+
26 void Launcher::Resize()
27 {
28 UScreen* uscreen = UScreen::GetDefault();
29@@ -2955,7 +2960,8 @@
30 g_variant_get(parameters, "(ssiiiss)", &title, &icon, &icon_x, &icon_y, &icon_size, &desktop_file, &aptdaemon_task, NULL);
31
32 Launcher* self = (Launcher*)user_data;
33- self->launcher_addrequest_special.emit(desktop_file, AbstractLauncherIcon::Ptr(), aptdaemon_task, icon);
34+ self->launcher_addrequest_special.emit(desktop_file, AbstractLauncherIcon::Ptr(), aptdaemon_task, icon,
35+ icon_x, icon_y, icon_size);
36
37 g_dbus_method_invocation_return_value(invocation, nullptr);
38 g_free(icon);
39
40=== modified file 'plugins/unityshell/src/Launcher.h'
41--- plugins/unityshell/src/Launcher.h 2012-03-21 14:44:41 +0000
42+++ plugins/unityshell/src/Launcher.h 2012-03-28 22:26:18 +0000
43@@ -40,6 +40,7 @@
44 #include "LauncherHideMachine.h"
45 #include "LauncherHoverMachine.h"
46 #include "UBusWrapper.h"
47+#include "SoftwareCenterLauncherIcon.h"
48
49
50 namespace unity
51@@ -68,6 +69,7 @@
52 AbstractLauncherIcon::Ptr GetSelectedMenuIcon() const;
53
54 void SetIconSize(int tile_size, int icon_size);
55+ int GetIconSize() const;
56
57 LauncherHideMachine* HideMachine() { return _hide_machine; }
58
59@@ -113,8 +115,10 @@
60 void Resize();
61
62 sigc::signal<void, char*, AbstractLauncherIcon::Ptr> launcher_addrequest;
63- sigc::signal<void, std::string const&, AbstractLauncherIcon::Ptr, std::string const&, std::string const&> launcher_addrequest_special;
64+ sigc::signal<void, std::string const&, AbstractLauncherIcon::Ptr, std::string const&, std::string const&,
65+ int, int, int> launcher_addrequest_special;
66 sigc::signal<void, AbstractLauncherIcon::Ptr> launcher_removerequest;
67+ sigc::signal<void, AbstractLauncherIcon::Ptr> icon_animation_complete;
68 sigc::signal<void> selection_change;
69 sigc::signal<void> hidden_changed;
70
71@@ -128,6 +132,8 @@
72
73 static const int ANIM_DURATION_SHORT;
74
75+ void RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLauncherIcon::Ptr icon, nux::ObjectPtr<nux::IOpenGLBaseTexture> texture);
76+
77 protected:
78 // Introspectable methods
79 std::string GetName() const;
80@@ -279,8 +285,6 @@
81
82 void OnActionDone(GVariant* data);
83
84- void RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLauncherIcon::Ptr icon, nux::ObjectPtr<nux::IOpenGLBaseTexture> texture);
85-
86 AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y);
87 void EventLogic();
88 void MouseDownLogic(int x, int y, unsigned long button_flags, unsigned long key_flags);
89
90=== modified file 'plugins/unityshell/src/LauncherController.cpp'
91--- plugins/unityshell/src/LauncherController.cpp 2012-03-21 19:49:38 +0000
92+++ plugins/unityshell/src/LauncherController.cpp 2012-03-28 22:26:18 +0000
93@@ -87,9 +87,12 @@
94 void OnIconRemoved(AbstractLauncherIcon::Ptr icon);
95
96 void OnLauncherAddRequest(char* path, AbstractLauncherIcon::Ptr before);
97- void OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon::Ptr before, std::string const& aptdaemon_trans_id, std::string const& icon_path);
98+ void OnLauncherAddRequestSpecial(std::string const& path, AbstractLauncherIcon::Ptr before, std::string const& aptdaemon_trans_id, std::string const& icon_path,
99+ int icon_x, int icon_y, int icon_size);
100 void OnLauncherRemoveRequest(AbstractLauncherIcon::Ptr icon);
101
102+ void OnSCIconAnimationComplete(AbstractLauncherIcon::Ptr icon);
103+
104 void OnLauncherEntryRemoteAdded(LauncherEntryRemote* entry);
105 void OnLauncherEntryRemoteRemoved(LauncherEntryRemote* entry);
106
107@@ -114,7 +117,7 @@
108
109 AbstractLauncherIcon::Ptr CreateFavorite(const char* file_path);
110
111- AbstractLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path);
112+ SoftwareCenterLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path);
113
114 void SetupBamf();
115
116@@ -377,6 +380,8 @@
117 launcher->launcher_addrequest_special.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequestSpecial));
118 launcher->launcher_removerequest.connect(sigc::mem_fun(this, &Impl::OnLauncherRemoveRequest));
119
120+ launcher->icon_animation_complete.connect(sigc::mem_fun(this, &Impl::OnSCIconAnimationComplete));
121+
122 parent_->AddChild(launcher);
123
124 return launcher;
125@@ -430,24 +435,35 @@
126 Controller::Impl::OnLauncherAddRequestSpecial(std::string const& path,
127 AbstractLauncherIcon::Ptr before,
128 std::string const& aptdaemon_trans_id,
129- std::string const& icon_path)
130+ std::string const& icon_path,
131+ int icon_x,
132+ int icon_y,
133+ int icon_size)
134 {
135- auto launchers = model_->GetSublist<BamfLauncherIcon>();
136- for (auto icon : launchers)
137+ auto bamf_icons = model_->GetSublist<BamfLauncherIcon>();
138+ for (auto icon : bamf_icons)
139 {
140 if (icon->DesktopFile() == path)
141 return;
142 }
143
144- AbstractLauncherIcon::Ptr result = CreateSCLauncherIcon(path, aptdaemon_trans_id, icon_path);
145+ SoftwareCenterLauncherIcon::Ptr result = CreateSCLauncherIcon(path, aptdaemon_trans_id, icon_path);
146+
147+ launcher_->ForceReveal(true);
148+
149 if (result)
150 {
151+ result->SetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE, false);
152+ result->Animate(launcher_, icon_x, icon_y, icon_size);
153 RegisterIcon(result);
154-
155- if (before)
156- model_->ReorderBefore(result, before, false);
157+ Save();
158 }
159- Save();
160+}
161+
162+void Controller::Impl::OnSCIconAnimationComplete(AbstractLauncherIcon::Ptr icon)
163+{
164+ icon->SetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE, true);
165+ launcher_->ForceReveal(false);
166 }
167
168 void Controller::Impl::SortAndUpdate()
169@@ -733,13 +749,12 @@
170 return result;
171 }
172
173-AbstractLauncherIcon::Ptr
174-Controller::Impl::CreateSCLauncherIcon(std::string const& file_path,
175- std::string const& aptdaemon_trans_id,
176- std::string const& icon_path)
177+SoftwareCenterLauncherIcon::Ptr Controller::Impl::CreateSCLauncherIcon(std::string const& file_path,
178+ std::string const& aptdaemon_trans_id,
179+ std::string const& icon_path)
180 {
181 BamfApplication* app;
182- AbstractLauncherIcon::Ptr result;
183+ SoftwareCenterLauncherIcon::Ptr result;
184
185 app = bamf_matcher_get_application_for_desktop_file(matcher_, file_path.c_str(), true);
186 if (!BAMF_IS_APPLICATION(app))
187@@ -751,13 +766,10 @@
188 return result;
189 }
190
191- g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1));
192-
193 bamf_view_set_sticky(BAMF_VIEW(app), true);
194- AbstractLauncherIcon::Ptr icon(new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path));
195- icon->SetSortPriority(sort_priority_++);
196+ result = new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path);
197+ result->SetSortPriority(sort_priority_++);
198
199- result = icon;
200 return result;
201 }
202
203
204=== modified file 'plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp'
205--- plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp 2012-03-28 20:28:50 +0000
206+++ plugins/unityshell/src/SoftwareCenterLauncherIcon.cpp 2012-03-28 22:26:18 +0000
207@@ -18,29 +18,42 @@
208 * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
209 */
210
211+#include <NuxCore/Logger.h>
212 #include <glib/gi18n-lib.h>
213 #include "SoftwareCenterLauncherIcon.h"
214+#include "Launcher.h"
215+#include "LauncherDragWindow.h"
216+#include "LauncherModel.h"
217
218 namespace unity
219 {
220 namespace launcher
221 {
222
223+NUX_IMPLEMENT_OBJECT_TYPE(SoftwareCenterLauncherIcon);
224+
225 SoftwareCenterLauncherIcon::SoftwareCenterLauncherIcon(BamfApplication* app,
226 std::string const& aptdaemon_trans_id,
227 std::string const& icon_path)
228 : BamfLauncherIcon(app),
229- _aptdaemon_trans("org.debian.apt",
230+ aptdaemon_trans_("org.debian.apt",
231 aptdaemon_trans_id,
232 "org.debian.apt.transaction",
233 G_BUS_TYPE_SYSTEM,
234 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START)
235+, finished_(true)
236+, needs_urgent_(false)
237 {
238- _aptdaemon_trans.Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged));
239- _aptdaemon_trans.Connect("Finished", [&] (GVariant *) {
240+
241+ aptdaemon_trans_.Connect("PropertyChanged", sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnPropertyChanged));
242+ aptdaemon_trans_.Connect("Finished", [&] (GVariant *)
243+ {
244 tooltip_text = BamfName();
245 SetQuirk(QUIRK_PROGRESS, false);
246+ SetQuirk(QUIRK_URGENT, true);
247 SetProgress(0.0f);
248+ finished_ = true;
249+ needs_urgent_ = true;
250 });
251
252 SetIconType(TYPE_APPLICATION);
253@@ -48,8 +61,76 @@
254 tooltip_text = _("Waiting to install");
255 }
256
257-void
258-SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params)
259+void SoftwareCenterLauncherIcon::Animate(nux::ObjectPtr<Launcher> launcher,
260+ int icon_x,
261+ int icon_y,
262+ int icon_size)
263+{
264+ int target_x = 0;
265+ int target_y = 0;
266+
267+ launcher_ = launcher;
268+
269+ icon_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(
270+ launcher->GetIconSize(),
271+ launcher->GetIconSize(),
272+ 1,
273+ nux::BITFMT_R8G8B8A8);
274+
275+ drag_window_ = new LauncherDragWindow(icon_texture_);
276+
277+ launcher->RenderIconToTexture(nux::GetWindowThread()->GetGraphicsEngine(),
278+ AbstractLauncherIcon::Ptr(this),
279+ icon_texture_);
280+ nux::Geometry geo = drag_window_->GetGeometry();
281+ drag_window_->SetBaseXY(icon_x, icon_y);
282+ drag_window_->ShowWindow(true);
283+ drag_window_->SinkReference();
284+
285+ // Find out the center of last BamfLauncherIcon with non-zero co-ordinates
286+ auto bamf_icons = launcher->GetModel()->GetSublist<BamfLauncherIcon>();
287+ //TODO: don't iterate through them and pick the last one, just use back() to get the last one.
288+ for (auto current_bamf_icon : bamf_icons)
289+ {
290+ int x = (int) current_bamf_icon->GetCenter(launcher->monitor).x;
291+ int y = (int) current_bamf_icon->GetCenter(launcher->monitor).y;
292+ if (x != 0 && y != 0)
293+ {
294+ target_x = x;
295+ target_y = y;
296+ }
297+ }
298+
299+ target_y = target_y + (launcher->GetIconSize() / 2);
300+ drag_window_->SetAnimationTarget(target_x, target_y);
301+
302+ drag_window_->on_anim_completed = drag_window_->anim_completed.connect(sigc::mem_fun(this, &SoftwareCenterLauncherIcon::OnDragAnimationFinished));
303+ drag_window_->StartAnimation();
304+}
305+
306+void SoftwareCenterLauncherIcon::OnDragAnimationFinished()
307+{
308+ drag_window_->ShowWindow(false);
309+ launcher_->icon_animation_complete.emit(AbstractLauncherIcon::Ptr(this));
310+ drag_window_ = nullptr;
311+}
312+
313+void SoftwareCenterLauncherIcon::ActivateLauncherIcon(ActionArg arg)
314+{
315+ if (finished_)
316+ {
317+ if (needs_urgent_)
318+ {
319+ SetQuirk(QUIRK_URGENT, false);
320+ needs_urgent_ = false;
321+ }
322+ BamfLauncherIcon::ActivateLauncherIcon(arg);
323+ }
324+ else
325+ SetQuirk(QUIRK_STARTING, false);
326+}
327+
328+void SoftwareCenterLauncherIcon::OnPropertyChanged(GVariant* params)
329 {
330 gint32 progress;
331 glib::String property_name;
332@@ -63,12 +144,19 @@
333 g_variant_get(property_value, "i", &progress);
334
335 if (progress < 100)
336+ {
337 SetQuirk(QUIRK_PROGRESS, true);
338+ finished_ = false;
339+ }
340
341 SetProgress(progress/100.0f);
342 g_variant_unref(property_value);
343 }
344+}
345
346+std::string SoftwareCenterLauncherIcon::GetName() const
347+{
348+ return "SoftwareCenterLauncherIcon";
349 }
350
351 }
352
353=== modified file 'plugins/unityshell/src/SoftwareCenterLauncherIcon.h'
354--- plugins/unityshell/src/SoftwareCenterLauncherIcon.h 2012-03-14 06:24:18 +0000
355+++ plugins/unityshell/src/SoftwareCenterLauncherIcon.h 2012-03-28 22:26:18 +0000
356@@ -21,25 +21,45 @@
357 #ifndef SOFTWARE_CENTER_LAUNCHERICON_H
358 #define SOFTWARE_CENTER_LAUNCHERICON_H
359
360+#include <UnityCore/GLibDBusProxy.h>
361 #include "BamfLauncherIcon.h"
362-#include <UnityCore/GLibDBusProxy.h>
363+
364+class LauncherDragWindow;
365
366 namespace unity
367 {
368 namespace launcher
369 {
370+class Launcher;
371
372 class SoftwareCenterLauncherIcon : public BamfLauncherIcon
373 {
374+ NUX_DECLARE_OBJECT_TYPE(SoftwareCenterLauncherIcon, BamfLauncherIcon);
375 public:
376+ typedef nux::ObjectPtr<SoftwareCenterLauncherIcon> Ptr;
377+
378 SoftwareCenterLauncherIcon(BamfApplication* app,
379 std::string const& aptdaemon_trans_id,
380 std::string const& icon_path);
381
382+ void Animate(nux::ObjectPtr<Launcher> launcher, int icon_x, int icon_y, int icon_size);
383+
384+ std::string GetName() const;
385+
386+protected:
387+ void ActivateLauncherIcon(ActionArg arg);
388+
389 private:
390 void OnPropertyChanged(GVariant* params);
391-
392- glib::DBusProxy _aptdaemon_trans;
393+ void OnDragAnimationFinished();
394+
395+ glib::DBusProxy aptdaemon_trans_;
396+
397+ nux::ObjectPtr<nux::IOpenGLBaseTexture> icon_texture_;
398+ nux::ObjectPtr<LauncherDragWindow> drag_window_;
399+ nux::ObjectPtr<Launcher> launcher_;
400+ bool finished_;
401+ bool needs_urgent_;
402 };
403
404 }
405
406=== modified file 'tests/autopilot/autopilot/emulators/X11.py'
407--- tests/autopilot/autopilot/emulators/X11.py 2012-03-28 21:22:42 +0000
408+++ tests/autopilot/autopilot/emulators/X11.py 2012-03-28 22:26:18 +0000
409@@ -338,7 +338,14 @@
410 `monitor` must be an integer between 0 and the number of configured monitors.
411 ValueError is raised if an invalid monitor is specified.
412
413+ BlacklistedDriverError is raised if your video driver does not support this.
414+
415 """
416+ glxinfo_out = subprocess.check_output("glxinfo")
417+ for dri in self._blacklisted_drivers:
418+ if dri in glxinfo_out:
419+ raise ScreenGeometry.BlacklistedDriverError('Impossible change the primary monitor for the given driver')
420+
421 if monitor < 0 or monitor >= self.get_num_monitors():
422 raise ValueError('Monitor %d is not in valid range of 0 <= monitor < %d.' % (self.get_num_monitors()))
423
424@@ -347,15 +354,10 @@
425 if not monitor_name:
426 raise ValueError('Could not get monitor name from monitor number %d.' % (monitor))
427
428- glxinfo_out = subprocess.check_output("glxinfo")
429- for dri in self._blacklisted_drivers:
430- if dri in glxinfo_out:
431- raise ScreenGeometry.BlacklistedDriverError('Impossible change the primary monitor for the given driver')
432-
433 ret = os.spawnlp(os.P_WAIT, "xrandr", "xrandr", "--output", monitor_name, "--primary")
434
435 if ret != 0:
436- raise RuntimeError('Xrandr can\'t set the primary monitor')
437+ raise RuntimeError('Xrandr can\'t set the primary monitor. error code: %d' % (ret))
438
439 def get_screen_width(self):
440 return self._default_screen.get_width()
441
442=== modified file 'tests/autopilot/autopilot/emulators/unity/icons.py'
443--- tests/autopilot/autopilot/emulators/unity/icons.py 2012-03-04 23:12:19 +0000
444+++ tests/autopilot/autopilot/emulators/unity/icons.py 2012-03-28 22:26:18 +0000
445@@ -48,3 +48,6 @@
446
447 class DesktopLauncherIcon(SimpleLauncherIcon):
448 """Represents an icon that may appear in the switcher."""
449+
450+class SoftwareCenterLauncherIcon(BamfLauncherIcon):
451+ """Represents a launcher icon of a Software Center app."""
452
453=== modified file 'tests/autopilot/autopilot/emulators/unity/launcher.py'
454--- tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-25 21:25:54 +0000
455+++ tests/autopilot/autopilot/emulators/unity/launcher.py 2012-03-28 22:26:18 +0000
456@@ -7,6 +7,7 @@
457 # by the Free Software Foundation.
458 #
459
460+import dbus
461 import logging
462 from time import sleep
463
464@@ -14,7 +15,7 @@
465 from autopilot.emulators.unity import UnityIntrospectionObject
466 from autopilot.emulators.unity.icons import BamfLauncherIcon, SimpleLauncherIcon
467 from autopilot.emulators.X11 import Mouse, ScreenGeometry
468-
469+from autopilot.emulators.dbus_handler import session_bus
470
471 logger = logging.getLogger(__name__)
472
473@@ -41,6 +42,18 @@
474 def key_nav_monitor(self):
475 return self.key_nav_launcher_monitor
476
477+ def add_launcher_item_from_position(self,name,icon,icon_x,icon_y,icon_size,desktop_file,aptdaemon_task):
478+ """ Emulate a DBus call from Software Center to pin an icon to the launcher """
479+ launcher_object = session_bus.get_object('com.canonical.Unity.Launcher',
480+ '/com/canonical/Unity/Launcher')
481+ launcher_iface = dbus.Interface(launcher_object, 'com.canonical.Unity.Launcher')
482+ launcher_iface.AddLauncherItemFromPosition(name,
483+ icon,
484+ icon_x,
485+ icon_y,
486+ icon_size,
487+ desktop_file,
488+ aptdaemon_task)
489
490 class Launcher(UnityIntrospectionObject, KeybindingsHelper):
491 """An individual launcher for a monitor."""
492
493=== modified file 'tests/autopilot/autopilot/tests/test_launcher.py'
494--- tests/autopilot/autopilot/tests/test_launcher.py 2012-03-27 20:48:14 +0000
495+++ tests/autopilot/autopilot/tests/test_launcher.py 2012-03-28 22:26:18 +0000
496@@ -8,7 +8,7 @@
497 # by the Free Software Foundation.
498
499 import logging
500-from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan
501+from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan, Not, Is
502 from time import sleep
503
504 from autopilot.tests import AutopilotTestCase, multiply_scenarios
505@@ -24,7 +24,7 @@
506 num_monitors = screen_geometry.get_num_monitors()
507
508 if num_monitors == 1:
509- monitor_scenarios = [('Single Monitor', {'launcher_monitor': 0, 'only_primary': True})]
510+ monitor_scenarios = [('Single Monitor', {'launcher_monitor': 0})]
511 else:
512 monitor_scenarios = [('Monitor %d' % (i), {'launcher_monitor': i}) for i in range(num_monitors)]
513
514@@ -481,6 +481,41 @@
515 self.assertThat(self.launcher.key_nav_is_active, Equals(False))
516
517
518+ def test_software_center_add_icon(self):
519+ """ Test the ability to add a SoftwareCenterLauncherIcon """
520+
521+ launcher_instance = self.get_launcher()
522+ sc_desktop_file = "/usr/share/applications/ubuntu-software-center.desktop"
523+
524+ def cleanup():
525+ if icon is not None:
526+ launcher_instance.unlock_from_launcher(icon[0])
527+
528+ # Check if SC is pinned to the launcher already
529+ icon = self.launcher.model.get_icon_by_desktop_file(sc_desktop_file)
530+ if icon != None:
531+ launcher_instance.unlock_from_launcher(icon[0])
532+ sleep(2.0) # Animation of removing icon can take over a second
533+ else:
534+ self.addCleanup(cleanup)
535+
536+ self.launcher.add_launcher_item_from_position("Unity Test",
537+ "softwarecenter",
538+ 100,
539+ 100,
540+ 32,
541+ sc_desktop_file,
542+ "")
543+
544+ sleep(1.0)
545+
546+ icon = self.launcher.model.get_icon_by_desktop_file(sc_desktop_file)
547+ self.assertThat(icon, Not(Is(None)))
548+
549+ # Check for whether:
550+ # The new launcher icon has a 'Waiting to install' tooltip
551+ self.assertThat(icon[0].tooltip_text, Equals("Waiting to install"))
552+
553 class LauncherRevealTests(ScenariodLauncherTests):
554 """Test the launcher reveal bahavior when in autohide mode."""
555