Skip to content

Commit

Permalink
action_entry: Add activate_async helper
Browse files Browse the repository at this point in the history
This is a helper function in a similar vein to
gtk4-rs's `install_action_async ()` for widgets.
It allows applications to install actions
that use async/await without having to manually
create a glib::MainContext in the callback.
  • Loading branch information
BrainBlasted committed Jan 19, 2023
1 parent 3a7bf73 commit 7c20e1b
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion gio/src/action_entry.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use glib::{prelude::*, Variant, VariantTy, VariantType};
use glib::{prelude::*, MainContext, Variant, VariantTy, VariantType};
use std::future::Future;

use crate::{ActionMap, SimpleAction};

Expand Down Expand Up @@ -87,6 +88,30 @@ where
self
}

pub fn activate_async<Fut, F>(mut self, callback: F) -> Self
where
F: Fn(&O, &SimpleAction, Option<&Variant>) -> Fut + 'static + Clone,
Fut: Future<Output = ()>,
{
let future_cb = move |map: &O, action: &SimpleAction, variant: Option<&Variant>| {
let ctx = MainContext::thread_default().unwrap_or_else(|| {
let ctx = glib::MainContext::default();
assert!(ctx.is_owner(), "Current thread does not own the default main context and has no thread-default main context");
ctx
});

let variant = variant.map(ToOwned::to_owned);
ctx.spawn_local(
glib::clone!(@strong callback, @strong map, @strong action => async move {
callback(&map, &action, variant.as_ref()).await;
}),
);
};

self.0.activate = Some(Box::new(future_cb));
self
}

pub fn change_state<F: Fn(&O, &SimpleAction, Option<&Variant>) + 'static>(
mut self,
callback: F,
Expand Down

0 comments on commit 7c20e1b

Please sign in to comment.