Cross-platform notifications
Send a notification on macOS, Windows, and Linux from a single Kotlin DSL — title, message, image, action buttons, lifecycle callbacks.
Every desktop platform ships a different notification stack — UserNotifications on macOS, WinRT toasts on Windows, FreeDesktop D-Bus on Linux. notification-common collapses the intersection into one Kotlin DSL so the 80% case is a single dependency.
TL;DR
- One DSL:
notification { … }.send(). - Title, body, large image, small icon, up to five action buttons, lifecycle callbacks.
- Routes to
notification-macos,notification-windows, ornotification-linuxat runtime. - Drop down to the per-OS module when you want progress bars, scheduling, categories.
Install
dependencies {
implementation("dev.nucleusframework:nucleus.notification-common:<version>")
}This pulls in all three platform modules transitively; only the matching one is loaded at runtime.
Quickstart
import dev.nucleusframework.notification.common.*
NotificationManager.initialize()
val n = notification {
title = "Download complete"
message = "report.pdf has been saved"
button("Open") { openFile() }
button("Show in folder") { showInFolder() }
}
n.send()How it works
NotificationManager resolves the active platform at startup and delegates to the matching native bridge. The DSL captures the lowest common denominator: text, an image, up to five buttons, and lifecycle events (onShown, onDismissed, onAction). Anything richer — schedules, categories, hero images, progress bars — stays in the per-OS module.
You can mix the two: send most notifications through the common API, and reach for WindowsNotificationCenter or NotificationCenter (macOS) when a specific notification needs the long tail.
Routes to notification-macos. Requires user authorisation and a bundled, signed app (./gradlew runDistributable).
Routes to notification-windows. The AUMID is derived from NucleusApp.appId for unpackaged apps; MSIX apps use their package identity.
Routes to notification-linux and uses org.freedesktop.Notifications over D-Bus. Works on GNOME, KDE, Cinnamon, anything that ships a notification daemon.
Reference
Build a notification
val n = notification {
title = "New message from Alice"
message = "Have you seen the latest build?"
button("Reply") { /* … */ }
button("Mute") { /* … */ }
onShown { id -> log.info("shown: $id") }
onDismissed { reason -> log.info("dismissed: $reason") }
}Send
when (val result = n.send()) {
is NotificationResult.Shown -> /* delivered */
is NotificationResult.Failed -> log.warn(result.toString())
}Capability check
if (!NotificationManager.isAvailable()) {
// The current OS / sandbox does not allow notifications.
}Notes
OS integration
Reach into every OS API a desktop dev needs — notifications, tray, dock, dark mode, global hotkeys, media controls, accent color — from idiomatic Kotlin.
Notifications on macOS
Full Kotlin mapping of Apple's UserNotifications framework — categories, attachments, text input, schedules, interruption levels.