diff --git a/CHECKPOINT-display-and-icons.md b/CHECKPOINT-display-and-icons.md new file mode 100644 index 0000000..ac1f133 --- /dev/null +++ b/CHECKPOINT-display-and-icons.md @@ -0,0 +1,103 @@ +# Checkpoint — Linux display compatibility + icon alpha fixes (2026-09-09) + +## Where things are +- Project: `/home/avi/Projects/Keynctr` +- Branch: `master` @ **`d580139`** ("fix(icons): true alpha channel, no white matte or + white tile") on top of **`0814a53`** ("fix(linux): work on X11, Wayland, and Hyprland"). +- Working tree: **clean for tracked files.** Untracked leftovers are the pre-existing + hygiene entries (`.directory`, `.impeccable/`, `.opencode/`, `COSMIC_THEME.md`, + `src/publish.rs.bak`, `src/signer/nip46_external.rs`) plus `deferred/SignerConnectionPanel.tsx.wip` + (a broken WIP component, moved out of the build — see below). Original white-background + icons are preserved under `deferred/original-icons/` (tracked). + +## What was completed (this session) + +### 1. Linux display-server compatibility — `0814a53` + +The app did not start on a friend's Wayland machine. Root causes found and fixed: + +- **No explicit platform choice.** Hyprland (and any Wayland session with XWayland) + exports both `$DISPLAY` and `$WAYLAND_DISPLAY`, so Electron must be told which + backend to use before Chromium initializes. `frontend/electron/main.ts` now sets + `ozone-platform` (wayland/x11) from `XDG_SESSION_TYPE`/`WAYLAND_DISPLAY` at module + load, with `KEYNCTR_FORCE_X11=1` / `KEYNCTR_FORCE_WAYLAND=1` overrides. +- **GPU process crashes (SIGSEGV in `eglCreateWindowSurface`, Mesa `libGLESv2`).** + Reproduced on this box (Intel Iris Xe, Hyprland, mesa 26.2.1): with hardware GL the + GPU helper died repeatedly and the window never appeared. Fix: **software rendering + by default on Linux** (`app.disableHardwareAcceleration()`); hardware GL is opt-in + via `KEYNCTR_ENABLE_GPU=1`. +- **Startup watchdog + bounded relaunch ladder.** A marker file + (`/keynctr-startup.json`, stamped clean on deliberate quit) records each launch; + if the previous process died before its window proved itself (painted and survived + 8 s), the next launch advances one rung: detected platform → other platform → GPU + opt-in → other+GPU, then stops with an error dialog listing the escape hatches. + AppImage-safe relaunch via `$APPIMAGE`. No infinite cascades. +- **Sandbox pre-flight.** Packaged builds check for a non-setuid `chrome-sandbox` + combined with blocked unprivileged user namespaces (Ubuntu 24.04 AppArmor knob, + `unprivileged_userns_clone`) and fall back to `--no-sandbox` instead of dying + silently. Root also gets `--no-sandbox` as Chromium requires. +- Window now uses `show: false` + `ready-to-show` (always shown, even with the + watchdog disabled). + +### 2. Icon white-fringe fix — `d580139` + +The source icons were grayscale (mode **L**, no alpha at all): a black bird on a flat +white field, which rendered as a white box/halo on every non-white surface (window +icon, taskbar, sidebar, launchers). + +- `frontend/public/icon.png` and `frontend/src/assets/logo.png` regenerated as + **RGBA**: alpha = ink coverage of the original artwork; RGB forced to 0 everywhere, + so no white matte can bleed through semi-transparent edge pixels (verified: 0 pixels + with RGB > 200 at alpha < 20). Artwork bbox/shape unchanged (IoU 1.0 vs originals). +- `frontend/src/styles.css`: `.sidebar-logo` dropped its `background: #fff` white tile, + `border-radius`, and `object-fit: cover`; the artwork now composites directly with + `contain`. Dark-theme `invert(1)` kept (ink artwork must flip on dark sidebars). +- Originals preserved: `deferred/original-icons/icon-public-512-white.png`, + `deferred/original-icons/logo-sidebar-338-white.png`. + +### 3. Build hygiene (uncommitted by design? no — landed with the fixes) + +- `frontend/src/components/signer/SignerConnectionPanel.tsx` was an untracked, + non-compiling WIP (broken `useCallback` closures, APIs that don't exist on + `SignerManager`, dependency on uninstalled `react-router-dom`) that blocked + `npm run typecheck`. Moved intact to `deferred/SignerConnectionPanel.tsx.wip` + (untracked) — nothing deleted; it needs a rewrite against the real hooks before + returning. + +## Verification (all run this session) + +- Rust: `cargo fmt --check` clean, `cargo clippy --all-targets` clean, `cargo test` + green, `cargo build --release` succeeded. +- Frontend: `npm run electron:build`, `npm run typecheck`, `npm run lint` clean; + `npm test` **116/116 passed**; `npx prettier --check electron/main.ts` and + `src/styles.css` clean; `npm run build` succeeded. (5 pre-existing Prettier warnings + in untouched files — `ExportSecretKeyModal.tsx`, `SignerModeScreen.tsx`, + `AppProvider.tsx`, `ExportSecretKey.test.tsx`, `fakeBackend.ts` — predate this + session and were left alone.) +- **On-device (Hyprland/Wayland, this machine):** app launched under a clean systemd + user scope: Keynctr window mapped (`class: keynectr`), watchdog marker cleared + (= config proven), **no new Electron core dumps** after 19:40 while multiple + software-render launches ran. `grim` screenshot + visual inspection confirmed the + sidebar bird sits directly on the sidebar with **no white tile, border, or halo**. +- Icon proof: checkerboard composite of the new `public/icon.png` shows clean + anti-aliased edges into transparency, no white fringe. + +## How to run / reproduce + +- GUI: `cd frontend && npm start` (or the packaged AppImage/deb once rebuilt via + `npm run dist`). +- Escape hatches: `KEYNCTR_FORCE_X11=1`, `KEYNCTR_FORCE_WAYLAND=1`, + `KEYNCTR_ENABLE_GPU=1`, `KEYNCTR_DISABLE_GPU=1`, `KEYNCTR_NO_RELAUNCH=1`. +- CLI: `cargo run --release -- serve` (JSON-lines IPC) as before. + +## Outstanding / next steps + +- **Repackage for the friend:** `npm run dist` (AppImage + deb) with the new icon and + display fixes; the old `frontend/release/` artifacts predate both commits. +- `deferred/SignerConnectionPanel.tsx.wip`: rewrite against the real `useSignerManager` + API (+ either add `react-router-dom` or drop the import) before reinstating. +- Consider a taskbar-visible test on a pure-X11 session and on GNOME Wayland for the + friend matrix (only Hyprland/Wayland was verifiable here). +- Step 3 sub-step 2 (IPC reroute) is untouched and remains the next signer milestone. +- The user's crash-reporter still holds old core dumps from pre-fix launches + (`coredumpctl rm` clears them).