Merge lp:~3v1n0/unity/unset-bamficon-on-removal into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 2369
Proposed branch: lp:~3v1n0/unity/unset-bamficon-on-removal
Merge into: lp:unity
Diff against target: 196 lines (+42/-33)
5 files modified
UnityCore/GLibSignal.cpp (+3/-5)
UnityCore/GLibSignal.h (+1/-1)
launcher/BamfLauncherIcon.cpp (+6/-3)
launcher/LauncherController.cpp (+12/-24)
tests/test_glib_signals.cpp (+20/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/unset-bamficon-on-removal
Reviewer Review Type Date Requested Status
Tim Penhey (community) Approve
Review via email: mp+107071@code.launchpad.net

Commit message

BamfLauncherIcon: Unset the BamfApplication when removing the icon.

Doing this manually, we prevent that a duplicated application can be added between the removal of the BamfLauncherIcon and the effective destruction (that is controlled by a timeout in LauncherModel).

Description of the change

In some rare cases, when a BamfLauncherIcon is set as removed and before of being actually destroyed by the LauncherModel (that uses a timeout), it could happen that two BamfLauncherIcon's that wrap the same BamfApplication could be created. And this causes a duplicated Launcher Icon.

Unsetting the signals on removal and the BamfApplication, would avoid this.
We already have tests for duplicated icons checks. This case can't be easily reproduced.

Updated also the glib::SignalManager so that it's possible to disconnect from all signals of a given object (tests included).

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/GLibSignal.cpp'
2--- UnityCore/GLibSignal.cpp 2012-04-16 12:12:05 +0000
3+++ UnityCore/GLibSignal.cpp 2012-05-23 19:37:18 +0000
4@@ -71,12 +71,10 @@
5 // (it allows you to pass in a GObject without casting up).
6 void SignalManager::Disconnect(void* object, std::string const& signal_name)
7 {
8- for (ConnectionVector::iterator it = connections_.begin();
9- it != connections_.end();
10- ++it)
11+ for (auto it = connections_.begin(); it != connections_.end(); ++it)
12 {
13- if ((*it)->object() == object
14- && (*it)->name() == signal_name)
15+ if ((*it)->object() == object &&
16+ (signal_name.empty() || (*it)->name() == signal_name))
17 {
18 (*it)->Disconnect();
19 connections_.erase(it, it);
20
21=== modified file 'UnityCore/GLibSignal.h'
22--- UnityCore/GLibSignal.h 2011-07-21 14:59:25 +0000
23+++ UnityCore/GLibSignal.h 2012-05-23 19:37:18 +0000
24@@ -295,7 +295,7 @@
25
26 SignalManager();
27 void Add(SignalBase* signal);
28- void Disconnect(void* object, std::string const& signal_name);
29+ void Disconnect(void* object, std::string const& signal_name = "");
30
31 private:
32 ConnectionVector connections_;
33
34=== modified file 'launcher/BamfLauncherIcon.cpp'
35--- launcher/BamfLauncherIcon.cpp 2012-05-15 18:52:54 +0000
36+++ launcher/BamfLauncherIcon.cpp 2012-05-23 19:37:18 +0000
37@@ -191,9 +191,12 @@
38 /* Removing the unity-seen flag to the wrapped bamf application, on remove
39 * request we make sure that if the bamf application is re-opened while
40 * the removal process is still ongoing, the application will be shown
41- * on the launcher. */
42+ * on the launcher. Disconnecting from signals and nullifying the _bamf_app
43+ * we make sure that this icon won't be reused (no duplicated icon). */
44+ _gsignals.Disconnect(_bamf_app);
45 g_object_set_qdata(G_OBJECT(_bamf_app.RawPtr()),
46 g_quark_from_static_string("unity-seen"), nullptr);
47+ _bamf_app = nullptr;
48
49 SimpleLauncherIcon::Remove();
50 }
51@@ -749,8 +752,8 @@
52 const gchar** nicks = indicator_desktop_shortcuts_get_nicks(_desktop_shortcuts);
53
54 int index = 0;
55- while (nicks[index]) {
56-
57+ while (nicks[index])
58+ {
59 // Build a dbusmenu item for each nick that is the desktop
60 // file that is built from it's name and includes a callback
61 // to the desktop shortcuts object to execute the nick
62
63=== modified file 'launcher/LauncherController.cpp'
64--- launcher/LauncherController.cpp 2012-05-17 19:34:56 +0000
65+++ launcher/LauncherController.cpp 2012-05-23 19:37:18 +0000
66@@ -130,6 +130,8 @@
67
68 void OnWindowFocusChanged (guint32 xid);
69
70+ void OnViewOpened(BamfMatcher* matcher, BamfView* view);
71+
72 void ReceiveMouseDownOutsideArea(int x, int y, unsigned long button_flags, unsigned long key_flags);
73
74 void ReceiveLauncherKeyPress(unsigned long eventType,
75@@ -138,17 +140,14 @@
76 const char* character,
77 unsigned short keyCount);
78
79- /* statics */
80-
81- static void OnViewOpened(BamfMatcher* matcher, BamfView* view, gpointer data);
82-
83 Controller* parent_;
84 glib::Object<BamfMatcher> matcher_;
85+ glib::Signal<void, BamfMatcher*, BamfView*> view_opened_signal_;
86 LauncherModel::Ptr model_;
87 nux::ObjectPtr<Launcher> launcher_;
88 nux::ObjectPtr<Launcher> keyboard_launcher_;
89 int sort_priority_;
90- DeviceLauncherSection* device_section_;
91+ DeviceLauncherSection device_section_;
92 LauncherEntryRemoteModel remote_model_;
93 AbstractLauncherIcon::Ptr expo_icon_;
94 AbstractLauncherIcon::Ptr desktop_icon_;
95@@ -157,7 +156,6 @@
96 Display* display_;
97
98 guint bamf_timer_handler_id_;
99- guint on_view_opened_id_;
100 guint launcher_key_press_handler_id_;
101 guint launcher_label_show_handler_id_;
102 guint launcher_hide_handler_id_;
103@@ -210,9 +208,7 @@
104 EnsureLaunchers(primary, monitors);
105
106 launcher_ = launchers[0];
107-
108- device_section_ = new DeviceLauncherSection();
109- device_section_->IconAdded.connect(sigc::mem_fun(this, &Impl::OnIconAdded));
110+ device_section_.IconAdded.connect(sigc::mem_fun(this, &Impl::OnIconAdded));
111
112 num_workspaces_ = WindowManager::Default()->WorkspaceCount();
113 if (num_workspaces_ > 1)
114@@ -289,11 +285,6 @@
115
116 if (bamf_timer_handler_id_ != 0)
117 g_source_remove(bamf_timer_handler_id_);
118-
119- if (matcher_ != nullptr && on_view_opened_id_ != 0)
120- g_signal_handler_disconnect((gpointer) matcher_, on_view_opened_id_);
121-
122- delete device_section_;
123 }
124
125 void Controller::Impl::EnsureLaunchers(int primary, std::vector<nux::Geometry> const& monitors)
126@@ -724,15 +715,12 @@
127 }
128
129 /* static private */
130-void Controller::Impl::OnViewOpened(BamfMatcher* matcher, BamfView* view, gpointer data)
131+void Controller::Impl::OnViewOpened(BamfMatcher* matcher, BamfView* view)
132 {
133- Impl* self = static_cast<Impl*>(data);
134- BamfApplication* app;
135-
136 if (!BAMF_IS_APPLICATION(view))
137 return;
138
139- app = BAMF_APPLICATION(view);
140+ BamfApplication* app = BAMF_APPLICATION(view);
141
142 if (bamf_view_is_sticky(view) ||
143 g_object_get_qdata(G_OBJECT(app), g_quark_from_static_string("unity-seen")))
144@@ -741,10 +729,10 @@
145 }
146
147 AbstractLauncherIcon::Ptr icon(new BamfLauncherIcon(app));
148- icon->visibility_changed.connect(sigc::mem_fun(self, &Impl::SortAndUpdate));
149- icon->SetSortPriority(self->sort_priority_++);
150- self->RegisterIcon(icon);
151- self->SortAndUpdate();
152+ icon->visibility_changed.connect(sigc::mem_fun(this, &Impl::SortAndUpdate));
153+ icon->SetSortPriority(sort_priority_++);
154+ RegisterIcon(icon);
155+ SortAndUpdate();
156 }
157
158 AbstractLauncherIcon::Ptr Controller::Impl::CreateFavorite(const char* file_path)
159@@ -821,7 +809,7 @@
160 }
161
162 apps = bamf_matcher_get_applications(matcher_);
163- on_view_opened_id_ = g_signal_connect(matcher_, "view-opened", (GCallback) &Impl::OnViewOpened, this);
164+ view_opened_signal_.Connect(matcher_, "view-opened", sigc::mem_fun(this, &Impl::OnViewOpened));
165
166 for (l = apps; l; l = l->next)
167 {
168
169=== modified file 'tests/test_glib_signals.cpp'
170--- tests/test_glib_signals.cpp 2011-07-21 14:59:25 +0000
171+++ tests/test_glib_signals.cpp 2012-05-23 19:37:18 +0000
172@@ -364,4 +364,24 @@
173 EXPECT_FALSE(signal0_received_);
174 }
175
176+TEST_F(TestGLibSignals, TestManagerObjectDisconnection)
177+{
178+ SignalManager manager;
179+
180+ manager.Add(new Signal<void, TestSignals*>(test_signals_,
181+ "signal0",
182+ sigc::mem_fun(this, &TestGLibSignals::Signal0Callback)));
183+
184+ manager.Add(new Signal<void, TestSignals*, const char*>(test_signals_,
185+ "signal1",
186+ sigc::mem_fun(this, &TestGLibSignals::Signal1Callback)));
187+
188+ manager.Disconnect(test_signals_);
189+
190+ g_signal_emit_by_name(test_signals_, "signal0");
191+ EXPECT_FALSE(signal0_received_);
192+ g_signal_emit_by_name(test_signals_, "signal1", "test");
193+ EXPECT_FALSE(signal1_received_);
194+}
195+
196 }