khal-calendar

June 14, 2026 · View on GitHub

A DankBar widget that shows upcoming calendar events from a khal-managed vdir, with a full popout panel for viewing, creating, editing, and deleting events.

type:widget capability:dankbar-widget

screenshot

Features

  • Works with any CalDAV server via vdirsyncer (iCloud, Google, Nextcloud, etc.)
  • All khal calendars available — filter which ones appear in the widget
  • Create, edit, and delete events directly from the popout
  • Desktop notifications before upcoming events
  • Middle-click an event to open URLs from its description or location
  • Scrollable popout with momentum scrolling and auto-hiding scrollbar
  • Per-calendar name display and event location display
  • Configurable look-ahead window and refresh interval

Architecture

QML widget → khal CLI → local vdir ← vdirsyncer (user-managed) → CalDAV server

The plugin reads and writes events through khal against a local vdir directory. vdirsyncer handles CalDAV synchronization independently — configure it separately with a systemd timer or cron job.

Bar Display

  • Horizontal pill: shows the next upcoming event with time and title (e.g. 14:00 Meeting)
  • Vertical pill: shows the total event count with a "cal" label

Popout Panel

  • Grouped event list by day with time ranges
  • Color-coded all-day and timed events
  • Left-click an event to edit title, time, and location
  • Middle-click an event to open URLs found in its description or location
  • Add new events with calendar selection, date/time pickers, and optional location
  • Delete events from the edit form
  • Last updated timestamp with manual refresh button
  • DankFlickable scrolling with mouse wheel, touchpad momentum, and auto-hiding scrollbar

Prerequisites

Setup

1. Configure vdirsyncer

Create ~/.config/vdirsyncer/config with your CalDAV accounts. Example for Google:

[general]
status_path = ~/.vdirsyncer/status/

[pair google]
a = google_remote
b = google_local
collections = ["from a", "from b"]

[storage google_remote]
type = google_calendar
token_file = ~/.vdirsyncer/google_token
client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET

[storage google_local]
type = filesystem
path = ~/.vdirsyncer/calendars/google/
fileext = .ics

Run discovery and initial sync:

vdirsyncer discover google
vdirsyncer sync

Set up a recurring sync (systemd timer or cron):

# Example systemd timer: sync every 5 minutes
systemctl --user enable vdirsyncer.timer

2. Configure khal

Create ~/.config/khal/config:

[calendars]
[[google_local]]
path = ~/.vdirsyncer/calendars/google/*
type = discover

[locale]
timeformat = %H:%M
dateformat = %Y-%m-%d
longdateformat = %Y-%m-%d
datetimeformat = %Y-%m-%d %H:%M
longdatetimeformat = %Y-%m-%d %H:%M

[default]
default_calendar = YourCalendarName

Verify with khal list to confirm events appear.

3. Install the plugin

git clone https://github.com/szabolcsf/dms-khal-calendar.git
cp -r dms-khal-calendar ~/.config/DankMaterialShell/plugins/khalCalendar

Enable the plugin in DMS Settings → Plugins, then add it to your DankBar.

4. Configure plugin settings

In the plugin settings:

  • Vdir base path: set to your khal calendars directory (default: ~/.local/share/khal/calendars/)
  • Calendar filter: comma-separated calendar names to show, or leave empty for all. Use khal printcalendars to see available names.

Settings

SettingDescriptionDefault
Calendar filterComma-separated calendar names to show (empty = all)
Vdir base pathPath to khal's vdir calendars directory~/.local/share/khal/calendars/
Look-ahead (days)How many days into the future to show events7
Refresh interval (minutes)How often to fetch events5
Show event locationDisplay location for events that have oneOn
Show calendar nameDisplay which calendar each event belongs toOff
Desktop notificationsSend a notification before upcoming eventsOn
Notify before (minutes)How far in advance to notify15

How it works

Event listing

khal list <today> <today+Nd> --json ... fetches events. khal outputs one JSON array per day — each parsed and merged into the event list. The calendar filter passes -a <name> flags to restrict which calendars appear.

Event creation

khal new -a <calendar> <start> <end> <summary> --location <loc> creates events. All-day events use date-only format; timed events use YYYY-MM-DD HH:MM.

Event editing / deletion

The plugin reads the event's .ics file from <vdir>/<calendar>/<uid>.ics, modifies SUMMARY, DTSTART, DTEND, and LOCATION fields via sed, and writes back. khal picks up changes on the next operation. Deletion removes the .ics file directly.

Notifications

khal at <now> --notstarted --json ... checks for events starting within the notify window. Deduplication uses persisted state. Sends notifications for upcoming events.

URL opening

Middle-clicking an event scans its description and location for https?:// URLs and opens each via xdg-open.

Compositors

Tested on Niri. Should work on any compositor supported by DankMaterialShell.

License

MIT