Skip to content

Settings: choose whether the countdown shows the time left or the end time - #132

Open
ChemaAlfonso wants to merge 2 commits into
krishhgg:mainfrom
ChemaAlfonso:feat/countdown-style
Open

ChemaAlfonso wants to merge 2 commits into
krishhgg:mainfrom
ChemaAlfonso:feat/countdown-style

Conversation

@ChemaAlfonso

@ChemaAlfonso ChemaAlfonso commented Oct 19, 2026 •

Copy link
Copy Markdown

What changes

Closes #131.

Adds a Countdown setting with two choices:

  • Time left (default): the menu bar countdown as today. A config.json without the key, or with a value this build does not know, reads as this.
  • End time: the menu bar shows the clock time the session ends at, in the system's 12 or 24 hour style. On another day it adds the weekday (Sat 03:00), and from a week away the date. The text changes only with the session, so no timer redraws the status item.

Also:

  • With End time, the right-click menu gains a "Time left: 2h 14m" line after the sleep line. With Time left the menu is unchanged.
  • A change in Settings applies to a running session at once, through .onChange and SessionManager.countdownStyleChanged(), as the Low Power Mode toggle does with reevaluateFloors().
  • While a start or an extension is pending, the projected countdown reads the same text the manager will, follows a style change at once, and ticks at 1 Hz only with Time left.
  • docs/spec.md (sections 1, 4, 10, 11 and the event table) and a new item in the "Menu bar" list of docs/releasing.md.

The end time is formatted when the session starts or changes, when the lid opens, on a right-click and when the setting changes. Nothing else redraws it, so a Tue 02:00 stays as it is past midnight (still right), and a change of time zone or of the 12/24 hour setting during a session shows at the next of those. Following such changes on their own would need observers for the system clock and locale, which the app has none of today, so I left that out to keep the change small.

How it was tested

22 new tests:

  • ConfigTests: default, config from an earlier build, saved by name, unknown value falls back and keeps the rest of the config.
  • SessionMathTests: end time today, with weekday, with date from a week away, 12 hour locale, and the style switch.
  • UIStatusTests: no countdown timer with End time, the timer kept with Time left, a style change reaching a running session, a paused (lid closed) countdown not restarting on a style change, no timer after the lid opens with End time, the end time following an extension, the projection equal to the manager's text in both styles, the pending tick only with Time left, and the menu line.
  • UIStartupTests: a style change while a start or an extension is pending restyles the projected countdown and starts or stops its tick.
  • StatusMenuWarningTests: the "Time left" line with a session, and none without one.

swift test: 1294 tests, 0 failures, 13 skipped for want of tmux. swift build -c release -Xswiftc -warnings-as-errors is clean.

By hand on a MacBook Pro (Mac16,8, M4 Pro), macOS 27.0.1, with the steps of the new "Menu bar" item: mean %cpu over 20 s of 1.695% with Time left and 0.0075% with End time, same session and build, only the setting changed. The real-Mac report comment has the details.

The Countdown setting in Settings

The menu bar with the end time, two days ahead

The right-click menu with the Time left line

Real-Mac evidence

In a comment, for the head commit.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the previous pending-countdown issue is fixed.

Summary

Adds a choice between time left and the session’s end time in the menu bar.

  • The menu bar can show a session’s end time instead of time left.
  • Pending sessions show the countdown style chosen in Settings.
  • The right-click menu shows time left when the bar shows the end time.

Reviews (2) · Last reviewed commit: "Menu bar: restyle a pending countdown wh..." · Reviewed by Greptile

… time

Adds a Countdown setting. The menu bar shows either the time left, as before,
or the clock time the session ends at. The end time changes only with the
session, so nothing redraws the status item each second, and the right-click
menu gains a Time left line. A change in Settings reaches a running session at
once. The time left stays the default, and a config from an earlier build keeps
working.
@ChemaAlfonso

Copy link
Copy Markdown
Author

Build

  • git rev-parse HEAD: 6a646533ed40179228963a0ac88623676bc7c02b
  • git status --short: prints nothing
  • Installed with ./scripts/install.sh from a clean checkout of that commit, with no other pull requests applied (binary built 10:14:19 UTC, after the commit at 10:06:19 UTC).

Mac

sw_vers
ProductName:		macOS
ProductVersion:		27.0.1
BuildVersion:		26A434
sysctl -n hw.model
Mac16,8
sysctl -n machdep.cpu.brand_string
Apple M4 Pro

Checks

