# Panel landscape on the keyboard case — 2026-10-13 Board: the second T-Display-K230, on a non-persistent trial (`switch-to-configuration test`) of the landscape system built from `.#kernelMainlineDrmShellLandscapeBootFiles`. A reboot returns it to the installed portrait image. Kernel 7.3.0-rc5. Sway output `DSI-1`, `mode 568x1232 transform 270`, logical size 1232x568. Each file below is labelled with its evidence class. Classes are not interchangeable: a host render is not a board capture, an injected touch is not a finger, and a native capture is not what the glass looks like. ## Host renders (`host/`) `cargo run --release --example render_responsive_evidence -- ` in `nix/rust-shell-client`, which now also renders Shade, Power and Help and adds 1232x568. Before the layout fixes the landscape Home had one icon row, the Shade ended above its notification list, and Help shrank to half size. After them, every portrait and HDMI render (568x1232, 768x1024, 1080x1920, 1920x1080; Home, Drawer, Settings, Shade, Power, Help, wallpaper) is byte-identical to the same harness built from `0804c0aa`; only `home`, `shade` and `help` at 1232x568 differ. ## Native board captures (`board/`) `grim` on the board at native resolution, 2026-10-13 between 08:17 and 08:40 CDT. | File | How the surface was reached | | --- | --- | | `home.png` | Home after the startup terminal was moved to the scratchpad. The 4x2 clock widget fits the two-row landscape page. | | `drawer-cli.png`, `shade-cli.png`, `settings-cli.png` | `k230-shell-rust --surface drawer|shade|settings`. `k230-shell-rust` RSS stayed 102-111 MB across them. | | `keyboard-search-injected.png` | Injected tap on the drawer's search field, then an injected tap on the 240 px landscape keyboard's `w`. | | `drawer-bottom-swipe-injected.png` | Injected bottom-edge swipe on Home, after the card shell fix. | | `overview-bottom-swipe-injected.png` | Injected bottom-edge swipe from the open drawer: the card overview with its shrunk landscape card. | | `shade-top-pull-injected.png` | Injected top-edge pull-down. | Injected touches come from `tools/inject-tap.sh` on an `evemu-device` clone of the real controller, converted from landscape logical `(x, y)` to panel `(px, py) = (y, 1232 - x)`. They prove routing from libinput onward, not the glass. ## Camera (`camera-2026-10-13T0852.jpg`) One C920 frame from the bench camera at the device's top edge, rotated 180° to the typist's view. The panel is landscape above the keyboard, with the drawer upright from the keyboard side. It shows orientation only, not touch. ## Operator, real glass - Before the card-shell fix: "gestures to open the app drawer in the current layout don't seem to work. nor settings drawer". - After it: "my gestures work on the home screen now but i can't swipe up to show the cards now either right now". `touch-range.md` gives the cause. - After a live calibration matrix that matches the device-tree correction there: "it works now". ## Defects found and fixed here 1. `k230-shell-rust` was OOM-killed (anon-rss 694 MB) right after `home-configure 1232x568`. A 2-row widget never fitted the one-row landscape page, so `HomeLayout::place_first_fit` added empty pages forever. Reproduced on the host by `place_first_fit_terminates_when_a_widget_is_taller_than_a_page`. 2. The card shell never started in landscape. `cs_default_config(1232, 568)` gave an 80%-tall card that `valid_config` rejects. `ensure_ui` then failed ("card shell requires one Pixman output"), so the bottom-edge drawer swipe, the shade pull-down and the overview were all dead. 3. The touch controller's X range is 0..1079, not 0..1023; see `touch-range.md`. ## Installed on the second board — 2026-10-13 09:40 CDT Bundle `.#kernelMainlineDrmShellLandscapeBootFiles` at `839cba2d` (`48v1rj39…-k230-coherent-shell-boot-files`, system `06biwlw7…`). It differs from the installed portrait boot partition only in `k230-tdisplay.dtb` (sha256 `98beefab…`, `touchscreen-size-x` 0x438) and `bootargs.txt` (sha256 `722b85e4…`, `init=` the landscape system). `Image` and `initrd.uimg` are byte-identical. Both files were copied as `.new`, hash-checked, and renamed into place. The previous pair is kept as `*.portrait-20261013` on `/boot` and in `/var/lib/k230/boot-backup-20261013-portrait/` with the previous profile link. The profile was then set to the landscape system, followed by `sync` and an ordinary `systemctl reboot` with no U-Boot input. After boot (serial log kept privately, plus SSH): 7.3.0-rc5; profile, booted and current system all `06biwlw7…`; the device tree reports `touchscreen-size-x` 1080; no calibration matrix and no trace drop-in; `shell`, `shell-ui` and `theme-helper` active; `running` with no failed units; `k230-shell-rust` RSS 105 MB. `board/installed-home.png` is the native capture. This is not the coherent-shell install tool. The board already ran this repository's own SD image, so only two boot files changed. Rollback: restore the two `*.portrait-20261013` files and the saved profile link, then reboot. From U-Boot, use `ums 0 mmc 1` and do the same from the host. ## Reinstalled with the rotate-once renderer — 2026-10-13 ~10:40 CDT `rotation-performance.md` explains the drawer jank and its fix. The landscape profile now runs the patched wlroots with `WLR_PIXMAN_OUTPUT_TURN=1`. The same two-file install as above put bundle `gb7wd950…` (system `xr7d1339…`) in place. Only the `init=` path in the DTB's `chosen/bootargs` and in `bootargs.txt` changed; `Image` and `initrd.uimg` are identical. After an ordinary reboot: booted, current and profile system `xr7d1339…`; `touchscreen-size-x` 1080; `WLR_PIXMAN_OUTPUT_TURN=1` in sway's environment; no `/run` drop-ins; services active; `running`. Native capture: `board/installed-home-output-turn.png`. The operator: "ok yeah it's plenty fast now". ## Not established here The 1080 width on the first board, the remaining real-glass checks (task 8.6) and HDMI (task 8.7). ## Host renders of the remaining 8.3 surfaces (2026-10-14) `host/` also holds 1232x568 host renders of the Wi-Fi pages, the theme chooser, the open-folder overlay and the shade with several notifications (`wifi-*`, `theme-chooser`, `folder-*`, `shade-*-notifications`), written by cargo run --offline --example render_landscape_surfaces -- in `nix/rust-shell-client`, with fixture data from `evidence_render` (long and short notification text, a critical row, rows with and without a tap action, one long network name, no theme thumbnails). `host/shade-1232x568.png` was regenerated for the new shade layout. These are host renders: they prove the paint and its hit rectangles, not the board's glass. The same example also writes 568x1232 renders; those are not committed, but are byte-identical to the base's (`6aa0795d`). Native captures of these surfaces follow. ## Native captures on the installed image (2026-10-14 04:57–05:00 UTC) System `9lp7f072…` (this branch plus the charger commit), booted, rotate-once renderer. Each file is a native `grim` at 1232x568, taken as user `shell`. Surfaces were opened with `k230-shell-rust --surface ` unless the name says `injected` (an `evemu-event` tap written to the touchscreen's event node; a software proxy, not a finger). | File | Surface | How opened | | --- | --- | --- | | `board/installed-terminal-app.png` | foot terminal, focused app | already open | | `board/installed-drawer.png` | Drawer | CLI | | `board/installed-settings.png` | Settings, three columns | CLI | | `board/installed-power.png` | power sheet | CLI | | `board/installed-help.png` | Help, two columns | CLI | | `board/installed-shade-notifications.png` | shade with four notifications from `k230-notifications emit` | CLI | | `board/installed-wifi-injected.png` | Settings → Wi-Fi, two columns | injected tap on the Wi-Fi row | | `board/installed-wifi-network-injected.png` | saved-network page | injected tap on the network row | | `board/installed-theme-chooser-injected.png` | Settings → Themes, chooser and backgrounds side by side | injected tap on `Themes ›`, captured 12 s later once thumbnails loaded | The two Wi-Fi captures had the connected network's name painted over (`[name removed]`) before commit; everything else is as captured. Reviewed: nothing overlaps or leaves the output; every control named in task 8.3 is on screen. The theme chooser shows a spinner over the first card for the first seconds while backgrounds load; the earlier 2 s capture shows it and was not kept. Home itself is `board/installed-home.png` and `board/installed-home-output-turn.png` above. Still owed for task 8.5: a camera frame from the keyboard side (the bench webcam currently sits at glass level and cannot read the panel). ## Operator real-glass pass (task 8.6), 2026-10-14 On the installed image `9lp7f072…`, asked to open Settings and an app, type on the keyboard base and return Home by finger (Drawer, Shade and the card overview were already reported 2026-10-13), the operator reported: "real finger check worked fine". Evidence class: operator report, real glass; no camera frame. ## Folder, Home widgets and the on-screen keyboard (2026-10-14 05:20–05:32 UTC) For these captures `~shell/.local/state/k230-shell/home.json` was backed up and given a five-game folder and a Battery widget, then restored afterwards. - `board/installed-home-folder-battery-widget.png` (system `9lp7f072…`, 05:26 UTC): Home with Clock, Video, the `Games` folder and Battery (100 %). - `board/installed-folder-open-injected.png`: the folder opened by an injected tap; five members in one row of the wide overlay. - `board/installed-keyboard-before-fix-injected.png`: Drawer search focused by an injected tap. The keyboard is 120 px tall, but the drawer stops its grid ~200 px above it. The cause: wvkbd was started with `-H 240` only. `-H` is its portrait height; on an output wider than tall it uses `-L`, which defaulted to 120, while the shell and the compositor reserve `keyboardHeight` (240) plus the 56 px grip. The faint folder behind the translucent drawer is from the previous capture. - `board/installed-keyboard-injected.png` (system `s53ywx90…`, 05:32 UTC): after `nix/shell.nix` passes `-L` with the same value. wvkbd runs as `wvkbd-mobintl -H 240 -L 240`, the keyboard and its grip fill exactly the reserved band, and the drawer grid ends at the grip. The same change gives a landscape HDMI monitor under the portrait profile a keyboard of `keyboardHeight` (400) instead of 120, matching what the shell and compositor already reserved there; that is not yet seen on a monitor (task 8.7).