Skip to content

Fix standalone Nvidia issues found during hardware validation - #5

Merged
Fi3w0 merged 13 commits into
claude/new-session-bppt7lfrom
fiw/testing-fixes
Sep 25, 2026
Merged

Fi3w0 merged 13 commits into
claude/new-session-bppt7lfrom
fiw/testing-fixes

Conversation

@Fi3w0

@Fi3w0 Fi3w0 commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Fixes found during the first standalone run on real Nvidia hardware (RTX 3060, proprietary 595.99.02, Gentoo), plus the results of that pass. Stacked on claude/new-session-bppt7l: this PR only contains the 13 commits below.

What changed and why

Behavior fixes

  • 2727de9 Client drag and drop works. WaylandDndGrabHandler was an empty impl, so Smithay's default dnd_requested cancelled every drag source immediately. Nothing could be dragged between apps, and Firefox detached every dragged tab into a new window. Drags now start a DnDGrab (pointer and touch); the icon is drawn at the pointer on udev (never over the lock screen), gets frame callbacks, and is cleared on drop/cancel.
  • 3286393 Glass shows the wallpaper at the right size on fractional scales. Captures render at scale 1.0 in physical pixels but reused the logical-size wallpaper element, so at 1.25x every capture (frost/water glass, layer glass, shader sources, workspace transitions) drew the wallpaper at 80% size from the top-left.
  • 8ebb259 output { } blocks apply on config reload. The wlr-output-management apply path is now a shared apply_output_changes(); reload uses it for transform/scale/position. A different mode or enabled = false still needs a modeset and now shows a notice instead of being ignored.
  • 6517964 spawn takes quoted arguments ('...', "...", \ escapes; still no shell expansion; unterminated quotes fall back to the old split). tidectl re-quotes spawn arguments, reads global flags only before the command, and tidectl help prints help.
  • e4867b1 IPC requests that end at EOF without a newline are answered (or get the normal invalid request error) instead of being dropped silently.
  • 182df1b cursor_hide_after = 0 is accepted as documented.
  • 490df73 doctor enumerates /dev/dri and reports render and card nodes separately.
  • e2385eb preserves the documented doctor --json and perf --json spellings while still leaving flags after actions such as spawn untouched.

Default change

  • c593da7 Automatic attention depth is opt-in (depth { enabled = false } in code and in the generated config).

Docs

  • 2830ab7 pointer_modifier row in the settings table (it does not follow @mod); spawn quoting rules.
  • 13b104e CHANGELOG entries.
  • c41a9a4, ad0ed6b TECHNICAL_REPORT.md / report.md: the Nvidia pass.

How it was verified

  • cargo fmt --all -- --check, cargo clippy --locked --all-targets -- -D warnings (with and without --features screencast), cargo test --locked: all green. New regression tests for the depth default, spawn splitting and tidectl quoting, capture wallpaper size, and cursor_hide_after.
  • Standalone udev session on the RTX 3060, two outputs (2560x1440@144 at 1.25x, 1920x1080@180 at 1.0x), iGPU excluded with gpu { }:
    • drag and drop Dolphin to Firefox, tab drag out and back in;
    • frost glass on the 1.25x output lines up with the wallpaper (screenshot comparison before/after);
    • swapping the two output positions in the config applied live and back;
    • quoted spawn arrived as a single argument (checked in /proc/<pid>/cmdline);
    • portal screen sharing from native Vesktop worked;
    • doctor all-pass.
  • Nested run of the same build: tidectl help, quoted spawn, flags after the command, and EOF/truncated IPC requests.

RAM / perf impact

None on the render path in normal use: the DnD icon only renders during a drag, and the capture wallpaper is the same texture at a different size. Measured on this build (details in report.md): idle ~1% of one core, 131 MiB TideWM VRAM; nine frost windows ~0-1% CPU, 139 MiB. On Nvidia, PSS plateaus near 180 MiB after warm-up, of which ~60-95 MiB is /dev/nvidia* mappings. Open/close cycles return to the same value with a flat heap, so it is not a leak, but the doctor's decorated-tier limit (280 MiB) can be reached on Nvidia.

Still open

  • Tearing on the HDMI output only, unchanged at scale 1.0; likely the cable or HDMI bandwidth at 1440p144.
  • Firefox PDF text selection improved but still imprecise.
  • Layer glass and layer shaders were not exercised (no layer-shell client).