All times are UTC. "Menu bar" in docs/releasing.md, both items, plus a lid close and open and the 12/24 hour setting. One session of 30 minutes started at 10:16:32 with Countdown set to End time, lid open, on AC power, external display attached.

  1. End time (the new item): pass.
    • 10:16:32 session started. The bar showed the end time, hours and minutes only.
    • Right-click menu: a "Time left: 22m" line after the sleep line.
    • 10:16:54 to 10:17:15, ps -o %cpu= -p <pid> every 0.5 s, 40 samples: mean 0.0075%, max 0.3%.
  2. Time left (the existing item), and the setting reaching a running session: pass.
    • 10:30:45 Countdown changed to Time left in Settings, with the session running and without extending it. The bar switched to the countdown at once, and it changes every second.
    • 10:30:56 to 10:31:17, 40 samples: mean 1.695%, max 6.3%, under the 5% the item allows.
  3. End time on another day, and following an extension: pass.
    • Countdown back to End time, then at 10:32:12 the session extended by one day. The bar shows the weekday before the time (Tue and the time).
    • Right-click menu: Time left: 1d.
  4. Lid close and open with End time: pass.
    • 10:32:25 lid closed, 10:34:05 lid opened. After the open the bar still shows the end time and no countdown timer runs.
    • 10:35:00 to 10:35:21, 40 samples: mean 0.0025%, max 0.1%.
  5. 12/24 hour setting during a session: pass.
    • With 24-hour time turned off in System Settings, a right-click on the icon changed the bar to the 12 hour time. With it turned back on, the next right-click brought the 24 hour time back.

Raw output:

  • ps -o %cpu=, End time (check 1), 40 samples: 0.0 39 times and one 0.3.
  • ps -o %cpu=, Time left (check 2), 40 samples: 2.1 0.2 2.0 0.3 1.8 0.3 1.8 0.3 0.8 4.9 1.0 5.4 1.0 6.3 1.1 5.2 0.5 3.3 0.6 3.2 0.5 3.3 0.6 4.2 0.7 2.2 0.3 2.2 0.3 1.8 0.3 2.4 0.3 2.1 0.3 1.6 0.3 1.0 0.1 1.2
  • ps -o %cpu=, End time after the lid opened (check 4), 40 samples: 0.0 39 times and one 0.1.
  • Idle wakeups over each 20 s window, from top -l 1 -pid <pid> -stats idlew read before and after it: End time 0, Time left 4, End time after the lid opened 0.
  • pmset sampler, started 10:15:58 and left running until 10:36:16, 243 samples every 5 s: SleepDisabled 0 in the 6 samples before the session and SleepDisabled 1 from 10:16:28 on. The Battery Power powermode line read 0, then 1 from 10:32:30 (Low Power Mode while the lid is closed) and 0 again from 10:34:10.
  • pmset -g log | grep -E ' (Sleep|Wake|DarkWake) ' from 10:14 on: no lines, the Mac did not sleep.
  • ~/Library/Logs/Insomnia/insomnia.log for the run (status item geometry lines left out, and the names of the output device and frozen apps replaced):
2026-10-19T10:16:16Z [info] insomnia: startup lid state open
2026-10-19T10:16:16Z [info] insomnia: startup battery 100%
2026-10-19T10:16:16Z [info] insomnia: startup thermal state nominal
2026-10-19T10:16:16Z [info] insomnia: launched, version 0.1.0 (1)
2026-10-19T10:16:16Z [info] insomnia: wifi interface en0
2026-10-19T10:16:16Z [info] insomnia: reconcile: no session, nothing to restore
2026-10-19T10:16:18Z [info] insomnia: wifi interface en0
2026-10-19T10:16:32Z [info] insomnia: session started until 2026-10-19T10:46:27Z (1800s requested)
2026-10-19T10:16:32Z [info] insomnia: lid observer started (lid open)
2026-10-19T10:16:32Z [info] insomnia: notification authorization granted
2026-10-19T10:16:32Z [info] insomnia: power monitor started (battery 100%, charging, thermal nominal)
2026-10-19T10:16:32Z [info] insomnia: wifi interface en0
2026-10-19T10:16:32Z [info] insomnia: network failover started (wifi en0)
2026-10-19T10:32:12Z [info] insomnia: session extended by 86400s until 2026-10-20T10:46:27Z
2026-10-19T10:32:25Z [info] insomnia: lid closed
2026-10-19T10:32:25Z [error] insomnia: display darken on lid close skipped: display 2 cannot change brightness
2026-10-19T10:32:25Z [info] insomnia: keyboard backlight read while suppressed or dimmed (0.0); journaling the last trusted sample 0.4453595
2026-10-19T10:32:25Z [info] insomnia: keyboard backlight off (was brightness 0.4453595)
2026-10-19T10:32:25Z [info] insomnia: display sleep requested
2026-10-19T10:32:25Z [info] insomnia: muted <output device> (was volume 0.55, muted false)
2026-10-19T10:32:25Z [info] insomnia: froze <app 1> (1 pid(s), 0 skipped)
2026-10-19T10:32:25Z [info] insomnia: froze <app 2> (1 pid(s), 0 skipped)
2026-10-19T10:32:25Z [info] insomnia: low power mode on
2026-10-19T10:32:25Z [info] insomnia: low power mode on (lid closed)
2026-10-19T10:34:05Z [info] insomnia: lid open
2026-10-19T10:34:05Z [info] insomnia: resumed 2 frozen pid(s); 0 gone, 0 failed, 0 unverifiable, 0 unobserved
2026-10-19T10:34:05Z [info] insomnia: audio restored on <output device> (volume 0.55, muted false)
2026-10-19T10:34:05Z [info] insomnia: keyboard backlight restored (brightness 0.4453595)
2026-10-19T10:34:05Z [info] insomnia: low power mode off
2026-10-19T10:34:05Z [info] insomnia: low power mode off (lid opened)
2026-10-19T10:34:07Z [info] insomnia: keyboard restore re-asserted (brightness 0.4453595)

