From 72ffd58316265bb770dddfc77983117bf9b91f0a Mon Sep 17 00:00:00 2001 From: Scott Jones Date: Mon, 3 Aug 2026 17:29:14 -0400 Subject: [PATCH] Offer AM/PM clock formats when right-clicking the bar clock (#6536) Every preset in the right-click ring was 24-hour, so a 12-hour label was something you had to hand-write into shell.json. Pair each locale-shaped time preset with its AM/PM twin, and give vertical bars one stacked variant. The ISO preset keeps its 24-hour clock, since ISO 8601 writes time that way. Co-authored-by: Claude Opus 5 (1M context) --- shell/plugins/panels/clock/Model.js | 13 ++++++++++++- test/shell.d/clock-test.sh | 27 ++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/shell/plugins/panels/clock/Model.js b/shell/plugins/panels/clock/Model.js index 8d42f7fc..9607a4a6 100644 --- a/shell/plugins/panels/clock/Model.js +++ b/shell/plugins/panels/clock/Model.js @@ -12,18 +12,29 @@ var WEEKDAY_NAMES = ["sunday", "monday", "tuesday", "wednesday", "thursday", "fr // ---- Bar label formats. Right-clicking the clock walks these in order and // writes the result back to shell.json, so the label the bar shows and // the format the config stores are always the same thing. +// +// The locale-shaped time presets are each followed by their 12-hour twin, so +// the walk from a 24-hour label to the same label in AM/PM is a single right +// click rather than a lap of the ring. The ISO preset is deliberately left +// without one: ISO 8601 writes time on a 24-hour clock, so an AM/PM variant +// would contradict the only thing that format is for. var CLOCK_FORMATS = [ "dddd HH:mm", + "dddd h:mm AP", "HH:mm", + "h:mm AP", "ddd d MMM HH:mm", + "ddd d MMM h:mm AP", "d MMMM 'W'ww yyyy", "yyyy-MM-dd HH:mm" ] // Vertical bars have room for a few stacked lines and nothing else, so the -// ring stays short. +// ring stays short. AM/PM costs a fourth line, which is why only the plain +// time carries it here. var VERTICAL_CLOCK_FORMATS = [ "HH\n—\nmm", + "h\n—\nmm\nAP", "dd\nMMM\n'W'ww\n''yy", "HH\nmm" ] diff --git a/test/shell.d/clock-test.sh b/test/shell.d/clock-test.sh index 6ed9cd6f..582f7736 100755 --- a/test/shell.d/clock-test.sh +++ b/test/shell.d/clock-test.sh @@ -138,7 +138,32 @@ assertDeepEqual(calendar.clockFormatRing('', '', []), ['HH:mm'], 'clock keeps a assertEqual(calendar.nextClockFormat(ring, ring[0]), ring[1], 'clock steps to the next format') assertEqual(calendar.nextClockFormat(ring, ring[ring.length - 1]), ring[0], 'clock wraps the format ring') assertEqual(calendar.nextClockFormat(ring, 'HH:mm:ss'), ring[0], 'clock starts at the top from a format outside the ring') -assertEqual(calendar.clockFormats(true)[0], 'HH\n\u2014\nmm', 'clock keeps stacked formats for vertical bars') +// Both rings, contents and order: a right click walks this list and writes +// the result back to shell.json, so an inserted preset should have to be +// acknowledged here. +assertDeepEqual( + calendar.clockFormats(false), + [ + 'dddd HH:mm', 'dddd h:mm AP', + 'HH:mm', 'h:mm AP', + 'ddd d MMM HH:mm', 'ddd d MMM h:mm AP', + "d MMMM 'W'ww yyyy", + // No twin: ISO 8601 writes time on a 24-hour clock, so an AM/PM variant + // would contradict the one thing that format is for. + 'yyyy-MM-dd HH:mm' + ], + 'clock offers the horizontal presets in this order' +) +assertDeepEqual( + calendar.clockFormats(true), + ['HH\n\u2014\nmm', 'h\n\u2014\nmm\nAP', "dd\nMMM\n'W'ww\n''yy", 'HH\nmm'], + 'clock offers the stacked presets in this order' +) +assertEqual( + calendar.nextClockFormat(ring, 'dddd HH:mm'), + 'dddd h:mm AP', + 'clock reaches an AM/PM twin in one right click' +) assertEqual(calendar.isoWeekLiteral(2026, 0, 5), '02', 'clock zero-pads the ISO week token') // ---- widget wiring