Skip to main content

max / alloy_tui

9.1 KB · 105 lines History Blame Raw
1 # Hardware target: Framework Laptop 12
2
3 The Framework 12 is the first hardware target Alloy is being built against on real metal. This document records what the device is, how the 2-in-1 form factor bends the stack, and every hardware-adjacent decision Alloy has to make earlier than it otherwise would. Companion to [STACK.md]STACK.md.
4
5 Per-device docs are the pattern: this is `HARDWARE-FW12.md`. If Alloy is later validated against a Framework 13, a ThinkPad, or a Star Labs machine, each gets its own file. Cross-device concerns get promoted to a shared doc only when a second device demands it.
6
7 ## Why this device, why now
8
9 The Framework 12 is a 12.2" convertible (360-degree hinge, touchscreen, optional stylus) with the standard Framework expansion-card mainboard, x86_64 Intel silicon, and full Linux firmware support via LVFS. It is repairable, has good Linux upstream driver coverage in current Fedora kernels, and Framework itself validates Fedora as a supported distribution on the device.
10
11 It is also the *most demanding* first target Alloy could pick: convertible hardware forces the project to answer questions a clamshell laptop lets it defer for a year (touch, on-screen keyboard, rotation, tablet-mode input gating). Answering these once, up front, is cheaper than answering them after the design system has already ossified around a keyboard-only assumption.
12
13 ## Alloy's stance on the 2-in-1 form factor
14
15 **Alloy stays keyboard-first, and the FW12 is supported as a laptop.** The fold-to-notes tablet gesture (a stylus notes canvas on hinge fold) was **shelved in the 2026-07-17 pivot**: it needs a stylus GUI (Rnote), which clashes with the TUI-first direction. The "Fold-to-notes" section below is kept as a record and revives only if a tablet UX returns.
16
17 The manifesto commits Alloy to a keyboard-driven tiling environment. A 2-in-1 does not change that thesis. In clamshell use:
18
19 - **Clamshell mode is the entire Alloy experience.** Sway and the full terminal-first stack, unchanged.
20 - **Touch and stylus in clamshell mode are pointer input, nothing more.** Tap to focus a window, drag to scroll, stylus behaves as a pointer. Sway and libinput already do this without Alloy code.
21 - **Folding the screen back does nothing special** now that the notes flow is shelved; the session stays as-is.
22
23 This stance is deliberate. Building a general-purpose touch UI is a years-shaped project (Phosh, GNOME Shell-for-mobile, Plasma Mobile). Alloy is a months-shaped project, and a TUI-first one; a custom tablet shell is out of scope.
24
25 ## Display
26
27 - **Native panel:** 12.2" 1920x1200 (16:10), matte, IPS-class, ~185 PPI. Sits in the awkward middle where 1.0x is too small and 2.0x is too big.
28 - **Alloy default scale:** 1.25x fractional under sway (`output eDP-1 scale 1.25` in the sway config's per-machine drop-in). sway handles the compositor side; terminal apps scale with the compositor, so there is no per-app fractional-scale work as there would have been for egui. Verify glyph crispness at v0 sanity check.
29 - **Contrast/color:** validate the DESIGN-LANGUAGE.md dark-mode L stops on this panel specifically (currently deferred in `todo.md`). Matte 400-nit IPS is roughly the panel class most Alloy users are likely to have; if the tokens miss here, they miss for the base audience.
30
31 Rejected: 1.0x default (glyphs too small at arm's length on 12.2"), 1.5x default (wastes usable columns in a scrollable-tiling model where horizontal density matters).
32
33 ## Touch and stylus as pointer
34
35 Touch and stylus both work out of the box on Wayland via libinput. Sway routes them to clients as pointer events. No Alloy code required for the base case.
36
37 - **Touch:** tap to focus, drag to scroll. Sway's built-in touch handling covers workspace-switch gestures.
38 - **Stylus:** USI 2.0 supported by the FW12 panel. Routes through libinput's tablet-tool path as pointer input. Pressure and tilt are available to any client that asks; Alloy's own widgets do not consume them.
39 - **Palm rejection:** handled by libinput. No Alloy work.
40
41 `alloy_tui` does not ship a Touch/Pointer input-mode split; a TUI is keyboard-first by nature and terminal apps take pointer input only incidentally. If touch ergonomics ever matter, revisit, but not preemptively.
42
43 ## Fold-to-notes (SHELVED)
44
45 **Shelved in the 2026-07-17 pivot** (TUI-first clashes with a stylus GUI). Kept as a record; the `alloy-hinged` daemon, the notes workspace, and the Rnote pick below are not on the roadmap and revive only if a tablet UX returns. The niri IPC calls below are historical.
46
47 The kernel exposes hinge state via `SW_TABLET_MODE` on Framework's ACPI/EC path. The shelved design consumed it for one purpose: switching to a dedicated notes workspace on fold, and back on unfold.
48
49 **Behavior:**
50
51 - On fold: `niri msg action focus-workspace notes`. If the notes app is not already running on that workspace, spawn it. Fullscreen it.
52 - On unfold: `niri msg action focus-workspace previous` (or the named workspace the user was on before).
53 - Notes app keeps running in the background between folds. State preserved by the app's own autosave, not by Alloy.
54
55 **Notes app pick: Rnote.** Rust, GTK4, purpose-built for stylus free-hand notes. Ships in Fedora repos. Infinite canvas, pressure and tilt, eraser, autosave, export to PDF/SVG. Fits Alloy's Rust-forward posture and the workflow exactly.
56
57 Rejected: Xournal++ (mature but heavier and more PDF-annotation-shaped than free-writing-shaped), a custom egui note app (real design-system win but a marquee-app-sized project for a feature Rnote already solves well; revisit only if Rnote hits a wall).
58
59 **Daemon.** Small user-session Rust binary, single-purpose. Reads `SW_TABLET_MODE` transitions (via evdev or `iio-sensor-proxy`) and issues Niri IPC commands. Approximately 100 LOC. Ships as a systemd user service. Named `alloy-hinged` (working name).
60
61 Not a general "device-adaptation layer"; deliberately single-purpose. If rotation, OSK, ambient light, or lid handling ever become real needs, they get their own daemons or get absorbed here with intent; not preemptively scaffolded.
62
63 **Physical keyboard and trackpad when folded.** The kernel usually suppresses these on `SW_TABLET_MODE` transitions, but behavior varies by device. Verify on the FW12 specifically. If it doesn't, one extra libinput toggle in `alloy-hinged` on fold/unfold covers it.
64
65 **Auto-rotation: deferred.** Rnote's infinite canvas makes landscape fine; no portrait requirement. If a user asks for it later, `iio-sensor-proxy` + a few lines in `alloy-hinged` adds it.
66
67 ## Fingerprint reader
68
69 Framework 12 ships a fingerprint reader on the power button. Upstream Linux support is via `libfprint`; enrollment through `fprintd`. Fedora Silverblue includes the stack.
70
71 - Alloy configures PAM to allow fingerprint at sudo and at the lockscreen.
72 - Fingerprint unlock wires through swaylock's PAM stack (the authored egui lockscreen was dropped in the pivot). No Alloy code beyond PAM config.
73
74 ## Firmware (fwupd / LVFS)
75
76 Framework publishes firmware via LVFS. Fedora Silverblue ships `fwupd` and enables LVFS by default.
77
78 Alloy's contribution: nothing new, but the installer/setup flow should verify `fwupdmgr get-devices` succeeds and prompt for `fwupdmgr update` on first boot. A first-boot Alloy device with stale firmware is a bad first impression on a laptop this dependent on EC updates.
79
80 ## Power management
81
82 - **Suspend model:** s2idle (Modern Standby / S0ix) only. S3 is not available on the platform. Idle drain during s2idle has historically been a Linux pain point on Intel; Fedora's `power-profiles-daemon` + tuned defaults are the current best baseline. Track s2idle drain as an open concern; do not layer TLP on top of ppd.
83 - **Profiles:** default to `balanced`. Expose profile switching via the `alloy` console (an `alloy power` verb, or within `alloy display`), not a dedicated power tool.
84 - **Lid close:** suspend, standard.
85
86 ## Wi-Fi, Bluetooth, webcam, audio
87
88 All expected to work with in-tree Fedora kernel drivers. No Alloy-specific handling planned. If a specific chipset in the FW12 turns out to need out-of-tree firmware, add a note here and to the image-composition manifest.
89
90 Physical camera and microphone switches are on the chassis (Framework standard). Alloy does not need to plumb software mute: the hardware switch is authoritative.
91
92 ## Expansion cards
93
94 Framework's expansion-card system is a hardware concern, not a software one, but Alloy should:
95
96 - Not assume a fixed USB-C port layout. UI that talks about "the left port" is wrong on a Framework.
97 - Handle hot-plug of storage expansion cards cleanly (this is a udev + userspace-mount concern, mostly not Alloy's).
98
99 ## Open questions
100
101 - [ ] fprintd unlock through swaylock's PAM stack on the FW12: enroll, then verify unlock at swaylock and at sudo.
102 - [ ] Fractional-scale validation at 1.25x on this panel under sway: do terminal glyph metrics stay crisp?
103 - [ ] s2idle drain measurement on FW12 running the Alloy image, baseline vs. tuned. If drain is bad enough to matter, revisit whether Alloy ships any power tweaks or leaves it to Fedora defaults.
104 - [ ] shelved The `alloy-hinged` fold-to-notes questions (keyboard/trackpad suppression on `SW_TABLET_MODE`, Rnote fullscreen behavior) revive only if the tablet flow comes back.
105