Skip to content

Commit

Permalink
feat(core): add hotkey to toggle devtools, closes #3776 (#3791)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Mar 28, 2022
1 parent 9ddf8d8 commit e05d718
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 64 deletions.
6 changes: 6 additions & 0 deletions .changes/devtools-apis.md
@@ -0,0 +1,6 @@
---
"tauri-runtime": minor
"tauri-runtime-wry": minor
---

Added `close_devtools` and `is_devtools_open` APIs to the `Dispatch` trait.
5 changes: 5 additions & 0 deletions .changes/devtools-hotkey.md
@@ -0,0 +1,5 @@
---
"tauri": patch
---

Toggle devtools when `Ctrl + Shift + I` or `Command + Option + I` is pressed.
5 changes: 5 additions & 0 deletions .changes/window-devtools-apis.md
@@ -0,0 +1,5 @@
---
"tauri": patch
---

Added `close_devtools` and `is_devtools_open` APIs to the `Window` struct.
33 changes: 33 additions & 0 deletions core/tauri-runtime-wry/src/lib.rs
Expand Up @@ -984,8 +984,13 @@ unsafe impl Send for GtkWindow {}

#[derive(Debug, Clone)]
pub enum WindowMessage {
// Devtools
#[cfg(any(debug_assertions, feature = "devtools"))]
OpenDevTools,
#[cfg(any(debug_assertions, feature = "devtools"))]
CloseDevTools,
#[cfg(any(debug_assertions, feature = "devtools"))]
IsDevToolsOpen(Sender<bool>),
// Getters
ScaleFactor(Sender<f64>),
InnerPosition(Sender<Result<PhysicalPosition<i32>>>),
Expand Down Expand Up @@ -1174,6 +1179,20 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
);
}

#[cfg(any(debug_assertions, feature = "devtools"))]
fn close_devtools(&self) {
let _ = send_user_message(
&self.context,
Message::Window(self.window_id, WindowMessage::CloseDevTools),
);
}

/// Gets the devtools window's current open state.
#[cfg(any(debug_assertions, feature = "devtools"))]
fn is_devtools_open(&self) -> Result<bool> {
window_getter!(self, WindowMessage::IsDevToolsOpen)
}

// Getters

fn scale_factor(&self) -> Result<f64> {
Expand Down Expand Up @@ -2002,6 +2021,20 @@ fn handle_user_message<T: UserEvent>(
w.open_devtools();
}
}
#[cfg(any(debug_assertions, feature = "devtools"))]
WindowMessage::CloseDevTools => {
if let WindowHandle::Webview(w) = &webview.inner {
w.close_devtools();
}
}
#[cfg(any(debug_assertions, feature = "devtools"))]
WindowMessage::IsDevToolsOpen(tx) => {
if let WindowHandle::Webview(w) = &webview.inner {
tx.send(w.is_devtools_open()).unwrap();
} else {
tx.send(false).unwrap();
}
}
// Getters
WindowMessage::ScaleFactor(tx) => tx.send(window.scale_factor()).unwrap(),
WindowMessage::InnerPosition(tx) => tx
Expand Down
130 changes: 66 additions & 64 deletions core/tauri-runtime/src/lib.rs
Expand Up @@ -284,33 +284,29 @@ pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'st
fn create_window(
&self,
pending: PendingWindow<T, Self::Runtime>,
) -> crate::Result<DetachedWindow<T, Self::Runtime>>;
) -> Result<DetachedWindow<T, Self::Runtime>>;

/// Run a task on the main thread.
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()>;
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;

#[cfg(all(windows, feature = "system-tray"))]
#[cfg_attr(doc_cfg, doc(cfg(all(windows, feature = "system-tray"))))]
fn remove_system_tray(&self) -> crate::Result<()>;
fn remove_system_tray(&self) -> Result<()>;
}

/// A global shortcut manager.
pub trait GlobalShortcutManager: Debug + Clone + Send + Sync {
/// Whether the application has registered the given `accelerator`.
fn is_registered(&self, accelerator: &str) -> crate::Result<bool>;
fn is_registered(&self, accelerator: &str) -> Result<bool>;

/// Register a global shortcut of `accelerator`.
fn register<F: Fn() + Send + 'static>(
&mut self,
accelerator: &str,
handler: F,
) -> crate::Result<()>;
fn register<F: Fn() + Send + 'static>(&mut self, accelerator: &str, handler: F) -> Result<()>;

/// Unregister all accelerators registered by the manager instance.
fn unregister_all(&mut self) -> crate::Result<()>;
fn unregister_all(&mut self) -> Result<()>;

/// Unregister the provided `accelerator`.
fn unregister(&mut self, accelerator: &str) -> crate::Result<()>;
fn unregister(&mut self, accelerator: &str) -> Result<()>;
}

/// Clipboard manager.
Expand Down Expand Up @@ -342,12 +338,12 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
type EventLoopProxy: EventLoopProxy<T>;

