Skip to content

wm_api: a hosted app may answer a close; the terminal does - #68

Merged
ymote merged 1 commit into
mainfrom
feat/wm-close-refused
Sep 30, 2026
Merged

ymote merged 1 commit into
mainfrom
feat/wm-close-refused

Conversation

@ymote

@ymote ymote commented Sep 30, 2026 •

Copy link
Copy Markdown

For OctoSense-org/OctoSense#179 (the shell side is OctoSense-org/OctoSense#187).

A WM that follows CloseRequested with Kill ends a process terminal's running jobs even though the terminal (since #65) refuses the close and asks. A WM cannot wait for an answer it cannot tell from silence, so this adds two additive requests:

  • WmRequest::AsksBeforeClose: this app answers CloseRequested itself. The terminal sends it in reply to WmEvent::Hosted.
  • WmRequest::CloseRefused: not now, the app is asking the person. The terminal sends it on every refusal. A repeated close gets a fresh answer, so a WM can tell a live, asking app from a hung one.

Found while testing: the hosted (Studio stdin) runtime on macOS drops CxOsOp::Quit, so cx.quit() does nothing in a hosted app. Until now the WM's Kill hid this. A hosted terminal that agrees to close (nothing running, or the person said yes) now sends WmRequest::Close. Standalone it calls cx.quit() as before. Ctrl+Shift+W on the last tab takes the same path.

apps/wm still closes with CloseRequested + Kill and ignores both new words. A test pins the wire form ({"wm":{"CloseRefused":[]}}), because OctoSense matches on that exact text so it works with older pins.

Tests

  • cargo test -p makepad-wm-api: 5 passed, including the new close_answers_round_trip.
  • cargo check -p makepad-terminal -p makepad-wm: clean. rustfmt --check passes on the touched files.
  • cargo test -p makepad-terminal: 388 passed, 4 failed. The 4 are session::tests::* PTY tests. They fail the same way on main (bcb0583) on this machine, so this change did not cause them.
  • End to end in a hidden OctoSense release desktop, with this change applied to its .sources/makepad: see the OctoSense PR.

🤖 Generated with Claude Code

A WM that followed CloseRequested with Kill ended a process terminal's
running jobs even though the terminal refused the close and asked
(OctoSense-org/OctoSense#179). A WM cannot wait for an answer it cannot
tell from silence, so two additive requests say it:

- WmRequest::AsksBeforeClose: this app answers CloseRequested itself.
  The terminal sends it in reply to WmEvent::Hosted.
- WmRequest::CloseRefused: not now, the app is asking the person. The
  terminal sends it on every refusal, so a repeated close is answered
  again and a WM can tell a live, asking app from a hung one.

The hosted (Studio stdin) runtime ignores cx.quit(), so a hosted
terminal that agrees to close (nothing running, or the person said
yes) now asks the WM to close it with WmRequest::Close; standalone it
quits as before. Ctrl+Shift+W on the last tab uses the same path.

apps/wm keeps closing with CloseRequested + Kill and ignores both words.
The wire form ({"wm":{"CloseRefused":[]}}) is pinned by a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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