Scale stage 3: shortcuts service + Ctrl/Cmd +/-/0 for the scale
Groundwork for the vim-style bindings planned next: the app previously had NO
keyboard abstraction — `event.metaKey || event.ctrlKey` copy-pasted inline in
six places, no typing-target guard anywhere, every window root matching keys
by hand.
New @core/shortcuts.service.ts owns:
- isMod() (also accepts MouseEvent — Mod+click toggle-select uses the same
rule) and isTypingTarget();
- ONE declarative keymap: resolve(event, scope) -> ShortcutId | null, scoped
main / editor / manager. Layout rules are encoded once: digits, +/- and
Alt-letter chords match on event.code (AZERTY digit rows, layouts where '+'
needs Shift, macOS Option-Z producing Ω); plain letter chords match on
event.key so they follow the user's layout.
Both app.ts, both editor-window.ts and both connection-manager.ts now resolve
through the service and switch on ids — behaviour-preserving for every
existing shortcut, including the deliberate quirks (Ctrl+Tab never meta
because Cmd-Tab is the macOS app switcher; Cmd+9 = last tab; editor Mod+W is
the Windows/Linux arm, macOS routes via the app menu). Escape and Tab stay
component-local on purpose: their meaning is per-window state (find bar open?
close prompt up? caret in the textarea?), not a global binding. The file
panels keep their contextual key state machine but delegate modifier tests.
On top of the table: Ctrl/Cmd +/-/0 steps/resets the interface scale in every
window kind, all three previously unclaimed. isTypingTarget is applied
per-shortcut, not globally in resolve(): the scale keys must not fire while
typing ('-' in a rename prompt must type '-'), but the editor WANTS Mod+S
mid-typing and the tab shortcuts keep their existing reach.
Docs: architecture.md's density prose now describes the uiScale lever;
gotchas.md gains the scale section — the disassembly evidence that native
page zoom is an empty stub on Linux (so nobody tries it again), the
everything-must-be-rem rule, the skinfix-outranks-variants trap the harness
caught (48px close button silently 29px), and the px-mirrors-in-TS class of
bug with the remPx() remedy.
Verified: tsc + build clean; live boot with the user's real legacy settings
file migrates textSize:large -> uiScale 1.2 and renders scaled. Not verified
here (needs interaction): the stepper clicks and the shortcut keys themselves.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,38 @@ touching the adjacent code.
|
||||
it** — not even in an HTML comment. A backtick in a comment terminates the
|
||||
literal and the errors point at the prose, not at the quoting.
|
||||
|
||||
## The interface scale (root font-size lever)
|
||||
|
||||
- **electrobun's native page zoom is a silent no-op on Linux — do not reach for
|
||||
it.** `webviewSetPageZoom` in the shipped `libNativeWrapper.so` (v1.18.1, and
|
||||
the `_cef.so`, and the copy in our own build output) is a compiled
|
||||
empty-body stub: the disassembly has no `call` instruction, and
|
||||
`webkit_web_view_set_zoom_level` is not even in the library's imports.
|
||||
`webviewGetPageZoom` returns a hardcoded `1.0` from `.rodata`, so the failure
|
||||
is unobservable through the API — set 2.0, read back "1.0 = success". The
|
||||
JSDoc's "(WebKit only)" means macOS WKWebView. This is why the scale is CSS.
|
||||
- **Everything the UI sizes with must be rem.** The scale works by setting the
|
||||
root font-size, so a px value freezes while everything around it grows. The
|
||||
three px reservoirs were: the panel-chrome tokens (`--row-h` etc.), 93
|
||||
`text-[11px]` arbitraries, and 7.css itself — 370 px values, zero rem, with
|
||||
`--w7-font` reaching only 15 rules' typography. 7like.css's `skinfix` carries
|
||||
a scale bridge re-expressing 7.css's vars and hardcoded box metrics in rem.
|
||||
1px hairlines and focus rects stay px deliberately (crisp at any scale; the
|
||||
`tr` border exists to stop selection shifting rows).
|
||||
- **Restating a 7.css rule in `skinfix` also outranks 7.css's VARIANTS of that
|
||||
rule — by layer, regardless of specificity.** The title-bar-controls
|
||||
restatement silently shrank the close button from 48px to 29px (7.css widens
|
||||
it via `button[aria-label=Close]`), and the tablist padding flattened the
|
||||
active tab's 4px raise. Caught only by the harness pixel diff. When bridging
|
||||
a rule, grep 7.scoped.css for every variant that overrides the same
|
||||
properties and restate those too.
|
||||
- **px constants in TS that mirror rem-sized CSS are latent scale bugs.** The
|
||||
shadlike context menu's `MENU_W = 224` was a hardcoded mirror of `w-56`
|
||||
(14rem): box grew, math didn't, flip fired at the wrong edge. Convert through
|
||||
`@core/metrics` `remPx()` at use time — it reads the LIVE root font-size,
|
||||
and per call, since the scale changes mid-session. The editor's canvas-based
|
||||
`charWidth` is cached keyed on the computed font string for the same reason.
|
||||
|
||||
## The two skin trees (`ui/src/app/skins/`)
|
||||
|
||||
- **`.win7` is not a name we may change.** `7.scoped.css` is precompiled with
|
||||
|
||||
Reference in New Issue
Block a user