Dux Calendar
IPC
IPC
The dcal daemon exposes a scriptable IPC surface, handy for compositor keybinds and automation. Invoke a method and pass params as key=value pairs:
dcal ipc ui.toggle
dcal ipc events.list from=2026-06-01T00:00:00Z to=2026-06-30T23:59:59Z
dcal ipc reminders.upcoming limit=5
List every available method and its params:
dcal ipc list
Results are printed as JSON, so they pipe cleanly into jq and friends.
Common Methods
UI
| Method | Description |
|---|---|
ui.show | Show the calendar window — view (month|week|day|agenda) |
ui.hide | Hide the calendar window |
ui.toggle | Toggle the calendar window — view (month|week|day|agenda) |
ui.open | Open a webcal:// or https ICS subscription link — url* |
ui.openEvent | Open a specific event's details window — uid*, start (RFC3339) |
ui.quit | Quit the running daemon |
ui.openEvent addresses events by their iCal UID (events.list includes it as uid), so external tools like bar widgets can jump straight to an event's native details view. Recurring occurrences share the series UID; pass the occurrence's start to pin a specific instance:
If the calendar window isn't open yet, it launches and navigates once loaded.
Events
| Method | Params |
|---|---|
events.list | query, from (RFC3339), to (RFC3339), limit, offset (all optional) |
events.get | uid*, calendarId, start (occurrence start RFC3339 for recurring events) |
events.create | calendarId*, summary*, start*, end*, description, location, allDay, status (confirmed|tentative|cancelled), reminders, recurrence (RRULE list) |
events.update | id*, plus any of the create fields, plus occurrenceStart (RFC3339 — shift a single occurrence of a recurring series) |
events.delete | id* |
events.rsvp | id*, response* (accept|decline|tentative) — reply to a meeting invitation |
Tasks
| Method | Params |
|---|---|
tasks.list | query, calendarId, includeCompleted (true|false, default true), limit, offset (all optional) |
tasks.get | id* |
tasks.create | calendarId*, summary*, description, location, due (RFC3339), start (RFC3339), allDay, priority (0-9), status (needs_action|in_process|completed|cancelled), parentUid, reminders, recurrence |
tasks.update | id*, plus any of the create fields, plus percentComplete (0-100) |
tasks.complete | id*, completed (true|false, default true) |
tasks.delete | id* |
Calendars
| Method | Params |
|---|---|
calendars.list | — |
calendars.create | accountId*, name* (create a calendar in a local account) |
calendars.setHidden | calendarId*, hidden* (true|false) |
calendars.rename | calendarId*, name (empty clears the override) |
calendars.setReminders | calendarId*, overrides (omit to inherit global settings) |
calendars.delete | calendarId* |
Accounts
| Method | Params |
|---|---|
accounts.list | — |
accounts.refresh | accountId (empty syncs all) |
Reminders
| Method | Params |
|---|---|
reminders.upcoming | limit (default 20) |
reminders.test | Fire a test notification |
System
| Method | Params |
|---|---|
system.autostart.get | Report autostart status |
system.autostart.set | enabled* (true|false) |
system.colorScheme.get | Current portal color scheme (0 no preference, 1 dark, 2 light) |
system.openUri | uri* — open a URI with the desktop portal's default handler |
Live Updates
Subscribe to push events instead of polling. Handy for bar widgets that mirror calendar state:
| Method | Params |
|---|---|
subscribe | topics — comma list of accounts,calendars,events,tasks,sync,ui (all if omitted) |
unsubscribe | topics — topics to stop receiving |
ping | Liveness check |
version | Daemon and API version |
describe | List every method and its params (same data as ipc list) |
* marks a required param. Run dcal ipc list for the complete, always-up-to-date set of methods on your installed version.
Keybind Example
Bind a key in your compositor to toggle the calendar. For niri:
binds {
Mod+Shift+C { spawn "dcal" "ipc" "ui.toggle"; }
}