/// Creates a new webview runtime. Must be used on the main thread.
fn new() -> crate::Result<Self>;
fn new() -> Result<Self>;

/// Creates a new webview runtime on any thread.
#[cfg(any(windows, target_os = "linux"))]
#[cfg_attr(doc_cfg, doc(cfg(any(windows, target_os = "linux"))))]
fn new_any_thread() -> crate::Result<Self>;
fn new_any_thread() -> Result<Self>;

/// Creates an `EventLoopProxy` that can be used to dispatch user events to the main event loop.
fn create_proxy(&self) -> Self::EventLoopProxy;
Expand All @@ -362,15 +358,12 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
fn clipboard_manager(&self) -> Self::ClipboardManager;

/// Create a new webview window.
fn create_window(
&self,
pending: PendingWindow<T, Self>,
) -> crate::Result<DetachedWindow<T, Self>>;
fn create_window(&self, pending: PendingWindow<T, Self>) -> Result<DetachedWindow<T, Self>>;

/// Adds the icon to the system tray with the specified menu items.
#[cfg(feature = "system-tray")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))]
fn system_tray(&self, system_tray: SystemTray) -> crate::Result<Self::TrayHandler>;
fn system_tray(&self, system_tray: SystemTray) -> Result<Self::TrayHandler>;

/// Registers a system tray event handler.
#[cfg(feature = "system-tray")]
Expand Down Expand Up @@ -398,76 +391,85 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
type WindowBuilder: WindowBuilder;

/// Run a task on the main thread.
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()>;
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;

/// Registers a window event handler.
fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> Uuid;

/// Registers a window event handler.
fn on_menu_event<F: Fn(&window::MenuEvent) + Send + 'static>(&self, f: F) -> Uuid;

/// Open the web inspector which is usually called devtools.
#[cfg(any(debug_assertions, feature = "devtools"))]
fn open_devtools(&self);

/// Close the web inspector which is usually called devtools.
#[cfg(any(debug_assertions, feature = "devtools"))]
fn close_devtools(&self);

/// Gets the devtools window's current open state.
#[cfg(any(debug_assertions, feature = "devtools"))]
fn is_devtools_open(&self) -> Result<bool>;

// GETTERS

/// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa.
fn scale_factor(&self) -> crate::Result<f64>;
fn scale_factor(&self) -> Result<f64>;

/// Returns the position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop.
fn inner_position(&self) -> crate::Result<PhysicalPosition<i32>>;
fn inner_position(&self) -> Result<PhysicalPosition<i32>>;

/// Returns the position of the top-left hand corner of the window relative to the top-left hand corner of the desktop.
fn outer_position(&self) -> crate::Result<PhysicalPosition<i32>>;
fn outer_position(&self) -> Result<PhysicalPosition<i32>>;

/// Returns the physical size of the window's client area.
///
/// The client area is the content of the window, excluding the title bar and borders.
fn inner_size(&self) -> crate::Result<PhysicalSize<u32>>;
fn inner_size(&self) -> Result<PhysicalSize<u32>>;

/// Returns the physical size of the entire window.
///
/// These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead.
fn outer_size(&self) -> crate::Result<PhysicalSize<u32>>;
fn outer_size(&self) -> Result<PhysicalSize<u32>>;

/// Gets the window's current fullscreen state.
fn is_fullscreen(&self) -> crate::Result<bool>;
fn is_fullscreen(&self) -> Result<bool>;

/// Gets the window's current maximized state.
fn is_maximized(&self) -> crate::Result<bool>;
fn is_maximized(&self) -> Result<bool>;

/// Gets the window’s current decoration state.
fn is_decorated(&self) -> crate::Result<bool>;
fn is_decorated(&self) -> Result<bool>;

/// Gets the window’s current resizable state.
fn is_resizable(&self) -> crate::Result<bool>;
fn is_resizable(&self) -> Result<bool>;

/// Gets the window's current vibility state.
fn is_visible(&self) -> crate::Result<bool>;
fn is_visible(&self) -> Result<bool>;

/// Gets the window menu current visibility state.
fn is_menu_visible(&self) -> crate::Result<bool>;
fn is_menu_visible(&self) -> Result<bool>;

/// Returns the monitor on which the window currently resides.
///
/// Returns None if current monitor can't be detected.
fn current_monitor(&self) -> crate::Result<Option<Monitor>>;
fn current_monitor(&self) -> Result<Option<Monitor>>;

/// Returns the primary monitor of the system.
///
/// Returns None if it can't identify any monitor as a primary one.
fn primary_monitor(&self) -> crate::Result<Option<Monitor>>;
fn primary_monitor(&self) -> Result<Option<Monitor>>;

/// Returns the list of all the monitors available on the system.
fn available_monitors(&self) -> crate::Result<Vec<Monitor>>;
fn available_monitors(&self) -> Result<Vec<Monitor>>;

/// Returns the native handle that is used by this window.
#[cfg(windows)]
fn hwnd(&self) -> crate::Result<HWND>;
fn hwnd(&self) -> Result<HWND>;

