diff --git a/apps/desktop/src/renderer/hotkeys/registry.ts b/apps/desktop/src/renderer/hotkeys/registry.ts index e04d7c4b3a1..24db8d60b85 100644 --- a/apps/desktop/src/renderer/hotkeys/registry.ts +++ b/apps/desktop/src/renderer/hotkeys/registry.ts @@ -101,24 +101,6 @@ export const HOTKEYS_REGISTRY = { label: "Switch to Workspace 9", category: "Workspace", }, - PREV_WORKSPACE: { - key: { - mac: "meta+alt+up", - windows: "ctrl+shift+alt+up", - linux: "ctrl+shift+alt+up", - }, - label: "Previous Workspace", - category: "Workspace", - }, - NEXT_WORKSPACE: { - key: { - mac: "meta+alt+down", - windows: "ctrl+shift+alt+down", - linux: "ctrl+shift+alt+down", - }, - label: "Next Workspace", - category: "Workspace", - }, CLOSE_WORKSPACE: { key: { mac: "meta+shift+backspace", @@ -334,24 +316,6 @@ export const HOTKEYS_REGISTRY = { category: "Terminal", description: "Scroll the active terminal to the bottom", }, - PREV_TAB: { - key: { - mac: "meta+alt+left", - windows: "ctrl+shift+alt+left", - linux: "ctrl+shift+alt+left", - }, - label: "Previous Tab", - category: "Terminal", - }, - NEXT_TAB: { - key: { - mac: "meta+alt+right", - windows: "ctrl+shift+alt+right", - linux: "ctrl+shift+alt+right", - }, - label: "Next Tab", - category: "Terminal", - }, PREV_TAB_ALT: { key: { mac: "ctrl+shift+tab", @@ -366,25 +330,45 @@ export const HOTKEYS_REGISTRY = { label: "Next Tab (Alt)", category: "Terminal", }, - PREV_PANE: { + FOCUS_PANE_LEFT: { key: { - mac: "meta+shift+left", + mac: "meta+alt+left", windows: "ctrl+shift+alt+left", linux: "ctrl+shift+alt+left", }, - label: "Previous Pane", + label: "Focus Pane Left", category: "Terminal", - description: "Focus the previous pane in the current tab", + description: "Focus the pane to the left of the active pane", }, - NEXT_PANE: { + FOCUS_PANE_RIGHT: { key: { - mac: "meta+shift+right", + mac: "meta+alt+right", windows: "ctrl+shift+alt+right", linux: "ctrl+shift+alt+right", }, - label: "Next Pane", + label: "Focus Pane Right", + category: "Terminal", + description: "Focus the pane to the right of the active pane", + }, + FOCUS_PANE_UP: { + key: { + mac: "meta+alt+up", + windows: "ctrl+shift+alt+up", + linux: "ctrl+shift+alt+up", + }, + label: "Focus Pane Up", + category: "Terminal", + description: "Focus the pane above the active pane", + }, + FOCUS_PANE_DOWN: { + key: { + mac: "meta+alt+down", + windows: "ctrl+shift+alt+down", + linux: "ctrl+shift+alt+down", + }, + label: "Focus Pane Down", category: "Terminal", - description: "Focus the next pane in the current tab", + description: "Focus the pane below the active pane", }, JUMP_TO_TAB_1: { key: { diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarShortcuts/useDashboardSidebarShortcuts.ts b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarShortcuts/useDashboardSidebarShortcuts.ts index eaedf913f8a..dbe6240106d 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarShortcuts/useDashboardSidebarShortcuts.ts +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarShortcuts/useDashboardSidebarShortcuts.ts @@ -1,4 +1,4 @@ -import { useMatchRoute, useNavigate } from "@tanstack/react-router"; +import { useNavigate } from "@tanstack/react-router"; import { useCallback, useMemo } from "react"; import { useHotkey } from "renderer/hotkeys"; import { navigateToV2Workspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; @@ -48,33 +48,5 @@ export function useDashboardSidebarShortcuts( useHotkey("JUMP_TO_WORKSPACE_8", () => switchToWorkspace(7)); useHotkey("JUMP_TO_WORKSPACE_9", () => switchToWorkspace(8)); - // Prev/next workspace navigation (cycles) - const matchRoute = useMatchRoute(); - const currentWorkspaceMatch = matchRoute({ - to: "/v2-workspace/$workspaceId", - fuzzy: true, - }); - const currentWorkspaceId = - currentWorkspaceMatch !== false ? currentWorkspaceMatch.workspaceId : null; - - useHotkey("PREV_WORKSPACE", () => { - if (!currentWorkspaceId || flattenedWorkspaces.length === 0) return; - const index = flattenedWorkspaces.findIndex( - (w) => w.id === currentWorkspaceId, - ); - const prevIndex = index <= 0 ? flattenedWorkspaces.length - 1 : index - 1; - navigateToV2Workspace(flattenedWorkspaces[prevIndex].id, navigate); - }); - - useHotkey("NEXT_WORKSPACE", () => { - if (!currentWorkspaceId || flattenedWorkspaces.length === 0) return; - const index = flattenedWorkspaces.findIndex( - (w) => w.id === currentWorkspaceId, - ); - const nextIndex = - index >= flattenedWorkspaces.length - 1 || index === -1 ? 0 : index + 1; - navigateToV2Workspace(flattenedWorkspaces[nextIndex].id, navigate); - }); - return workspaceShortcutLabels; } diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspaceHotkeys/useWorkspaceHotkeys.ts b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspaceHotkeys/useWorkspaceHotkeys.ts index ef5bf804a13..c791446a404 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspaceHotkeys/useWorkspaceHotkeys.ts +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspaceHotkeys/useWorkspaceHotkeys.ts @@ -1,4 +1,8 @@ -import type { WorkspaceStore } from "@superset/panes"; +import { + type FocusDirection, + getSpatialNeighborPaneId, + type WorkspaceStore, +} from "@superset/panes"; import { useCallback } from "react"; import { useHotkey } from "renderer/hotkeys"; import { useCollections } from "renderer/routes/_authenticated/providers/CollectionsProvider"; @@ -83,23 +87,6 @@ export function useWorkspaceHotkeys({ } }); - useHotkey("PREV_TAB", () => { - const state = store.getState(); - if (!state.activeTabId || state.tabs.length === 0) return; - const index = state.tabs.findIndex((t) => t.id === state.activeTabId); - const prevIndex = index <= 0 ? state.tabs.length - 1 : index - 1; - state.setActiveTab(state.tabs[prevIndex].id); - }); - - useHotkey("NEXT_TAB", () => { - const state = store.getState(); - if (!state.activeTabId || state.tabs.length === 0) return; - const index = state.tabs.findIndex((t) => t.id === state.activeTabId); - const nextIndex = - index >= state.tabs.length - 1 || index === -1 ? 0 : index + 1; - state.setActiveTab(state.tabs[nextIndex].id); - }); - useHotkey("PREV_TAB_ALT", () => { const state = store.getState(); if (!state.activeTabId || state.tabs.length === 0) return; @@ -138,25 +125,25 @@ export function useWorkspaceHotkeys({ // --- Pane management --- - useHotkey("PREV_PANE", () => { - const state = store.getState(); - const tab = state.getActiveTab(); - if (!tab || !tab.activePaneId) return; - const paneIds = Object.keys(tab.panes); - const index = paneIds.indexOf(tab.activePaneId); - const prevIndex = index <= 0 ? paneIds.length - 1 : index - 1; - state.setActivePane({ tabId: tab.id, paneId: paneIds[prevIndex] }); - }); + const moveFocusDirectional = useCallback( + (dir: FocusDirection) => { + const state = store.getState(); + const tab = state.getActiveTab(); + if (!tab || !tab.activePaneId) return; + const neighbor = getSpatialNeighborPaneId( + tab.layout, + tab.activePaneId, + dir, + ); + if (neighbor) state.setActivePane({ tabId: tab.id, paneId: neighbor }); + }, + [store], + ); - useHotkey("NEXT_PANE", () => { - const state = store.getState(); - const tab = state.getActiveTab(); - if (!tab || !tab.activePaneId) return; - const paneIds = Object.keys(tab.panes); - const index = paneIds.indexOf(tab.activePaneId); - const nextIndex = index >= paneIds.length - 1 ? 0 : index + 1; - state.setActivePane({ tabId: tab.id, paneId: paneIds[nextIndex] }); - }); + useHotkey("FOCUS_PANE_LEFT", () => moveFocusDirectional("left")); + useHotkey("FOCUS_PANE_RIGHT", () => moveFocusDirectional("right")); + useHotkey("FOCUS_PANE_UP", () => moveFocusDirectional("up")); + useHotkey("FOCUS_PANE_DOWN", () => moveFocusDirectional("down")); useHotkey("SPLIT_AUTO", () => { const state = store.getState(); diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx index 254916f1cb2..5ca024491e9 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx @@ -1,5 +1,5 @@ import type { ExternalApp } from "@superset/local-db"; -import { createFileRoute, notFound, useNavigate } from "@tanstack/react-router"; +import { createFileRoute, notFound } from "@tanstack/react-router"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useCopyToClipboard } from "renderer/hooks/useCopyToClipboard"; import { useFileOpenMode } from "renderer/hooks/useFileOpenMode"; @@ -8,7 +8,6 @@ import { electronTrpc } from "renderer/lib/electron-trpc"; import { electronTrpcClient as trpcClient } from "renderer/lib/trpc-client"; import { usePresets } from "renderer/react-query/presets"; import type { WorkspaceSearchParams } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; -import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { usePresetHotkeys } from "renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/hooks/usePresetHotkeys"; import { useWorkspaceRunCommand } from "renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/hooks/useWorkspaceRunCommand"; import { NotFound } from "renderer/routes/not-found"; @@ -35,8 +34,6 @@ import { useTabsWithPresets } from "renderer/stores/tabs/useTabsWithPresets"; import { findPanePath, getFirstPaneId, - getNextPaneId, - getPreviousPaneId, resolveActiveTabIdForWorkspace, } from "renderer/stores/tabs/utils"; import { @@ -93,7 +90,6 @@ function WorkspacePage() { worktreePath: workspace?.worktreePath, enabled: Boolean(workspace?.worktreePath), }); - const navigate = useNavigate(); const routeNavigate = Route.useNavigate(); const { tabId: searchTabId, paneId: searchPaneId } = Route.useSearch(); @@ -228,20 +224,6 @@ function WorkspacePage() { } }); - useHotkey("PREV_TAB", () => { - if (!activeTabId || tabs.length === 0) return; - const index = tabs.findIndex((t) => t.id === activeTabId); - const prevIndex = index <= 0 ? tabs.length - 1 : index - 1; - setActiveTab(workspaceId, tabs[prevIndex].id); - }); - - useHotkey("NEXT_TAB", () => { - if (!activeTabId || tabs.length === 0) return; - const index = tabs.findIndex((t) => t.id === activeTabId); - const nextIndex = index >= tabs.length - 1 || index === -1 ? 0 : index + 1; - setActiveTab(workspaceId, tabs[nextIndex].id); - }); - useHotkey("PREV_TAB_ALT", () => { if (!activeTabId || tabs.length === 0) return; const index = tabs.findIndex((t) => t.id === activeTabId); @@ -276,22 +258,6 @@ function WorkspacePage() { useHotkey("JUMP_TO_TAB_8", () => switchToTab(7)); useHotkey("JUMP_TO_TAB_9", () => switchToTab(8)); - useHotkey("PREV_PANE", () => { - if (!activeTabId || !activeTab?.layout || !focusedPaneId) return; - const prevPaneId = getPreviousPaneId(activeTab.layout, focusedPaneId); - if (prevPaneId) { - setFocusedPane(activeTabId, prevPaneId); - } - }); - - useHotkey("NEXT_PANE", () => { - if (!activeTabId || !activeTab?.layout || !focusedPaneId) return; - const nextPaneId = getNextPaneId(activeTab.layout, focusedPaneId); - if (nextPaneId) { - setFocusedPane(activeTabId, nextPaneId); - } - }); - // Open in last used app shortcut const projectId = workspace?.projectId; const { data: defaultApp } = electronTrpc.projects.getDefaultApp.useQuery( @@ -427,31 +393,6 @@ function WorkspacePage() { } }); - // Navigate to previous workspace (⌘↑) - const getPreviousWorkspace = - electronTrpc.workspaces.getPreviousWorkspace.useQuery( - { id: workspaceId }, - { enabled: !!workspaceId }, - ); - useHotkey("PREV_WORKSPACE", () => { - const prevWorkspaceId = getPreviousWorkspace.data; - if (prevWorkspaceId) { - navigateToWorkspace(prevWorkspaceId, navigate); - } - }); - - // Navigate to next workspace (⌘↓) - const getNextWorkspace = electronTrpc.workspaces.getNextWorkspace.useQuery( - { id: workspaceId }, - { enabled: !!workspaceId }, - ); - useHotkey("NEXT_WORKSPACE", () => { - const nextWorkspaceId = getNextWorkspace.data; - if (nextWorkspaceId) { - navigateToWorkspace(nextWorkspaceId, navigate); - } - }); - return (