From 888d3d8890b674dbc8a0475eeb7156de44bad2fd Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 21 May 2026 10:34:04 +0800 Subject: [PATCH 1/2] feat(app): add new query shortcut --- apps/desktop/src/App.vue | 7 +++++++ apps/desktop/src/i18n/locales/en.ts | 1 + apps/desktop/src/i18n/locales/es.ts | 1 + apps/desktop/src/i18n/locales/zh-CN.ts | 1 + apps/desktop/src/lib/keyboardShortcuts.ts | 4 ++++ apps/desktop/src/lib/shortcutRegistry.ts | 15 ++++++++++++++- packages/app-tests/keyboardShortcuts.test.ts | 13 +++++++++++++ packages/app-tests/settingsStore.test.ts | 4 +++- 8 files changed, 44 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/App.vue b/apps/desktop/src/App.vue index 8c78ac5b63..92d06b8305 100644 --- a/apps/desktop/src/App.vue +++ b/apps/desktop/src/App.vue @@ -38,6 +38,7 @@ import { isCloseTabShortcut, isExecuteSqlShortcut, isFocusSearchShortcut, + isNewQueryShortcut, isObjectSourceSaveShortcutTarget, isRefreshDataShortcut, isSaveShortcut, @@ -587,6 +588,12 @@ function handleKeydown(e: KeyboardEvent) { contentAreaRef.value?.refreshData(); return; } + if (isNewQueryShortcut(e, shortcuts)) { + e.preventDefault(); + e.stopPropagation(); + void newQuery(); + return; + } if (isCloseTabShortcut(e, shortcuts)) { e.preventDefault(); if (showDriverStore.value) { diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index cdf1101f86..30ee23c9b5 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -1198,6 +1198,7 @@ export default { redisScanPageSizeOption: "{count} keys", shortcutExecuteSql: "Execute SQL", shortcutSaveSql: "Save SQL", + shortcutNewQuery: "New query", shortcutCloseTab: "Close tab", shortcutFocusSearch: "Focus search", shortcutRefreshData: "Refresh data", diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts index c4e88f471d..c801bba8ad 100644 --- a/apps/desktop/src/i18n/locales/es.ts +++ b/apps/desktop/src/i18n/locales/es.ts @@ -1097,6 +1097,7 @@ export default { redisScanPageSizeOption: "{count} claves", shortcutExecuteSql: "Ejecutar SQL", shortcutSaveSql: "Guardar SQL", + shortcutNewQuery: "Nueva consulta", shortcutCloseTab: "Cerrar pestaña", shortcutFocusSearch: "Enfocar búsqueda", shortcutRefreshData: "Actualizar datos", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index b6798ed50d..791f1612d4 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -1176,6 +1176,7 @@ export default { redisScanPageSizeOption: "{count} 个 Key", shortcutExecuteSql: "执行 SQL", shortcutSaveSql: "保存 SQL", + shortcutNewQuery: "新建查询", shortcutCloseTab: "关闭标签页", shortcutFocusSearch: "聚焦搜索", shortcutRefreshData: "刷新数据", diff --git a/apps/desktop/src/lib/keyboardShortcuts.ts b/apps/desktop/src/lib/keyboardShortcuts.ts index e2c53f9b0d..46a6003344 100644 --- a/apps/desktop/src/lib/keyboardShortcuts.ts +++ b/apps/desktop/src/lib/keyboardShortcuts.ts @@ -76,6 +76,10 @@ export function isCloseTabShortcut(event: ShortcutLikeEvent, shortcuts?: Partial return matchesShortcut(event, actionShortcut("closeTab", shortcuts)); } +export function isNewQueryShortcut(event: ShortcutLikeEvent, shortcuts?: Partial): boolean { + return matchesShortcut(event, actionShortcut("newQuery", shortcuts)); +} + export function isFocusSearchShortcut(event: ShortcutLikeEvent, shortcuts?: Partial): boolean { return matchesShortcut(event, actionShortcut("focusSearch", shortcuts)); } diff --git a/apps/desktop/src/lib/shortcutRegistry.ts b/apps/desktop/src/lib/shortcutRegistry.ts index 426c24b893..d34397a866 100644 --- a/apps/desktop/src/lib/shortcutRegistry.ts +++ b/apps/desktop/src/lib/shortcutRegistry.ts @@ -1,4 +1,11 @@ -export type ShortcutActionId = "executeSql" | "saveSql" | "closeTab" | "focusSearch" | "refreshData" | "cancelSearch"; +export type ShortcutActionId = + | "executeSql" + | "saveSql" + | "newQuery" + | "closeTab" + | "focusSearch" + | "refreshData" + | "cancelSearch"; export type ShortcutScope = "global" | "editor" | "search"; @@ -24,6 +31,12 @@ export const SHORTCUT_DEFINITIONS: ShortcutDefinition[] = [ scope: "editor", defaultShortcut: "Mod+S", }, + { + id: "newQuery", + labelKey: "settings.shortcutNewQuery", + scope: "global", + defaultShortcut: "Mod+T", + }, { id: "closeTab", labelKey: "settings.shortcutCloseTab", diff --git a/packages/app-tests/keyboardShortcuts.test.ts b/packages/app-tests/keyboardShortcuts.test.ts index 27f20a15ac..8abaa3a186 100644 --- a/packages/app-tests/keyboardShortcuts.test.ts +++ b/packages/app-tests/keyboardShortcuts.test.ts @@ -6,6 +6,7 @@ import { isCloseTabShortcut, isExecuteSqlShortcut, isFocusSearchShortcut, + isNewQueryShortcut, isObjectSourceSaveShortcutTarget, isRefreshDataShortcut, isSaveShortcut, @@ -44,6 +45,18 @@ test("matches Ctrl+Enter for SQL execution", () => { assert.equal(isExecuteSqlShortcut({ key: "Enter", ctrlKey: true }), true); }); +test("matches Cmd+T for opening a new query", () => { + assert.equal(isNewQueryShortcut({ key: "t", metaKey: true }), true); +}); + +test("matches custom shortcut settings for opening a new query", () => { + assert.equal(isNewQueryShortcut({ key: "t", metaKey: true }, { newQuery: "Shift+Mod+N" } as any), false); + assert.equal( + isNewQueryShortcut({ key: "n", ctrlKey: true, shiftKey: true } as any, { newQuery: "Shift+Mod+N" } as any), + true, + ); +}); + test("ignores Enter without modifier", () => { assert.equal(isExecuteSqlShortcut({ key: "Enter" }), false); }); diff --git a/packages/app-tests/settingsStore.test.ts b/packages/app-tests/settingsStore.test.ts index 02715447bb..32ae8027cb 100644 --- a/packages/app-tests/settingsStore.test.ts +++ b/packages/app-tests/settingsStore.test.ts @@ -28,14 +28,16 @@ test("defaults shortcut settings", () => { assert.equal(settings.shortcuts.executeSql, "Mod+Enter"); assert.equal(settings.shortcuts.saveSql, "Mod+S"); + assert.equal(settings.shortcuts.newQuery, "Mod+T"); assert.equal(settings.shortcuts.focusSearch, "Mod+F"); assert.equal(settings.shortcuts.refreshData, "F5"); }); test("keeps saved shortcut overrides", () => { - const settings = normalizeEditorSettings({ shortcuts: { executeSql: "Shift+Mod+Enter" } as any }); + const settings = normalizeEditorSettings({ shortcuts: { executeSql: "Shift+Mod+Enter", newQuery: "Shift+Mod+N" } as any }); assert.equal(settings.shortcuts.executeSql, "Shift+Mod+Enter"); + assert.equal(settings.shortcuts.newQuery, "Shift+Mod+N"); assert.equal(settings.shortcuts.saveSql, "Mod+S"); }); From c8d1b842d3519fa3ada42972134762017c1d2171 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 21 May 2026 10:42:03 +0800 Subject: [PATCH 2/2] fix(app): remove mac fullscreen toolbar gap --- .../src/components/layout/AppToolbar.vue | 7 ++++--- .../src/composables/useWindowControls.ts | 19 ++++++++++++++----- .../windowControlsFullscreenInset.test.ts | 10 ++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 packages/app-tests/windowControlsFullscreenInset.test.ts diff --git a/apps/desktop/src/components/layout/AppToolbar.vue b/apps/desktop/src/components/layout/AppToolbar.vue index c34d1f6df3..4ccdf45a26 100644 --- a/apps/desktop/src/components/layout/AppToolbar.vue +++ b/apps/desktop/src/components/layout/AppToolbar.vue @@ -28,7 +28,7 @@ import { } from "@/components/ui/dropdown-menu"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import WindowControls from "@/components/layout/WindowControls.vue"; -import { useWindowControls } from "@/composables/useWindowControls"; +import { shouldReserveMacTrafficLightInset, useWindowControls } from "@/composables/useWindowControls"; import { currentLocale, setLocale, type Locale } from "@/i18n"; import type { AppThemeMode } from "@/lib/appTheme"; @@ -68,7 +68,8 @@ const emit = defineEmits<{ }>(); const { t } = useI18n(); -const { isMac, isDesktop, showControls, isMaximized, minimize, toggleMaximize, close } = useWindowControls(); +const { isMac, isDesktop, showControls, isMaximized, isFullscreen, minimize, toggleMaximize, close } = + useWindowControls(); function onToolbarDblClick(e: MouseEvent) { if (isDesktop) return; @@ -81,7 +82,7 @@ function onToolbarDblClick(e: MouseEvent) {