remove deprecated MainContext channel

This commit is contained in:
ranfdev
2024-02-01 14:48:15 +01:00
parent f790748e0a
commit 410569689c
5 changed files with 81 additions and 79 deletions

View File

@ -265,38 +265,40 @@ impl NotifyApplication {
// `Invalid client serial` and it's broken. // `Invalid client serial` and it's broken.
// Until https://github.com/flatpak/xdg-dbus-proxy/issues/46 is solved, I have to handle these things // Until https://github.com/flatpak/xdg-dbus-proxy/issues/46 is solved, I have to handle these things
// in the main thread. Uff. // in the main thread. Uff.
let (tx, rx) = glib::MainContext::channel(Default::default());
let (s, r) = async_channel::unbounded::<models::Notification>();
let app = self.clone(); let app = self.clone();
rx.attach(None, move |n: models::Notification| { glib::MainContext::ref_thread_default().spawn_local(async move {
let gio_notif = gio::Notification::new(&n.title); while let Ok(n) = r.recv().await {
gio_notif.set_body(Some(&n.body)); let gio_notif = gio::Notification::new(&n.title);
gio_notif.set_body(Some(&n.body));
let action_name = |a| { let action_name = |a| {
let json = serde_json::to_string(a).unwrap(); let json = serde_json::to_string(a).unwrap();
gio::Action::print_detailed_name("app.message-action", Some(&json.into())) gio::Action::print_detailed_name("app.message-action", Some(&json.into()))
}; };
for a in n.actions.iter() { for a in n.actions.iter() {
match a { match a {
models::Action::View { label, .. } => { models::Action::View { label, .. } => {
gio_notif.add_button(&label, &action_name(a)) gio_notif.add_button(&label, &action_name(a))
}
models::Action::Http { label, .. } => {
gio_notif.add_button(&label, &action_name(a))
}
_ => {}
} }
models::Action::Http { label, .. } => {
gio_notif.add_button(&label, &action_name(a))
}
_ => {}
} }
app.send_notification(None, &gio_notif);
} }
app.send_notification(None, &gio_notif);
glib::ControlFlow::Continue
}); });
struct Proxies { struct Proxies {
notification: glib::Sender<models::Notification>, notification: async_channel::Sender<models::Notification>,
} }
impl models::NotificationProxy for Proxies { impl models::NotificationProxy for Proxies {
fn send(&self, n: models::Notification) -> anyhow::Result<()> { fn send(&self, n: models::Notification) -> anyhow::Result<()> {
self.notification.send(n)?; self.notification.send_blocking(n)?;
Ok(()) Ok(())
} }
} }
@ -317,7 +319,7 @@ impl NotifyApplication {
Box::pin(rx) Box::pin(rx)
} }
} }
let proxies = std::sync::Arc::new(Proxies { notification: tx }); let proxies = std::sync::Arc::new(Proxies { notification: s });
ntfy_daemon::system_client::start( ntfy_daemon::system_client::start(
socket_path.to_owned(), socket_path.to_owned(),
dbpath.to_str().unwrap(), dbpath.to_str().unwrap(),

View File

@ -1,28 +1,28 @@
use std::cell::Cell; use std::cell::Cell;
use std::rc::Rc; use std::rc::Rc;
use glib::Receiver;
use glib::SourceId; use glib::SourceId;
use gtk::glib; use gtk::glib;
pub fn debounce_channel<T: 'static>( #[derive(Clone)]
duration: std::time::Duration, pub struct Debouncer {
source: Receiver<T>, scheduled: Rc<Cell<Option<SourceId>>>,
) -> Receiver<T> { }
let (tx, rx) = glib::MainContext::channel(Default::default()); impl Debouncer {
let scheduled = Rc::new(Cell::new(None::<SourceId>)); pub fn new() -> Self {
source.attach(None, move |data| { Self {
if let Some(scheduled) = scheduled.take() { scheduled: Default::default(),
}
}
pub fn call(&self, duration: std::time::Duration, f: impl Fn() -> () + 'static) {
if let Some(scheduled) = self.scheduled.take() {
scheduled.remove(); scheduled.remove();
} }
let tx = tx.clone(); let scheduled_clone = self.scheduled.clone();
let scheduled_clone = scheduled.clone();
let source_id = glib::source::timeout_add_local_once(duration, move || { let source_id = glib::source::timeout_add_local_once(duration, move || {
tx.send(data).unwrap(); f();
scheduled_clone.take(); scheduled_clone.take();
}); });
scheduled.set(Some(source_id)); self.scheduled.set(Some(source_id));
glib::ControlFlow::Continue }
});
rx
} }

View File

@ -145,24 +145,29 @@ impl AddSubscriptionDialog {
}, },
} }
let (tx, rx) = glib::MainContext::channel(Default::default()); let debounced_error_check = {
let txc = tx.clone(); let db = crate::async_utils::Debouncer::new();
topic_entry.delegate().unwrap().connect_changed(move |_| { let objc = obj.clone();
txc.send(()).unwrap(); move || {
}); db.call(std::time::Duration::from_millis(500), move || {
let txc = tx.clone(); objc.check_errors()
server_entry.delegate().unwrap().connect_changed(move |_| { });
txc.send(()).unwrap(); }
}); };
server_expander.connect_enable_expansion_notify(move |_| {
tx.send(()).unwrap(); let f = debounced_error_check.clone();
}); topic_entry
let rx = crate::async_utils::debounce_channel(std::time::Duration::from_millis(500), rx); .delegate()
let objc = obj.clone(); .unwrap()
rx.attach(None, move |_| { .connect_changed(move |_| f.clone()());
objc.check_errors(); let f = debounced_error_check.clone();
glib::ControlFlow::Continue server_entry
}); .delegate()
.unwrap()
.connect_changed(move |_| f.clone()());
let f = debounced_error_check.clone();
server_expander.connect_enable_expansion_notify(move |_| f.clone()());
imp.widgets.replace(Widgets { imp.widgets.replace(Widgets {
topic_entry, topic_entry,
server_expander, server_expander,

View File

@ -9,6 +9,8 @@ use gtk::{gdk, gio, glib};
use ntfy_daemon::models; use ntfy_daemon::models;
use tracing::error; use tracing::error;
use crate::widgets::window::SpawnWithToast;
mod imp { mod imp {
use super::*; use super::*;
@ -161,10 +163,10 @@ impl MessageRow {
Ok(bytes) Ok(bytes)
} }
fn build_image(&self, url: String) -> gtk::Picture { fn build_image(&self, url: String) -> gtk::Picture {
let (tx, rx) = glib::MainContext::channel(Default::default()); let (s, r) = async_channel::unbounded();
gio::spawn_blocking(move || { gio::spawn_blocking(move || {
if let Err(e) = if let Err(e) = Self::fetch_image_bytes(&url)
Self::fetch_image_bytes(&url).map(|bytes| tx.send(glib::Bytes::from_owned(bytes))) .map(|bytes| s.send_blocking(glib::Bytes::from_owned(bytes)))
{ {
error!(error = %e) error!(error = %e)
} }
@ -174,18 +176,15 @@ impl MessageRow {
picture.set_can_shrink(true); picture.set_can_shrink(true);
picture.set_height_request(350); picture.set_height_request(350);
let picturec = picture.clone(); let picturec = picture.clone();
rx.attach(Default::default(), move |b| {
self.spawn_with_near_toast(async move {
let b = r.recv().await?;
let stream = gio::MemoryInputStream::from_bytes(&b); let stream = gio::MemoryInputStream::from_bytes(&b);
let pixbuf = match Pixbuf::from_stream(&stream, gio::Cancellable::NONE) { let pixbuf = Pixbuf::from_stream(&stream, gio::Cancellable::NONE)?;
Ok(res) => res,
Err(e) => {
error!(error = %e, "parsing image contents");
return glib::ControlFlow::Break;
}
};
picturec.set_paintable(Some(&gdk::Texture::for_pixbuf(&pixbuf))); picturec.set_paintable(Some(&gdk::Texture::for_pixbuf(&pixbuf)));
glib::ControlFlow::Break Ok::<(), anyhow::Error>(())
}); });
picture picture
} }
fn build_action_btn(&self, action: models::Action) -> gtk::Button { fn build_action_btn(&self, action: models::Action) -> gtk::Button {

View File

@ -49,23 +49,19 @@ mod imp {
self.parent_constructed(); self.parent_constructed();
let this = self.obj().clone(); let this = self.obj().clone();
let (tx, rx) = glib::MainContext::channel(glib::Priority::default());
let rx =
crate::async_utils::debounce_channel(std::time::Duration::from_millis(500), rx);
rx.attach(None, move |entry| {
this.update_display_name(&entry);
glib::ControlFlow::Continue
});
let this = self.obj().clone();
self.display_name_entry self.display_name_entry
.set_text(&this.subscription().unwrap().display_name()); .set_text(&this.subscription().unwrap().display_name());
self.muted_switch_row self.muted_switch_row
.set_active(this.subscription().unwrap().muted()); .set_active(this.subscription().unwrap().muted());
let debouncer = crate::async_utils::Debouncer::new();
self.display_name_entry.connect_changed({ self.display_name_entry.connect_changed({
move |entry| { move |entry| {
tx.send(entry.clone()).unwrap(); let entry = entry.clone();
let this = this.clone();
debouncer.call(std::time::Duration::from_millis(500), move || {
this.update_display_name(&entry);
})
} }
}); });
let this = self.obj().clone(); let this = self.obj().clone();