fix(desktop): redirect menu bar events to window (#5200)
This commit is contained in:
parent
b1d4ad2bf8
commit
224525be66
2 changed files with 110 additions and 142 deletions
|
|
@ -2,10 +2,8 @@ pub mod logger;
|
|||
pub mod server;
|
||||
pub mod updater;
|
||||
|
||||
use std::ops::Not;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use tauri::menu::{MenuBuilder, MenuItemBuilder, SubmenuBuilder};
|
||||
use tauri::{Emitter, Manager};
|
||||
use tauri_plugin_appload::VendorConfigBuilder;
|
||||
use tauri_plugin_deep_link::DeepLinkExt;
|
||||
|
|
@ -23,144 +21,6 @@ fn hopp_auth_port() -> u16 {
|
|||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
let new_tab = MenuItemBuilder::with_id("new_tab", "New Tab")
|
||||
.accelerator("CmdOrCtrl+T")
|
||||
.build(app)
|
||||
.expect("Failed to build new tab menu item");
|
||||
|
||||
let close_tab = MenuItemBuilder::with_id("close_tab", "Close Tab")
|
||||
.accelerator("CmdOrCtrl+W")
|
||||
.build(app)
|
||||
.expect("Failed to build close tab menu item");
|
||||
|
||||
let reopen_tab = MenuItemBuilder::with_id("reopen_tab", "Reopen Closed Tab")
|
||||
.accelerator("CmdOrCtrl+Shift+T")
|
||||
.build(app)
|
||||
.expect("Failed to build reopen tab menu item");
|
||||
|
||||
let file_menu = SubmenuBuilder::new(app, "File")
|
||||
.item(&new_tab)
|
||||
.item(&close_tab)
|
||||
.item(&reopen_tab)
|
||||
.build()
|
||||
.expect("Failed to build file menu");
|
||||
|
||||
let focus_url = MenuItemBuilder::with_id("focus_url", "Focus Address Bar")
|
||||
.accelerator("CmdOrCtrl+L")
|
||||
.build(app)
|
||||
.expect("Failed to build focus URL menu item");
|
||||
|
||||
let view_menu = SubmenuBuilder::new(app, "View")
|
||||
.item(&focus_url)
|
||||
.build()
|
||||
.expect("Failed to build view menu");
|
||||
|
||||
let next_tab = MenuItemBuilder::with_id("next_tab", "Next Tab")
|
||||
.accelerator("CmdOrCtrl+Alt+Right")
|
||||
.build(app)
|
||||
.expect("Failed to build next tab menu item");
|
||||
|
||||
let prev_tab = MenuItemBuilder::with_id("prev_tab", "Previous Tab")
|
||||
.accelerator("CmdOrCtrl+Alt+Left")
|
||||
.build(app)
|
||||
.expect("Failed to build previous tab menu item");
|
||||
|
||||
let tab_first = MenuItemBuilder::with_id("tab_first", "Switch to First Tab")
|
||||
.accelerator("CmdOrCtrl+Alt+9")
|
||||
.build(app)
|
||||
.expect("Failed to build first tab menu item");
|
||||
|
||||
let tab_last = MenuItemBuilder::with_id("tab_last", "Switch to Last Tab")
|
||||
.accelerator("CmdOrCtrl+Alt+0")
|
||||
.build(app)
|
||||
.expect("Failed to build last tab menu item");
|
||||
|
||||
let tabs_menu = SubmenuBuilder::new(app, "Tabs")
|
||||
.item(&next_tab)
|
||||
.item(&prev_tab)
|
||||
.separator()
|
||||
.item(&tab_first)
|
||||
.item(&tab_last)
|
||||
.build()
|
||||
.expect("Failed to build tabs menu");
|
||||
|
||||
let menu = MenuBuilder::new(app)
|
||||
.item(&file_menu)
|
||||
.item(&view_menu)
|
||||
.item(&tabs_menu)
|
||||
.build()
|
||||
.expect("Failed to build menu");
|
||||
|
||||
app.set_menu(menu).expect("Failed to set menu");
|
||||
|
||||
let handle = app.handle().clone();
|
||||
app.on_menu_event(move |app, event| {
|
||||
let event_id = event.id().as_ref();
|
||||
let webview_windows = app.webview_windows();
|
||||
let perhaps_window = webview_windows
|
||||
.iter()
|
||||
// Any window that's not `main` since there can
|
||||
// only be one window open at the moment.
|
||||
//
|
||||
// NOTE: Generally this should use `get_focused_window`
|
||||
// but that requires `unstable` flag currently
|
||||
// and causes arrow keys to insert escape sequences on MacOS
|
||||
// see: https://github.com/hoppscotch/hoppscotch/pull/5108
|
||||
.filter(|kv| kv.0.eq_ignore_ascii_case("main").not())
|
||||
.last()
|
||||
.map(|lw| lw.1);
|
||||
|
||||
if let Some(window) = perhaps_window {
|
||||
let shortcut_event = match event_id {
|
||||
"new_tab" => {
|
||||
tracing::info!("New Tab menu item triggered (CMD+T/Ctrl+T)");
|
||||
Some("ctrl-t")
|
||||
}
|
||||
"close_tab" => {
|
||||
tracing::info!("Close Tab menu item triggered (CMD+W/Ctrl+W)");
|
||||
Some("ctrl-w")
|
||||
}
|
||||
"reopen_tab" => {
|
||||
tracing::info!(
|
||||
"Reopen Tab menu item triggered (CMD+Shift+T/Ctrl+Shift+T)"
|
||||
);
|
||||
Some("ctrl-shift-t")
|
||||
}
|
||||
"next_tab" => {
|
||||
tracing::info!("Next Tab menu item triggered (CMD+Alt+Right/Ctrl+Alt+Right)");
|
||||
Some("ctrl-alt-right")
|
||||
}
|
||||
"prev_tab" => {
|
||||
tracing::info!(
|
||||
"Previous Tab menu item triggered (CMD+Alt+Left/Ctrl+Alt+Left)"
|
||||
);
|
||||
Some("ctrl-alt-left")
|
||||
}
|
||||
"tab_first" => {
|
||||
tracing::info!("Switch to First Tab menu item triggered (CMD+Alt+9/Ctrl+Alt+9)");
|
||||
Some("ctrl-alt-9")
|
||||
}
|
||||
"tab_last" => {
|
||||
tracing::info!("Switch to Last Tab menu item triggered (CMD+Alt+0/Ctrl+Alt+0)");
|
||||
Some("ctrl-alt-0")
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(shortcut) = shortcut_event {
|
||||
window
|
||||
.emit("hoppscotch_desktop_shortcut", shortcut)
|
||||
.unwrap_or_else(|e| {
|
||||
tracing::error!(
|
||||
error.message = %e,
|
||||
shortcut = shortcut,
|
||||
"Failed to emit shortcut event from menu"
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let server_port = portpicker::pick_unused_port().expect("Cannot find unused port");
|
||||
tracing::info!("Selected server port: {}", server_port);
|
||||
SERVER_PORT
|
||||
|
|
@ -168,10 +28,11 @@ pub fn run() {
|
|||
.expect("Failed to set server port");
|
||||
let port = *SERVER_PORT.get().expect("Server port not initialized");
|
||||
tracing::info!(port = port, "Initializing server with pre-selected port");
|
||||
let port = server::init(port, handle.clone());
|
||||
let port = server::init(port, app.handle().clone());
|
||||
tracing::info!(port = port, "Server initialization complete");
|
||||
|
||||
tracing::info!(app_name = %app.package_info().name, "Configuring deep link handler");
|
||||
let handle = app.handle().clone();
|
||||
app.deep_link().on_open_url(move |event| {
|
||||
let urls = event.urls();
|
||||
tracing::info!(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { ref } from "vue"
|
||||
import { listen } from "@tauri-apps/api/event"
|
||||
import { listen, emit } from "@tauri-apps/api/event"
|
||||
|
||||
import { createHoppApp } from "@hoppscotch/common"
|
||||
|
||||
import { def as webAuth } from "@platform/auth/web"
|
||||
|
|
@ -209,8 +210,114 @@ async function initApp() {
|
|||
window.addEventListener(
|
||||
"keydown",
|
||||
function (e) {
|
||||
// Prevent backspace navigation
|
||||
// NOTE: Only for "non-text" inputs
|
||||
if (e.key === "Backspace" && !isTextInput(e.target)) {
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
const isCtrlOrCmd = e.ctrlKey || e.metaKey
|
||||
let shortcutEvent: string | null = null
|
||||
|
||||
if (
|
||||
isCtrlOrCmd &&
|
||||
!e.shiftKey &&
|
||||
!e.altKey &&
|
||||
e.key.toLowerCase() === "t"
|
||||
) {
|
||||
// Ctrl/Cmd + T - New Tab
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "ctrl-t"
|
||||
} else if (
|
||||
isCtrlOrCmd &&
|
||||
!e.shiftKey &&
|
||||
!e.altKey &&
|
||||
e.key.toLowerCase() === "w"
|
||||
) {
|
||||
// Ctrl/Cmd + W - Close Tab
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "ctrl-w"
|
||||
} else if (
|
||||
isCtrlOrCmd &&
|
||||
e.shiftKey &&
|
||||
!e.altKey &&
|
||||
e.key.toLowerCase() === "t"
|
||||
) {
|
||||
// Ctrl/Cmd + Shift + T - Reopen Tab
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "ctrl-shift-t"
|
||||
} else if (
|
||||
isCtrlOrCmd &&
|
||||
!e.shiftKey &&
|
||||
e.altKey &&
|
||||
e.key === "ArrowRight"
|
||||
) {
|
||||
// Ctrl/Cmd + Alt + Right - Next Tab
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "ctrl-alt-right"
|
||||
} else if (
|
||||
isCtrlOrCmd &&
|
||||
!e.shiftKey &&
|
||||
e.altKey &&
|
||||
e.key === "ArrowLeft"
|
||||
) {
|
||||
// Ctrl/Cmd + Alt + Left - Previous Tab
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "ctrl-alt-left"
|
||||
} else if (
|
||||
isCtrlOrCmd &&
|
||||
!e.shiftKey &&
|
||||
e.altKey &&
|
||||
(e.key === "9" || e.code === "Digit9")
|
||||
) {
|
||||
// Ctrl/Cmd + Alt + 9 - First Tab
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "ctrl-alt-9"
|
||||
} else if (
|
||||
isCtrlOrCmd &&
|
||||
!e.shiftKey &&
|
||||
e.altKey &&
|
||||
(e.key === "0" || e.code === "Digit0")
|
||||
) {
|
||||
// Ctrl/Cmd + Alt + 0 - Last Tab
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "ctrl-alt-0"
|
||||
} else if (
|
||||
isCtrlOrCmd &&
|
||||
!e.shiftKey &&
|
||||
!e.altKey &&
|
||||
e.key.toLowerCase() === "l"
|
||||
) {
|
||||
// Ctrl/Cmd + L - Focus Address Bar
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.stopImmediatePropagation()
|
||||
shortcutEvent = "focus-url"
|
||||
}
|
||||
|
||||
if (shortcutEvent) {
|
||||
setTimeout(() => {
|
||||
emit("hoppscotch_desktop_shortcut", shortcutEvent).catch(
|
||||
(error) => {
|
||||
console.error("Failed to emit shortcut event:", error)
|
||||
}
|
||||
)
|
||||
}, 0)
|
||||
}
|
||||
},
|
||||
true
|
||||
|
|
|
|||
Loading…
Reference in a new issue