Merge lp:~unity-api-team/indicator-network/krillin-wifi into lp:indicator-network/14.10

Proposed by Antti Kaijanmäki
Status: Merged
Approved by: Antti Kaijanmäki
Approved revision: 433
Merged at revision: 435
Proposed branch: lp:~unity-api-team/indicator-network/krillin-wifi
Merge into: lp:indicator-network/14.10
Diff against target: 691 lines (+236/-87)
16 files modified
src/connectivity-cpp/dbus-cpp/services/urfkill.h (+3/-3)
src/connectivity-cpp/include/connectivity/networking/manager.h (+5/-0)
src/connectivity-cpp/src/platform/nmofono/kill-switch.cpp (+2/-0)
src/connectivity-cpp/src/platform/nmofono/kill-switch.h (+1/-0)
src/connectivity-cpp/src/platform/nmofono/manager.cpp (+89/-4)
src/connectivity-cpp/src/platform/nmofono/manager.h (+6/-0)
src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp (+5/-2)
src/indicator/quick-access-section.cpp (+13/-4)
src/indicator/wifi-link-item.h (+0/-37)
src/indicator/wifi-section.cpp (+53/-11)
src/menumodel-cpp/action-group-exporter.h (+7/-5)
src/menumodel-cpp/action.cpp (+3/-1)
src/menumodel-cpp/gio-helpers/util.cpp (+7/-2)
src/menumodel-cpp/gio-helpers/util.h (+3/-2)
src/menumodel-cpp/menu-merger.h (+17/-9)
src/menumodel-cpp/menu.h (+22/-7)
To merge this branch: bzr merge lp:~unity-api-team/indicator-network/krillin-wifi
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Charles Kerr (community) Approve
Review via email: mp+235879@code.launchpad.net

Commit message

Fix wifi toggle on krillin.

Description of the change

fix wifi toggle on krillin.

To post a comment you must log in.
Revision history for this message
Charles Kerr (charlesk) wrote :

LGTM

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

Nice thread fixes. :)

There are a couple of warts here that I've talked with Antti about offline, but they don't block this Critical and can wait until the next MP.

review: Approve
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

