Skip to content

fix(helper-ui): make the copy button copy, and say the display was slept - #151

Merged
ArangoGutierrez merged 2 commits into
mainfrom
fix/c-helper-ui
Aug 19, 2026
Merged

fix(helper-ui): make the copy button copy, and say the display was slept#151
ArangoGutierrez merged 2 commits into
mainfrom
fix/c-helper-ui

Conversation

@ArangoGutierrez

Copy link
Copy Markdown
Owner

Closes #142. Closes #143.

Two defects on the lid-closed control, both found by using the shipped v0.3.0 build.

#142 — the button offering to copy could not be clicked

There is one button whose title flips with the bundle's signature: Arm lid-closed mode on a signed build, Copy the command instead on an unsigned or Homebrew one. Its .disabled clause carried || helperAvailability == .unavailable, which is exactly the case where the title says "copy". So the control named an action and refused it, and on a Homebrew install that title is the only route the user gets to the command.

The press is now decided on the model side and read by the view, matching how every other sentence on this surface is composed. A build that cannot register still never reaches the OS with an arm request.

#143 — arming blanks the screen and nothing said so

ArmService is constructed with PmsetDisplaySleeper, whose forceSleep() runs pmset displaysleepnow, so the screen goes black the instant you arm. That is required behaviour, recorded in the engineering notes as "Force display off ... Required alongside disablesleep", and it is the whole point: the machine is being made ready for the lid to close.

But no user-facing text said it. The maintainer read it as a crash on first live use of the shipped button. The armed sentence now reads:

Lid-closed mode is armed for N, and the display was put to sleep so you can close the lid. coffee-bar's helper is supervising it and will put the setting back.

Not in this PR

#146 remains open. On a signed build whose helper is not registered, the stale-probe advisory still offers only the pre-v0.3.0 sudo install route rather than mentioning the button. The advisory already consults availability() and suppresses itself when a registered helper is active, so the gap is narrower than the issue as filed.

Testing done

  • Both fixes carry tests, in PreferencesView_test.swift and PrivilegedHelperClient_test.swift.
  • swift test verified independently on a clean scratch path.
  • theLidClosedSummaryIsInThePreferencesWindowAndNotInThePanel, a deliberate negative guard, is unbroken.

Breaking changes

None.

… arms

Arming runs `pmset displaysleepnow` through `PmsetDisplaySleeper.forceSleep()`,
so the screen goes black the instant the button is pressed. That is required
behaviour, recorded in docs/coffee-bar-HANDOFF.md as "Force display off ...
Required alongside disablesleep", but no user-facing text said so and the
maintainer read the blanking as a crash on first live use of the shipped button.

The armed sentence now names the display and says the lid can be closed. It
states what coffee-bar DID rather than what the display now IS: LidClosedSession
treats a nil from DisplayStateProbe as not-awake, so an .armed reply proves
`pmset displaysleepnow` returned nought, not that the panel is dark.

Closes #143

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
An unsigned or ad-hoc bundle takes the .unavailable branch of
PrivilegedHelperClient.decide(), which titles the one control "Copy the command
instead". The view then disabled it on the same term, so the control named an
action and refused to perform it. The Homebrew bundle is ad-hoc signed, always
takes that branch, and the greyed button was the only route it offered to
lid-closed mode: the command was recoverable only by selecting the sentence
beside it by hand.

The press now writes ServingModel.lidClosedCommand to the pasteboard and the
window says so. The decision is a value, HelperAvailability.buttonAction, rather
than a switch in the closure, because design 5.4 forbids asserting on rendered
AppKit text and a branch written in a View is a branch no check reads.

The safety property is unchanged. The copy branch ends at the pasteboard, and
arm(seconds:) opens with register(), which re-reads availability(), so a build
that cannot register still never reaches the OS with an arm request.

Closes #142

Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
@ArangoGutierrez
ArangoGutierrez merged commit f2c2c5a into main Aug 19, 2026
2 checks passed
@ArangoGutierrez
ArangoGutierrez deleted the fix/c-helper-ui branch August 19, 2026 17:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant