11 KiB
Calendar Agenda design
Summary
Panama will use Evolution Data Server (EDS), the same calendar backend already used by GNOME Calendar, to turn the existing date menu into a live Daybook. The shell will display synchronized Google, iCloud/CalDAV, Nextcloud, local, and ICS subscription events without owning account credentials or implementing calendar sync.
The approved visual direction is A · Daybook: a 760-pixel Prism panel with a month calendar on the left and the selected day's agenda on the right. GNOME Calendar remains the account-management and event-editing application.
Goals
- Show events from every enabled EDS calendar already visible to GNOME Calendar.
- Keep month context and the selected day's schedule visible together.
- Represent all-day, timed, recurring, and multi-day events correctly.
- Preserve the complete notification center, weather, and conditional media controls in the date menu.
- Open events in GNOME Calendar and expose a Join action for recognized meeting links.
- Surface upcoming events globally only when they are timely and actionable.
- Continue working from EDS's local cache while account providers are offline.
Non-goals
- Panama will not store account passwords, OAuth tokens, or CalDAV credentials.
- Panama will not add, remove, or reconfigure calendar accounts.
- Panama will not create or edit events in the first release. Those actions open GNOME Calendar.
- Panama will not implement reminders, alarms, tasks, or email invitations.
- Panama will not parse remote ICS URLs or synchronize calendar data itself.
- Wi-Fi QR sharing is no longer planned.
Existing system
The workstation runs Evolution Data Server 3.60.2 and GNOME Calendar 50. EDS currently reports ten enabled event sources backed by CalDAV, contacts, and a local calendar. The GNOME Shell calendar service also works in the Hyprland session and reports that calendars are available.
Panama can therefore integrate below the GNOME Calendar user interface:
Google / iCloud / Nextcloud / ICS subscriptions
│
▼
Evolution Data Server
┌──────┴──────┐
▼ ▼
GNOME Calendar Panama Daybook
manage + edit glance + launch
Architecture
Calendar bridge
Add config/dot/quickshell/scripts/calendar-agenda, a small Python/GObject
bridge using the installed EDataServer and ECal introspection libraries. A
native EDS client is preferred over scraping GNOME Calendar or reading source
files because it preserves recurrence, time-zone, source, and cached-sync
semantics.
The bridge exposes three commands:
probereports whether EDS, the source registry, and at least one enabled event source are available. It never emits account names or event contents.query START ENDreturns one normalized JSON snapshot and exits. It is used by tests and as a recovery path.watch START ENDemits newline-delimited JSON snapshots. It refreshes when a source changes and periodically as a defensive fallback. Restartingwatchwith a new range is how the shell follows month navigation.
watch queries enabled E_SOURCE_EXTENSION_CALENDAR sources, connects an
ECal.Client for each one, and expands recurrence instances for the requested
time range. One unavailable source does not suppress healthy sources. Refreshes
are debounced so a provider sync produces one shell update rather than a burst.
Each snapshot has one stable contract:
{
"ok": true,
"generatedAt": 1786978200,
"sources": [
{
"id": "source-id",
"name": "Calendar name",
"color": "#82aaff"
}
],
"events": [
{
"id": "source-id:event-id:instance",
"sourceId": "source-id",
"uid": "event-id",
"summary": "Event title",
"start": 1786978200,
"end": 1786980000,
"allDay": false,
"location": "",
"joinUrl": ""
}
],
"errors": []
}
Source and event identifiers remain local. Descriptions and attendee lists are not sent to Quickshell. The bridge inspects the component URL, location, and description only to extract an HTTPS Google Meet, Zoom, Microsoft Teams, Webex, or Jitsi URL; it does not include the original description in its output.
Quickshell service
Add services/CalendarAgenda.qml as the single shell-facing calendar state
owner. It will:
- Start and supervise the bridge.
- Hold normalized source and event arrays.
- Track loading, ready, degraded, and unavailable states.
- Expose events and colored day markers for a requested date or month.
- Calculate the next timed event and its relative start text.
- Open GNOME Calendar by event UUID, or by date when no event UUID exists.
- Open recognized meeting links through
xdg-open. - Restart the bridge when the visible month leaves the current loaded range.
The normal range begins seven days before the visible month and ends seven days after it. This covers all 42 calendar cells and the near-future bar capsule with one query.
The service refreshes when the Daybook opens, after a bridge change event, at midnight, and every ten minutes as a fallback. It never writes event data to Panama configuration or logs.
Daybook interface
Panel structure
The date menu grows from 480 to 760 logical pixels and keeps the current Prism surface, top-center anchor, type system, and open motion.
┌ Monday, August 17 ─────────────── DND · Open Calendar ┐
│ August 2026 │ Up next · in 24 minutes │
│ S M T W T F S │ Command Center standup Join │
│ month grid │─────────────────────────────│
│ colored markers │ Today · Your schedule │
│ │ 1:00 Release planning │
│ weather / media │ 2:30 Focus time │
│ │ 6:30 Dinner │
│ │ 2 notifications View │
└─────────────────────────┴─────────────────────────────┘
The left column is 310 pixels wide. It contains the month grid followed by the conditional media card and weather. The right column owns either the agenda or the full notification list. Its content scrolls independently when necessary; the panel itself does not grow beyond the usable monitor height.
Calendar interaction
- Opening from the clock selects today and shows the agenda.
- Clicking a current-month day selects it and updates the right column.
- Clicking an adjacent-month day navigates to that month and selects the day.
- Month arrows retain the selected day where possible and request a new range.
- Today uses the solid blue accent. The selected non-today date uses a restrained accent surface.
- A day shows up to three source-colored dots. Additional events do not add more dots.
- Calendar source names appear beside events rather than in a permanent legend, which remains usable when more than three calendars are enabled.
Agenda interaction
- The first future timed event on the selected day becomes the Up Next card.
- Up Next shows a Join action only for a recognized meeting URL.
- All-day events appear before timed events and do not become Up Next.
- Timed events are sorted by start time. Past events remain visible but dimmed.
- Each event shows its source color, time, summary, source name, and concise location when present.
- Clicking an event opens it in GNOME Calendar with
--uuid. - An empty day says
Nothing scheduledand keeps anOpen Calendaraction. - Event titles are single-line and elide; full details belong in GNOME Calendar.
Notifications, media, and weather
The notification summary appears at the bottom of the agenda only when history is non-empty. Clicking it replaces the right column with the existing grouped notification list. Opening the panel from the notification indicator starts in that notification view; opening it from the clock starts in Agenda.
Notification view keeps DND and Clear All. A Back to agenda action restores
the selected day without resetting the month. Existing inline replies remain
keyboard-accessible.
The media card stays conditional and moves beneath the calendar. Weather remains the quiet final item in the left column. Neither competes with Up Next.
Quiet global event capsule
The bar does not permanently display calendar content and Panama does not emit calendar toasts or sounds.
A compact event capsule appears only for the next timed event:
- fifteen minutes before its start;
- through five minutes after its start; and
- only when the event is not marked all-day.
The capsule shows a calendar glyph and relative time, such as 12m or Now.
The title stays in a tooltip to avoid exposing work details across the bar.
Clicking opens the Daybook on today. If a meeting URL exists, a small secondary
Join affordance is available inside the Daybook, not on the bar.
The capsule uses event-driven transitions only. It has no pulse, shimmer, or continuous animation.
Failure and privacy behavior
- If one account is offline, cached events from that source remain visible when EDS provides them; healthy sources continue normally.
- If the bridge fails, the calendar grid, notifications, media, and weather
remain usable. The agenda says
Calendar data is unavailableand offersOpen Calendar. - Malformed event fields are omitted individually rather than crashing the service.
- Live event summaries, locations, URLs, and account names are never written to shell logs, settings, fixture files, or repository content. Synthetic fixture copy is intentionally generic.
- The bridge does not access EDS authentication extensions or credential stores.
- URL actions require a user click and only allow
https://links.
Testing
Focused tests will cover:
- The bridge's probe and normalized JSON contract without printing live event contents.
- Time-range filtering, ordering, all-day handling, recurrence identifiers, meeting-link allowlisting, and malformed component handling through synthetic local fixtures.
- CalendarAgenda state, selected-date filtering, month marker aggregation, and next-event timing through a deterministic fixture mode.
- Daybook panel structure, date activation, notification-view routing, and GNOME Calendar launch commands through contract tests.
- A live read-only EDS smoke test that asserts enabled source and event counts while redacting names and summaries.
- Fresh Quickshell compilation, Hyprland configuration verification, visual fixture screenshots, and a live panel check against the current EDS cache.
No test creates, modifies, or deletes a real calendar event.
Documentation updates
- Mark Calendar Agenda live in
config/dot/hypr/DESKTOP-PARITY.md. - Remove Wi-Fi QR sharing from the remaining roadmap and package guidance.
- Document GNOME Calendar as the account/editing handoff and the quiet capsule
behavior in
config/dot/hypr/README.md.