Skip to content

Commit 4c58f19

Browse files
committed
refactor(nmrs-gui): use Arc<Notify> for monitor callbacks to satisfy Send bound
1 parent 7ddc160 commit 4c58f19

3 files changed

Lines changed: 57 additions & 70 deletions

File tree

nmrs-gui/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
All notable changes to the `nmrs-gui` crate will be documented in this file.
44

55
## [Unreleased]
6+
### Changed
7+
- Use `Arc<Notify>` for monitor callbacks to satisfy `Send` bound ([#359](https://github.com/cachebag/nmrs/pull/359))
68

79
## [1.5.1] - 2026-04-10
810
### Fixed

nmrs-gui/src/ui/mod.rs

Lines changed: 54 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use gtk::{
1212
};
1313
use std::cell::Cell;
1414
use std::rc::Rc;
15+
use std::sync::Arc;
16+
use tokio::sync::Notify;
1517

1618
use crate::ui::header::THEMES;
1719

@@ -164,46 +166,15 @@ pub fn build_ui(app: &Application) {
164166

165167
{
166168
let nm_device_monitor = nm.clone();
167-
let list_container_device = list_container_clone.clone();
168-
let is_scanning_device = is_scanning_clone.clone();
169-
let ctx_device = ctx.clone();
170-
let pending_device_refresh = Rc::new(std::cell::RefCell::new(false));
169+
let device_notify = Arc::new(Notify::new());
171170

171+
let notify_clone = device_notify.clone();
172172
glib::MainContext::default().spawn_local(async move {
173173
loop {
174-
let ctx_device_clone = ctx_device.clone();
175-
let list_container_clone = list_container_device.clone();
176-
let is_scanning_clone = is_scanning_device.clone();
177-
let pending_device_refresh_clone = pending_device_refresh.clone();
178-
174+
let notify = notify_clone.clone();
179175
let result = nm_device_monitor
180176
.monitor_device_changes(move || {
181-
let ctx = ctx_device_clone.clone();
182-
let list_container = list_container_clone.clone();
183-
let is_scanning = is_scanning_clone.clone();
184-
let pending_refresh = pending_device_refresh_clone.clone();
185-
186-
if pending_refresh.replace(true) {
187-
return;
188-
}
189-
190-
glib::MainContext::default().spawn_local(async move {
191-
glib::timeout_future_seconds(3).await;
192-
*pending_refresh.borrow_mut() = false;
193-
194-
let current_page = ctx.stack.visible_child_name();
195-
let on_networks_page =
196-
current_page.as_deref() == Some("networks");
197-
198-
if !is_scanning.get() && on_networks_page {
199-
header::refresh_networks_no_scan(
200-
ctx,
201-
&list_container,
202-
&is_scanning,
203-
)
204-
.await;
205-
}
206-
});
177+
notify.notify_one();
207178
})
208179
.await;
209180

@@ -213,50 +184,41 @@ pub fn build_ui(app: &Application) {
213184
glib::timeout_future_seconds(5).await;
214185
}
215186
});
187+
188+
let list_container_device = list_container_clone.clone();
189+
let is_scanning_device = is_scanning_clone.clone();
190+
let ctx_device = ctx.clone();
191+
glib::MainContext::default().spawn_local(async move {
192+
loop {
193+
device_notify.notified().await;
194+
glib::timeout_future_seconds(3).await;
195+
196+
let current_page = ctx_device.stack.visible_child_name();
197+
let on_networks_page = current_page.as_deref() == Some("networks");
198+
199+
if !is_scanning_device.get() && on_networks_page {
200+
header::refresh_networks_no_scan(
201+
ctx_device.clone(),
202+
&list_container_device,
203+
&is_scanning_device,
204+
)
205+
.await;
206+
}
207+
}
208+
});
216209
}
217210

218211
{
219212
let nm_network_monitor = nm.clone();
220-
let list_container_network = list_container_clone.clone();
221-
let is_scanning_network = is_scanning_clone.clone();
222-
let ctx_network = ctx.clone();
223-
let pending_network_refresh = Rc::new(std::cell::RefCell::new(false));
213+
let network_notify = Arc::new(Notify::new());
224214

215+
let notify_clone = network_notify.clone();
225216
glib::MainContext::default().spawn_local(async move {
226217
loop {
227-
let ctx_network_clone = ctx_network.clone();
228-
let list_container_clone = list_container_network.clone();
229-
let is_scanning_clone = is_scanning_network.clone();
230-
let pending_network_refresh_clone = pending_network_refresh.clone();
231-
218+
let notify = notify_clone.clone();
232219
let result = nm_network_monitor
233220
.monitor_network_changes(move || {
234-
let ctx = ctx_network_clone.clone();
235-
let list_container = list_container_clone.clone();
236-
let is_scanning = is_scanning_clone.clone();
237-
let pending_refresh = pending_network_refresh_clone.clone();
238-
239-
if pending_refresh.replace(true) {
240-
return;
241-
}
242-
243-
glib::MainContext::default().spawn_local(async move {
244-
glib::timeout_future_seconds(8).await;
245-
*pending_refresh.borrow_mut() = false;
246-
247-
let current_page = ctx.stack.visible_child_name();
248-
let on_networks_page =
249-
current_page.as_deref() == Some("networks");
250-
251-
if !is_scanning.get() && on_networks_page {
252-
header::refresh_networks_no_scan(
253-
ctx,
254-
&list_container,
255-
&is_scanning,
256-
)
257-
.await;
258-
}
259-
});
221+
notify.notify_one();
260222
})
261223
.await;
262224

@@ -266,6 +228,28 @@ pub fn build_ui(app: &Application) {
266228
glib::timeout_future_seconds(5).await;
267229
}
268230
});
231+
232+
let list_container_network = list_container_clone.clone();
233+
let is_scanning_network = is_scanning_clone.clone();
234+
let ctx_network = ctx.clone();
235+
glib::MainContext::default().spawn_local(async move {
236+
loop {
237+
network_notify.notified().await;
238+
glib::timeout_future_seconds(8).await;
239+
240+
let current_page = ctx_network.stack.visible_child_name();
241+
let on_networks_page = current_page.as_deref() == Some("networks");
242+
243+
if !is_scanning_network.get() && on_networks_page {
244+
header::refresh_networks_no_scan(
245+
ctx_network.clone(),
246+
&list_container_network,
247+
&is_scanning_network,
248+
)
249+
.await;
250+
}
251+
}
252+
});
269253
}
270254
}
271255
Err(err) => {

nmrs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ All notable changes to the `nmrs` crate will be documented in this file.
1717
- Support for specifying Bluetooth adapter in `BluetoothIdentity` ([#267](https://github.com/cachebag/nmrs/pull/267))
1818

1919
### Fixed
20+
- Add `Send` bound to monitoring stream trait objects so `monitor_network_changes` and `monitor_device_changes` work with `tokio::spawn` ([#359](https://github.com/cachebag/nmrs/pull/359))
2021
- Line-accurate source locations for `.ovpn` directives and blocks ([#318](https://github.com/cachebag/nmrs/pull/318))
2122
- `key_direction` when nested under `tls_auth` and as a standalone directive ([#320](https://github.com/cachebag/nmrs/pull/320))
2223

0 commit comments

Comments
 (0)