feat(app): make the New tab launcher keyboard-first
Cmd/Ctrl+T now opens the focused pane's launcher, while explicit target shortcuts bypass the menu. Dispatcher ownership is scoped to the app tree so retained workspaces cannot intercept commands.
This commit is contained in:
@@ -44,7 +44,7 @@ import {
|
||||
type CommandCenterScope,
|
||||
} from "@/stores/keyboard-shortcuts-store";
|
||||
import { navigateToWorkspace } from "@/stores/navigation-active-workspace-store";
|
||||
import { keyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher";
|
||||
import { useKeyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher-context";
|
||||
import {
|
||||
clearCommandCenterFocusRestoreElement,
|
||||
takeCommandCenterFocusRestoreElement,
|
||||
@@ -220,6 +220,7 @@ interface CommandCenterState {
|
||||
}
|
||||
|
||||
function useCommandCenterState(): CommandCenterState {
|
||||
const keyboardActionDispatcher = useKeyboardActionDispatcher();
|
||||
const { t } = useTranslation();
|
||||
const open = useKeyboardShortcutsStore((state) => state.commandCenterOpen);
|
||||
const scope = useKeyboardShortcutsStore((state) => state.commandCenterScope);
|
||||
@@ -321,7 +322,7 @@ function useCommandCenterState(): CommandCenterState {
|
||||
keyboardActionDispatcher.dispatch({ id: "message-input.focus", scope: "message-input" }),
|
||||
});
|
||||
return cancel;
|
||||
}, [open]);
|
||||
}, [keyboardActionDispatcher, open]);
|
||||
|
||||
return {
|
||||
open,
|
||||
|
||||
@@ -16,7 +16,7 @@ import { withUnistyles } from "react-native-unistyles";
|
||||
import { getIsElectronRuntime } from "@/constants/layout";
|
||||
import { useKeyboardShortcutOverrides } from "@/hooks/use-keyboard-shortcut-overrides";
|
||||
import { useOpenAddProject } from "@/hooks/use-open-add-project";
|
||||
import { keyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher";
|
||||
import { useKeyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher-context";
|
||||
import { useKeyboardShortcutsAvailable } from "@/keyboard/availability";
|
||||
import { resolveShortcutKeysForAction } from "@/keyboard/keyboard-shortcuts";
|
||||
import { useKeyboardShortcutsStore } from "@/stores/keyboard-shortcuts-store";
|
||||
@@ -92,6 +92,7 @@ function CircleDashedIcon({ size }: CommandCenterIconProps) {
|
||||
}
|
||||
|
||||
export function CommandCenterRootActions() {
|
||||
const keyboardActionDispatcher = useKeyboardActionDispatcher();
|
||||
const { t } = useTranslation();
|
||||
const { overrides } = useKeyboardShortcutOverrides();
|
||||
const shortcutsAvailable = useKeyboardShortcutsAvailable();
|
||||
@@ -266,6 +267,7 @@ export function CommandCenterRootActions() {
|
||||
}, [
|
||||
groupMode,
|
||||
homeRoute,
|
||||
keyboardActionDispatcher,
|
||||
openAddProject,
|
||||
overrides,
|
||||
schedulesRoute,
|
||||
|
||||
@@ -114,7 +114,7 @@ describe("workspace command center contributions", () => {
|
||||
for (const contribution of contributions) contribution.run();
|
||||
|
||||
expect(fixture.dispatched).toEqual([
|
||||
{ id: "workspace.tab.new", scope: "workspace" },
|
||||
{ id: "workspace.agent.new", scope: "workspace" },
|
||||
{ id: "workspace.terminal.new", scope: "workspace" },
|
||||
{ id: "workspace.browser.new", scope: "workspace" },
|
||||
{ id: "workspace.pane.split.right", scope: "workspace" },
|
||||
|
||||
@@ -108,7 +108,7 @@ export function buildWorkspaceCommandCenterContributions(
|
||||
keywords: ["tab", "new", "agent", "chat"],
|
||||
icon: source.icons.newAgent,
|
||||
shortcutKeys: source.shortcuts.newAgent,
|
||||
action: { id: "workspace.tab.new", scope: "workspace" },
|
||||
action: { id: "workspace.agent.new", scope: "workspace" },
|
||||
visibility: "always",
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
resolveShortcutKeysForAction,
|
||||
type ShortcutOverrides,
|
||||
} from "@/keyboard/keyboard-shortcuts";
|
||||
import { keyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher";
|
||||
import { useKeyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher-context";
|
||||
import { useActiveWorkspaceSelection } from "@/stores/navigation-active-workspace-store";
|
||||
import { useWorkspaceDirectory } from "@/stores/session-store-hooks";
|
||||
import { clearCommandCenterFocusRestoreElement } from "@/utils/command-center-focus-restore";
|
||||
@@ -55,6 +55,7 @@ function resolveWorkspaceShortcuts(overrides: ShortcutOverrides): WorkspaceComma
|
||||
}
|
||||
|
||||
export function useWorkspaceCommandCenterActions(): void {
|
||||
const keyboardActionDispatcher = useKeyboardActionDispatcher();
|
||||
const { t } = useTranslation();
|
||||
const selection = useActiveWorkspaceSelection();
|
||||
const serverId = selection?.serverId ?? null;
|
||||
@@ -96,7 +97,7 @@ export function useWorkspaceCommandCenterActions(): void {
|
||||
},
|
||||
runGitAction,
|
||||
}),
|
||||
[gitActions, isCompact, overrides, runGitAction, t],
|
||||
[gitActions, isCompact, keyboardActionDispatcher, overrides, runGitAction, t],
|
||||
);
|
||||
|
||||
useCommandCenterActions({
|
||||
|
||||
Reference in New Issue
Block a user