Notifications sous Linux
Notifications FreeDesktop sur D-Bus — urgence, hints, sons, callbacks d'action, avec les particularités documentées par serveur.
Sous Linux, les notifications passent par le service D-Bus org.freedesktop.Notifications — tous les desktops modernes (GNOME, KDE, Cinnamon, Xfce, Pantheon) l'implémentent, chacun avec ses particularités. notification-linux est un mapping Kotlin complet de la spec, au-dessus de GLib/GIO.
En bref
- D-Bus pur via
libgio-2.0— pas de JNA, pas de bibliothèque D-Bus Java. - Couverture complète : urgence, hints, boutons d'action, image data, sons, flags transient / resident.
- Détection par serveur via
getServerInformation(). - Callbacks d'action livrés par
LinuxNotificationListener.
Installation
dependencies {
implementation("dev.nucleusframework:nucleus.notification-linux:<version>")
}Tire freedesktop-icons transitivement pour les noms d'icônes typés.
Démarrage rapide
import dev.nucleusframework.notification.linux.*
import dev.nucleusframework.freedesktop.icons.FreedesktopIcon
val id = LinuxNotificationCenter.send(
Notification(
appName = "Mon App",
summary = "Build terminé",
body = "artifact-2.0.0.zip est prêt",
appIcon = FreedesktopIcon.Status.DIALOG_INFORMATION,
hints = NotificationHints(urgency = Urgency.NORMAL),
actions = listOf(NotificationAction("open", "Ouvrir")),
),
)Fonctionnement
LinuxNotificationCenter ouvre une connexion D-Bus session au démarrage et la réutilise. Chaque appel notification touche org.freedesktop.Notifications.Notify et renvoie l'id assigné par le serveur. Les invocations d'action et les événements de fermeture reviennent par signaux D-Bus ; on enregistre un LinuxNotificationListener pour les recevoir.
La spec est cohérente ; les serveurs ne le sont pas. La matrice ci-dessous couvre les cas à connaître :
Particularités par serveur
- GNOME Shell : ignore
appIconquand l'app a une fenêtre focus. Mets toujourshints.imagePathpour un rendu fiable. - KDE Plasma : respecte tous les hints, y compris
transient,resident,category,image-data. - Notify-send / dunst : rendu minimal, parfois pas de boutons d'action.
- Sandboxes Snap / Flatpak : le daemon filtre, certains hints (chemins de son) peuvent être ignorés.
Appelle LinuxNotificationCenter.getServerInformation() au démarrage et logge le serveur détecté + ses capacités, ça aide en support.
Référence
Urgence
hints = NotificationHints(urgency = Urgency.CRITICAL)LOW, NORMAL, CRITICAL. Les notifications critiques outrepassent généralement le mode ne-pas-déranger et persistent jusqu'à rejet.
Boutons d'action
val n = Notification(
appName = "Mon App",
summary = "Nouveau message",
actions = listOf(
NotificationAction("reply", "Répondre"),
NotificationAction("archive", "Archiver"),
),
)
LinuxNotificationCenter.setListener(object : LinuxNotificationListener {
override fun onAction(id: Long, actionKey: String) { /* … */ }
override fun onClosed(id: Long, reason: CloseReason) { /* … */ }
})Image inline
hints = NotificationHints(
imageData = ImageData.fromArgb(width, height, bytes),
)Utile quand on n'a pas de fichier sur disque — par exemple un avatar généré.
Sons
hints = NotificationHints(
soundName = NotificationSound.Notification.DIALOG_INFORMATION,
)Fermer par programme
LinuxNotificationCenter.close(id)Notes
- Sous
Xvfbou en CI headless : l'appel rendra la main sans erreur, mais aucun daemon n'affichera la notification. - Si tout marche en dev mais que rien ne s'affiche sous Flatpak, vérifie la permission portail
org.freedesktop.Notificationsdans le manifeste.
Notifications sur Windows
Toast Notifications WinRT en Kotlin — layouts adaptatifs, images héros, boutons, saisie texte, barres de progression, en-têtes, snooze / dismiss.
System tray
Une icône de tray rendue par Compose et un menu contextuel natif sur macOS, Windows et Linux — réactif, compatible GraalVM, sans pipeline d'export d'icônes.