/// Returns the native handle that is used by this window.
#[cfg(target_os = "macos")]
fn ns_window(&self) -> crate::Result<*mut std::ffi::c_void>;
fn ns_window(&self) -> Result<*mut std::ffi::c_void>;

/// Returns the `ApplicatonWindow` from gtk crate that is used by this window.
#[cfg(any(
Expand All @@ -477,96 +479,96 @@ pub trait Dispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static
target_os = "netbsd",
target_os = "openbsd"
))]
fn gtk_window(&self) -> crate::Result<gtk::ApplicationWindow>;
fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;

// SETTERS

/// Centers the window.
fn center(&self) -> crate::Result<()>;
fn center(&self) -> Result<()>;

/// Opens the dialog to prints the contents of the webview.
fn print(&self) -> crate::Result<()>;
fn print(&self) -> Result<()>;

/// Requests user attention to the window.
///
/// Providing `None` will unset the request for user attention.
fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> crate::Result<()>;
fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;

/// Create a new webview window.
fn create_window(
&mut self,
pending: PendingWindow<T, Self::Runtime>,
) -> crate::Result<DetachedWindow<T, Self::Runtime>>;
) -> Result<DetachedWindow<T, Self::Runtime>>;

/// Updates the window resizable flag.
fn set_resizable(&self, resizable: bool) -> crate::Result<()>;
fn set_resizable(&self, resizable: bool) -> Result<()>;

/// Updates the window title.
fn set_title<S: Into<String>>(&self, title: S) -> crate::Result<()>;
fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;

/// Maximizes the window.
fn maximize(&self) -> crate::Result<()>;
fn maximize(&self) -> Result<()>;

/// Unmaximizes the window.
fn unmaximize(&self) -> crate::Result<()>;
fn unmaximize(&self) -> Result<()>;

/// Minimizes the window.
fn minimize(&self) -> crate::Result<()>;
fn minimize(&self) -> Result<()>;

/// Unminimizes the window.
fn unminimize(&self) -> crate::Result<()>;
fn unminimize(&self) -> Result<()>;

/// Shows the window menu.
fn show_menu(&self) -> crate::Result<()>;
fn show_menu(&self) -> Result<()>;

/// Hides the window menu.
fn hide_menu(&self) -> crate::Result<()>;
fn hide_menu(&self) -> Result<()>;

/// Shows the window.
fn show(&self) -> crate::Result<()>;
fn show(&self) -> Result<()>;

/// Hides the window.
fn hide(&self) -> crate::Result<()>;
fn hide(&self) -> Result<()>;

/// Closes the window.
fn close(&self) -> crate::Result<()>;
fn close(&self) -> Result<()>;

/// Updates the hasDecorations flag.
fn set_decorations(&self, decorations: bool) -> crate::Result<()>;
fn set_decorations(&self, decorations: bool) -> Result<()>;

/// Updates the window alwaysOnTop flag.
fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()>;
fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;

/// Resizes the window.
fn set_size(&self, size: Size) -> crate::Result<()>;
fn set_size(&self, size: Size) -> Result<()>;

/// Updates the window min size.
fn set_min_size(&self, size: Option<Size>) -> crate::Result<()>;
fn set_min_size(&self, size: Option<Size>) -> Result<()>;

/// Updates the window max size.
fn set_max_size(&self, size: Option<Size>) -> crate::Result<()>;
fn set_max_size(&self, size: Option<Size>) -> Result<()>;

/// Updates the window position.
fn set_position(&self, position: Position) -> crate::Result<()>;
fn set_position(&self, position: Position) -> Result<()>;

/// Updates the window fullscreen state.
fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()>;
fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;

/// Bring the window to front and focus.
fn set_focus(&self) -> crate::Result<()>;
fn set_focus(&self) -> Result<()>;

/// Updates the window icon.
fn set_icon(&self, icon: WindowIcon) -> crate::Result<()>;
fn set_icon(&self, icon: WindowIcon) -> Result<()>;

/// Whether to show the window icon in the task bar or not.
fn set_skip_taskbar(&self, skip: bool) -> crate::Result<()>;
fn set_skip_taskbar(&self, skip: bool) -> Result<()>;

/// Starts dragging the window.
fn start_dragging(&self) -> crate::Result<()>;
fn start_dragging(&self) -> Result<()>;

/// Executes javascript on the window this [`Dispatch`] represents.
fn eval_script<S: Into<String>>(&self, script: S) -> crate::Result<()>;
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;

/// Applies the specified `update` to the menu item associated with the given `id`.
fn update_menu_item(&self, id: u16, update: menu::MenuUpdate) -> crate::Result<()>;
fn update_menu_item(&self, id: u16, update: menu::MenuUpdate) -> Result<()>;
}
2 changes: 2 additions & 0 deletions core/tauri/scripts/hotkey.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e05d718

Please sign in to comment.