Merge lp:~3v1n0/unity/avoid-duplicate-icons into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Didier Roche-Tolomelli
Approved revision: no longer in the source branch.
Merged at revision: 2345
Proposed branch: lp:~3v1n0/unity/avoid-duplicate-icons
Merge into: lp:unity
Diff against target: 226 lines (+84/-17)
6 files modified
plugins/unityshell/src/BamfLauncherIcon.cpp (+2/-1)
plugins/unityshell/src/LauncherController.cpp (+4/-3)
tests/autopilot/autopilot/emulators/bamf.py (+10/-0)
tests/autopilot/autopilot/emulators/unity/launcher.py (+13/-11)
tests/autopilot/autopilot/tests/__init__.py (+6/-2)
tests/autopilot/autopilot/tests/test_launcher.py (+49/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/avoid-duplicate-icons
Reviewer Review Type Date Requested Status
Michal Hruby (community) Approve
Tim Penhey (community) Approve
Marco Trevisan (Treviño) Pending
Thomi Richards Pending
Review via email: mp+103611@code.launchpad.net

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

Commit message

We need to flag a bamf view that we control using an icon using the "unity-seen" qdata, or unity will duplicate it on bamfdaemon respawn. (LP: #928912)

Description of the change

We need to flag a bamf view that we control using an icon using the "unity-seen" qdata, or unity will duplicate it on bamfdaemon respawn.

AP tests included.

This MP was superseeded to use thomi's test fixes from lp:~thomir/unity/avoid-duplicate-icons

To post a comment you must log in.
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote : Posted in a previous version of this proposal

Hi,

Please try and replace the call() lines with this:

call("kill `pidof %s`" % (app['process-name']), shell=True)

Don't use pkill -f - it's dangerous. Once making these changes, please ensure that all the tests still pass.

130 + self.start_app("Calculator")
131 + self.start_app("System Settings")
132 + os.spawnlp(os.P_NOWAIT, "xterm", "xterm", "-title", "Autopilot XTerm", "-e", "sh")
133 + self.addCleanup(call, ["killall", "xterm"])
134 +
135 + # FIXME bamf emulator should wait until a window is open
136 + sleep(1)
137 + [xterm_win] = [w for w in self.bamf.get_open_windows() if w.name == "Autopilot XTerm"]
138 + self.assertTrue(xterm_win.is_focused)

Please put all this in a method called "start_test_apps or something similar, then call it from your test.

154 + same_desktop = [i for i in bamf_icons if i.desktop_file == icon.desktop_file]
155 + self.assertThat(len(same_desktop), Equals(1))

Can you use 'get_icon_by_desktop_file' on the launcher model, to avoid this?

157 + same_appid = [i for i in bamf_icons if i.application_id == icon.application_id]
158 + self.assertThat(len(same_appid), Equals(1))

Similar thing here... we should probable add something to the launcher model like this:

def get_icon_by_filter(self, **kwargs):
        """Gets a launcher icon that matches the filter specified.

        Returns None if there is no such launcher icon.
        """
        icons = self.get_children_by_type(SimpleLauncherIcon, **kwargs)
        if len(icons):
            return icons[0]

        return None

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

+1

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

This has a few problems:

1) I can't verify this without the libbamf fix (remember this isn't my branch, I'm just fixing the AP tests).
2) (possibly the same as above) - unity keeps the xclock icon around forever.

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

Looks like the requested changes were done.

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

No commit message specified.

Revision history for this message
Michal Hruby (mhr3) wrote :

