keyboard, and back off the size a quarter step
── keys ── `rfb.ts` already had a `key()` that nothing called. It now has `keysymFor`, mapping `KeyboardEvent.key` to an X11 keysym — `key` rather than `code`, because it is already the character the user's own layout produced and `code` would need that layout re-implemented here to get back to a symbol. Latin-1 passes straight through, above it uses X's 0x01000000 Unicode offset, and the named keys come from keysymdef.h. The canvas is focusable and takes focus on mousedown. Scoping keys to focus is what stops the panel eating keys meant for the rest of the app — this is one panel on a dashboard, so a window listener would be a global keyboard trap. Modified keys and unmapped keys are left alone: cmd-W stays the browser's and Tab keeps moving focus. preventDefault only for keys actually sent. Keys reach wine without a window manager — verified by pressing F2 on the display and watching the board reset. So the README's guess that wine needed a WM to hand it focus was wrong; Auto Options ignores Escape because that VB6 form has no Cancel button, which is a different thing. Corrected there. 20 keysym cases checked against keysymdef.h, including the off-by-one I put in my own test first: XK_F2 is 0xffbf, not 0xffc0. ── size ── Half steps overshot: 2x to 2.5x is too small to too large with nothing in between. Quarter steps from 2x up, which keeps cells whole for the same reason halves did — a 16px grid at 2.25x is a 36px cell — and lets the picture track the panel instead of lurching. Plus a 24px device-pixel margin, because filling the panel edge to edge is most of what "too large" looks like. Also: the scale was ignoring the panel's own CSS `zoom`. `devicePixelRatio` knows nothing about it, so at 75% every cell boundary went back onto fractional device pixels — the exact defect the snapping exists to prevent, reachable from a button in the panel header. Effective ratio is now dpr x zoom, read as getBoundingClientRect().width / offsetWidth. In a 1300x900 device-pixel panel: 2.5x becomes 2.25x, 1260 to 1134 px wide. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: de3ed4e6-f88a-429c-94e6-a760336ba83b
This commit is contained in:
@@ -55,9 +55,14 @@ Worth knowing before you conclude something is broken. Neither is hard to fix; n
|
||||
its own OK button is fine — the run-time error box is — but Extras → Auto Options has neither an OK button
|
||||
nor a Cancel, and its only exit was the title bar. Restarting the sidecar clears it.
|
||||
|
||||
**The panel sends no keyboard events at all.** `MinesweeperPanel` forwards pointer events and nothing else,
|
||||
so Escape does not reach the game and a Custom board cannot be typed in. Adding keys to the RFB client is
|
||||
the smaller half of this; wine also expects a window manager to hand it focus.
|
||||
**Keys go to the canvas, and only while it has focus.** It takes focus on mousedown — the gesture you use
|
||||
to play — and `keysymFor` in `rfb.ts` maps `KeyboardEvent.key` to an X11 keysym. Anything with a modifier,
|
||||
and anything unmapped, is left to the browser rather than swallowed: this is one panel on a dashboard, not
|
||||
a full-screen viewer, so a global key trap would be the wrong shape.
|
||||
|
||||
Keys reach wine perfectly well without a window manager — verified by pressing F2 on the display and
|
||||
watching the board reset. The Auto Options dialog ignoring Escape is that VB6 form having no Cancel button,
|
||||
which is a different thing from keys not arriving.
|
||||
|
||||
## Two things worth knowing before you change anything
|
||||
|
||||
@@ -85,9 +90,16 @@ resizing the panel, and the surround is teal (`-solid`) rather than the root's b
|
||||
**The stage is small because the panel scales it by whole numbers.** Pixel art at a fractional scale gets
|
||||
uneven cells — some three screen pixels wide, their neighbours two — which reads as "not quite right"
|
||||
rather than as blur, and `image-rendering: pixelated` does not help because unevenness is not blur. So the
|
||||
panel snaps the scale, in DEVICE pixels, to whole numbers below 2x and half steps above it. Halves are safe
|
||||
because the unit that has to stay regular is the CELL: at 3.5x a cell is exactly 56 screen pixels, as even
|
||||
as at 3x, and only sub-cell pixels alternate.
|
||||
panel snaps the scale, in DEVICE pixels, to whole numbers below 2x and QUARTER steps above it. Quarters are
|
||||
safe because the unit that has to stay regular is the CELL: the board is a 16px grid, so at 2.25x a cell is
|
||||
exactly 36 screen pixels, as even as at 2x, and only sub-cell pixels alternate. They are quarters rather
|
||||
than halves because coarse steps overshoot — with halves this jumped 2x to 2.5x, too small to too large
|
||||
with nothing in between.
|
||||
|
||||
Two things the scale has to know about that are easy to miss. `devicePixelRatio` is not the whole story:
|
||||
the panel header has its own CSS `zoom`, so the effective ratio is `devicePixelRatio × zoom`, read as
|
||||
`getBoundingClientRect().width / offsetWidth`. And the stage is fitted into the box MINUS a margin, because
|
||||
filling the panel edge to edge is most of what "too large" looks like.
|
||||
|
||||
That makes the size QUANTISED, which is the thing to understand before changing the stage: at 3x the game
|
||||
is the same width whether the stage is 512 or 560. Trimming the surround is worth nothing on its own — it
|
||||
|
||||
Reference in New Issue
Block a user