atagen

monolith

public
Star0
Watch0
b001ce7817edaa5aa390e22c424edecab96d7f0a
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: design/review-2026-10-19.md

189b5d01e76fatagen2026-10-19 07:07 UTC1
# Review, 2026-10-19
189b5d01e76fatagen2026-10-19 07:07 UTC2
189b5d01e76fatagen2026-10-19 07:07 UTC3
A whole-compositor pass after the memory work. Four reviewers covered protocols and client behaviour, backend and pacing, the Vulkan renderer, and the WM core. Each read plan.md, decisions.md, parked.md, review-notes.md and the test checklist first, so what follows is unmapped unless marked. The high items were rechecked against the code. Items marked (verify) rest on client or driver behaviour that was not tested.
189b5d01e76fatagen2026-10-19 07:07 UTC4
189b5d01e76fatagen2026-10-19 07:07 UTC5
## Broken for users today
189b5d01e76fatagen2026-10-19 07:07 UTC6
189b5d01e76fatagen2026-10-19 07:07 UTC7
1. **Popups.** `xdg.rs` `grab` is empty, so menus never get `popup_done` and stay open when you click elsewhere. Positioners use `get_geometry()` and never unconstrain, so menus near an edge go off screen. `scene.rs` draws popups inside their window's z-slot, so a menu from the left tile is hidden and unclickable under the right one.
189b5d01e76fatagen2026-10-19 07:07 UTC8
2. **Drag and drop.** `seat.rs` `dnd_requested` cancels every source. No tab tear-off, no file drags, no text drags.
189b5d01e76fatagen2026-10-19 07:07 UTC9
3. **X11 and Wayland clipboards are separate.** `XwmHandler` implements none of the selection hooks, and smithay's default refuses access. Copy and paste between Steam, Wine or Java and Wayland apps fails both ways.
189b5d01e76fatagen2026-10-19 07:07 UTC10
4. **Hide-to-tray leaves a blank tile.** Nothing treats a null-buffer commit as an unmap, so Telegram, Discord and Steam keep their slot and focus with nothing drawn, then remap without going through `map_window`.
189b5d01e76fatagen2026-10-19 07:07 UTC11
5. **Fullscreen asked for before the first commit is lost.** `set_fullscreen` needs a mapped window id and `map_window` never reads the pending state. The X11 path ignores `_NET_WM_STATE_FULLSCREEN` at map. mpv `--fs`, SDL and Wine games start windowed. `fullscreen_request` also ignores its output argument.
189b5d01e76fatagen2026-10-19 07:07 UTC12
6. **A fullscreen window hides its own dialogs.** Fullscreen is raised last, frame callbacks go only to the covering window, and new windows still take focus. A save dialog from a fullscreen game is invisible yet focused, and `focus left` walks into covered tiles.
189b5d01e76fatagen2026-10-19 07:07 UTC13
7. **VRR content frames wait on the cursor cap.** In `drm.rs` `schedule`, an armed cursor-wait timer makes a later content commit bail on `scheduled.is_some()`, so a fullscreen VRR game is held to the cursor cadence while the mouse moves. `draw`'s one-refresh retry timer has the same shape.
189b5d01e76fatagen2026-10-19 07:07 UTC14
8. **Monitor unplug and replug.** The `GlobalId` from `create_global` is dropped and never removed, so clients keep phantom outputs and see duplicates on replug. Layer and lock surfaces stay on the dead `Output`. `DrmScanEvent::Changed`, which smithay-drm-extras emits for the EDID race, falls into `_ => {}`. A failed `initialize_output` is never retried and there is no rescan on VT return, so a monitor can stay dark until the next hotplug.
189b5d01e76fatagen2026-10-19 07:07 UTC15
9. **A failed frame can wedge an output.** After a `render_frame` or `queue_frame` error, `redraw` is reset to `animating`. A lost flip leaves `queued` true forever, with no watchdog.
189b5d01e76fatagen2026-10-19 07:07 UTC16
10. **Output scale is fixed at 1.** `Scale::Integer(1)` is hard-coded, there is no scale option, and neither fractional-scale nor viewporter is advertised. A HiDPI panel is unusable, and Xwayland's RandR emulation for games that pick a non-native mode needs viewporter (verify).
189b5d01e76fatagen2026-10-19 07:07 UTC17
189b5d01e76fatagen2026-10-19 07:07 UTC18
## Missing protocols, by what clients lose
189b5d01e76fatagen2026-10-19 07:07 UTC19
189b5d01e76fatagen2026-10-19 07:07 UTC20
- **wp_presentation, fifo-v1, commit-timing.** mpv display-sync, Mesa WSI present-wait and Proton FIFO pacing all fall back to frame-callback guesses. DRM already has exact flip times to feed it.
189b5d01e76fatagen2026-10-19 07:07 UTC21
- **xdg-foreign and xdg-dialog.** Portal file choosers arrive with no parent, so they tile and reshuffle the layout.
189b5d01e76fatagen2026-10-19 07:07 UTC22
- **text-input-v3, input-method-v2, virtual-keyboard, virtual-pointer.** No fcitx5 or ibus, no CJK input in Electron, no wtype or on-screen keyboards.
189b5d01e76fatagen2026-10-19 07:07 UTC23
- **Output power (wlr-output-power-management or an IPC command).** Monitors can never be blanked, and idle-notify has nothing to act on.
189b5d01e76fatagen2026-10-19 07:07 UTC24
- **Touch, tablet, pointer-gestures, switch events, keyboard LEDs.** All dropped in `drm.rs` `on_input`. Lid close does nothing and Caps Lock never lights.
189b5d01e76fatagen2026-10-19 07:07 UTC25
- **security-context.** Data-control, session-lock, capture and foreign-toplevel are open to every client, sandboxed ones included.
189b5d01e76fatagen2026-10-19 07:07 UTC26
- **KDE server-decoration.** Promised in decisions.md but not advertised.
189b5d01e76fatagen2026-10-19 07:07 UTC27
- **wlr-screencopy.** Older recorders and OBS plugins only speak that.
189b5d01e76fatagen2026-10-19 07:07 UTC28
- **Per-surface dmabuf feedback with a scanout tranche.** Fullscreen clients are never steered to plane-capable modifiers, and window elements are `Kind::Unspecified`, so overlay-plane scanout can never trigger on Intel or AMD.
189b5d01e76fatagen2026-10-19 07:07 UTC29
189b5d01e76fatagen2026-10-19 07:07 UTC30
## Wrong or wasteful behaviour
189b5d01e76fatagen2026-10-19 07:07 UTC31
189b5d01e76fatagen2026-10-19 07:07 UTC32
- Frame callbacks are never sent to X11 override-redirect surfaces or client cursor surfaces, so animated cursors freeze and X11 menus may stop updating (verify).
189b5d01e76fatagen2026-10-19 07:07 UTC33
- A paused session re-arms the deadline timer at refresh rate, because `render_surface` returns before clearing `redraw`. On resume the vblank grid and `target_ns` are stale, the first frame logs a miss and adds slack for 30 s.
189b5d01e76fatagen2026-10-19 07:07 UTC34
- Redraw and animation state are global. Any commit, even from a hidden tag, recomposes every output, and an animation on one monitor keeps a fullscreen VRR output recomposing.
189b5d01e76fatagen2026-10-19 07:07 UTC35
- `layout.arrange` rebuilds the arrangement per output on every pointer motion, several times per frame and per drag event, and `identity()` allocates two Strings per root commit.
189b5d01e76fatagen2026-10-19 07:07 UTC36
- Window capture keeps streaming while the session is locked. Output capture is safe.
189b5d01e76fatagen2026-10-19 07:07 UTC37
- The pointer cursor is never reset when it leaves a client, so a hidden or I-beam cursor persists over gaps, layers and Xwayland.
189b5d01e76fatagen2026-10-19 07:07 UTC38
- Client move, resize, maximize and minimize requests are ignored on both xdg and X11, while the default wm_capabilities still advertise them, so titlebar buttons are dead.
189b5d01e76fatagen2026-10-19 07:07 UTC39
- `Suspended` and `configure_bounds` are never sent. Browsers on hidden tags keep decoding.
189b5d01e76fatagen2026-10-19 07:07 UTC40
- The 300 ms first-buffer timeout consumes `natural_size` even with no buffer yet, so a slow dialog floats at the 60 % default forever.
189b5d01e76fatagen2026-10-19 07:07 UTC41
- Floats are second class. They are never resized on client request, never clamped on drag, never rescaled when the output area changes, and X11 `configure_request` is ignored.
189b5d01e76fatagen2026-10-19 07:07 UTC42
- Urgency is dropped for visible windows, and there is no per-window urgent anywhere.
189b5d01e76fatagen2026-10-19 07:07 UTC43
- Window rules only cover tag, output, floating, sticky and scratchpad, and run once at map, before many apps set their real title.
189b5d01e76fatagen2026-10-19 07:07 UTC44
- Config errors are invisible. Reload replies `Ok` with warnings, and a TOML syntax error at startup silently replaces the whole config, binds included, with the default.
189b5d01e76fatagen2026-10-19 07:07 UTC45
- IPC addresses only the focused window and active output, and subscribe sends whole snapshots with no event kind, so window switchers and bars cannot target windows or learn what changed.
189b5d01e76fatagen2026-10-19 07:07 UTC46
- Duplicate binds (`Mod+h` and `Super+h`) resolve alphabetically without a warning. Binds die on the lock screen, media keys included.
189b5d01e76fatagen2026-10-19 07:07 UTC47
- The nested backend ignores host focus leave, so a modifier held while alt-tabbing out stays stuck.
189b5d01e76fatagen2026-10-19 07:07 UTC48
189b5d01e76fatagen2026-10-19 07:07 UTC49
## Renderer
189b5d01e76fatagen2026-10-19 07:07 UTC50
189b5d01e76fatagen2026-10-19 07:07 UTC51
- Every shm upload is its own queue submit. A frame uploading more than eight surfaces can skip right past the window `absorb_submit_stall` aims for, letting the NVIDIA 1024th-submit stall land mid-frame. Batch uploads into one submit.
189b5d01e76fatagen2026-10-19 07:07 UTC52
- No wait has a timeout and `ERROR_DEVICE_LOST` maps to `Interrupted`. Reap treats failed fence queries as signalled. A GPU hang blocks the main thread forever, and a lost device spins warnings over a frozen screen.
189b5d01e76fatagen2026-10-19 07:07 UTC53
- Pipelines compile lazily mid-frame with no `VkPipelineCache`, so the first spawn animation hitches.
189b5d01e76fatagen2026-10-19 07:07 UTC54
- Blending is always on and opaque regions are ignored.
189b5d01e76fatagen2026-10-19 07:07 UTC55
- Barriers are `ALL_COMMANDS` to `ALL_COMMANDS`, one call per image, and every upload waits on all earlier queue work.
189b5d01e76fatagen2026-10-19 07:07 UTC56
- Screencopy to shm allocates a fresh full-size image per frame, waits twice on the main thread, copies twice and reports full damage.
189b5d01e76fatagen2026-10-19 07:07 UTC57
- Formats are 8-bit RGB only. Multi-plane modifiers are dropped, which loses Intel CCS and AMD DCC compression. There is no NV12 or P010 for video, and no 10-bit SDR.
189b5d01e76fatagen2026-10-19 07:07 UTC58
- Shm damage collapses to one bounding box, so a cursor blink plus a clock copies most of the buffer.
189b5d01e76fatagen2026-10-19 07:07 UTC59
- The device block is still 256 MiB of VRAM reserved on first use.
189b5d01e76fatagen2026-10-19 07:07 UTC60
- Layouts are recorded as changed before submit succeeds, and a failed submit leaks the command buffer.
189b5d01e76fatagen2026-10-19 07:07 UTC61
- `copy_texture` would read a sample-only dmabuf import without `TRANSFER_SRC` (latent).
189b5d01e76fatagen2026-10-19 07:07 UTC62
- The attachment view of X-format targets carries the alpha swizzle (verify against the dynamic-rendering VUIDs).
189b5d01e76fatagen2026-10-19 07:07 UTC63
- `y_inverted` dmabufs are ignored. `has_dmabuf` is all-or-nothing over five extensions.
189b5d01e76fatagen2026-10-19 07:07 UTC64
189b5d01e76fatagen2026-10-19 07:07 UTC65
## Structure and readability
189b5d01e76fatagen2026-10-19 07:07 UTC66
189b5d01e76fatagen2026-10-19 07:07 UTC67
- `apply_layout` is still about 150 lines. Its glide and summon diff should be a pure, testable function, and "mutate layout, then call apply_layout" is an unenforced protocol across about 36 sites.
189b5d01e76fatagen2026-10-19 07:07 UTC68
- `CompositorHandler::commit` does eight jobs and looks the window up twice. review-notes item 1 is closed but the role-based routing it proposed never landed.
189b5d01e76fatagen2026-10-19 07:07 UTC69
- `drm.rs` mixes session, connectors, output config, pacing and libinput. `Surface` has 17 fields, `render_surface` is 130 lines, and one lookup pattern repeats eight times. Split it into session, outputs, present and input modules.
189b5d01e76fatagen2026-10-19 07:07 UTC70
- `renderer/mod.rs` is about 900 lines. Recording, transfer and the trait impls want their own modules. The staging pool lives in `image.rs`, which makes `device` and `image` depend on each other, and its destroy-and-free sequence is written three times.
189b5d01e76fatagen2026-10-19 07:07 UTC71
- Animation vocabulary (`Transition`, `Effect`) lives in the renderer crate.
189b5d01e76fatagen2026-10-19 07:07 UTC72
- The fullscreen toggle is written three times (xdg, xwayland, toplevels) and the root-surface walk twice. `x11_window_id` is a linear scan beside `by_surface`. Output setup and the end-of-render tail are duplicated between drm and nested.
189b5d01e76fatagen2026-10-19 07:07 UTC73
- There are three unrelated types named `Kind`, and the CLI `Backend` enum shadows `backend::Backend`. config depends on ipc, which depends on layout, just to share `Command`.
189b5d01e76fatagen2026-10-19 07:07 UTC74
- `layer_commit` locks every output's layer map on every commit, and `reserve_layers` ends in `sync_focus` even when nothing changed, so a 60 Hz bar reruns focus sync at 60 Hz.
189b5d01e76fatagen2026-10-19 07:07 UTC75
- Failures are swallowed in many places, including `scheduled = token.ok()`, which stops an output drawing with no log line. `Staging::bytes_mut` returns an empty slice on a failed map and `stage_rows` then panics.
189b5d01e76fatagen2026-10-19 07:07 UTC76
- Slow spans go to stderr and skip the file log. There is no panic hook and no SIGTERM handling, so logout skips socket and X11 lock cleanup. `monolith.log` at the repo root is tracked in git.
189b5d01e76fatagen2026-10-19 07:07 UTC77
189b5d01e76fatagen2026-10-19 07:07 UTC78
## Stale docs
189b5d01e76fatagen2026-10-19 07:07 UTC79
189b5d01e76fatagen2026-10-19 07:07 UTC80
- parked.md says xdg dialogs with a parent tile like any window, but `xdg.rs` floats them.
189b5d01e76fatagen2026-10-19 07:07 UTC81
- review-notes.md item 1 is marked closed although commit routing by role was not done.
189b5d01e76fatagen2026-10-19 07:07 UTC82
- plan.md says DRM gets presentation feedback, but only the nested host side exists.
189b5d01e76fatagen2026-10-19 07:07 UTC83
189b5d01e76fatagen2026-10-19 07:07 UTC84
## Already mapped, not counted
189b5d01e76fatagen2026-10-19 07:07 UTC85
189b5d01e76fatagen2026-10-19 07:07 UTC86
M8 tearing, pointer constraints, relative pointer and shortcuts inhibit. Gamma, HDR, output management and hybrid GPUs under Later. The NVIDIA submit stall, direct scanout setup cost, SCHED_RR needing CAP_SYS_NICE, wlr-foreign-toplevel minimize, X11 stacking, parent and cgroup launch ranking, and the state-split move of `apply_layout`.