ソースを参照

Fix shortcut by wrapping callback

Jonathan Kelley 1 年間 前
コミット
2ade193a5b
2 ファイル変更17 行追加6 行削除
  1. 5 1
      packages/desktop/src/hooks.rs
  2. 12 5
      packages/hooks/src/use_callback.rs

+ 5 - 1
packages/desktop/src/hooks.rs

@@ -9,6 +9,7 @@ use dioxus_core::{
     use_hook,
 };
 
+use dioxus_hooks::use_callback;
 use tao::{event::Event, event_loop::EventLoopWindowTarget};
 use wry::RequestAsyncResponder;
 
@@ -56,8 +57,11 @@ pub fn use_global_shortcut(
     accelerator: impl IntoAccelerator,
     handler: impl FnMut() + 'static,
 ) -> Result<ShortcutHandle, ShortcutRegistryError> {
+    // wrap the user's handler in something that will carry the scope/runtime with it
+    let mut cb = use_callback(handler);
+
     use_hook_with_cleanup(
-        move || window().create_shortcut(accelerator.accelerator(), handler),
+        move || window().create_shortcut(accelerator.accelerator(), move || cb.call()),
         |handle| {
             if let Ok(handle) = handle {
                 handle.remove();

+ 12 - 5
packages/hooks/src/use_callback.rs

@@ -1,4 +1,4 @@
-use dioxus_core::prelude::use_hook;
+use dioxus_core::prelude::{current_scope_id, use_hook, Runtime};
 use dioxus_signals::CopyValue;
 use dioxus_signals::Writable;
 
@@ -18,10 +18,17 @@ pub fn use_callback<O>(f: impl FnMut() -> O + 'static) -> UseCallback<O> {
     inner.set(Some(f));
 
     // And then wrap that callback in a boxed callback so we're blind to the size of the actual callback
-    use_hook(|| UseCallback {
-        inner: CopyValue::new(Box::new(move || {
-            inner.with_mut(|f: &mut Option<_>| f.as_mut().unwrap()())
-        })),
+    use_hook(|| {
+        let cur_scope = current_scope_id().unwrap();
+        let rt = Runtime::current().unwrap();
+
+        UseCallback {
+            inner: CopyValue::new(Box::new(move || {
+                // run this callback in the context of the scope it was created in.
+                let run_callback = || inner.with_mut(|f: &mut Option<_>| f.as_mut().unwrap()());
+                rt.on_scope(cur_scope, run_callback)
+            })),
+        }
     })
 }