Skip to content

Commit 4105696

Browse files
committed
remove deprecated MainContext channel
1 parent f790748 commit 4105696

File tree

5 files changed

+82
-80
lines changed

5 files changed

+82
-80
lines changed

src/application.rs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -265,38 +265,40 @@ impl NotifyApplication {
265265
// `Invalid client serial` and it's broken.
266266
// Until https://github.com/flatpak/xdg-dbus-proxy/issues/46 is solved, I have to handle these things
267267
// in the main thread. Uff.
268-
let (tx, rx) = glib::MainContext::channel(Default::default());
268+
269+
let (s, r) = async_channel::unbounded::<models::Notification>();
270+
269271
let app = self.clone();
270-
rx.attach(None, move |n: models::Notification| {
271-
let gio_notif = gio::Notification::new(&n.title);
272-
gio_notif.set_body(Some(&n.body));
273-
274-
let action_name = |a| {
275-
let json = serde_json::to_string(a).unwrap();
276-
gio::Action::print_detailed_name("app.message-action", Some(&json.into()))
277-
};
278-
for a in n.actions.iter() {
279-
match a {
280-
models::Action::View { label, .. } => {
281-
gio_notif.add_button(&label, &action_name(a))
282-
}
283-
models::Action::Http { label, .. } => {
284-
gio_notif.add_button(&label, &action_name(a))
272+
glib::MainContext::ref_thread_default().spawn_local(async move {
273+
while let Ok(n) = r.recv().await {
274+
let gio_notif = gio::Notification::new(&n.title);
275+
gio_notif.set_body(Some(&n.body));
276+
277+
let action_name = |a| {
278+
let json = serde_json::to_string(a).unwrap();
279+
gio::Action::print_detailed_name("app.message-action", Some(&json.into()))
280+
};
281+
for a in n.actions.iter() {
282+
match a {
283+
models::Action::View { label, .. } => {
284+
gio_notif.add_button(&label, &action_name(a))
285+
}
286+
models::Action::Http { label, .. } => {
287+
gio_notif.add_button(&label, &action_name(a))
288+
}
289+
_ => {}
285290
}
286-
_ => {}
287291
}
288-
}
289292

290-
app.send_notification(None, &gio_notif);
291-
glib::ControlFlow::Continue
293+
app.send_notification(None, &gio_notif);
294+
}
292295
});
293-
294296
struct Proxies {
295-
notification: glib::Sender<models::Notification>,
297+
notification: async_channel::Sender<models::Notification>,
296298
}
297299
impl models::NotificationProxy for Proxies {
298300
fn send(&self, n: models::Notification) -> anyhow::Result<()> {
299-
self.notification.send(n)?;
301+
self.notification.send_blocking(n)?;
300302
Ok(())
301303
}
302304
}
@@ -317,7 +319,7 @@ impl NotifyApplication {
317319
Box::pin(rx)
318320
}
319321
}
320-
let proxies = std::sync::Arc::new(Proxies { notification: tx });
322+
let proxies = std::sync::Arc::new(Proxies { notification: s });
321323
ntfy_daemon::system_client::start(
322324
socket_path.to_owned(),
323325
dbpath.to_str().unwrap(),

src/async_utils.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
use std::cell::Cell;
22
use std::rc::Rc;
33

4-
use glib::Receiver;
54
use glib::SourceId;
65
use gtk::glib;
76

8-
pub fn debounce_channel<T: 'static>(
9-
duration: std::time::Duration,
10-
source: Receiver<T>,
11-
) -> Receiver<T> {
12-
let (tx, rx) = glib::MainContext::channel(Default::default());
13-
let scheduled = Rc::new(Cell::new(None::<SourceId>));
14-
source.attach(None, move |data| {
15-
if let Some(scheduled) = scheduled.take() {
7+
#[derive(Clone)]
8+
pub struct Debouncer {
9+
scheduled: Rc<Cell<Option<SourceId>>>,
10+
}
11+
impl Debouncer {
12+
pub fn new() -> Self {
13+
Self {
14+
scheduled: Default::default(),
15+
}
16+
}
17+
pub fn call(&self, duration: std::time::Duration, f: impl Fn() -> () + 'static) {
18+
if let Some(scheduled) = self.scheduled.take() {
1619
scheduled.remove();
1720
}
18-
let tx = tx.clone();
19-
let scheduled_clone = scheduled.clone();
21+
let scheduled_clone = self.scheduled.clone();
2022
let source_id = glib::source::timeout_add_local_once(duration, move || {
21-
tx.send(data).unwrap();
23+
f();
2224
scheduled_clone.take();
2325
});
24-
scheduled.set(Some(source_id));
25-
glib::ControlFlow::Continue
26-
});
27-
rx
26+
self.scheduled.set(Some(source_id));
27+
}
2828
}

src/widgets/add_subscription_dialog.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -145,24 +145,29 @@ impl AddSubscriptionDialog {
145145
},
146146
}
147147

148-
let (tx, rx) = glib::MainContext::channel(Default::default());
149-
let txc = tx.clone();
150-
topic_entry.delegate().unwrap().connect_changed(move |_| {
151-
txc.send(()).unwrap();
152-
});
153-
let txc = tx.clone();
154-
server_entry.delegate().unwrap().connect_changed(move |_| {
155-
txc.send(()).unwrap();
156-
});
157-
server_expander.connect_enable_expansion_notify(move |_| {
158-
tx.send(()).unwrap();
159-
});
160-
let rx = crate::async_utils::debounce_channel(std::time::Duration::from_millis(500), rx);
161-
let objc = obj.clone();
162-
rx.attach(None, move |_| {
163-
objc.check_errors();
164-
glib::ControlFlow::Continue
165-
});
148+
let debounced_error_check = {
149+
let db = crate::async_utils::Debouncer::new();
150+
let objc = obj.clone();
151+
move || {
152+
db.call(std::time::Duration::from_millis(500), move || {
153+
objc.check_errors()
154+
});
155+
}
156+
};
157+
158+
let f = debounced_error_check.clone();
159+
topic_entry
160+
.delegate()
161+
.unwrap()
162+
.connect_changed(move |_| f.clone()());
163+
let f = debounced_error_check.clone();
164+
server_entry
165+
.delegate()
166+
.unwrap()
167+
.connect_changed(move |_| f.clone()());
168+
let f = debounced_error_check.clone();
169+
server_expander.connect_enable_expansion_notify(move |_| f.clone()());
170+
166171
imp.widgets.replace(Widgets {
167172
topic_entry,
168173
server_expander,

src/widgets/message_row.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use gtk::{gdk, gio, glib};
99
use ntfy_daemon::models;
1010
use tracing::error;
1111

12+
use crate::widgets::window::SpawnWithToast;
13+
1214
mod imp {
1315
use super::*;
1416

@@ -161,10 +163,10 @@ impl MessageRow {
161163
Ok(bytes)
162164
}
163165
fn build_image(&self, url: String) -> gtk::Picture {
164-
let (tx, rx) = glib::MainContext::channel(Default::default());
166+
let (s, r) = async_channel::unbounded();
165167
gio::spawn_blocking(move || {
166-
if let Err(e) =
167-
Self::fetch_image_bytes(&url).map(|bytes| tx.send(glib::Bytes::from_owned(bytes)))
168+
if let Err(e) = Self::fetch_image_bytes(&url)
169+
.map(|bytes| s.send_blocking(glib::Bytes::from_owned(bytes)))
168170
{
169171
error!(error = %e)
170172
}
@@ -174,18 +176,15 @@ impl MessageRow {
174176
picture.set_can_shrink(true);
175177
picture.set_height_request(350);
176178
let picturec = picture.clone();
177-
rx.attach(Default::default(), move |b| {
179+
180+
self.spawn_with_near_toast(async move {
181+
let b = r.recv().await?;
178182
let stream = gio::MemoryInputStream::from_bytes(&b);
179-
let pixbuf = match Pixbuf::from_stream(&stream, gio::Cancellable::NONE) {
180-
Ok(res) => res,
181-
Err(e) => {
182-
error!(error = %e, "parsing image contents");
183-
return glib::ControlFlow::Break;
184-
}
185-
};
183+
let pixbuf = Pixbuf::from_stream(&stream, gio::Cancellable::NONE)?;
186184
picturec.set_paintable(Some(&gdk::Texture::for_pixbuf(&pixbuf)));
187-
glib::ControlFlow::Break
185+
Ok::<(), anyhow::Error>(())
188186
});
187+
189188
picture
190189
}
191190
fn build_action_btn(&self, action: models::Action) -> gtk::Button {

src/widgets/subscription_info_dialog.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,19 @@ mod imp {
4949
self.parent_constructed();
5050
let this = self.obj().clone();
5151

52-
let (tx, rx) = glib::MainContext::channel(glib::Priority::default());
53-
let rx =
54-
crate::async_utils::debounce_channel(std::time::Duration::from_millis(500), rx);
55-
rx.attach(None, move |entry| {
56-
this.update_display_name(&entry);
57-
glib::ControlFlow::Continue
58-
});
59-
60-
let this = self.obj().clone();
6152
self.display_name_entry
6253
.set_text(&this.subscription().unwrap().display_name());
6354
self.muted_switch_row
6455
.set_active(this.subscription().unwrap().muted());
6556

57+
let debouncer = crate::async_utils::Debouncer::new();
6658
self.display_name_entry.connect_changed({
6759
move |entry| {
68-
tx.send(entry.clone()).unwrap();
60+
let entry = entry.clone();
61+
let this = this.clone();
62+
debouncer.call(std::time::Duration::from_millis(500), move || {
63+
this.update_display_name(&entry);
64+
})
6965
}
7066
});
7167
let this = self.obj().clone();

0 commit comments

Comments
 (0)