Skip to content

Releases: lispnik/utc-status-app

utc-status 0.3.0

Choose a tag to compare

@lispnik lispnik released this 08 Sep 18:13

A macOS menu-bar clock showing UTC, with copyable ISO 8601 renderings.

Download UTC-Status-0.3.0.dmg, open it, drag UTC Status to Applications.
The disk image and the application are both signed with a Developer ID and
notarised by Apple, so it opens with no warning and no right-click dance.

Requires macOS 11 or later, Apple silicon or Intel.

What it does

The menu-bar title is the current time in UTC, laid out the way your system
clock is laid out — it reads the same day-of-week, date and seconds settings, and
follows them within ten seconds if you change them. Clicking it offers eleven ISO
8601 renderings of the current instant, from microseconds down to the year plus
the compact, week-date and ordinal forms; choosing one copies it to the
clipboard. Show Seconds, Show UTC Label and Start at Login are in the
same menu.

New in 0.3.0

  • Signed and notarised. 0.2.0 built a bundle that could not be signed at all:
    save-lisp-and-die :executable t appends the core past the end of the Mach-O
    and past the code signature, and codesign refuses the trailing data. The core
    now ships as a sealed resource with the SBCL runtime as the executable.
  • It runs on other Macs. The runtime linked Homebrew's libzstd by absolute
    path, which notarises perfectly well and then fails with a dyld error on a
    machine without Homebrew. Rebuilt without core compression; it now links
    libSystem and nothing else.
  • Start at Login, appearing in System Settings → General → Login Items.
  • An icon, drawn by tools/icon.lisp using the same Objective-C bindings the
    application is built on.

Known

The item may not appear if your menu bar is full — macOS gives it a frame and
then has nowhere to draw it, with no warning. make agent-status or
--login-status will show it running regardless.

Built with objc and
asdf-macos-app.

utc-status 0.2.0

Choose a tag to compare

@lispnik lispnik released this 08 Sep 22:34

Release 0.2.0 -- a signed bundle, an icon, and preferences

The headline is that the .app can now be signed, which 0.1.0 could not manage
and which is the difference between an application and a thing that only runs
where it was built.

SIGNING. An SBCL image dumped with :EXECUTABLE T cannot be codesigned at all:
SAVE-LISP-AND-DIE appends the core to the runtime's Mach-O past the end of
__LINKEDIT and past the code signature -- measured, both end at byte 410,952 of
a 47,782,952-byte image -- and codesign refuses 47MB of trailing data it cannot
cover, with "main executable failed strict validation", for a Developer ID as
much as for ad hoc.

asdf-macos-app now ships the core as a sealed resource with the SBCL runtime as
the executable and a relative symlink between them. The runtime finds a core
named sbcl.core beside itself with no arguments, which is what LaunchServices
gives a double-clicked app; the core cannot live in MacOS/ because codesign
treats everything there as nested code; a symlink is found by one and sealed by
the other. No C launcher, so still no C toolchain in the build.

The result signs with the hardened runtime, passes codesign --verify --deep
--strict, launches through LaunchServices, and detects a modified core. Ad hoc
is enough to run locally; a Developer ID in utc-status-app-bundle.asd is all
that notarisation needs.

AN ICON, drawn rather than checked in. tools/icon.lisp uses the same objc
bindings the application is built on: a grey clock face -- ring, twelve marks,
hour and minute hands at ten past ten -- under a gold TZ monogram. `make icon'
draws the PNG and asdf-macos-app converts it to an .icns, so changing the colour
is an edit and there is no binary artwork in the repository.

PREFERENCES. Show Seconds and Show UTC Label, checkable in the menu and stored
in com.lispnik.utc-status. Absent means "follow the system", so the first click
writes the opposite of whatever is on screen; an explicit off is not the same as
never having chosen, which matters on a Mac whose own clock shows seconds.

AND IT FOLLOWS SETTINGS CHANGED UNDER IT. Turning on 24-Hour Time in System
Settings used to leave the menu bar the wrong shape until the next launch; the
clock re-reads every ten seconds and rebuilds its formatter only when the
preferences actually differ. Polling rather than a notification, deliberately:
NSUserDefaultsDidChangeNotification is posted for changes made in THIS process,
and the change worth reacting to happens in another.

Three bugs found by running it as a real bundle rather than as a binary:
-initWithSuiteName: returns nil for your own bundle identifier, and the next
message sent to that nil was a crash on every launch; SB-EXT:EXIT left a
buffered log stream unflushed, so --print wrote nowhere at all; and
:DEFSYSTEM-DEPENDS-ON is resolved when an .asd is read, which made
asdf-macos-app a hard requirement for loading the library.

109 checks, 107 without the clipboard ones. Green on arm64 and Intel.

utc-status 0.1.0

Choose a tag to compare

@lispnik lispnik released this 08 Sep 22:34

Release 0.1.0 -- a menu-bar UTC clock with copyable ISO 8601 renderings

The title is the current time in UTC, laid out the way the system clock is
laid out. Clicking it opens a menu of ISO 8601 renderings at descending
resolution -- microseconds down to the year, plus the compact, week-date and
ordinal-date forms -- and choosing one copies that rendering of the current
instant to the clipboard. The menu retitles itself just before it opens, so
every line is a live example and the line you click is the string you get.

Built on the objc bindings: the status item, its menu, the timers and the
pasteboard are Objective-C objects driven from Lisp, and the menu's actions
are Lisp methods on a Lisp-defined class.

WHAT IS IN IT

bin/utc-status the binary, and a command line -- --print, --list
UTC Status.app an .app bundle built by asdf-macos-app, LSUIElement
a LaunchAgent start it at login, pointing at either
two preferences Show Seconds and Show UTC Label, in the menu

MATCHING THE SYSTEM CLOCK is not a hardcoded format. Its shape is a set of
preferences, so this reads com.apple.menuextra.clock, turns them into a
Unicode date-field skeleton, and lets +dateFormatFromTemplate: decide the
field order -- en_US gives "EEE MMM d", en_GB "EEE d MMM", and neither is
written down. The hour field is j' rather than H', so it follows the
24-Hour Time switch instead of overriding it; CI shows the two apart, since
the runners have no such setting and render 7:18 AM where this Mac renders
07:18. A setting changed while it runs takes effect within ten seconds.

WHAT IS NOT IN IT, AND WHY

Signing. An SBCL image cannot be codesigned on this toolchain at all:
save-lisp-and-die appends the core to a Mach-O Homebrew already shipped
linker-signed, and codesign answers "main executable failed strict
validation" -- for a Developer ID as much as for ad hoc, and whether or not
the old signature is stripped first. The bundle launches on the runtime's
own signature but cannot be notarised, so it cannot be handed to anyone
else. This is the one thing standing between 0.1.0 and something
shippable.

An icon. LSUIElement means no Dock icon and no application switcher entry,
so it would be visible only in Finder.

KNOWN: the item may not appear on a crowded menu bar. It is created, reports
itself visible, is given a real frame -- and macOS has nowhere to draw it.
Nothing warns you; `make agent-status' will show it running regardless.

109 checks, green on arm64 and Intel.