Skip to content

Commit 7c20e1b

Browse files
committed
action_entry: Add activate_async helper
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.
1 parent 3a7bf73 commit 7c20e1b

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

gio/src/action_entry.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Take a look at the license at the top of the repository in the LICENSE file.
22

3-
use glib::{prelude::*, Variant, VariantTy, VariantType};
3+
use glib::{prelude::*, MainContext, Variant, VariantTy, VariantType};
4+
use std::future::Future;
45

56
use crate::{ActionMap, SimpleAction};
67

@@ -87,6 +88,30 @@ where
8788
self
8889
}
8990

91+
pub fn activate_async<Fut, F>(mut self, callback: F) -> Self
92+
where
93+
F: Fn(&O, &SimpleAction, Option<&Variant>) -> Fut + 'static + Clone,
94+
Fut: Future<Output = ()>,
95+
{
96+
let future_cb = move |map: &O, action: &SimpleAction, variant: Option<&Variant>| {
97+
let ctx = MainContext::thread_default().unwrap_or_else(|| {
98+
let ctx = glib::MainContext::default();
99+
assert!(ctx.is_owner(), "Current thread does not own the default main context and has no thread-default main context");
100+
ctx
101+
});
102+
103+
let variant = variant.map(ToOwned::to_owned);
104+
ctx.spawn_local(
105+
glib::clone!(@strong callback, @strong map, @strong action => async move {
106+
callback(&map, &action, variant.as_ref()).await;
107+
}),
108+
);
109+
};
110+
111+
self.0.activate = Some(Box::new(future_cb));
112+
self
113+
}
114+
90115
pub fn change_state<F: Fn(&O, &SimpleAction, Option<&Variant>) + 'static>(
91116
mut self,
92117
callback: F,

0 commit comments

Comments
 (0)