Switch deployments on and off from the menu #1

Merged
geusebio merged 3 commits from feature/deployment-toggles into main 2026-08-14 18:21:49 +00:00
Owner

The tray switches deployments on and off. Needs scclient #2 (pinned and vendored here) and the platform's #575.

What changed

Every deployment row was Disable()d with the label "toggle lands with /cli activate". Now each one carries the two gestures as submenu entries, and shows only the one the platform will accept — the listing reports running/activatable per name, so a click never comes back 409:

[S⠿C]
├── synced 19:44:02 · 1 application
├── Top up credit…              (hidden until something is refused for want of credit)
├── test-webserver (grey-ooo) · #1
│   ├── ● main · running (#1)
│   │   └── Confirm stop main   (Activate main takes its place when it is down)
│   └── Open in browser
├── Refresh
└── Quit
  • Off asks twice. Confirm stop <name> is a second, explicitly-labelled click rather than the one that opens the row: teardown removes a live stack, and a tray row is easier to fat-finger than a page button. On stays a single Activate <name> — its failure mode is a deploy, not an outage.
  • An activation is followed to its outcome, on the progress stream sc deploy uses, rather than waiting up to 10s for the poll to notice — and the outcome raises one desktop notification, the case the plan names as worth one. Stop keeps the poll: the stream ends at running, which is where a teardown starts.
  • A credit refusal reveals Top up credit…, pointing at the organization's billing page — the one refusal a client can offer a way out of.
  • Notifications are hand-rolled on osascript and notify-send, for the same reason opening a browser is: two commands and a fallback, against a module whose discipline is having no dependencies. Nothing important is only in a notification — every outcome also lands on the status row, so Windows losing the pop-up loses nothing.
  • Filled dot = there is a stack to take down, which includes a half-placed deploying revision. Hollow for everything else.

Verified

Built and run against a live platform dev stack, with sc driving the same endpoints from the other side (transcript in #575): stop flips the row to ○ main · built (#1) and swaps Confirm stop for Activate.

go build, go vet, go test ./... clean, vendored (GOWORK=off passes offline, which is what CI runs), and all four static cross-compile targets still build with CGO_ENABLED=0.

Evidence

Captured from the running binary, not drawn: hack/screenshot boots a headless Linux desktop in a container — Xvfb, a window manager, a StatusNotifierItem watcher and host — runs sc-tray against a fixed stub scene, opens the menu with xdotool and photographs it. The rows are the ones the binary exported over DBusMenu. ./hack/screenshot/run.sh re-runs the whole thing.

The menu. Applications above the controls — which is a fix in this PR: systray appends, so rows drawn on the first poll used to land below Refresh and Quit. Found by looking at it, which until this harness nobody could do.

The tray menu

A running deployment. Filled dot, and the only gesture offered is the confirming second click.

Confirm stop

One that is down. Hollow dot, Activate staging in place of the stop.

Activate

macOS and Windows have no equivalent that runs without their own machine, so they stay uncaptured rather than invented — the menu tree is the same on all three, the drawing is each platform's own. The icon in these is still the colour placeholder (#576).

Deliberately not here

  • Press-and-hold to stop, with an animation — a tray menu is drawn by the OS: one click event, no press/release pair, and on macOS the menu closes on click, so an animation after it is invisible. It needs a real window, which today means Fyne, cgo, and losing the static cross-compile. It lands with v2's Fyne surfaces.
  • Theme-aware icon (#576), signed-in browser links (#577), who you are signed in as (#578), and the burn sparkline.
The tray switches deployments on and off. Needs [scclient #2](https://git.grey.ooo/Grey.ooo/someones.computer_scclient/pulls/2) (pinned and vendored here) and the platform's [#575](https://git.grey.ooo/Grey.ooo/Someones.Computer/pulls/575). ## What changed Every deployment row was `Disable()`d with the label "toggle lands with /cli activate". Now each one carries the two gestures as submenu entries, and shows **only the one the platform will accept** — the listing reports `running`/`activatable` per name, so a click never comes back 409: ``` [S⠿C] ├── synced 19:44:02 · 1 application ├── Top up credit… (hidden until something is refused for want of credit) ├── test-webserver (grey-ooo) · #1 │ ├── ● main · running (#1) │ │ └── Confirm stop main (Activate main takes its place when it is down) │ └── Open in browser ├── Refresh └── Quit ``` - **Off asks twice.** `Confirm stop <name>` is a second, explicitly-labelled click rather than the one that opens the row: teardown removes a live stack, and a tray row is easier to fat-finger than a page button. On stays a single `Activate <name>` — its failure mode is a deploy, not an outage. - **An activation is followed to its outcome**, on the progress stream `sc deploy` uses, rather than waiting up to 10s for the poll to notice — and the outcome raises one desktop notification, the case [the plan](https://git.grey.ooo/Grey.ooo/Someones.Computer/src/branch/main/docs/tray-app.md) names as worth one. Stop keeps the poll: the stream ends at `running`, which is where a teardown starts. - **A credit refusal reveals `Top up credit…`**, pointing at the organization's billing page — the one refusal a client can offer a way *out* of. - **Notifications are hand-rolled** on `osascript` and `notify-send`, for the same reason opening a browser is: two commands and a fallback, against a module whose discipline is having no dependencies. Nothing important is *only* in a notification — every outcome also lands on the status row, so Windows losing the pop-up loses nothing. - **Filled dot = there is a stack to take down**, which includes a half-placed `deploying` revision. Hollow for everything else. ## Verified Built and run against a live platform dev stack, with `sc` driving the same endpoints from the other side (transcript in [#575](https://git.grey.ooo/Grey.ooo/Someones.Computer/pulls/575)): stop flips the row to `○ main · built (#1)` and swaps `Confirm stop` for `Activate`. `go build`, `go vet`, `go test ./...` clean, vendored (`GOWORK=off` passes offline, which is what CI runs), and all four static cross-compile targets still build with `CGO_ENABLED=0`. ## Evidence Captured from the running binary, not drawn: `hack/screenshot` boots a headless Linux desktop in a container — Xvfb, a window manager, a StatusNotifierItem watcher and host — runs `sc-tray` against a fixed stub scene, opens the menu with `xdotool` and photographs it. The rows are the ones the binary exported over DBusMenu. `./hack/screenshot/run.sh` re-runs the whole thing. **The menu.** Applications above the controls — which is a fix in this PR: systray appends, so rows drawn on the first poll used to land *below* Refresh and Quit. Found by looking at it, which until this harness nobody could do. ![The tray menu](https://git.grey.ooo/Grey.ooo/someones.computer_tray/raw/commit/4d264f65c8cc7bcb53c068f6483f0f35af052ca9/docs/images/tray-menu.png) **A running deployment.** Filled dot, and the only gesture offered is the confirming second click. ![Confirm stop](https://git.grey.ooo/Grey.ooo/someones.computer_tray/raw/commit/4d264f65c8cc7bcb53c068f6483f0f35af052ca9/docs/images/tray-gestures.png) **One that is down.** Hollow dot, `Activate staging` in place of the stop. ![Activate](https://git.grey.ooo/Grey.ooo/someones.computer_tray/raw/commit/4d264f65c8cc7bcb53c068f6483f0f35af052ca9/docs/images/tray-activate.png) macOS and Windows have no equivalent that runs without their own machine, so they stay uncaptured rather than invented — the menu tree is the same on all three, the drawing is each platform's own. The icon in these is still the colour placeholder ([#576](https://git.grey.ooo/Grey.ooo/Someones.Computer/issues/576)). ## Deliberately not here - **Press-and-hold to stop, with an animation** — a tray menu is drawn by the OS: one click event, no press/release pair, and on macOS the menu closes on click, so an animation after it is invisible. It needs a real window, which today means Fyne, cgo, and losing the static cross-compile. It lands with v2's Fyne surfaces. - **Theme-aware icon** ([#576](https://git.grey.ooo/Grey.ooo/Someones.Computer/issues/576)), **signed-in browser links** ([#577](https://git.grey.ooo/Grey.ooo/Someones.Computer/issues/577)), **who you are signed in as** ([#578](https://git.grey.ooo/Grey.ooo/Someones.Computer/issues/578)), and the burn sparkline.
Switch deployments on and off from the menu
All checks were successful
CI / build (pull_request) Successful in 42s
59be5e5623
The scaffold listed and linked; every deployment row was disabled with a
label saying the toggle was waiting on the platform. It isn't any more.

Each deployment row now carries the two gestures as submenu entries, and
shows only the one the platform will accept — the listing says which, so a
click never comes back 409. Off is a `Confirm stop <name>` entry rather than
the click that opens it: teardown removes a live stack, and a tray row is
easier to fat-finger than a page button. On is a single `Activate <name>`,
because its failure mode is a deploy, not an outage.

An activation is followed to its outcome on the progress stream `sc deploy`
uses, rather than waiting up to ten seconds for the poll to notice, and the
outcome raises one desktop notification — the case the plan names as worth
one. Notifications are hand-rolled on osascript and notify-send for the same
reason opening a browser is: two commands and a fallback, against a module
whose discipline is having no dependencies. Nothing important is *only* in a
notification; every outcome also lands on the status row, so Windows losing
the pop-up loses nothing.

A refusal for want of credit reveals a "Top up credit…" row pointing at the
organization's billing page — the one refusal a client can offer a way out
of.

The row titles carry the state the listing now reports: a filled dot for a
stack that exists (including a half-placed `deploying` one, which is exactly
what stop takes down), hollow for everything else.
Draw the applications above the controls, and photograph the menu to prove it
Some checks failed
CI / build (pull_request) Has been cancelled
212c13b73d
systray appends, so rows drawn on the first poll landed *below* Refresh and
Quit — a menu about applications with the applications at the bottom. The
first fetch now happens before those two are added, which puts them where a
reader expects and costs the menu the length of one bounded fetch.

That was found by looking at it, which until now nobody could do: a menu-bar
dropdown cannot be captured on a developer's own machine without a human
holding it open at the right instant. hack/screenshot boots a headless Linux
desktop in a container — Xvfb, a window manager, a StatusNotifierItem watcher
and host — runs the binary against a fixed stub scene, opens the menu with
xdotool and captures it. The rows in docs/images are the ones the binary
exported over DBusMenu, not a mockup, and re-running it differs only where
the menu did.
Pin scclient to the merged contract commit
All checks were successful
CI / build (pull_request) Successful in 2m56s
4d264f65c8
geusebio changed title from WIP: Switch deployments on and off from the menu to Switch deployments on and off from the menu 2026-08-14 18:18:35 +00:00
Sign in to join this conversation.
No reviewers
No labels
in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Grey.ooo/someones.computer_tray!1
No description provided.