Add Elsewhen, the world clock plugin for the Omarchy shell - #1
Merged
Merged
Conversation
A bar widget that opens a panel of clocks, one row per city, with a spinnable orthographic globe behind it. Times come from a single date probe per refresh because Qt's QML engine has no Intl; temperature and currency come from a small python script with an on-disk cache. The README carries the design notes. Written by Jason Fried; committed as received, ahead of packaging.
The plugin id, IPC target, cache directory, user agent and the README's install and IPC examples move from jbf.worldclock to omacom.elsewhen, the repository this now lives in. The manifest declares smoothMotion, which Panel.qml already read but the schema never listed, and the README gains an Installing section with the add and remove commands, the runtime dependencies and the network sources. Authorship stays with Jason Fried in the manifest and the license.
tests/run runs every check under tests/ and exits non-zero if any of them fails; CI calls it with --offline so a third-party feed hiccup cannot fail a PR. A second job mirrors the checks in omarchy plugin validate against manifest.json, parses the data files, and compiles the python.
Model.addZone took any two strings, but the zones setting is a "Label|Zone, Label|Zone" line: a label with a comma came back from shell.json as two rows and an id with a delimiter became a different id altogether. The picker never produced such input, but the IPC add does, and it wrote the result straight into shell.json. addZone now refuses an id parseZones would drop and replaces the two delimiters in a label with spaces. The row's name is also drawn as plain text, so a label can not be read as markup. hasZone had no callers and goes.
ubuntu-latest ships an iso-codes that predates ZWG, so CI flagged Zimbabwe Gold as not a current ISO 4217 code. Allow that one by name, the same way XK is allowed as a country, and say why.
spencerbull
force-pushed
the
init-elsewhen
branch
from
September 10, 2026 02:50
bd8d254 to
4f5fde5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
The initial import of Elsewhen, the world clock plugin for the Omarchy shell: a bar button that opens a panel of clocks, one row per city, with a spinnable orthographic globe behind it. The README carries the design notes; this PR body covers what changed for the import and what was checked.
Authorship
The plugin was written by Jason Fried (@jasonfried). The first commit on this branch is his code exactly as received, authored in his name; the commits after it are packaging by Spencer Bull.
Identity
The plugin arrived as
jbf.worldclock. It is nowomacom.elsewheneverywhere the id is load-bearing: the manifest,moduleNameandipcTargetinPanel.qml, the on-disk cache (~/.cache/omacom-elsewhen/), the user agent the data script sends, and the README's install and IPC examples. The manifestauthorand the LICENSE copyright name Jason Fried.The manifest also gains
smoothMotion, a booleanPanel.qmlwas already reading but the schema never declared.Added for the repo
tests/run: runs every check undertests/and exits non-zero if any fails.--offlineskips the live Open-Meteo and FX cross-checks..github/workflows/ci.yml: two jobs. Manifest mirrors the checks inomarchy plugin validate(schema version, required fields, id shape and reserved namespace, entry points exist and are safe, a kind for every entry point, no symlinks), parses the data files, and compiles the python. Tests installs the Qt 6 test runner and iso-codes on ubuntu-latest and runstests/run --offline.LICENSE(MIT, Jason Fried) and.gitignore; the license text itself sits onmain.tests/run, which the marketplace listing requires.Verified locally
tests/runpasses: 13 node checks (4,984 assertions), the currency table against iso-codes and the live FX feed, and the QML pointer test underqmltestrunner(6 passed).omarchy plugin validate .passes on the current shell.Panel.setting,KeyboardPanel,PanelKeyCatcher,BarIconButton,Style/Colortokens, and the scopedupdateEntryInlinea third-party widget gets for its own entry, which first-run seeding and city persistence depend on.qmllintwith the shell's import path reports no errors on any QML file.Review
A read-only review pass over the branch turned up five findings. Three are fixed in the last commit, and the new tests fail on the old code:
addcould corrupt the zones setting.Model.addZoneaccepted any strings, soadd Asia/Tokyo "Tokyo, Japan"came back fromshell.jsonas two rows called Tokyo and Japan, and an id containing a delimiter turned into a different id. It now refuses an idparseZoneswould drop and replaces,and|in a label with spaces.Texthad notextFormat, so a label sent over IPC could carry markup. It is nowText.PlainText.Model.hasZonewas dead code. Removed.Two are left for follow-up rather than folded into the import:
refreshFactswaits onfactsProc.runningand nothing kills the process, so a hung network call (DNS that never answers, which python's socket timeout does not bound) would stop weather and currency refreshing for the rest of the session. The panel keeps working. A Quickshell-side timer that stops the process, plus incremental cache saves in the script so a killed run keeps its geocodes, is the fix.addreturns the list after re-parsing, so a caller cannot tell an accepted add from a refused one. Cosmetic.Not verified
omarchy plugin add https://github.com/omacom/elsewhen.git --enableon a Quattro install is the remaining check.preview.pngyet; the marketplace listing wants one.Left as found
Panel.qmlexposes aherelineIPC method markedTEMPORARY - remove with the header-arc trial; the three header styles it switches are still live UI, so it stays until that trial is settled.