just a simple timeout increase.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/connectivity-cpp/dbus-cpp/services/urfkill.h'
2--- src/connectivity-cpp/dbus-cpp/services/urfkill.h 2014-08-19 19:55:15 +0000
3+++ src/connectivity-cpp/dbus-cpp/services/urfkill.h 2014-09-26 13:07:38 +0000
4@@ -162,7 +162,7 @@
5
6 static std::chrono::milliseconds default_timeout()
7 {
8- return std::chrono::seconds{5};
9+ return std::chrono::seconds{15};
10 }
11 };
12
13@@ -179,7 +179,7 @@
14
15 static std::chrono::milliseconds default_timeout()
16 {
17- return std::chrono::seconds{5};
18+ return std::chrono::seconds{15};
19 }
20 };
21
22@@ -196,7 +196,7 @@
23
24 static std::chrono::milliseconds default_timeout()
25 {
26- return std::chrono::seconds{1};
27+ return std::chrono::seconds{5};
28 }
29 };
30 };
31
32=== modified file 'src/connectivity-cpp/include/connectivity/networking/manager.h'
33--- src/connectivity-cpp/include/connectivity/networking/manager.h 2014-08-19 19:55:15 +0000
34+++ src/connectivity-cpp/include/connectivity/networking/manager.h 2014-09-26 13:07:38 +0000
35@@ -128,6 +128,11 @@
36 */
37 virtual const core::Property<std::uint32_t>& characteristics() const = 0;
38
39+ virtual const core::Property<bool>& hasWifi() const = 0;
40+ virtual const core::Property<bool>& wifiEnabled() const = 0;
41+ virtual bool enableWifi() = 0;
42+ virtual bool disableWifi() = 0;
43+
44 protected:
45 /**
46 * @brief The default constructor is protected.
47
48=== modified file 'src/connectivity-cpp/src/platform/nmofono/kill-switch.cpp'
49--- src/connectivity-cpp/src/platform/nmofono/kill-switch.cpp 2014-08-19 19:55:15 +0000
50+++ src/connectivity-cpp/src/platform/nmofono/kill-switch.cpp 2014-09-26 13:07:38 +0000
51@@ -38,6 +38,8 @@
52 {
53 switch(value) {
54 case URfkill::Interface::Killswitch::State::not_available:
55+ state.set(KillSwitch::State::not_available);
56+ break;
57 case URfkill::Interface::Killswitch::State::unblocked:
58 state.set(KillSwitch::State::unblocked);
59 break;
60
61=== modified file 'src/connectivity-cpp/src/platform/nmofono/kill-switch.h'
62--- src/connectivity-cpp/src/platform/nmofono/kill-switch.h 2014-08-19 19:55:15 +0000
63+++ src/connectivity-cpp/src/platform/nmofono/kill-switch.h 2014-09-26 13:07:38 +0000
64@@ -61,6 +61,7 @@
65
66 enum class State
67 {
68+ not_available,
69 unblocked,
70 soft_blocked,
71 hard_blocked
72
73=== modified file 'src/connectivity-cpp/src/platform/nmofono/manager.cpp'
74--- src/connectivity-cpp/src/platform/nmofono/manager.cpp 2014-08-28 12:13:29 +0000
75+++ src/connectivity-cpp/src/platform/nmofono/manager.cpp 2014-09-26 13:07:38 +0000
76@@ -55,6 +55,31 @@
77 core::Property<connectivity::networking::Manager::NetworkingStatus> m_status;
78 core::Property<std::uint32_t> m_characteristics;
79 std::unique_ptr<State> m_state;
80+
81+ core::Property<bool> m_hasWifi;
82+ core::Property<bool> m_wifiEnabled ;
83+ std::shared_ptr<KillSwitch> m_wifiKillSwitch;
84+
85+ void updateHasWifi()
86+ {
87+ if (m_wifiKillSwitch->state().get() != KillSwitch::State::not_available) {
88+ m_hasWifi.set(true);
89+ if (m_wifiKillSwitch->state().get() == KillSwitch::State::unblocked)
90+ m_wifiEnabled.set(true);
91+ else
92+ m_wifiEnabled.set(false);
93+ return;
94+ }
95+
96+ // ok, killswitch not supported, but we still might have wifi devices
97+ bool haswifi = false;
98+ for (auto link : m_links.get()) {
99+ if (link->type() == networking::Link::Type::wifi)
100+ haswifi = true;
101+ }
102+ m_hasWifi.set(haswifi);
103+ m_wifiEnabled.set(haswifi);
104+ }
105 };
106 }
107 }
108@@ -143,6 +168,10 @@
109 /// @todo offload the initialization to a thread or something
110 /// @todo those Id() thingies
111
112+ p->m_wifiKillSwitch = std::make_shared<KillSwitch>(p->urfkill,
113+ p->urfkill->switches[fdo::URfkill::Interface::Killswitch::Type::wlan]);
114+ p->m_wifiKillSwitch->state().changed().connect(std::bind(&Private::updateHasWifi, p.get()));
115+
116 p->nm->device_added->connect([this](const dbus::types::ObjectPath &path){
117 std::cout << "Device Added:" << path.as_string() << std::endl;
118 auto links = p->m_links.get();
119@@ -158,10 +187,11 @@
120 if (dev.type() == NM::Interface::Device::Type::wifi) {
121 links.insert(std::make_shared<wifi::Link>(dev,
122 *p->nm.get(),
123- std::make_shared<KillSwitch>(p->urfkill,
124- p->urfkill->switches[fdo::URfkill::Interface::Killswitch::Type::wlan])));
125+ p->m_wifiKillSwitch));
126 p->m_links.set(links);
127 }
128+
129+ p->updateHasWifi();
130 });
131 p->nm->device_removed->connect([this](const dbus::types::ObjectPath &path){
132 std::cout << "Device Removed:" << path.as_string() << std::endl;
133@@ -173,6 +203,8 @@
134 }
135 }
136 p->m_links.set(links);
137+
138+ p->updateHasWifi();
139 });
140 std::set<std::shared_ptr<networking::Link> > links;
141 for(auto dev : p->nm->get_devices()) {
142@@ -182,8 +214,7 @@
143 std::shared_ptr<networking::Link> link;
144 link.reset(new wifi::Link(dev,
145 *p->nm.get(),
146- std::make_shared<KillSwitch>(p->urfkill,
147- p->urfkill->switches[fdo::URfkill::Interface::Killswitch::Type::wlan])));
148+ p->m_wifiKillSwitch));
149 links.insert(link);
150 break;
151 }
152@@ -219,6 +250,8 @@
153
154 /// @todo set by the default connections.
155 p->m_characteristics.set(networking::Link::Characteristics::empty);
156+
157+ p->updateHasWifi();
158 }
159
160 void
161@@ -269,3 +302,55 @@
162 {
163 return p->m_characteristics;
164 }
165+
166+const core::Property<bool>&
167+Manager::hasWifi() const
168+{
169+ return p->m_hasWifi;
170+}
171+
172+const core::Property<bool>&
173+Manager::wifiEnabled() const
174+{
175+ return p->m_wifiEnabled;
176+}
177+
178+
179+bool
180+Manager::enableWifi()
181+{
182+ if (!p->m_hasWifi.get())
183+ return false;
184+
185+ try {
186+ if (p->m_wifiKillSwitch->state() == KillSwitch::State::soft_blocked) {
187+ // try to unblock. throws if fails.
188+ p->m_wifiKillSwitch->unblock();
189+ }
190+ p->nm->wireless_enabled->set(true);
191+ } catch(std::runtime_error &e) {
192+ std::cerr << __PRETTY_FUNCTION__ << ": " << e.what() << std::endl;
193+ return false;
194+ }
195+ return true;
196+}
197+
198+bool
199+Manager::disableWifi()
200+{
201+ if (!p->m_hasWifi.get())
202+ return false;
203+
204+ try {
205+ if (p->m_wifiKillSwitch->state() == KillSwitch::State::unblocked) {
206+ // block the device. that will disable it also
207+ p->m_wifiKillSwitch->block();
208+ }
209+ p->nm->wireless_enabled->set(false);
210+ } catch(std::runtime_error &e) {
211+ std::cerr << __PRETTY_FUNCTION__ << ": " << e.what() << std::endl;
212+ return false;
213+ }
214+ return true;
215+}
216+
217
218=== modified file 'src/connectivity-cpp/src/platform/nmofono/manager.h'
219--- src/connectivity-cpp/src/platform/nmofono/manager.h 2014-08-19 19:55:15 +0000
220+++ src/connectivity-cpp/src/platform/nmofono/manager.h 2014-09-26 13:07:38 +0000
221@@ -51,6 +51,12 @@
222 void disableFlightMode() override;
223 const core::Property<connectivity::networking::Manager::FlightModeStatus>& flightMode() const override;
224
225+ const core::Property<bool>& hasWifi() const override;
226+ const core::Property<bool>& wifiEnabled() const override;
227+
228+ bool enableWifi() override;
229+ bool disableWifi() override;
230+
231 const core::Property<std::set<std::shared_ptr<connectivity::networking::Link>>>& links() const;
232 const core::Property<std::set<std::shared_ptr<connectivity::networking::Service>>>&services() const override;
233 const core::Property<connectivity::networking::Manager::NetworkingStatus> & status() const override;
234
235=== modified file 'src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp'
236--- src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp 2014-09-04 07:48:13 +0000
237+++ src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp 2014-09-26 13:07:38 +0000
238@@ -100,6 +100,8 @@
239 org::freedesktop::NetworkManager::Interface::NetworkManager nm;
240
241 KillSwitch::Ptr killSwitch;
242+ // hack hack
243+ std::vector<core::ScopedConnection> switchConnection;
244
245 std::map<AccessPointKey, std::shared_ptr<GroupedAccessPoint>> grouper;
246 bool disabled;
247@@ -146,9 +148,9 @@
248 // std::uint32_t reason = std::get<2>(args);
249 updateDeviceState(new_state);
250 });
251- p->killSwitch->state().changed().connect([this](platform::nmofono::KillSwitch::State){
252+ p->switchConnection.emplace_back(p->killSwitch->state().changed().connect([this](platform::nmofono::KillSwitch::State){
253 updateDeviceState(p->lastState);
254- });
255+ }));
256 }
257
258 Link::~Link()
259@@ -428,6 +430,7 @@
260 case KillSwitch::State::soft_blocked:
261 p->status_.set(Status::disabled);
262 break;
263+ case KillSwitch::State::not_available:
264 case KillSwitch::State::unblocked:
265 p->status_.set(Status::offline);
266 }
267
268=== modified file 'src/indicator/quick-access-section.cpp'
269--- src/indicator/quick-access-section.cpp 2014-05-27 16:06:14 +0000
270+++ src/indicator/quick-access-section.cpp 2014-09-26 13:07:38 +0000
271@@ -65,10 +65,19 @@
272 }
273 });
274 m_flightModeSwitch->activated().connect([this](){
275- if (m_flightModeSwitch->state().get())
276- m_manager->enableFlightMode();
277- else
278- m_manager->disableFlightMode();
279+ if (m_flightModeSwitch->state().get()) {
280+ try {
281+ m_manager->enableFlightMode();
282+ } catch (const std::exception &e) {
283+ std::cout << e.what() << std::endl;
284+ }
285+ } else {
286+ try {
287+ m_manager->disableFlightMode();
288+ } catch (const std::exception &e) {
289+ std::cout << e.what() << std::endl;
290+ }
291+ }
292 });
293
294 m_actionGroupMerger->add(*m_flightModeSwitch);
295
296=== modified file 'src/indicator/wifi-link-item.h'
297--- src/indicator/wifi-link-item.h 2014-08-15 11:49:44 +0000
298+++ src/indicator/wifi-link-item.h 2014-09-26 13:07:38 +0000
299@@ -42,8 +42,6 @@
300 /// @todo do something with me...
301 Action::Ptr m_actionBusy;
302
303- SwitchItem::Ptr m_switch;
304-
305 networking::wifi::AccessPoint::Ptr m_activeAccessPoint;
306 std::map<networking::wifi::AccessPoint::Ptr, AccessPointItem::Ptr> m_accessPoints;
307
308@@ -85,40 +83,6 @@
309
310 m_rootMerger = std::make_shared<MenuMerger>();
311
312- m_switch = std::make_shared<SwitchItem>(_("Wi-Fi"), "wifi", "enable");
313- m_actionGroupMerger->add(*m_switch);
314- switch (m_link->status().get()) {
315- case networking::Link::Status::disabled:
316- m_switch->state().set(false);
317- break;
318- case networking::Link::Status::offline:
319- case networking::Link::Status::connecting:
320- case networking::Link::Status::connected:
321- case networking::Link::Status::online:
322- m_switch->state().set(true);
323- break;
324- }
325- m_link->status().changed().connect([this](networking::Link::Status value){
326- switch (value) {
327- case networking::Link::Status::disabled:
328- m_switch->state().set(false);
329- break;
330- case networking::Link::Status::offline:
331- case networking::Link::Status::connecting:
332- case networking::Link::Status::connected:
333- case networking::Link::Status::online:
334- m_switch->state().set(true);
335- break;
336- }
337- });
338- m_switch->activated().connect([this](){
339- if (m_switch->state().get()) {
340- m_link->enable();
341- } else {
342- m_link->disable();
343- }
344- });
345-
346 m_accessPointCompare = [](MenuItem::Ptr a, MenuItem::Ptr b){
347 // order alphabetically by SSID
348
349@@ -152,7 +116,6 @@
350 m_otherNetwork = std::make_shared<TextItem>(_("Other network…"), "wifi", "othernetwork");
351 //m_actionGroupMerger->add(*m_otherNetwork);
352
353- m_topMenu->append(*m_switch);
354 m_rootMerger->append(m_topMenu);
355
356 m_apsMerger->append(m_connectedBeforeApsMenu);
357
358=== modified file 'src/indicator/wifi-section.cpp'
359--- src/indicator/wifi-section.cpp 2014-05-12 11:36:59 +0000
360+++ src/indicator/wifi-section.cpp 2014-09-26 13:07:38 +0000
361@@ -32,6 +32,8 @@
362 Menu::Ptr m_menu;
363 Menu::Ptr m_settingsMenu;
364
365+ SwitchItem::Ptr m_switch;
366+
367 WifiLinkItem::Ptr m_wifiLink;
368 TextItem::Ptr m_openWifiSettings;
369
370@@ -44,19 +46,36 @@
371 m_settingsMenu = std::make_shared<Menu>();
372
373
374- for (auto link : m_manager->links().get()) {
375- auto wifi_link = std::dynamic_pointer_cast<networking::wifi::Link>(link);
376- m_wifiLink = std::make_shared<WifiLinkItem>(wifi_link);
377-
378- m_actionGroupMerger->add(*m_wifiLink);
379- m_menu->append(*m_wifiLink);
380- m_settingsMenu->append(*m_wifiLink);
381-
382- // just take the first one now.
383- /// @todo multiple links and links()->changed()
384- break;
385+ m_switch = std::make_shared<SwitchItem>(_("Wi-Fi"), "wifi", "enable");
386+
387+ /// @todo don't now really care about actully being able to detach the whole
388+ /// wifi chipset. on touch devices we always have wifi.
389+ if (m_manager->hasWifi().get()) {
390+ m_actionGroupMerger->add(*m_switch);
391+ m_menu->append(*m_switch);
392+ m_settingsMenu->append(*m_switch);
393 }
394
395+ m_switch->state().set(m_manager->wifiEnabled().get());
396+ m_manager->wifiEnabled().changed().connect([this](bool value) {
397+ m_switch->state().set(value);
398+ });
399+ m_switch->activated().connect([this](){
400+ if (m_switch->state().get()) {
401+ if (!m_manager->enableWifi()) {
402+ /// try to work around the switch getting out of state on unity8 side
403+ m_switch->state().set(false);
404+ }
405+ } else {
406+ if (!m_manager->disableWifi())
407+ m_switch->state().set(true);
408+ }
409+ });
410+
411+
412+ m_manager->links().changed().connect(std::bind(&Private::updateLinks, this));
413+ updateLinks();
414+
415 m_openWifiSettings = std::make_shared<TextItem>(_("Wi-Fi settings…"), "wifi", "settings");
416 m_openWifiSettings->activated().connect([](){
417 UrlDispatcher::send("settings:///system/wifi", [](std::string url, bool success){
418@@ -69,6 +88,29 @@
419 m_menu->append(*m_openWifiSettings);
420 }
421
422+ void updateLinks()
423+ {
424+ // remove all and recreate. we have top 1 now anyway
425+ if (m_wifiLink) {
426+ m_actionGroupMerger->remove(*m_wifiLink);
427+ m_menu->removeAll(*m_wifiLink);
428+ m_settingsMenu->removeAll(*m_wifiLink);
429+ m_wifiLink.reset();
430+ }
431+
432+ for (auto link : m_manager->links().get()) {
433+ auto wifi_link = std::dynamic_pointer_cast<networking::wifi::Link>(link);
434+ m_wifiLink = std::make_shared<WifiLinkItem>(wifi_link);
435+
436+ m_actionGroupMerger->add(*m_wifiLink);
437+ m_menu->append(*m_wifiLink);
438+ m_settingsMenu->append(*m_wifiLink);
439+
440+ // just take the first one
441+ break;
442+ }
443+ }
444+
445 public:
446 };
447
448
449=== modified file 'src/menumodel-cpp/action-group-exporter.h'
450--- src/menumodel-cpp/action-group-exporter.h 2014-08-14 23:23:06 +0000
451+++ src/menumodel-cpp/action-group-exporter.h 2014-09-26 13:07:38 +0000
452@@ -63,19 +63,21 @@
453 return;
454 }
455
456+
457+ auto group = m_gSimpleActionGroup;
458 GMainLoopDispatch([=](){
459 for (auto action : actionGroup->actions()) {
460- g_action_map_add_action(G_ACTION_MAP(m_gSimpleActionGroup.get()), action->gaction().get());
461+ g_action_map_add_action(G_ACTION_MAP(group.get()), action->gaction().get());
462 }
463 });
464- actionGroup->actionAdded().connect([this](Action::Ptr action){
465+ actionGroup->actionAdded().connect([=](Action::Ptr action){
466 GMainLoopDispatch([=](){
467- g_action_map_add_action(G_ACTION_MAP(m_gSimpleActionGroup.get()), action->gaction().get());
468+ g_action_map_add_action(G_ACTION_MAP(group.get()), action->gaction().get());
469 });
470 });
471- actionGroup->actionRemoved().connect([this](Action::Ptr action){
472+ actionGroup->actionRemoved().connect([=](Action::Ptr action){
473 GMainLoopDispatch([=](){
474- g_action_map_remove_action(G_ACTION_MAP(m_gSimpleActionGroup.get()),
475+ g_action_map_remove_action(G_ACTION_MAP(group.get()),
476 action->name().c_str());
477 });
478 });
479
480=== modified file 'src/menumodel-cpp/action.cpp'
481--- src/menumodel-cpp/action.cpp 2014-08-14 23:23:06 +0000
482+++ src/menumodel-cpp/action.cpp 2014-09-26 13:07:38 +0000
483@@ -85,6 +85,7 @@
484 g_signal_handler_disconnect(m_gaction.get(), m_activateHandlerId);
485 if (m_changeStateHandlerId)
486 g_signal_handler_disconnect(m_gaction.get(), m_changeStateHandlerId);
487+ GMainLoopSync([]{});
488 }
489
490 std::string
491@@ -99,8 +100,9 @@
492 {
493 std::lock_guard<std::recursive_mutex> lg(m_mutex);
494 m_state = value;
495+ auto action = m_gaction;
496 GMainLoopDispatch([=](){
497- g_simple_action_set_state(G_SIMPLE_ACTION(m_gaction.get()), value);
498+ g_simple_action_set_state(G_SIMPLE_ACTION(action.get()), value);
499 });
500 /// @todo state changes don't work properly. We probably need to make the
501 /// state a Property to be able to get signals on change.
502
503=== modified file 'src/menumodel-cpp/gio-helpers/util.cpp'
504--- src/menumodel-cpp/gio-helpers/util.cpp 2014-08-14 23:23:06 +0000
505+++ src/menumodel-cpp/gio-helpers/util.cpp 2014-09-26 13:07:38 +0000
506@@ -20,7 +20,7 @@
507 #include "util.h"
508
509 std::mutex GMainLoopDispatch::_lock;
510-std::vector<GMainLoopDispatch::Func *> GMainLoopDispatch::_funcs;
511+std::list<GMainLoopDispatch::Func *> GMainLoopDispatch::_funcs;
512
513 gboolean
514 GMainLoopDispatch::dispatch_cb(gpointer)
515@@ -37,7 +37,12 @@
516 GMainLoopDispatch::GMainLoopDispatch(std::function<void()> func)
517 {
518 if (g_main_context_acquire(g_main_context_default())) {
519- func();
520+ if (_funcs.empty())
521+ func();
522+ else {
523+ std::function<void()> *funcPtr = new std::function<void()>(func);
524+ _funcs.push_back(funcPtr);
525+ }
526 g_main_context_release(g_main_context_default());
527 } else {
528 std::lock_guard<std::mutex> lock(_lock);
529
530=== modified file 'src/menumodel-cpp/gio-helpers/util.h'
531--- src/menumodel-cpp/gio-helpers/util.h 2014-08-15 11:59:20 +0000
532+++ src/menumodel-cpp/gio-helpers/util.h 2014-09-26 13:07:38 +0000
533@@ -28,6 +28,7 @@
534 #include <condition_variable>
535 #include <iostream>
536 #include <vector>
537+#include <list>
538
539 struct GMainLoopSync
540 {
541@@ -72,8 +73,8 @@
542 public:
543 typedef std::function<void()> Func;
544 static std::mutex _lock;
545- // vector keeps the order of the functions
546- static std::vector<Func *> _funcs;
547+ // list keeps the order of the functions
548+ static std::list<Func *> _funcs;
549
550 //GMainLoopDispatch() = delete;
551 GMainLoopDispatch(std::function<void()> func);
552
553=== modified file 'src/menumodel-cpp/menu-merger.h'
554--- src/menumodel-cpp/menu-merger.h 2014-08-14 23:23:06 +0000
555+++ src/menumodel-cpp/menu-merger.h 2014-09-26 13:07:38 +0000
556@@ -56,15 +56,18 @@
557 gint added)
558 {
559 int offset = m_startPositions[model] + position;
560+ auto menu = m_gmenu;
561
562- for (int i = 0; i < removed; ++i) {
563- g_menu_remove(m_gmenu.get(), offset);
564- }
565- for (int i = added-1; i >= 0; --i) {
566- auto item = g_menu_item_new_from_model(model, position + i);
567- g_menu_insert_item(m_gmenu.get(), offset, item);
568- g_object_unref(item);
569- }
570+ GMainLoopDispatch([=](){
571+ for (int i = 0; i < removed; ++i) {
572+ g_menu_remove(menu.get(), offset);
573+ }
574+ for (int i = added-1; i >= 0; --i) {
575+ auto item = g_menu_item_new_from_model(model, position + i);
576+ g_menu_insert_item(menu.get(), offset, item);
577+ g_object_unref(item);
578+ }
579+ });
580
581 int delta = added - removed;
582 bool update = false;
583@@ -89,6 +92,12 @@
584 m_gmenu = make_gmenu_ptr();
585 }
586
587+ ~MenuMerger()
588+ {
589+ clear();
590+ GMainLoopSync([]{});
591+ }
592+
593 void append(MenuModel::Ptr menu)
594 {
595 // calculate the start position for the items for the new menu
596@@ -106,7 +115,6 @@
597
598 // add all items
599 itemsChanged(*menu, 0, 0, g_menu_model_get_n_items(*menu));
600-
601 m_handlerId[*menu] = g_signal_connect(menu->operator GMenuModel *(),
602 "items-changed",
603 G_CALLBACK(MenuMerger::items_changed_cb),
604
605=== modified file 'src/menumodel-cpp/menu.h'
606--- src/menumodel-cpp/menu.h 2014-08-14 23:23:06 +0000
607+++ src/menumodel-cpp/menu.h 2014-09-26 13:07:38 +0000
608@@ -51,14 +51,18 @@
609 virtual ~Menu()
610 {
611 std::lock_guard<std::recursive_mutex> lg(m_mutex);
612+ clear();
613+ GMainLoopSync([]{});
614 }
615
616 void append(MenuItem::Ptr item)
617 {
618 std::lock_guard<std::recursive_mutex> lg(m_mutex);
619 m_items.push_back(item);
620+ // prevent this-> from being captured
621+ auto menu = m_gmenu;
622 GMainLoopDispatch([=](){
623- g_menu_append_item(m_gmenu.get(), item->gmenuitem());
624+ g_menu_append_item(menu.get(), item->gmenuitem());
625 });
626 if (std::count(m_items.begin(), m_items.end(), item) == 1) {
627 /// @todo disconenct
628@@ -66,9 +70,11 @@
629 int index = 0;
630 for (auto iter = m_items.begin(); iter != m_items.end(); ++iter) {
631 if (*iter == item) {
632+ // prevent this-> from being captured
633+ auto menu = m_gmenu;
634 GMainLoopDispatch([=](){
635- g_menu_remove(m_gmenu.get(), index);
636- g_menu_insert_item(m_gmenu.get(), index, item->gmenuitem());
637+ g_menu_remove(menu.get(), index);
638+ g_menu_insert_item(menu.get(), index, item->gmenuitem());
639 });
640 }
641 ++index;
642@@ -88,8 +94,11 @@
643 ++index;
644 ++iter;
645 }
646+
647+ // prevent this-> from being captured
648+ auto menu = m_gmenu;
649 GMainLoopDispatch([=](){
650- g_menu_insert_item(m_gmenu.get(), index, item->gmenuitem());
651+ g_menu_insert_item(menu.get(), index, item->gmenuitem());
652 });
653 m_items.insert(position, item);
654 }
655@@ -132,8 +141,10 @@
656 if (iter == m_items.end())
657 return;
658
659+ // prevent this-> from being captured
660+ auto menu = m_gmenu;
661 GMainLoopDispatch([=](){
662- g_menu_remove(m_gmenu.get(), index);
663+ g_menu_remove(menu.get(), index);
664 });
665 m_items.erase(item);
666 }
667@@ -147,9 +158,11 @@
668 // work reversed so that GMenu positions match tbe m_items positions
669 int index = m_items.size()-1;
670 for (auto iter = m_items.rbegin(); iter != m_items.rend(); ++iter) {
671+ // prevent this-> from being captured
672+ auto menu = m_gmenu;
673 if (*iter == item) {
674 GMainLoopDispatch([=](){
675- g_menu_remove(m_gmenu.get(), index);
676+ g_menu_remove(menu.get(), index);
677 });
678 }
679 --index;
680@@ -201,8 +214,10 @@
681 void clear()
682 {
683 std::lock_guard<std::recursive_mutex> lg(m_mutex);
684+ // prevent this-> from being captured
685+ auto menu = m_gmenu;
686 GMainLoopDispatch([=](){
687- g_menu_remove_all(m_gmenu.get());
688+ g_menu_remove_all(menu.get());
689 });
690 m_items.clear();
691 }

Subscribers

People subscribed via source and target branches