The "display 2 cannot change brightness" line is the external display. The same line is in this log from 2026-10-16, with a build from before this change.

Not run

  • macOS 26 and an Intel Mac: not available to me.
  • The end of the session: it was still running when the report was written.
  • A change of time zone during a session: it would change the clock of a Mac in daily use. The code formats with the auto-updating calendar and locale, as check 5 shows for the 12/24 hour setting, and the unit tests cover the formatting with a fixed time zone and locale.

Comment thread Sources/Insomnia/UI/StatusItemController.swift
A style change while a start or an extension waits on the helper left the
projected countdown in the old style, and a pending start kept its 1 Hz
tick after End time was picked. The controller now observes the style, and
a pending extension keeps a projection like a pending start, so both redraw
in the new style and the tick follows it. Two spec lines this change had
left stale are corrected, and the pending tick test ends each session it
starts.
@ChemaAlfonso

ChemaAlfonso commented Oct 19, 2026 •

Copy link
Copy Markdown
Author

Real-Mac report for cab1050

  • Build. git rev-parse HEAD → cab1050e3d4154488235697444af67a3f24447e0, git status --short → nothing. Installed with ./scripts/install.sh from a clean checkout of this head (binary built 11:54:03 UTC, after the commit at 11:40:50 UTC; the app relaunched at 11:54:22 UTC).

  • Mac. macOS 27.0.1 (26A434), Mac16,8, Apple M4 Pro.

  • Delta from 6a64653.

    $ git diff --stat 6a64653 cab1050
     Sources/Insomnia/UI/MenuBarModel.swift         | 14 +++---
     Sources/Insomnia/UI/StatusItemController.swift | 38 +++++++++++++---
     Tests/InsomniaTests/UIStartupTests.swift       | 60 ++++++++++++++++++++++++++
     Tests/InsomniaTests/UIStatusTests.swift        |  6 +++
     docs/spec.md                                   |  9 ++--
    

    The change in Sources/ runs only while a start or an extension is pending, before the manager confirms it: the controller observes the style and redraws the projected countdown in it. MenuBarModel.swift changes doc comments only. Nothing under Sources/Insomnia/Core changed, so the running session's 1 Hz timer, its end time text and the lid pause and resume are the code the report above measured: End time 0.0075% and Time left 1.695% mean %cpu, and the lid close and open.

    The pending case is covered by testChangingTheStyleRestylesAPendingStart and testChangingTheStyleRestylesAPendingExtension, which fail without the change. swift test on this head: 1294 tests, 0 failures, 13 skipped for want of tmux. swift build -c release -Xswiftc -warnings-as-errors: clean.

krishhgg added a commit that referenced this pull request Oct 19, 2026
#132 cab1050 against main e242782: the Countdown setting, the bar with
Time left and End time in light and dark, the right-click menu, the
12/24 hour switch, an unknown value, and two GIFs (a switch during a
session and one while a start is pending).
#71 ffdb1bc and 2a45e18: the Lock the screen row and its help text.
#104 0baa658 against main: the Settings window, Default field Minutes,
the update check, and the Edit Apps and If Wi-Fi drops sheets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@krishhgg

Copy link
Copy Markdown
Owner