The unity side looks safe, tests pass with the not-yet-merged bamf branch.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/unityshell/src/BamfLauncherIcon.cpp'
--- plugins/unityshell/src/BamfLauncherIcon.cpp 2012-04-26 05:56:55 +0000
+++ plugins/unityshell/src/BamfLauncherIcon.cpp 2012-04-26 06:48:19 +0000
@@ -144,7 +144,7 @@
144{144{
145 g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()),145 g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()),
146 g_quark_from_static_string("unity-seen"),146 g_quark_from_static_string("unity-seen"),
147 GINT_TO_POINTER(0));147 GUINT_TO_POINTER(0));
148148
149 if (_fill_supported_types_id != 0)149 if (_fill_supported_types_id != 0)
150 g_source_remove(_fill_supported_types_id);150 g_source_remove(_fill_supported_types_id);
@@ -500,6 +500,7 @@
500 variant::BuilderWrapper(builder)500 variant::BuilderWrapper(builder)
501 .add("desktop_file", DesktopFile())501 .add("desktop_file", DesktopFile())
502 .add("desktop_id", GetDesktopID())502 .add("desktop_id", GetDesktopID())
503 .add("application_id", GPOINTER_TO_UINT(_bamf_app.RawPtr()))
503 .add("xids", g_variant_builder_end(&xids_builder))504 .add("xids", g_variant_builder_end(&xids_builder))
504 .add("sticky", IsSticky());505 .add("sticky", IsSticky());
505}506}
506507
=== modified file 'plugins/unityshell/src/LauncherController.cpp'
--- plugins/unityshell/src/LauncherController.cpp 2012-04-24 21:57:01 +0000
+++ plugins/unityshell/src/LauncherController.cpp 2012-04-26 06:48:19 +0000
@@ -740,6 +740,7 @@
740 return;740 return;
741 }741 }
742742
743 g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
743 AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app));744 AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app));
744 icon->visibility_changed.connect(sigc::mem_fun(self, &Impl::SortAndUpdate));745 icon->visibility_changed.connect(sigc::mem_fun(self, &Impl::SortAndUpdate));
745 icon->SetSortPriority(self->sort_priority_++);746 icon->SetSortPriority(self->sort_priority_++);
@@ -762,9 +763,8 @@
762 return result;763 return result;
763 }764 }
764765
765 g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1));
766
767 bamf_view_set_sticky(BAMF_VIEW(app), true);766 bamf_view_set_sticky(BAMF_VIEW(app), true);
767 g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
768 AbstractLauncherIcon::Ptr icon (new BamfLauncherIcon(app));768 AbstractLauncherIcon::Ptr icon (new BamfLauncherIcon(app));
769 icon->SetSortPriority(sort_priority_++);769 icon->SetSortPriority(sort_priority_++);
770 result = icon;770 result = icon;
@@ -790,6 +790,7 @@
790 }790 }
791791
792 bamf_view_set_sticky(BAMF_VIEW(app), true);792 bamf_view_set_sticky(BAMF_VIEW(app), true);
793 g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
793 result = new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path);794 result = new SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path);
794 result->SetSortPriority(sort_priority_++);795 result->SetSortPriority(sort_priority_++);
795796
@@ -831,8 +832,8 @@
831832
832 if (g_object_get_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen")))833 if (g_object_get_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen")))
833 continue;834 continue;
834 g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GINT_TO_POINTER(1));
835835
836 g_object_set_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen"), GUINT_TO_POINTER(1));
836 AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app));837 AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app));
837 icon->SetSortPriority(sort_priority_++);838 icon->SetSortPriority(sort_priority_++);
838 RegisterIcon(icon);839 RegisterIcon(icon);
839840
=== modified file 'tests/autopilot/autopilot/emulators/bamf.py'
--- tests/autopilot/autopilot/emulators/bamf.py 2012-04-16 00:34:04 +0000
+++ tests/autopilot/autopilot/emulators/bamf.py 2012-04-26 06:48:19 +0000
@@ -254,6 +254,16 @@
254 return self._x_win254 return self._x_win
255255
256 @property256 @property
257 def name(self):
258 """Get the window name.
259
260 Note: This may change according to the current locale. If you want a unique
261 string to match windows against, use the x_id instead.
262
263 """
264 return self._view_iface.Name()
265
266 @property
257 def title(self):267 def title(self):
258 """Get the window title.268 """Get the window title.
259269
260270
=== modified file 'tests/autopilot/autopilot/emulators/unity/launcher.py'
--- tests/autopilot/autopilot/emulators/unity/launcher.py 2012-04-23 16:41:53 +0000
+++ tests/autopilot/autopilot/emulators/unity/launcher.py 2012-04-26 06:48:19 +0000
@@ -327,17 +327,6 @@
327 return icon327 return icon
328 return None328 return None
329329
330 def get_icon_by_desktop_file(self, desktop_file):
331 """Gets a launcher icon with the specified desktop file.
332
333 Returns None if there is no such launcher icon.
334 """
335 icons = self.get_children_by_type(SimpleLauncherIcon, desktop_file=desktop_file)
336 if len(icons):
337 return icons[0]
338
339 return None
340
341 def get_icon_by_desktop_id(self, desktop_id):330 def get_icon_by_desktop_id(self, desktop_id):
342 """Gets a launcher icon with the specified desktop id.331 """Gets a launcher icon with the specified desktop id.
343332
@@ -349,6 +338,19 @@
349338
350 return None339 return None
351340
341 def get_icons_by_filter(self, **kwargs):
342 """Get a list of icons that satisfy the given filters.
343
344 For example:
345
346 >>> get_icons_by_filter(tooltip_text="My Application")
347 ... [...]
348
349 Returns an empty list if no icons matched the filter.
350
351 """
352 return self.get_children_by_type(SimpleLauncherIcon, **kwargs)
353
352 def num_launcher_icons(self):354 def num_launcher_icons(self):
353 """Get the number of icons in the launcher model."""355 """Get the number of icons in the launcher model."""
354 return len(self.get_launcher_icons())356 return len(self.get_launcher_icons())
355357
=== modified file 'tests/autopilot/autopilot/tests/__init__.py'
--- tests/autopilot/autopilot/tests/__init__.py 2012-04-24 22:26:55 +0000
+++ tests/autopilot/autopilot/tests/__init__.py 2012-04-26 06:48:19 +0000
@@ -224,6 +224,10 @@
224 'desktop-file': 'remmina.desktop',224 'desktop-file': 'remmina.desktop',
225 'process-name': 'remmina',225 'process-name': 'remmina',
226 },226 },
227 'System Settings' : {
228 'desktop-file': 'gnome-control-center.desktop',
229 'process-name': 'gnome-control-center',
230 },
227 'Text Editor' : {231 'Text Editor' : {
228 'desktop-file': 'gedit.desktop',232 'desktop-file': 'gedit.desktop',
229 'process-name': 'gedit',233 'process-name': 'gedit',
@@ -266,14 +270,14 @@
266 app = self.KNOWN_APPS[app_name]270 app = self.KNOWN_APPS[app_name]
267 self.bamf.launch_application(app['desktop-file'], files)271 self.bamf.launch_application(app['desktop-file'], files)
268 apps = self.bamf.get_running_applications_by_desktop_file(app['desktop-file'])272 apps = self.bamf.get_running_applications_by_desktop_file(app['desktop-file'])
269 self.addCleanup(call, ["killall", app['process-name']])273 self.addCleanup(call, "kill `pidof %s`" % (app['process-name']), shell=True)
270 self.assertThat(len(apps), Equals(1))274 self.assertThat(len(apps), Equals(1))
271 return apps[0]275 return apps[0]
272276
273 def close_all_app(self, app_name):277 def close_all_app(self, app_name):
274 """Close all instances of the app_name."""278 """Close all instances of the app_name."""
275 app = self.KNOWN_APPS[app_name]279 app = self.KNOWN_APPS[app_name]
276 call(["killall", app['process-name']])280 self.addCleanup(call, "kill `pidof %s`" % (app['process-name']), shell=True)
277 super(LoggedTestCase, self).tearDown()281 super(LoggedTestCase, self).tearDown()
278282
279 def get_app_instances(self, app_name):283 def get_app_instances(self, app_name):
280284
=== modified file 'tests/autopilot/autopilot/tests/test_launcher.py'
--- tests/autopilot/autopilot/tests/test_launcher.py 2012-04-23 16:41:53 +0000
+++ tests/autopilot/autopilot/tests/test_launcher.py 2012-04-26 06:48:19 +0000
@@ -8,9 +8,12 @@
8# by the Free Software Foundation.8# by the Free Software Foundation.
99
10import logging10import logging
11import os
12from subprocess import call
11from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan13from testtools.matchers import Equals, NotEquals, LessThan, GreaterThan
12from time import sleep14from time import sleep
1315
16from autopilot.emulators.bamf import Bamf
14from autopilot.emulators.unity.icons import BFBLauncherIcon17from autopilot.emulators.unity.icons import BFBLauncherIcon
15from autopilot.emulators.X11 import ScreenGeometry18from autopilot.emulators.X11 import ScreenGeometry
16from autopilot.matchers import Eventually19from autopilot.matchers import Eventually
@@ -568,6 +571,52 @@
568 for icon in self.launcher.model.get_launcher_icons():571 for icon in self.launcher.model.get_launcher_icons():
569 self.assertThat(icon.desaturated, Eventually(Equals(False)))572 self.assertThat(icon.desaturated, Eventually(Equals(False)))
570573
574class BamfDaemonTests(LauncherTestCase):
575 """Test interaction between the launcher and the BAMF Daemon."""
576
577 def start_test_apps(self):
578 """Starts some test applications."""
579 self.start_app("Calculator")
580 self.start_app("System Settings")
581
582 def get_test_apps(self):
583 """Return a tuple of test application instances.
584
585 We don't store these since when we kill the bamf daemon all references
586 to the old apps will die.
587
588 """
589 [calc] = self.get_app_instances("Calculator")
590 [sys_settings] = self.get_app_instances("System Settings")
591 return (calc, sys_settings)
592
593 def assertOnlyOneLauncherIcon(self, **kwargs):
594 """Asserts that there is only one launcher icon with the given filter."""
595 icons = self.launcher.model.get_icons_by_filter(**kwargs)
596 self.assertThat(len(icons), Equals(1))
597
598 def wait_for_bamf_daemon(self):
599 """Wait until the bamf daemon has been started."""
600 for i in range(10):
601 #pgrep returns 0 if it matched something:
602 if call(["pgrep", "bamfdaemon"]) == 0:
603 return
604 sleep(1)
605
606 def test_killing_bamfdaemon_does_not_duplicate_desktop_ids(self):
607 """Killing bamfdaemon should not duplicate any desktop ids in the model."""
608 self.start_test_apps()
609
610 call(["pkill", "bamfdaemon"])
611 sleep(1)
612
613 # trigger the bamfdaemon to be reloaded again, and wait for it to appear:
614 self.bamf = Bamf()
615 self.wait_for_bamf_daemon()
616
617 for test_app in self.get_test_apps():
618 self.assertOnlyOneLauncherIcon(desktop_id=test_app.desktop_file)
619
571620
572class LauncherCaptureTests(AutopilotTestCase):621class LauncherCaptureTests(AutopilotTestCase):
573 """Test the launchers ability to capture/not capture the mouse."""622 """Test the launchers ability to capture/not capture the mouse."""