Add a calendar popup to the clock
Clicking the clock reveals a month grid with ISO week numbers, a year progress meter, and month stepping. Right click walks the common label formats and writes the chosen one back to shell.json, so the bar shows what the config stores. The week start toggles from the grid's "W" heading and persists as weekStartDay, defaulting to the locale's own first day. Rich popup widgets live in their own plugin directories, so the clock moves out of bar/widgets/ into panels/clock/. The id is unchanged, so existing layouts and centerAnchor keep working. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c2610c3788
commit
e2d655d265
@@ -56,7 +56,7 @@ Example `shell.json` (bar subtree only shown):
|
||||
|---|---|---|
|
||||
| `omarchy.menu` | Omarchy menu launcher | left = menu · right = terminal |
|
||||
| `omarchy.workspaces` | Hyprland workspace switcher | left = focus workspace |
|
||||
| `omarchy.clock` | Date/time label | left = alternate format · right = timezone selector |
|
||||
| `omarchy.clock` | Date/time label + popup with a month grid, ISO week numbers, and month stepping | left = popup · right = cycle label format · middle = timezone selector |
|
||||
| `omarchy.media` | MPRIS now-playing — scrolling track + artist, cover-art popup | left = play/pause · middle = next · scroll = prev/next · right = popup |
|
||||
| `omarchy.indicators` | Manual state indicators | left = indicator action |
|
||||
| `omarchy.system-update` | Available update indicator | left = update |
|
||||
@@ -166,7 +166,7 @@ Widgets receive `bar` (the shell root), `moduleName` (string), and `settings` (o
|
||||
- `bar.requestPopout(owner)` / `bar.releasePopout(owner)` — one-popup-at-a-time coordinator
|
||||
|
||||
First-party bar widgets are manifest-backed just like third-party widgets.
|
||||
Simple widgets carry sibling manifests such as `widgets/Clock.manifest.json`;
|
||||
Simple widgets carry sibling manifests such as `widgets/Workspaces.manifest.json`;
|
||||
richer popup plugins live in feature directories such as `../panels/audio/`,
|
||||
`../panels/network/`, and `../model-usage/`; and feature plugins such as
|
||||
`omarchy.menu` and `omarchy.media` declare their bar-widget entry points in their own
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "omarchy.clock",
|
||||
"name": "Clock",
|
||||
"version": "1.0.0",
|
||||
"author": "Omarchy",
|
||||
"description": "Day/time label; click to toggle alternate format",
|
||||
"kinds": [
|
||||
"bar-widget"
|
||||
],
|
||||
"entryPoints": {
|
||||
"barWidget": "Clock.qml"
|
||||
},
|
||||
"barWidget": {
|
||||
"displayName": "Clock",
|
||||
"description": "Day/time label; click to toggle alternate format",
|
||||
"category": "Time",
|
||||
"allowMultiple": false
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Ui
|
||||
|
||||
BarWidget {
|
||||
id: root
|
||||
moduleName: "omarchy.clock"
|
||||
|
||||
property bool alt: false
|
||||
property date displayDate: clock.date
|
||||
|
||||
readonly property string activeFormat: alt
|
||||
? (vertical ? setting("verticalFormatAlt", "dd\nMMM\n'W'ww\n''yy") : setting("formatAlt", "d MMMM 'W'ww yyyy"))
|
||||
: (vertical ? setting("verticalFormat", "HH\n—\nmm") : setting("format", "dddd HH:mm"))
|
||||
readonly property string displayText: formatted(displayDate)
|
||||
readonly property var verticalLines: displayText.split("\n")
|
||||
|
||||
function refresh() {
|
||||
displayDate = new Date()
|
||||
}
|
||||
|
||||
function isoWeek(date) {
|
||||
var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()))
|
||||
var day = d.getUTCDay() || 7
|
||||
d.setUTCDate(d.getUTCDate() + 4 - day)
|
||||
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1))
|
||||
return Math.ceil(((d - yearStart) / 86400000 + 1) / 7)
|
||||
}
|
||||
|
||||
function isoWeekLiteral(date) {
|
||||
var week = isoWeek(date)
|
||||
return (week < 10 ? "0" : "") + week
|
||||
}
|
||||
|
||||
function formatted(date) {
|
||||
return Qt.formatDateTime(date, activeFormat.replace(/ww/g, isoWeekLiteral(date)))
|
||||
}
|
||||
|
||||
implicitWidth: button.implicitWidth
|
||||
implicitHeight: button.implicitHeight
|
||||
|
||||
SystemClock {
|
||||
id: clock
|
||||
precision: SystemClock.Minutes
|
||||
onDateChanged: root.displayDate = date
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "omarchy.clock"
|
||||
function refresh(): void { root.broadcast("refresh") }
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
text: root.vertical ? "" : root.displayText
|
||||
labelVisible: !root.vertical
|
||||
hasVisualContent: root.vertical ? root.verticalLines.length > 0 : text !== ""
|
||||
fixedHeight: root.vertical ? root.verticalLines.length * Style.bar.iconSlot : -1
|
||||
horizontalMargin: 8.75
|
||||
verticalPadding: 8.75
|
||||
onPressed: function(button) {
|
||||
if (!root.bar) return
|
||||
if (button === Qt.RightButton) root.bar.run("omarchy-menu-timezone")
|
||||
else root.alt = !root.alt
|
||||
}
|
||||
|
||||
Column {
|
||||
visible: root.vertical
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: root.verticalLines
|
||||
|
||||
OpticalGlyph {
|
||||
required property string modelData
|
||||
width: button.width
|
||||
height: Style.bar.iconSlot
|
||||
text: modelData
|
||||
fontFamily: button.fontFamily
|
||||
fontSize: modelData.length > 3
|
||||
? button.fontSize * 0.9
|
||||
: button.fontSize
|
||||
color: button.foreground
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user