What the Countdown setting looks like: macOS 27.0.1 VM test of cab1050

For @krishhgg to see the change. The maintainer's tooling made these in a macOS 27.0.1 VM. This is a test report, not a review or a merge decision.

Everything the PR describes behaved as described. The bar switched style at once during a session and while a start was pending. config.json got countdownStyle on each change. A config.json without the key, and one with an unknown value, both read as Time left.

Setup. macOS 27.0.1 (26A434) with Xcode 27. This PR's head cab1050 against main e242782, each built in the VM and installed with install.sh --allow-unverified-origin --app. Both started from the same config.json, which has no countdownStyle key. The VM's locale is de_DE, so the clock is 24 hour, and its clock is UTC.

Switching the style during a session

Switching between Time left and End time in Settings during a session

A 30 minute session is running with Time left, ticking. Picking End time in Settings changes the bar at once to Tue 00:01, when the session ends. It started at 23:31 on a Monday, so it ends after midnight and the bar adds the weekday. Picking Time left brings the countdown back, and it ticks again.

Menu bar, before and after

Light Dark
main
This PR, Time left
This PR, End time

Time left looks the same as main. With this wallpaper, macOS 27 draws the menu bar the same in light and dark. The dark menu further down shows the difference.

Settings

The new Countdown row sits under Default field. main has no such row (main's window, this PR's window).

The Countdown row in Settings

The Countdown menu: Time left and End time

Right-click menu

main This PR, End time This PR, Time left

With End time, the menu gains a "Time left: 29m" line. With Time left, it matches main. Dark, with End time:

The right-click menu in dark mode with the Time left line

12 and 24 hour clock

End time in 24 hour, then 12 hour, then 24 hour again

A 10 minute session with End time saved in config.json, switched in System Settings > General > Date & Time. From the top:

  1. 24 hour: 23:47.
  2. 24-hour time turned off. The system clock reads 11:38PM at once, but the bar still reads 23:47.
  3. After a right-click on the eye, the bar reads 11:47 PM.
  4. 24-hour time back on, then a right-click: 23:47.

The PR says the bar follows a 12/24 hour change at the next right-click, and that's what happened here. A defaults write of the same setting, with no System Settings, reached neither the running app nor the system clock, so the switch went through System Settings.

Changing the style while a start is pending

Picking End time while a start is pending

Settings was open, the pills were opened, 30 was typed into Minutes, then Enter. The projected countdown reads 30:00, then 29:59. End time was picked 1.7 s after Enter, and the bar switched to Tue 00:01 with no × yet, so the start was still pending. The start was confirmed 5 to 6 s after Enter (the log line session started until 2026-10-20T00:01:29Z is stamped 23:31:35). Then the × appeared and the text stayed the same. Still frame from 2.0 s after Enter:

End time shown while the start is pending

config.json

Check Result
config.json with no countdownStyle key Settings reads Time left, and the bar counts down
Picking End time, then Time left "countdownStyle": "endTime", then "remaining", in the file at once
"endTime" in the file at launch Settings reads End time, and the next session shows the end time
"sideways" in the file, with defaultPreset 7200 and lowPowerFloor 35 Countdown reads Time left. Default preset reads 2h, and lowPowerFloor stays 35 (Settings)

CPU

ps %cpu every 0.5 s for 20 s, same session: Time left mean 0.4% (max 3.6%), End time mean 0.0% (max 0.2%). The difference points the same way as the contributor's real-Mac numbers.

Worth knowing

  • A 30 minute session that crosses midnight shows the weekday: Tue 00:01 at 23:31 on Monday. That's what the spec says (another calendar day adds the weekday), but at a glance it can read like a day away.
  • A 12/24 hour change shows only at the next right-click, as the PR says, while the system clock changes at once.

Run notes: run-lab27.log. Builds: main, this PR. Installs: main, this PR. Nothing of the app was left installed in the VM afterwards.

🤖 Generated with Claude Code

@krishhgg

Copy link
Copy Markdown
Owner

Thank you for this. Your head commit cab1050 is merged unchanged into #145, together with five other menu bar pull requests that change the same files. When #145 merges, GitHub marks this pull request as merged too, with your commits and your authorship.

Please don't push to this branch from now on. A new commit wouldn't be in #145, so this pull request would stay open instead of showing as merged. If you want to change something, comment here and I'll add it to #145.

#145's description lists the conflicts resolved in its merge commits and the two maintainer fixes after them.

🤖 Generated with Claude Code

@krishhgg krishhgg mentioned this pull request Oct 24, 2026
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.

Optional countdown style: show the end time instead of the time left

2 participants