فهرست منبع

Add richer API for describing global shortcut accelerators.

Nolan Darilek 2 سال پیش
والد
کامیت
c84e028bd6
3فایلهای تغییر یافته به همراه37 افزوده شده و 27 حذف شده
  1. 1 1
      examples/shortcut.rs
  2. 4 9
      packages/desktop/src/desktop_context.rs
  3. 32 17
      packages/desktop/src/shortcut.rs

+ 1 - 1
examples/shortcut.rs

@@ -8,7 +8,7 @@ fn main() {
 
 fn app(cx: Scope) -> Element {
     let toggled = use_state(cx, || false);
-    use_global_shortcut(cx, KeyCode::S, ModifiersState::CONTROL, {
+    use_global_shortcut(cx, "ctrl+s", {
         to_owned![toggled];
         move || toggled.modify(|t| !*t)
     });

+ 4 - 9
packages/desktop/src/desktop_context.rs

@@ -6,8 +6,6 @@ use crate::create_new_window;
 use crate::eval::EvalResult;
 use crate::events::IpcMessage;
 use crate::query::QueryEngine;
-use crate::shortcut::IntoKeyCode;
-use crate::shortcut::IntoModifersState;
 use crate::shortcut::ShortcutId;
 use crate::shortcut::ShortcutRegistry;
 use crate::shortcut::ShortcutRegistryError;
@@ -18,6 +16,7 @@ use dioxus_core::VirtualDom;
 #[cfg(all(feature = "hot-reload", debug_assertions))]
 use dioxus_hot_reload::HotReloadMsg;
 use slab::Slab;
+use wry::application::accelerator::Accelerator;
 use wry::application::event::Event;
 use wry::application::event_loop::EventLoopProxy;
 use wry::application::event_loop::EventLoopWindowTarget;
@@ -237,15 +236,11 @@ impl DesktopContext {
     /// Linux: Only works on x11. See [this issue](https://github.com/tauri-apps/tao/issues/331) for more information.
     pub fn create_shortcut(
         &self,
-        key: impl IntoKeyCode,
-        modifiers: impl IntoModifersState,
+        accelerator: Accelerator,
         callback: impl FnMut() + 'static,
     ) -> Result<ShortcutId, ShortcutRegistryError> {
-        self.shortcut_manager.add_shortcut(
-            modifiers.into_modifiers_state(),
-            key.into_key_code(),
-            Box::new(callback),
-        )
+        self.shortcut_manager
+            .add_shortcut(accelerator, Box::new(callback))
     }
 
     /// Remove a global shortcut

+ 32 - 17
packages/desktop/src/shortcut.rs

@@ -1,4 +1,4 @@
-use std::{cell::RefCell, collections::HashMap, rc::Rc};
+use std::{cell::RefCell, collections::HashMap, rc::Rc, str::FromStr};
 
 use dioxus_core::ScopeState;
 use dioxus_html::input_data::keyboard_types::Modifiers;
@@ -57,11 +57,9 @@ impl ShortcutRegistry {
 
     pub(crate) fn add_shortcut(
         &self,
-        modifiers: impl Into<Option<ModifiersState>>,
-        key: KeyCode,
+        accelerator: Accelerator,
         callback: Box<dyn FnMut()>,
     ) -> Result<ShortcutId, ShortcutRegistryError> {
-        let accelerator = Accelerator::new(modifiers, key);
         let accelerator_id = accelerator.clone().id();
         let mut shortcuts = self.shortcuts.borrow_mut();
         Ok(
@@ -111,12 +109,6 @@ impl ShortcutRegistry {
         let mut shortcuts = self.shortcuts.borrow_mut();
         shortcuts.clear();
         let _ = self.manager.borrow_mut().unregister_all();
-        // prevent CTRL+R from reloading the page which breaks apps
-        let _ = self.add_shortcut(
-            Some(ModifiersState::CONTROL),
-            KeyCode::KeyR,
-            Box::new(|| {}),
-        );
     }
 }
 
@@ -144,22 +136,45 @@ pub struct ShortcutHandle {
     pub shortcut_id: ShortcutId,
 }
 
+pub trait IntoAccelerator {
+    fn accelerator(&self) -> Accelerator;
+}
+
+impl IntoAccelerator for (dioxus_html::KeyCode, ModifiersState) {
+    fn accelerator(&self) -> Accelerator {
+        Accelerator::new(Some(self.1), self.0.into_key_code())
+    }
+}
+
+impl IntoAccelerator for (ModifiersState, dioxus_html::KeyCode) {
+    fn accelerator(&self) -> Accelerator {
+        Accelerator::new(Some(self.0), self.1.into_key_code())
+    }
+}
+
+impl IntoAccelerator for dioxus_html::KeyCode {
+    fn accelerator(&self) -> Accelerator {
+        Accelerator::new(None, self.into_key_code())
+    }
+}
+
+impl IntoAccelerator for &str {
+    fn accelerator(&self) -> Accelerator {
+        Accelerator::from_str(self).unwrap()
+    }
+}
+
 /// Get a closure that executes any JavaScript in the WebView context.
 pub fn use_global_shortcut(
     cx: &ScopeState,
-    key: impl IntoKeyCode,
-    modifiers: impl IntoModifersState,
+    accelerator: impl IntoAccelerator,
     handler: impl FnMut() + 'static,
 ) -> &Result<ShortcutHandle, ShortcutRegistryError> {
     let desktop = use_window(cx);
     cx.use_hook(move || {
         let desktop = desktop.clone();
 
-        let id = desktop.create_shortcut(
-            key.into_key_code(),
-            modifiers.into_modifiers_state(),
-            handler,
-        );
+        let id = desktop.create_shortcut(accelerator.accelerator(), handler);
 
         Ok(ShortcutHandle {
             desktop,