Skip to content

internal/kawa: tear the compositor down when Run returns - #25

Merged
DeedleFake merged 2 commits into
kawa-cancelfrom
kawa-teardown
Oct 2, 2026
Merged

DeedleFake merged 2 commits into
kawa-cancelfrom
kawa-teardown

Conversation

@DeedleFake

Copy link
Copy Markdown
Owner

Why

Server.Run never destroyed Xwayland or the Wayland display. Every exit, Log Out included, left /tmp/.X11-unix/XN, /tmp/.XN-lock, and the wayland-N socket and lock in XDG_RUNTIME_DIR behind. wlr_xwayland_destroy and wl_display_destroy are what remove them. Run now defers teardown before init, so teardown runs on every return, including a failure partway through setup.

Scope

  • teardown in internal/kawa/kawa.go destroys things in this order:
    1. The new-surface listener on Xwayland, then Xwayland itself. wlroots restarts Xwayland if its client goes away while Xwayland is still alive, so Xwayland has to go before DestroyClients. sway does the same.
    2. display.DestroyClients, then release for the remaining listeners and both pipes.
    3. The background, status bar title, and menu item textures. Destroying the renderer frees its remaining textures, so these have to go first.
    4. The cursor manager and the cursor, then the allocator, the renderer, and the backend, then the display, in the same order as tinywl.
  • wlroots 0.20 asserts that an object has no listeners left when it is destroyed, so each server listener goes before its object. wlr.Listener.Destroy has a value receiver, so teardown zeroes the Xwayland listener field after it destroys the listener, and release no longer destroys it.
  • teardown checks Valid, or the zero value for wlr.Cursor, before it destroys an object that a failed init may not have created. Menu.Release destroys the textures of a menu's items.
  • The verify-kawa docs and cleanup.sh now say that the X lock sweep only matters when kawa gets killed.

Tradeoffs

A stack of cleanup functions pushed during init would not give the right order. Xwayland and the clients have to go first, and some textures come from later than init.

Blast Radius

Every exit now runs wlroots destroy code that never ran before. A mistake there crashes kawa on its way out, after the session is over. SIGKILL still leaves the files behind.

Verification

  • go vet, go test, golangci-lint run --disable=errcheck, and go fix -diff are clean, and each commit builds.
  • A script ran an ASan build nested on a private Xvfb with foot, weston-terminal hidden from the menu, swaybg, wl-copy holding the selection, xlogo, and xeyes. It stopped kawa 15 times, 5 each with SIGTERM, SIGINT, and Log Out. Every run exited with 0 and no ASan report. After every run /tmp/.X0-lock, /tmp/.X11-unix/X0, wayland-0, and wayland-0.lock were gone, and the next run got :0 again. Before this change all four stayed after every exit.
  • The same ASan build with the Xwayland listener destroyed twice reports a heap-use-after-free in Listener.Destroy, so the check does catch that mistake.
  • Without XDG_RUNTIME_DIR, Run fails after Xwayland starts. kawa exits with 1 and now leaves no X lock. With WLR_BACKENDS=bogus, init fails, and kawa exits with 1 and no ASan report.
  • verify-kawa covered boot, the registry, New, the New box, xlogo, and Log Out. The screenshots are pixel-identical to master, and Log Out leaves no X or Wayland socket.

Run never destroyed Xwayland or the display, so every exit left the X
lock and socket of its Xwayland and the Wayland socket behind. Run now
tears everything down on every return, including Log Out, a canceled
context, and a failure partway through setup.

The order follows sway and tinywl. Xwayland goes first, because
destroying its client along with the others makes wlroots restart it.
Then come the other clients, the server's listeners and pipes, the
textures, the cursor manager and cursor, the allocator, the renderer,
the backend, and last the display.
@DeedleFake
DeedleFake added this pull request to stack #26 October 2, 2026 21:56
@DeedleFake DeedleFake changed the title kawa: tear the compositor down when Run returns internal/kawa: tear the compositor down when Run returns Oct 2, 2026
@DeedleFake
DeedleFake merged commit 183c57a into master Oct 2, 2026
1 check passed
@DeedleFake
DeedleFake deleted the kawa-teardown branch October 2, 2026 22:01
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