Browse Source

refactor(core): add global-shortcut Cargo feature, enhancing binary size (#3956)

Lucas Fernandes Nogueira 3 years ago
parent
commit
e11878bcf7

+ 7 - 0
.changes/global-shortcut-feature.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": minor
+"tauri-runtime-wry": minor
+---
+
+**Breaking change::* Added the `global-shortcut` Cargo feature.

+ 1 - 0
core/tauri-codegen/src/context.rs

@@ -56,6 +56,7 @@ fn map_core_assets(
     if path.extension() == Some(OsStr::new("html")) {
     if path.extension() == Some(OsStr::new("html")) {
       let mut document = parse_html(String::from_utf8_lossy(input).into_owned());
       let mut document = parse_html(String::from_utf8_lossy(input).into_owned());
 
 
+      #[allow(clippy::collapsible_if)]
       if csp {
       if csp {
         #[cfg(target_os = "linux")]
         #[cfg(target_os = "linux")]
         ::tauri_utils::html::inject_csp_token(&mut document);
         ::tauri_utils::html::inject_csp_token(&mut document);

+ 1 - 0
core/tauri-runtime-wry/Cargo.toml

@@ -41,3 +41,4 @@ macos-private-api = [
 objc-exception = [ "wry/objc-exception" ]
 objc-exception = [ "wry/objc-exception" ]
 gtk-tray = [ "wry/gtk-tray" ]
 gtk-tray = [ "wry/gtk-tray" ]
 ayatana-tray = [ "wry/ayatana-tray" ]
 ayatana-tray = [ "wry/ayatana-tray" ]
+global-shortcut = [ "tauri-runtime/global-shortcut" ]

+ 164 - 0
core/tauri-runtime-wry/src/global_shortcut.rs

@@ -0,0 +1,164 @@
+// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-License-Identifier: MIT
+
+//! Global shortcut implementation.
+
+use std::{
+  collections::HashMap,
+  fmt,
+  sync::{
+    mpsc::{channel, Sender},
+    Arc, Mutex,
+  },
+};
+
+use crate::{getter, Context, Message};
+
+use tauri_runtime::{Error, GlobalShortcutManager, Result, UserEvent};
+pub use wry::application::global_shortcut::ShortcutManager as WryShortcutManager;
+use wry::application::{
+  accelerator::{Accelerator, AcceleratorId},
+  global_shortcut::GlobalShortcut,
+};
+
+pub type GlobalShortcutListeners = Arc<Mutex<HashMap<AcceleratorId, Box<dyn Fn() + Send>>>>;
+
+#[derive(Debug, Clone)]
+pub enum GlobalShortcutMessage {
+  IsRegistered(Accelerator, Sender<bool>),
+  Register(Accelerator, Sender<Result<GlobalShortcutWrapper>>),
+  Unregister(GlobalShortcutWrapper, Sender<Result<()>>),
+  UnregisterAll(Sender<Result<()>>),
+}
+
+#[derive(Debug, Clone)]
+pub struct GlobalShortcutWrapper(GlobalShortcut);
+
+// SAFETY: usage outside of main thread is guarded, we use the event loop on such cases.
+#[allow(clippy::non_send_fields_in_send_ty)]
+unsafe impl Send for GlobalShortcutWrapper {}
+
+/// Wrapper around [`WryShortcutManager`].
+#[derive(Clone)]
+pub struct GlobalShortcutManagerHandle<T: UserEvent> {
+  pub context: Context<T>,
+  pub shortcuts: Arc<Mutex<HashMap<String, (AcceleratorId, GlobalShortcutWrapper)>>>,
+  pub listeners: GlobalShortcutListeners,
+}
+
+// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`.
+#[allow(clippy::non_send_fields_in_send_ty)]
+unsafe impl<T: UserEvent> Sync for GlobalShortcutManagerHandle<T> {}
+
+impl<T: UserEvent> fmt::Debug for GlobalShortcutManagerHandle<T> {
+  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+    f.debug_struct("GlobalShortcutManagerHandle")
+      .field("context", &self.context)
+      .field("shortcuts", &self.shortcuts)
+      .finish()
+  }
+}
+
+impl<T: UserEvent> GlobalShortcutManager for GlobalShortcutManagerHandle<T> {
+  fn is_registered(&self, accelerator: &str) -> Result<bool> {
+    let (tx, rx) = channel();
+    getter!(
+      self,
+      rx,
+      Message::GlobalShortcut(GlobalShortcutMessage::IsRegistered(
+        accelerator.parse().expect("invalid accelerator"),
+        tx
+      ))
+    )
+  }
+
+  fn register<F: Fn() + Send + 'static>(&mut self, accelerator: &str, handler: F) -> Result<()> {
+    let wry_accelerator: Accelerator = accelerator.parse().expect("invalid accelerator");
+    let id = wry_accelerator.clone().id();
+    let (tx, rx) = channel();
+    let shortcut = getter!(
+      self,
+      rx,
+      Message::GlobalShortcut(GlobalShortcutMessage::Register(wry_accelerator, tx))
+    )??;
+
+    self.listeners.lock().unwrap().insert(id, Box::new(handler));
+    self
+      .shortcuts
+      .lock()
+      .unwrap()
+      .insert(accelerator.into(), (id, shortcut));
+
+    Ok(())
+  }
+
+  fn unregister_all(&mut self) -> Result<()> {
+    let (tx, rx) = channel();
+    getter!(
+      self,
+      rx,
+      Message::GlobalShortcut(GlobalShortcutMessage::UnregisterAll(tx))
+    )??;
+    self.listeners.lock().unwrap().clear();
+    self.shortcuts.lock().unwrap().clear();
+    Ok(())
+  }
+
+  fn unregister(&mut self, accelerator: &str) -> Result<()> {
+    if let Some((accelerator_id, shortcut)) = self.shortcuts.lock().unwrap().remove(accelerator) {
+      let (tx, rx) = channel();
+      getter!(
+        self,
+        rx,
+        Message::GlobalShortcut(GlobalShortcutMessage::Unregister(shortcut, tx))
+      )??;
+      self.listeners.lock().unwrap().remove(&accelerator_id);
+    }
+    Ok(())
+  }
+}
+
+pub fn handle_global_shortcut_message(
+  message: GlobalShortcutMessage,
+  global_shortcut_manager: &Arc<Mutex<WryShortcutManager>>,
+) {
+  match message {
+    GlobalShortcutMessage::IsRegistered(accelerator, tx) => tx
+      .send(
+        global_shortcut_manager
+          .lock()
+          .unwrap()
+          .is_registered(&accelerator),
+      )
+      .unwrap(),
+    GlobalShortcutMessage::Register(accelerator, tx) => tx
+      .send(
+        global_shortcut_manager
+          .lock()
+          .unwrap()
+          .register(accelerator)
+          .map(GlobalShortcutWrapper)
+          .map_err(|e| Error::GlobalShortcut(Box::new(e))),
+      )
+      .unwrap(),
+    GlobalShortcutMessage::Unregister(shortcut, tx) => tx
+      .send(
+        global_shortcut_manager
+          .lock()
+          .unwrap()
+          .unregister(shortcut.0)
+          .map_err(|e| Error::GlobalShortcut(Box::new(e))),
+      )
+      .unwrap(),
+    GlobalShortcutMessage::UnregisterAll(tx) => tx
+      .send(
+        global_shortcut_manager
+          .lock()
+          .unwrap()
+          .unregister_all()
+          .map_err(|e| Error::GlobalShortcut(Box::new(e))),
+      )
+      .unwrap(),
+  }
+}

+ 60 - 147
core/tauri-runtime-wry/src/lib.rs

@@ -16,9 +16,8 @@ use tauri_runtime::{
     dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
     dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
     CursorIcon, DetachedWindow, FileDropEvent, JsEventListenerKey, PendingWindow, WindowEvent,
     CursorIcon, DetachedWindow, FileDropEvent, JsEventListenerKey, PendingWindow, WindowEvent,
   },
   },
-  ClipboardManager, Dispatch, Error, EventLoopProxy, ExitRequestedEventAction,
-  GlobalShortcutManager, Result, RunEvent, RunIteration, Runtime, RuntimeHandle, UserAttentionType,
-  UserEvent, WindowIcon,
+  ClipboardManager, Dispatch, Error, EventLoopProxy, ExitRequestedEventAction, Result, RunEvent,
+  RunIteration, Runtime, RuntimeHandle, UserAttentionType, UserEvent, WindowIcon,
 };
 };
 
 
 use tauri_runtime::window::MenuEvent;
 use tauri_runtime::window::MenuEvent;
@@ -44,7 +43,6 @@ use tauri_utils::{config::WindowConfig, Theme};
 use uuid::Uuid;
 use uuid::Uuid;
 use wry::{
 use wry::{
   application::{
   application::{
-    accelerator::{Accelerator, AcceleratorId},
     clipboard::Clipboard,
     clipboard::Clipboard,
     dpi::{
     dpi::{
       LogicalPosition as WryLogicalPosition, LogicalSize as WryLogicalSize,
       LogicalPosition as WryLogicalPosition, LogicalSize as WryLogicalSize,
@@ -55,7 +53,6 @@ use wry::{
     event_loop::{
     event_loop::{
       ControlFlow, EventLoop, EventLoopProxy as WryEventLoopProxy, EventLoopWindowTarget,
       ControlFlow, EventLoop, EventLoopProxy as WryEventLoopProxy, EventLoopWindowTarget,
     },
     },
-    global_shortcut::{GlobalShortcut, ShortcutManager as WryShortcutManager},
     menu::{
     menu::{
       AboutMetadata as WryAboutMetadata, CustomMenuItem as WryCustomMenuItem, MenuBar,
       AboutMetadata as WryAboutMetadata, CustomMenuItem as WryCustomMenuItem, MenuBar,
       MenuId as WryMenuId, MenuItem as WryMenuItem, MenuItemAttributes as WryMenuItemAttributes,
       MenuId as WryMenuId, MenuItem as WryMenuItem, MenuItemAttributes as WryMenuItemAttributes,
@@ -109,13 +106,16 @@ mod system_tray;
 #[cfg(feature = "system-tray")]
 #[cfg(feature = "system-tray")]
 use system_tray::*;
 use system_tray::*;
 
 
+#[cfg(feature = "global-shortcut")]
+mod global_shortcut;
+#[cfg(feature = "global-shortcut")]
+use global_shortcut::*;
+
 type WebContextStore = Arc<Mutex<HashMap<Option<PathBuf>, WebContext>>>;
 type WebContextStore = Arc<Mutex<HashMap<Option<PathBuf>, WebContext>>>;
 // window
 // window
 type WindowEventHandler = Box<dyn Fn(&WindowEvent) + Send>;
 type WindowEventHandler = Box<dyn Fn(&WindowEvent) + Send>;
 type WindowEventListenersMap = Arc<Mutex<HashMap<Uuid, WindowEventHandler>>>;
 type WindowEventListenersMap = Arc<Mutex<HashMap<Uuid, WindowEventHandler>>>;
 type WindowEventListeners = Arc<Mutex<HashMap<WebviewId, WindowEventListenersMap>>>;
 type WindowEventListeners = Arc<Mutex<HashMap<WebviewId, WindowEventListenersMap>>>;
-// global shortcut
-type GlobalShortcutListeners = Arc<Mutex<HashMap<AcceleratorId, Box<dyn Fn() + Send>>>>;
 // menu
 // menu
 pub type MenuEventHandler = Box<dyn Fn(&MenuEvent) + Send>;
 pub type MenuEventHandler = Box<dyn Fn(&MenuEvent) + Send>;
 pub type MenuEventListeners = Arc<Mutex<HashMap<WebviewId, WindowMenuEventListeners>>>;
 pub type MenuEventListeners = Arc<Mutex<HashMap<WebviewId, WindowMenuEventListeners>>>;
@@ -134,9 +134,10 @@ impl WebviewIdStore {
   }
   }
 }
 }
 
 
+#[macro_export]
 macro_rules! getter {
 macro_rules! getter {
   ($self: ident, $rx: expr, $message: expr) => {{
   ($self: ident, $rx: expr, $message: expr) => {{
-    send_user_message(&$self.context, $message)?;
+    crate::send_user_message(&$self.context, $message)?;
     $rx.recv().map_err(|_| Error::FailedToReceiveMessage)
     $rx.recv().map_err(|_| Error::FailedToReceiveMessage)
   }};
   }};
 }
 }
@@ -156,6 +157,7 @@ fn send_user_message<T: UserEvent>(context: &Context<T>, message: Message<T>) ->
       UserMessageContext {
       UserMessageContext {
         webview_id_map: context.webview_id_map.clone(),
         webview_id_map: context.webview_id_map.clone(),
         window_event_listeners: &context.window_event_listeners,
         window_event_listeners: &context.window_event_listeners,
+        #[cfg(feature = "global-shortcut")]
         global_shortcut_manager: context.main_thread.global_shortcut_manager.clone(),
         global_shortcut_manager: context.main_thread.global_shortcut_manager.clone(),
         clipboard_manager: context.main_thread.clipboard_manager.clone(),
         clipboard_manager: context.main_thread.clipboard_manager.clone(),
         menu_event_listeners: &context.menu_event_listeners,
         menu_event_listeners: &context.menu_event_listeners,
@@ -175,7 +177,7 @@ fn send_user_message<T: UserEvent>(context: &Context<T>, message: Message<T>) ->
 }
 }
 
 
 #[derive(Clone)]
 #[derive(Clone)]
-struct Context<T: UserEvent> {
+pub struct Context<T: UserEvent> {
   webview_id_map: WebviewIdStore,
   webview_id_map: WebviewIdStore,
   main_thread_id: ThreadId,
   main_thread_id: ThreadId,
   proxy: WryEventLoopProxy<Message<T>>,
   proxy: WryEventLoopProxy<Message<T>>,
@@ -236,6 +238,7 @@ impl<T: UserEvent> Context<T> {
 struct DispatcherMainThreadContext<T: UserEvent> {
 struct DispatcherMainThreadContext<T: UserEvent> {
   window_target: EventLoopWindowTarget<Message<T>>,
   window_target: EventLoopWindowTarget<Message<T>>,
   web_context: WebContextStore,
   web_context: WebContextStore,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
   windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
@@ -461,93 +464,6 @@ impl From<NativeImage> for NativeImageWrapper {
   }
   }
 }
 }
 
 
-#[derive(Debug, Clone)]
-pub struct GlobalShortcutWrapper(GlobalShortcut);
-
-// SAFETY: usage outside of main thread is guarded, we use the event loop on such cases.
-#[allow(clippy::non_send_fields_in_send_ty)]
-unsafe impl Send for GlobalShortcutWrapper {}
-
-/// Wrapper around [`WryShortcutManager`].
-#[derive(Clone)]
-pub struct GlobalShortcutManagerHandle<T: UserEvent> {
-  context: Context<T>,
-  shortcuts: Arc<Mutex<HashMap<String, (AcceleratorId, GlobalShortcutWrapper)>>>,
-  listeners: GlobalShortcutListeners,
-}
-
-// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`.
-#[allow(clippy::non_send_fields_in_send_ty)]
-unsafe impl<T: UserEvent> Sync for GlobalShortcutManagerHandle<T> {}
-
-impl<T: UserEvent> fmt::Debug for GlobalShortcutManagerHandle<T> {
-  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    f.debug_struct("GlobalShortcutManagerHandle")
-      .field("context", &self.context)
-      .field("shortcuts", &self.shortcuts)
-      .finish()
-  }
-}
-
-impl<T: UserEvent> GlobalShortcutManager for GlobalShortcutManagerHandle<T> {
-  fn is_registered(&self, accelerator: &str) -> Result<bool> {
-    let (tx, rx) = channel();
-    getter!(
-      self,
-      rx,
-      Message::GlobalShortcut(GlobalShortcutMessage::IsRegistered(
-        accelerator.parse().expect("invalid accelerator"),
-        tx
-      ))
-    )
-  }
-
-  fn register<F: Fn() + Send + 'static>(&mut self, accelerator: &str, handler: F) -> Result<()> {
-    let wry_accelerator: Accelerator = accelerator.parse().expect("invalid accelerator");
-    let id = wry_accelerator.clone().id();
-    let (tx, rx) = channel();
-    let shortcut = getter!(
-      self,
-      rx,
-      Message::GlobalShortcut(GlobalShortcutMessage::Register(wry_accelerator, tx))
-    )??;
-
-    self.listeners.lock().unwrap().insert(id, Box::new(handler));
-    self
-      .shortcuts
-      .lock()
-      .unwrap()
-      .insert(accelerator.into(), (id, shortcut));
-
-    Ok(())
-  }
-
-  fn unregister_all(&mut self) -> Result<()> {
-    let (tx, rx) = channel();
-    getter!(
-      self,
-      rx,
-      Message::GlobalShortcut(GlobalShortcutMessage::UnregisterAll(tx))
-    )??;
-    self.listeners.lock().unwrap().clear();
-    self.shortcuts.lock().unwrap().clear();
-    Ok(())
-  }
-
-  fn unregister(&mut self, accelerator: &str) -> Result<()> {
-    if let Some((accelerator_id, shortcut)) = self.shortcuts.lock().unwrap().remove(accelerator) {
-      let (tx, rx) = channel();
-      getter!(
-        self,
-        rx,
-        Message::GlobalShortcut(GlobalShortcutMessage::Unregister(shortcut, tx))
-      )??;
-      self.listeners.lock().unwrap().remove(&accelerator_id);
-    }
-    Ok(())
-  }
-}
-
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub struct ClipboardManagerWrapper<T: UserEvent> {
 pub struct ClipboardManagerWrapper<T: UserEvent> {
   context: Context<T>,
   context: Context<T>,
@@ -1162,14 +1078,6 @@ pub enum TrayMessage {
   Close,
   Close,
 }
 }
 
 
-#[derive(Debug, Clone)]
-pub enum GlobalShortcutMessage {
-  IsRegistered(Accelerator, Sender<bool>),
-  Register(Accelerator, Sender<Result<GlobalShortcutWrapper>>),
-  Unregister(GlobalShortcutWrapper, Sender<Result<()>>),
-  UnregisterAll(Sender<Result<()>>),
-}
-
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub enum ClipboardMessage {
 pub enum ClipboardMessage {
   WriteText(String, Sender<()>),
   WriteText(String, Sender<()>),
@@ -1192,6 +1100,7 @@ pub enum Message<T: 'static> {
     Box<dyn FnOnce() -> (String, WryWindowBuilder) + Send>,
     Box<dyn FnOnce() -> (String, WryWindowBuilder) + Send>,
     Sender<Result<Weak<Window>>>,
     Sender<Result<Weak<Window>>>,
   ),
   ),
+  #[cfg(feature = "global-shortcut")]
   GlobalShortcut(GlobalShortcutMessage),
   GlobalShortcut(GlobalShortcutMessage),
   Clipboard(ClipboardMessage),
   Clipboard(ClipboardMessage),
   UserEvent(T),
   UserEvent(T),
@@ -1204,6 +1113,7 @@ impl<T: UserEvent> Clone for Message<T> {
       Self::Webview(i, m) => Self::Webview(*i, m.clone()),
       Self::Webview(i, m) => Self::Webview(*i, m.clone()),
       #[cfg(feature = "system-tray")]
       #[cfg(feature = "system-tray")]
       Self::Tray(m) => Self::Tray(m.clone()),
       Self::Tray(m) => Self::Tray(m.clone()),
+      #[cfg(feature = "global-shortcut")]
       Self::GlobalShortcut(m) => Self::GlobalShortcut(m.clone()),
       Self::GlobalShortcut(m) => Self::GlobalShortcut(m.clone()),
       Self::Clipboard(m) => Self::Clipboard(m.clone()),
       Self::Clipboard(m) => Self::Clipboard(m.clone()),
       Self::UserEvent(t) => Self::UserEvent(t.clone()),
       Self::UserEvent(t) => Self::UserEvent(t.clone()),
@@ -1680,7 +1590,9 @@ impl<T: UserEvent> EventLoopProxy<T> for EventProxy<T> {
 /// A Tauri [`Runtime`] wrapper around wry.
 /// A Tauri [`Runtime`] wrapper around wry.
 pub struct Wry<T: UserEvent> {
 pub struct Wry<T: UserEvent> {
   main_thread_id: ThreadId,
   main_thread_id: ThreadId,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager_handle: GlobalShortcutManagerHandle<T>,
   global_shortcut_manager_handle: GlobalShortcutManagerHandle<T>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   clipboard_manager_handle: ClipboardManagerWrapper<T>,
   clipboard_manager_handle: ClipboardManagerWrapper<T>,
@@ -1698,11 +1610,6 @@ impl<T: UserEvent> fmt::Debug for Wry<T> {
   fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
   fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     let mut d = f.debug_struct("Wry");
     let mut d = f.debug_struct("Wry");
     d.field("main_thread_id", &self.main_thread_id)
     d.field("main_thread_id", &self.main_thread_id)
-      .field("global_shortcut_manager", &self.global_shortcut_manager)
-      .field(
-        "global_shortcut_manager_handle",
-        &self.global_shortcut_manager_handle,
-      )
       .field("clipboard_manager", &self.clipboard_manager)
       .field("clipboard_manager", &self.clipboard_manager)
       .field("clipboard_manager_handle", &self.clipboard_manager_handle)
       .field("clipboard_manager_handle", &self.clipboard_manager_handle)
       .field("event_loop", &self.event_loop)
       .field("event_loop", &self.event_loop)
@@ -1710,6 +1617,12 @@ impl<T: UserEvent> fmt::Debug for Wry<T> {
       .field("web_context", &self.web_context);
       .field("web_context", &self.web_context);
     #[cfg(feature = "system-tray")]
     #[cfg(feature = "system-tray")]
     d.field("tray_context", &self.tray_context);
     d.field("tray_context", &self.tray_context);
+    #[cfg(feature = "global-shortcut")]
+    d.field("global_shortcut_manager", &self.global_shortcut_manager)
+      .field(
+        "global_shortcut_manager_handle",
+        &self.global_shortcut_manager_handle,
+      );
     d.finish()
     d.finish()
   }
   }
 }
 }
@@ -1793,7 +1706,10 @@ impl<T: UserEvent> Wry<T> {
     let proxy = event_loop.create_proxy();
     let proxy = event_loop.create_proxy();
     let main_thread_id = current_thread().id();
     let main_thread_id = current_thread().id();
     let web_context = WebContextStore::default();
     let web_context = WebContextStore::default();
+
+    #[cfg(feature = "global-shortcut")]
     let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
     let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
+
     let clipboard_manager = Arc::new(Mutex::new(Clipboard::new()));
     let clipboard_manager = Arc::new(Mutex::new(Clipboard::new()));
     let windows = Arc::new(Mutex::new(HashMap::default()));
     let windows = Arc::new(Mutex::new(HashMap::default()));
     let webview_id_map = WebviewIdStore::default();
     let webview_id_map = WebviewIdStore::default();
@@ -1812,6 +1728,7 @@ impl<T: UserEvent> Wry<T> {
       main_thread: DispatcherMainThreadContext {
       main_thread: DispatcherMainThreadContext {
         window_target: event_loop.deref().clone(),
         window_target: event_loop.deref().clone(),
         web_context: web_context.clone(),
         web_context: web_context.clone(),
+        #[cfg(feature = "global-shortcut")]
         global_shortcut_manager: global_shortcut_manager.clone(),
         global_shortcut_manager: global_shortcut_manager.clone(),
         clipboard_manager: clipboard_manager.clone(),
         clipboard_manager: clipboard_manager.clone(),
         windows: windows.clone(),
         windows: windows.clone(),
@@ -1820,14 +1737,19 @@ impl<T: UserEvent> Wry<T> {
       },
       },
     };
     };
 
 
+    #[cfg(feature = "global-shortcut")]
     let global_shortcut_listeners = GlobalShortcutListeners::default();
     let global_shortcut_listeners = GlobalShortcutListeners::default();
+
+    #[allow(clippy::redundant_clone)]
     let clipboard_manager_handle = ClipboardManagerWrapper {
     let clipboard_manager_handle = ClipboardManagerWrapper {
       context: event_loop_context.clone(),
       context: event_loop_context.clone(),
     };
     };
 
 
     Ok(Self {
     Ok(Self {
       main_thread_id,
       main_thread_id,
+      #[cfg(feature = "global-shortcut")]
       global_shortcut_manager,
       global_shortcut_manager,
+      #[cfg(feature = "global-shortcut")]
       global_shortcut_manager_handle: GlobalShortcutManagerHandle {
       global_shortcut_manager_handle: GlobalShortcutManagerHandle {
         context: event_loop_context,
         context: event_loop_context,
         shortcuts: Default::default(),
         shortcuts: Default::default(),
@@ -1850,6 +1772,7 @@ impl<T: UserEvent> Wry<T> {
 impl<T: UserEvent> Runtime<T> for Wry<T> {
 impl<T: UserEvent> Runtime<T> for Wry<T> {
   type Dispatcher = WryDispatcher<T>;
   type Dispatcher = WryDispatcher<T>;
   type Handle = WryHandle<T>;
   type Handle = WryHandle<T>;
+  #[cfg(feature = "global-shortcut")]
   type GlobalShortcutManager = GlobalShortcutManagerHandle<T>;
   type GlobalShortcutManager = GlobalShortcutManagerHandle<T>;
   type ClipboardManager = ClipboardManagerWrapper<T>;
   type ClipboardManager = ClipboardManagerWrapper<T>;
   #[cfg(feature = "system-tray")]
   #[cfg(feature = "system-tray")]
@@ -1886,6 +1809,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
         main_thread: DispatcherMainThreadContext {
         main_thread: DispatcherMainThreadContext {
           window_target: self.event_loop.deref().clone(),
           window_target: self.event_loop.deref().clone(),
           web_context: self.web_context.clone(),
           web_context: self.web_context.clone(),
+          #[cfg(feature = "global-shortcut")]
           global_shortcut_manager: self.global_shortcut_manager.clone(),
           global_shortcut_manager: self.global_shortcut_manager.clone(),
           clipboard_manager: self.clipboard_manager.clone(),
           clipboard_manager: self.clipboard_manager.clone(),
           windows: self.windows.clone(),
           windows: self.windows.clone(),
@@ -1896,6 +1820,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     }
     }
   }
   }
 
 
+  #[cfg(feature = "global-shortcut")]
   fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager {
   fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager {
     self.global_shortcut_manager_handle.clone()
     self.global_shortcut_manager_handle.clone()
   }
   }
@@ -1920,6 +1845,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
       main_thread: DispatcherMainThreadContext {
       main_thread: DispatcherMainThreadContext {
         window_target: self.event_loop.deref().clone(),
         window_target: self.event_loop.deref().clone(),
         web_context: self.web_context.clone(),
         web_context: self.web_context.clone(),
+        #[cfg(feature = "global-shortcut")]
         global_shortcut_manager: self.global_shortcut_manager.clone(),
         global_shortcut_manager: self.global_shortcut_manager.clone(),
         clipboard_manager: self.clipboard_manager.clone(),
         clipboard_manager: self.clipboard_manager.clone(),
         windows: self.windows.clone(),
         windows: self.windows.clone(),
@@ -2021,8 +1947,12 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     let menu_event_listeners = self.menu_event_listeners.clone();
     let menu_event_listeners = self.menu_event_listeners.clone();
     #[cfg(feature = "system-tray")]
     #[cfg(feature = "system-tray")]
     let tray_context = self.tray_context.clone();
     let tray_context = self.tray_context.clone();
+
+    #[cfg(feature = "global-shortcut")]
     let global_shortcut_manager = self.global_shortcut_manager.clone();
     let global_shortcut_manager = self.global_shortcut_manager.clone();
+    #[cfg(feature = "global-shortcut")]
     let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
     let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
+
     let clipboard_manager = self.clipboard_manager.clone();
     let clipboard_manager = self.clipboard_manager.clone();
     let mut iteration = RunIteration::default();
     let mut iteration = RunIteration::default();
 
 
@@ -2043,7 +1973,9 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
             windows: windows.clone(),
             windows: windows.clone(),
             webview_id_map: webview_id_map.clone(),
             webview_id_map: webview_id_map.clone(),
             window_event_listeners: &window_event_listeners,
             window_event_listeners: &window_event_listeners,
+            #[cfg(feature = "global-shortcut")]
             global_shortcut_manager: global_shortcut_manager.clone(),
             global_shortcut_manager: global_shortcut_manager.clone(),
+            #[cfg(feature = "global-shortcut")]
             global_shortcut_manager_handle: &global_shortcut_manager_handle,
             global_shortcut_manager_handle: &global_shortcut_manager_handle,
             clipboard_manager: clipboard_manager.clone(),
             clipboard_manager: clipboard_manager.clone(),
             menu_event_listeners: &menu_event_listeners,
             menu_event_listeners: &menu_event_listeners,
@@ -2063,10 +1995,15 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     let web_context = self.web_context;
     let web_context = self.web_context;
     let window_event_listeners = self.window_event_listeners.clone();
     let window_event_listeners = self.window_event_listeners.clone();
     let menu_event_listeners = self.menu_event_listeners.clone();
     let menu_event_listeners = self.menu_event_listeners.clone();
+
     #[cfg(feature = "system-tray")]
     #[cfg(feature = "system-tray")]
     let tray_context = self.tray_context;
     let tray_context = self.tray_context;
+
+    #[cfg(feature = "global-shortcut")]
     let global_shortcut_manager = self.global_shortcut_manager.clone();
     let global_shortcut_manager = self.global_shortcut_manager.clone();
+    #[cfg(feature = "global-shortcut")]
     let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
     let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
+
     let clipboard_manager = self.clipboard_manager.clone();
     let clipboard_manager = self.clipboard_manager.clone();
 
 
     self.event_loop.run(move |event, event_loop, control_flow| {
     self.event_loop.run(move |event, event_loop, control_flow| {
@@ -2079,7 +2016,9 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
           webview_id_map: webview_id_map.clone(),
           webview_id_map: webview_id_map.clone(),
           windows: windows.clone(),
           windows: windows.clone(),
           window_event_listeners: &window_event_listeners,
           window_event_listeners: &window_event_listeners,
+          #[cfg(feature = "global-shortcut")]
           global_shortcut_manager: global_shortcut_manager.clone(),
           global_shortcut_manager: global_shortcut_manager.clone(),
+          #[cfg(feature = "global-shortcut")]
           global_shortcut_manager_handle: &global_shortcut_manager_handle,
           global_shortcut_manager_handle: &global_shortcut_manager_handle,
           clipboard_manager: clipboard_manager.clone(),
           clipboard_manager: clipboard_manager.clone(),
           menu_event_listeners: &menu_event_listeners,
           menu_event_listeners: &menu_event_listeners,
@@ -2097,7 +2036,9 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
   webview_id_map: WebviewIdStore,
   webview_id_map: WebviewIdStore,
   windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
   windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
   window_event_listeners: &'a WindowEventListeners,
   window_event_listeners: &'a WindowEventListeners,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle<T>,
   global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle<T>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   menu_event_listeners: &'a MenuEventListeners,
   menu_event_listeners: &'a MenuEventListeners,
@@ -2108,6 +2049,7 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
 struct UserMessageContext<'a> {
 struct UserMessageContext<'a> {
   webview_id_map: WebviewIdStore,
   webview_id_map: WebviewIdStore,
   window_event_listeners: &'a WindowEventListeners,
   window_event_listeners: &'a WindowEventListeners,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   clipboard_manager: Arc<Mutex<Clipboard>>,
   menu_event_listeners: &'a MenuEventListeners,
   menu_event_listeners: &'a MenuEventListeners,
@@ -2126,6 +2068,7 @@ fn handle_user_message<T: UserEvent>(
     webview_id_map,
     webview_id_map,
     window_event_listeners,
     window_event_listeners,
     menu_event_listeners,
     menu_event_listeners,
+    #[cfg(feature = "global-shortcut")]
     global_shortcut_manager,
     global_shortcut_manager,
     clipboard_manager,
     clipboard_manager,
     windows,
     windows,
@@ -2427,44 +2370,10 @@ fn handle_user_message<T: UserEvent>(
         tray_context.items.lock().unwrap().clear();
         tray_context.items.lock().unwrap().clear();
       }
       }
     },
     },
-    Message::GlobalShortcut(message) => match message {
-      GlobalShortcutMessage::IsRegistered(accelerator, tx) => tx
-        .send(
-          global_shortcut_manager
-            .lock()
-            .unwrap()
-            .is_registered(&accelerator),
-        )
-        .unwrap(),
-      GlobalShortcutMessage::Register(accelerator, tx) => tx
-        .send(
-          global_shortcut_manager
-            .lock()
-            .unwrap()
-            .register(accelerator)
-            .map(GlobalShortcutWrapper)
-            .map_err(|e| Error::GlobalShortcut(Box::new(e))),
-        )
-        .unwrap(),
-      GlobalShortcutMessage::Unregister(shortcut, tx) => tx
-        .send(
-          global_shortcut_manager
-            .lock()
-            .unwrap()
-            .unregister(shortcut.0)
-            .map_err(|e| Error::GlobalShortcut(Box::new(e))),
-        )
-        .unwrap(),
-      GlobalShortcutMessage::UnregisterAll(tx) => tx
-        .send(
-          global_shortcut_manager
-            .lock()
-            .unwrap()
-            .unregister_all()
-            .map_err(|e| Error::GlobalShortcut(Box::new(e))),
-        )
-        .unwrap(),
-    },
+    #[cfg(feature = "global-shortcut")]
+    Message::GlobalShortcut(message) => {
+      handle_global_shortcut_message(message, &global_shortcut_manager)
+    }
     Message::Clipboard(message) => match message {
     Message::Clipboard(message) => match message {
       ClipboardMessage::WriteText(text, tx) => {
       ClipboardMessage::WriteText(text, tx) => {
         clipboard_manager.lock().unwrap().write_text(text);
         clipboard_manager.lock().unwrap().write_text(text);
@@ -2495,7 +2404,9 @@ fn handle_event_loop<T: UserEvent>(
     webview_id_map,
     webview_id_map,
     windows,
     windows,
     window_event_listeners,
     window_event_listeners,
+    #[cfg(feature = "global-shortcut")]
     global_shortcut_manager,
     global_shortcut_manager,
+    #[cfg(feature = "global-shortcut")]
     global_shortcut_manager_handle,
     global_shortcut_manager_handle,
     clipboard_manager,
     clipboard_manager,
     menu_event_listeners,
     menu_event_listeners,
@@ -2523,6 +2434,7 @@ fn handle_event_loop<T: UserEvent>(
       callback(RunEvent::Exit);
       callback(RunEvent::Exit);
     }
     }
 
 
+    #[cfg(feature = "global-shortcut")]
     Event::GlobalShortcutEvent(accelerator_id) => {
     Event::GlobalShortcutEvent(accelerator_id) => {
       for (id, handler) in &*global_shortcut_manager_handle.listeners.lock().unwrap() {
       for (id, handler) in &*global_shortcut_manager_handle.listeners.lock().unwrap() {
         if accelerator_id == *id {
         if accelerator_id == *id {
@@ -2701,6 +2613,7 @@ fn handle_event_loop<T: UserEvent>(
           UserMessageContext {
           UserMessageContext {
             webview_id_map,
             webview_id_map,
             window_event_listeners,
             window_event_listeners,
+            #[cfg(feature = "global-shortcut")]
             global_shortcut_manager,
             global_shortcut_manager,
             clipboard_manager,
             clipboard_manager,
             menu_event_listeners,
             menu_event_listeners,

+ 1 - 0
core/tauri-runtime/Cargo.toml

@@ -46,3 +46,4 @@ gtk = { version = "0.15", features = [ "v3_20" ] }
 devtools = [ ]
 devtools = [ ]
 system-tray = [ ]
 system-tray = [ ]
 macos-private-api = [ ]
 macos-private-api = [ ]
+global-shortcut = [ ]

+ 4 - 0
core/tauri-runtime/src/lib.rs

@@ -127,6 +127,7 @@ pub enum Error {
   #[error("failed to get monitor")]
   #[error("failed to get monitor")]
   FailedToGetMonitor,
   FailedToGetMonitor,
   /// Global shortcut error.
   /// Global shortcut error.
+  #[cfg(feature = "global-shortcut")]
   #[error(transparent)]
   #[error(transparent)]
   GlobalShortcut(Box<dyn std::error::Error + Send + Sync>),
   GlobalShortcut(Box<dyn std::error::Error + Send + Sync>),
   #[error("Invalid header name: {0}")]
   #[error("Invalid header name: {0}")]
@@ -294,6 +295,7 @@ pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'st
 }
 }
 
 
 /// A global shortcut manager.
 /// A global shortcut manager.
+#[cfg(feature = "global-shortcut")]
 pub trait GlobalShortcutManager: Debug + Clone + Send + Sync {
 pub trait GlobalShortcutManager: Debug + Clone + Send + Sync {
   /// Whether the application has registered the given `accelerator`.
   /// Whether the application has registered the given `accelerator`.
   fn is_registered(&self, accelerator: &str) -> Result<bool>;
   fn is_registered(&self, accelerator: &str) -> Result<bool>;
@@ -327,6 +329,7 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
   /// The runtime handle type.
   /// The runtime handle type.
   type Handle: RuntimeHandle<T, Runtime = Self>;
   type Handle: RuntimeHandle<T, Runtime = Self>;
   /// The global shortcut manager type.
   /// The global shortcut manager type.
+  #[cfg(feature = "global-shortcut")]
   type GlobalShortcutManager: GlobalShortcutManager;
   type GlobalShortcutManager: GlobalShortcutManager;
   /// The clipboard manager type.
   /// The clipboard manager type.
   type ClipboardManager: ClipboardManager;
   type ClipboardManager: ClipboardManager;
@@ -351,6 +354,7 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
   fn handle(&self) -> Self::Handle;
   fn handle(&self) -> Self::Handle;
 
 
   /// Gets the global shortcut manager.
   /// Gets the global shortcut manager.
+  #[cfg(feature = "global-shortcut")]
   fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager;
   fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager;
 
 
   /// Gets the clipboard manager.
   /// Gets the clipboard manager.

+ 2 - 1
core/tauri/Cargo.toml

@@ -141,6 +141,7 @@ shell-open-api = [ "open", "regex", "tauri-macros/shell-scope" ]
 fs-extract-api = [ "zip" ]
 fs-extract-api = [ "zip" ]
 reqwest-client = [ "reqwest", "bytes" ]
 reqwest-client = [ "reqwest", "bytes" ]
 process-command-api = [ "shared_child", "os_pipe" ]
 process-command-api = [ "shared_child", "os_pipe" ]
+global-shortcut = [ "tauri-runtime/global-shortcut", "tauri-runtime-wry/global-shortcut" ]
 dialog = [ "rfd" ]
 dialog = [ "rfd" ]
 notification = [ "notify-rust" ]
 notification = [ "notify-rust" ]
 cli = [ "clap" ]
 cli = [ "clap" ]
@@ -193,7 +194,7 @@ fs-remove-dir = [ ]
 fs-remove-file = [ ]
 fs-remove-file = [ ]
 fs-rename-file = [ ]
 fs-rename-file = [ ]
 fs-write-file = [ ]
 fs-write-file = [ ]
-global-shortcut-all = [ ]
+global-shortcut-all = [ "global-shortcut" ]
 http-all = [ "http-request" ]
 http-all = [ "http-request" ]
 http-request = [ "http-api" ]
 http-request = [ "http-api" ]
 notification-all = [ "notification", "dialog-ask" ]
 notification-all = [ "notification", "dialog-ask" ]

+ 10 - 0
core/tauri/src/app.rs

@@ -287,6 +287,7 @@ impl<R: Runtime> AssetResolver<R> {
 pub struct AppHandle<R: Runtime> {
 pub struct AppHandle<R: Runtime> {
   runtime_handle: R::Handle,
   runtime_handle: R::Handle,
   manager: WindowManager<R>,
   manager: WindowManager<R>,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager: R::GlobalShortcutManager,
   global_shortcut_manager: R::GlobalShortcutManager,
   clipboard_manager: R::ClipboardManager,
   clipboard_manager: R::ClipboardManager,
   #[cfg(feature = "system-tray")]
   #[cfg(feature = "system-tray")]
@@ -337,6 +338,7 @@ impl<R: Runtime> Clone for AppHandle<R> {
     Self {
     Self {
       runtime_handle: self.runtime_handle.clone(),
       runtime_handle: self.runtime_handle.clone(),
       manager: self.manager.clone(),
       manager: self.manager.clone(),
+      #[cfg(feature = "global-shortcut")]
       global_shortcut_manager: self.global_shortcut_manager.clone(),
       global_shortcut_manager: self.global_shortcut_manager.clone(),
       clipboard_manager: self.clipboard_manager.clone(),
       clipboard_manager: self.clipboard_manager.clone(),
       #[cfg(feature = "system-tray")]
       #[cfg(feature = "system-tray")]
@@ -442,6 +444,7 @@ impl<R: Runtime> ManagerBase<R> for AppHandle<R> {
 pub struct App<R: Runtime> {
 pub struct App<R: Runtime> {
   runtime: Option<R>,
   runtime: Option<R>,
   manager: WindowManager<R>,
   manager: WindowManager<R>,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager: R::GlobalShortcutManager,
   global_shortcut_manager: R::GlobalShortcutManager,
   clipboard_manager: R::ClipboardManager,
   clipboard_manager: R::ClipboardManager,
   #[cfg(feature = "system-tray")]
   #[cfg(feature = "system-tray")]
@@ -510,6 +513,8 @@ macro_rules! shared_app_impl {
       }
       }
 
 
       /// Gets a copy of the global shortcut manager instance.
       /// Gets a copy of the global shortcut manager instance.
+      #[cfg(feature = "global-shortcut")]
+      #[cfg_attr(doc_cfg, doc(cfg(feature = "global-shortcut")))]
       pub fn global_shortcut_manager(&self) -> R::GlobalShortcutManager {
       pub fn global_shortcut_manager(&self) -> R::GlobalShortcutManager {
         self.global_shortcut_manager.clone()
         self.global_shortcut_manager.clone()
       }
       }
@@ -1233,12 +1238,16 @@ impl<R: Runtime> Builder<R> {
     let runtime = R::new()?;
     let runtime = R::new()?;
 
 
     let runtime_handle = runtime.handle();
     let runtime_handle = runtime.handle();
+
+    #[cfg(feature = "global-shortcut")]
     let global_shortcut_manager = runtime.global_shortcut_manager();
     let global_shortcut_manager = runtime.global_shortcut_manager();
+
     let clipboard_manager = runtime.clipboard_manager();
     let clipboard_manager = runtime.clipboard_manager();
 
 
     let mut app = App {
     let mut app = App {
       runtime: Some(runtime),
       runtime: Some(runtime),
       manager: manager.clone(),
       manager: manager.clone(),
+      #[cfg(feature = "global-shortcut")]
       global_shortcut_manager: global_shortcut_manager.clone(),
       global_shortcut_manager: global_shortcut_manager.clone(),
       clipboard_manager: clipboard_manager.clone(),
       clipboard_manager: clipboard_manager.clone(),
       #[cfg(feature = "system-tray")]
       #[cfg(feature = "system-tray")]
@@ -1246,6 +1255,7 @@ impl<R: Runtime> Builder<R> {
       handle: AppHandle {
       handle: AppHandle {
         runtime_handle,
         runtime_handle,
         manager,
         manager,
+        #[cfg(feature = "global-shortcut")]
         global_shortcut_manager,
         global_shortcut_manager,
         clipboard_manager,
         clipboard_manager,
         #[cfg(feature = "system-tray")]
         #[cfg(feature = "system-tray")]

+ 2 - 1
core/tauri/src/lib.rs

@@ -23,6 +23,7 @@
 //! - **http-multipart**: Adds support to `multipart/form-data` requests.
 //! - **http-multipart**: Adds support to `multipart/form-data` requests.
 //! - **reqwest-client**: Uses `reqwest` as HTTP client on the `http` APIs. Improves performance, but increases the bundle size.
 //! - **reqwest-client**: Uses `reqwest` as HTTP client on the `http` APIs. Improves performance, but increases the bundle size.
 //! - **process-command-api**: Enables the [`api::process::Command`] APIs.
 //! - **process-command-api**: Enables the [`api::process::Command`] APIs.
+//! - **global-shortcut**: Enables the global shortcut APIs.
 //! - **process-relaunch-dangerous-allow-symlink-macos**: Allows the [`api::process::current_binary`] function to allow symlinks on macOS (this is dangerous, see the Security section in the documentation website).
 //! - **process-relaunch-dangerous-allow-symlink-macos**: Allows the [`api::process::current_binary`] function to allow symlinks on macOS (this is dangerous, see the Security section in the documentation website).
 //! - **dialog**: Enables the [`api::dialog`] module.
 //! - **dialog**: Enables the [`api::dialog`] module.
 //! - **notification**: Enables the [`api::notification`] module.
 //! - **notification**: Enables the [`api::notification`] module.
@@ -232,7 +233,7 @@ pub use {
       dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size},
       dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size},
       CursorIcon, FileDropEvent,
       CursorIcon, FileDropEvent,
     },
     },
-    ClipboardManager, GlobalShortcutManager, RunIteration, TrayIcon, UserAttentionType,
+    ClipboardManager, RunIteration, TrayIcon, UserAttentionType,
   },
   },
   self::state::{State, StateManager},
   self::state::{State, StateManager},
   self::utils::{
   self::utils::{

+ 9 - 3
core/tauri/src/test/mock_runtime.rs

@@ -12,8 +12,8 @@ use tauri_runtime::{
     dpi::{PhysicalPosition, PhysicalSize, Position, Size},
     dpi::{PhysicalPosition, PhysicalSize, Position, Size},
     CursorIcon, DetachedWindow, MenuEvent, PendingWindow, WindowEvent,
     CursorIcon, DetachedWindow, MenuEvent, PendingWindow, WindowEvent,
   },
   },
-  ClipboardManager, Dispatch, EventLoopProxy, GlobalShortcutManager, Result, RunEvent, Runtime,
-  RuntimeHandle, UserAttentionType, UserEvent, WindowIcon,
+  ClipboardManager, Dispatch, EventLoopProxy, Result, RunEvent, Runtime, RuntimeHandle,
+  UserAttentionType, UserEvent, WindowIcon,
 };
 };
 #[cfg(feature = "system-tray")]
 #[cfg(feature = "system-tray")]
 use tauri_runtime::{
 use tauri_runtime::{
@@ -92,12 +92,14 @@ pub struct MockDispatcher {
   context: RuntimeContext,
   context: RuntimeContext,
 }
 }
 
 
+#[cfg(feature = "global-shortcut")]
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub struct MockGlobalShortcutManager {
 pub struct MockGlobalShortcutManager {
   context: RuntimeContext,
   context: RuntimeContext,
 }
 }
 
 
-impl GlobalShortcutManager for MockGlobalShortcutManager {
+#[cfg(feature = "global-shortcut")]
+impl tauri_runtime::GlobalShortcutManager for MockGlobalShortcutManager {
   fn is_registered(&self, accelerator: &str) -> Result<bool> {
   fn is_registered(&self, accelerator: &str) -> Result<bool> {
     Ok(
     Ok(
       self
       self
@@ -543,6 +545,7 @@ impl<T: UserEvent> EventLoopProxy<T> for EventProxy {
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct MockRuntime {
 pub struct MockRuntime {
   pub context: RuntimeContext,
   pub context: RuntimeContext,
+  #[cfg(feature = "global-shortcut")]
   global_shortcut_manager: MockGlobalShortcutManager,
   global_shortcut_manager: MockGlobalShortcutManager,
   clipboard_manager: MockClipboardManager,
   clipboard_manager: MockClipboardManager,
   #[cfg(feature = "system-tray")]
   #[cfg(feature = "system-tray")]
@@ -556,6 +559,7 @@ impl MockRuntime {
       clipboard: Default::default(),
       clipboard: Default::default(),
     };
     };
     Self {
     Self {
+      #[cfg(feature = "global-shortcut")]
       global_shortcut_manager: MockGlobalShortcutManager {
       global_shortcut_manager: MockGlobalShortcutManager {
         context: context.clone(),
         context: context.clone(),
       },
       },
@@ -574,6 +578,7 @@ impl MockRuntime {
 impl<T: UserEvent> Runtime<T> for MockRuntime {
 impl<T: UserEvent> Runtime<T> for MockRuntime {
   type Dispatcher = MockDispatcher;
   type Dispatcher = MockDispatcher;
   type Handle = MockRuntimeHandle;
   type Handle = MockRuntimeHandle;
+  #[cfg(feature = "global-shortcut")]
   type GlobalShortcutManager = MockGlobalShortcutManager;
   type GlobalShortcutManager = MockGlobalShortcutManager;
   type ClipboardManager = MockClipboardManager;
   type ClipboardManager = MockClipboardManager;
   #[cfg(feature = "system-tray")]
   #[cfg(feature = "system-tray")]
@@ -599,6 +604,7 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
     }
     }
   }
   }
 
 
+  #[cfg(feature = "global-shortcut")]
   fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager {
   fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager {
     self.global_shortcut_manager.clone()
     self.global_shortcut_manager.clone()
   }
   }