Put every shortcut on one shared keymap and make the app keyboard-reachable
The keymap was scattered over ShortcutsService if-chains, the file panel's key switch, macOS-only menu accelerators and hand-typed hints in 16 tooltips x 7 locales, and large parts of the app had no keyboard path at all. src/shared/keymap.ts is now the one table: scopes, per-platform defaults, exact matching, formatting with localized key names, conflicts, reserved combos and native-menu accelerators, proven by keymap.spec.ts. - ShortcutsService resolves against the effective keymap: claim() takes the key (preventDefault, held keys repeat only movement, never mid-IME), and from a text field only chords and F-keys fire. The file panel, App, editor, manager and Settings windows all dispatch through it. - FileActionsService.run is the one file-command dispatcher for the list keys, the row menu, the macOS menu bar and the toolbar. - New keys: the row menu (Shift+F10 / Menu / Ctrl+Return), the source picker (Mod+K), the path bar (Mod+L), transfers (Mod+J), sorting (Alt+1-7), Shift+movement selection, close other tabs, move and disconnect tabs, refresh and edit on Windows/Linux, permissions, copy path, reveal, trash, open in default app, editor find next/previous. - Right-click menus: soft shortcut hints, icons on the everyday verbs (the toolbar's glyphs), section headers, scrolling, item keys while open, a highlighted first item when opened from the keyboard. The panel source picker now renders through the same menu. - Dialogs: role=dialog, a Tab trap via cycleFocus (WKWebView skips buttons on Tab without Keyboard navigation), initial focus, Esc that stops propagating; the chmod dialog takes focus and applies on Enter. - Fixed: Ctrl+Tab also flipped the active panel; Esc in a manager dialog closed the manager; Ctrl-F/T fired Cmd shortcuts on macOS; shortcuts fired under dialogs; keys died after any button click on macOS; the editor's save prompt and find box never got focus; WebView2 reload keys; a window could save default settings before its first load. - Settings closes on its own close-window key (new settingsClose request). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ import { ConnectionsService } from '@core/connections.service';
|
||||
import { ConfirmDialog } from '../dialogs/confirm-dialog';
|
||||
import { PromptDialog } from '../dialogs/prompt-dialog';
|
||||
import { DialogsService } from '@core/dialogs.service';
|
||||
import { blockNativeContextMenu, IS_MAC_CHROME } from '@core/platform';
|
||||
import { blockNativeContextMenu, blockReloadKeys, IS_MAC_CHROME } from '@core/platform';
|
||||
import { RpcService } from '@core/rpc.service';
|
||||
import { SettingsService } from '@core/settings.service';
|
||||
import { ShortcutsService } from '@core/shortcuts.service';
|
||||
@@ -148,12 +148,12 @@ export class ConnectionManager {
|
||||
|
||||
/** Any-window shortcuts (interface scale). Escape has its own binding above. */
|
||||
onWindowKeydown(event: KeyboardEvent): void {
|
||||
const match = this.shortcuts.resolve(event, 'manager');
|
||||
if (!match || this.shortcuts.isTypingTarget(event)) return;
|
||||
event.preventDefault();
|
||||
if (match.id === 'scale-up') this.settings.setUiScale(this.settings.uiScale() + 0.1);
|
||||
else if (match.id === 'scale-down') this.settings.setUiScale(this.settings.uiScale() - 0.1);
|
||||
else if (match.id === 'scale-reset') this.settings.setUiScale(1);
|
||||
const id = this.shortcuts.claim(event, 'manager');
|
||||
if (id === 'close-window') this.close();
|
||||
else if (id === 'scale-up') this.settings.setUiScale(this.settings.uiScale() + 0.1);
|
||||
else if (id === 'scale-down') this.settings.setUiScale(this.settings.uiScale() - 0.1);
|
||||
else if (id === 'scale-reset') this.settings.setUiScale(1);
|
||||
blockReloadKeys(event);
|
||||
}
|
||||
|
||||
blockContextMenu(event: Event): void {
|
||||
|
||||
Reference in New Issue
Block a user