depth { enabled } now defaults to false in DepthConfig and in the
generated first-run config, which gains an explicit
depth { enabled = false } block. Unfocused windows no longer fade into
the blue cool_color wash after 30 s or turn into title cards after 60 s
unless a config opts in with enabled = true.

depth_defaults_match_generated_config asserts the disabled default for
both sources; the tier-boundary test now enables depth explicitly
instead of relying on the default. DOCUMENTATION.md and CHANGELOG.md
updated.
WaylandDndGrabHandler was an empty impl, so Smithay's default
dnd_requested cancelled every drag source immediately. Dragging files,
text or links between apps did nothing, and Firefox treated every tab
drag as a drop outside the window and detached the tab.

Start a DnDGrab for pointer and touch drags, keep the client's icon
surface, draw it at the pointer with the cursor elements on the udev
backend (skipped while locked), send it frame callbacks, and clear it
on drop or cancel.
Offscreen captures render at scale 1.0 in output-local physical pixels
but used the on-screen wallpaper element, which is sized in logical
pixels and relies on the frame's scale. On a 1.25x output the wallpaper
inside glass, layer glass, shader and workspace-transition captures was
drawn at 80% size from the top-left, so frost showed a shrunken wallpaper
shifted away from the real one.

Captures now build the wallpaper at the output's physical size, rounded
like the visible frame.
DOCUMENTATION.md says 0 disables cursor hiding, but the key used the
duration parser that rejects zero, so cursor_hide_after = 0 (or 0ms)
was ignored with a warning. Use the zero-allowing parser that exists
for exactly this case.
spawn split commands on whitespace only, so no keybind, startup spawn or
tidectl spawn could pass an argument containing a space, and the doc
comment's advice to use sh -c "..." could never work. The splitter now
understands single quotes, double quotes and backslash escapes, still
without any shell expansion; an unterminated quote falls back to the old
whitespace split so existing configs keep working.

tidectl quotes spawn arguments that need it when joining them, parses
--json/--socket/--help only before the command so a spawned program's
own flags reach it, and treats `tidectl help` as help instead of
sending it to the compositor as an unknown action.
The gpu check probed three hard-coded paths and listed /dev/dri/card0
under "render nodes". Enumerate /dev/dri instead, and report renderD*
nodes and card* nodes separately, so a card1-only machine is seen and the
labels are right.
Requests were only handled once a newline arrived, so a client that
closed its write side after an unterminated line got no reply at all:
both a truncated request and a complete one sent without a trailing
newline (printf ... | socat) were silently dropped. Treat EOF as the end
of the last line, so the request is answered or rejected with the usual
invalid-request error. Only the read step changed; the request handling
moved out of the read match unchanged.
pointer_modifier had no row in the top-level settings table, so nothing
said it is separate from @mod and defaults to SUPER (the cause of Alt+drag
not moving windows with an older config). The spawn key, spawn: action and
--spawn flag now describe the quoting rules.
output { } blocks only took effect when an output was set up, so a
reload that moved, scaled or rotated a monitor was accepted and then
ignored. The wlr-output-management apply path (layout validation,
transform/scale/position change, floating-window translation, layer
re-arrange, retile) is now a shared apply_output_changes() that config
reload uses too. Outputs without a block keep their state. A different
mode or enabled = false still needs a modeset at output setup, so those
now produce a notice on the warning panel instead of being ignored
silently. The transform conversion moved to
OutputTransformConfig::to_transform() for both callers.
TECHNICAL_REPORT.md: the standalone DRM backend is verified on a real
RTX 3060 with two outputs at mixed scale; drop the open "Nvidia native
run" item. report.md: the validation pass with IPC robustness, idle and
nine-glass-window cost, the Nvidia PSS breakdown (driver mappings, no
leak), the fixes found during the pass, and what is still open.
Portal screen sharing from native Vesktop through the TideWM ScreenCast
backend worked on the RTX 3060 setup. Note that src/screencast only logs
failures, so a successful session leaves no trace in the log.
@Fi3w0
Fi3w0 merged commit df3a76c into claude/new-session-bppt7l Sep 25, 2026
1 check passed
@Fi3w0
Fi3w0 deleted the fiw/testing-fixes branch September 25, 2026 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant