From f586d748d6332d1f92bf3b322bb12301beed1b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 22 Aug 2026 15:57:42 +0000 Subject: [PATCH] ctrl+space opens spotlight, and ctrl+? tells you everything else MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fourth chord for the launcher, and the last move is a return: ctrl-space → shift-space → alt-space → ctrl-space. Every one was the owner naming a real collision, and this one is the interesting direction — alt-space is the GNOME window menu, he rebound the desktop to keep it, disliked what he rebound it to, and would rather move the app than the window manager. ctrl-space was ruled out on 2026-08-20 as "focuses the address bar in Brave". That observation was made before anything preventDefault'ed it, and the trade has changed: rebinding a browser is cheaper than rebinding a desktop. Written down in the file, because if the address bar still wins the key never reaches the handler and nothing in this repository can help — the fix would be in Brave. `!ev.shiftKey && !ev.altKey` matters: ctrl+SHIFT+space is the theme browser, and one chord opening both is the bug that needed a capture-phase listener to fix on the theme side. Verified in the built bundle that the two conditions are disjoint. CTRL+? renders every shortcut from a registry, ported in shape from vimazing's gameInfo.ts — controls declared as data, help screen renders them. Its renderer was a recursive `any` walk, right for a game whose help also carries rules and scoring; here the content is one shape, so the renderer is typed and boring and the value is in state/shortcuts.ts. The registry is deliberately NOT authoritative yet, and says so: the handlers still hold their own conditions, so changing a chord here does not move it. Each entry names the file that implements it, so the pair is one search apart. Making it the source of truth is the configurable-shortcuts work, and doing it now would rewrite three handlers for nothing visible. Also removed a line I put in the theme dropdown yesterday promising "alt+space to search every theme by name". Themes are not Spotlight items — that was an instruction for a feature nobody built, sitting in the UI as though it worked. It now points at ctrl+?, which exists. Two comments naming ctrl+alt+space for the theme browser were corrected to ctrl+shift+space with the older chord noted as still accepted. Co-Authored-By: Claude Opus 5 --- .../Dashboard/Layout/DashboardLayout.tsx | 4 + .../Dashboard/Layout/Header/ThemeSwitcher.tsx | 4 +- .../Dashboard/Layout/ShortcutsModal.tsx | 81 +++++++++++ .../Dashboard/Layout/Spotlight/Spotlight.tsx | 25 ++-- src/apps/officer-web/state/shortcuts.ts | 127 ++++++++++++++++++ src/workspaces/theme/src/useThemeKeys.ts | 4 +- 6 files changed, 233 insertions(+), 12 deletions(-) create mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/ShortcutsModal.tsx create mode 100644 src/apps/officer-web/state/shortcuts.ts diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx index b3491b8d..60f27099 100644 --- a/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx @@ -8,6 +8,7 @@ import { Background } from './Background'; import { Header } from './Header'; import { Dock, CORE_DOCK_ITEMS, dockItemsFromPlugins, defaultDockPaths } from './Dock'; import { Spotlight } from './Spotlight/Spotlight'; +import { ShortcutsModal } from './ShortcutsModal'; import { useIsTouch } from './useIsTouch'; import { usePageTitleSync } from '@/state/usePageTitle'; import { RouteGate } from './RouteGate'; @@ -51,6 +52,9 @@ export function DashboardLayout({ children }: DashboardLayoutProps) { {/* Outside the content region on purpose, like the header and the dock: whatever a screen is doing — maximised panel, error boundary, mid-navigation — ctrl-space still gets you off it. */} + {/* Outside the content region for the same reason Spotlight is: ctrl+? has to work from a maximised + panel, an error boundary, or mid-navigation. */} + {/* overflow-CLIP, not hidden: `hidden` still makes this a scroll container, and the nav Dock — absolute, parked below the bottom edge by translateY while hidden — adds its transformed box to the scrollable overflow. So clicking a link let the browser scroll this section ~70px to reveal diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Header/ThemeSwitcher.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Header/ThemeSwitcher.tsx index 0c1c7b86..1a1694e8 100644 --- a/src/apps/officer-web/Screens/Dashboard/Layout/Header/ThemeSwitcher.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Header/ThemeSwitcher.tsx @@ -23,7 +23,7 @@ const { * * ── The overlay ── * - * `ctrl+alt+space` opens a list in the middle of the screen; `j`/`k` move through it and `l` applies the + * `ctrl+shift+space` opens a list in the middle of the screen; `j`/`k` move through it and `l` applies the * focused theme to the app BEHIND it. That is the whole idea, and it is why this is a portal over a * translucent backdrop rather than a modal dialog: you are meant to watch the application change while * you browse, so as little of it as possible should be covered. @@ -90,7 +90,7 @@ export const ThemeSwitcher = () => {
ctrl+shift+←/→ cycle · ctrl+shift+space browse - alt+space to search every theme by name + ctrl+? for every shortcut