From 7c20e1b26c1d63459c8ce1cef26484cee2ab85a2 Mon Sep 17 00:00:00 2001 From: Christopher Davis Date: Wed, 18 Jan 2023 21:15:43 -0500 Subject: [PATCH] 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. --- gio/src/action_entry.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/gio/src/action_entry.rs b/gio/src/action_entry.rs index 118d418a8748..7087f4f1b5fb 100644 --- a/gio/src/action_entry.rs +++ b/gio/src/action_entry.rs @@ -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}; @@ -87,6 +88,30 @@ where self } + pub fn activate_async(mut self, callback: F) -> Self + where + F: Fn(&O, &SimpleAction, Option<&Variant>) -> Fut + 'static + Clone, + Fut: Future, + { + 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) + 'static>( mut self, callback: F,