Merge lp:~unity-api-team/indicator-network/krillin-wifi into lp:indicator-network/14.10
- krillin-wifi
- Merge into trunk.14.10
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 |
Related bugs: |
|
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.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:429
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
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.
Antti Kaijanmäki (kaijanmaki) wrote : | # |
just a simple timeout increase.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:433
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Preview Diff
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 | } |
LGTM