Build a Notification Center in Quickshell (2027 Edition)
Cette vidéo est un tutoriel complet pour construire un système de notifications complet (démon, popups et centre d’historique) avec QuickShell sur NixOS, en utilisant QML et JavaScript.

SYNTHÈSE STRUCTURÉE
Installation et configuration initiale de QuickShell
L’intervenant utilise NixOS avec QuickShell version 0.3.0 déjà disponible dans les paquets Nix. Il vérifie la présence du paquet dans sa configuration système, puis lance nixos-rebuild switch pour l’installer. La vérification se fait avec qs --version. Pour les autres distributions (Arch, Debian), il renvoie vers la documentation officielle sur quickshell.org. Le répertoire de travail est ~/.config/quickshell/, créé avec mkdir -p ~/.config/quickshell.
Fichier de configuration partagé (config.js)
Un fichier JavaScript config.js est créé pour centraliser les couleurs (Tokyo Night), la police (JetBrains Mono Nerd Font, taille 16), la hauteur de la barre (30) et un timeout global de 5000 ms pour les notifications. Ce fichier est importé dans les autres fichiers QML via import "config.js" as Config. L’intervenant précise : « Every file today that does import config.js is going to read these colors. »
Structure du fichier notifications.qml
Le fichier principal contient trois éléments dans un Scope (conteneur non visuel de QuickShell) :
- Un
NotificationServer(le démon) - Un
PanelWindowpour les popups - Un second
PanelWindowpour le centre de notifications
L’intervenant explique que le NotificationServer implémente la spécification freedesktop.org pour les notifications.
Configuration du NotificationServer
Le serveur est configuré avec trois attributs essentiels :
NotificationServer {
id: server
actionsSupported: true
bodySupported: true
imageSupported: true
}
Le gestionnaire onNotification active le suivi des notifications : server.tracked = true. L’intervenant précise que « QML takes any signal and autocreates a handler for it by capitalizing the name and prefixing on in front of it ».
Gestion des fenêtres popup
Le PanelWindow utilise exclusionMode: ExclusionMode.Ignore pour ne pas réserver d’espace sur le bureau. Les ancres sont positionnées en haut à droite avec des marges de 12 pixels. La largeur implicite est de 380 pixels, la hauteur utilise Math.max(1, column.implicitHeight). La couleur de fond est transparente.
Construction de la carte de notification (delegate)
Chaque notification est un Rectangle avec :
- Rayon de 8 pixels
- Bordure de 2 pixels (rouge si urgence critique, violet sinon)
- Hauteur préférée :
layout.implicitHeight + 20 - Couleur de fond issue du fichier config
Le contenu utilise un RowLayout avec une image (36x36, aspectFit), un titre (summary, bold, elide à droite) et un corps (body, wrap mode). L’intervenant précise : « We want to truncate the text here with ellipses here. So QML has a property called elide on text. »
Gestion du timeout et de la fermeture
Un Timer est ajouté à chaque carte :
Timer {
running: card.modelData.urgency !== NotificationUrgency.Critical
interval: Config.notificationsTimeout
onTriggered: card.modelData.dismiss()
}
Les notifications critiques ne se ferment pas automatiquement. La fermeture manuelle se fait via un MouseArea qui appelle card.modelData.dismiss().
Centre de notifications avec historique
Un second PanelWindow est créé pour l’historique, visible uniquement quand root.centerOpen est vrai. Il contient :
- Un en-tête avec le titre « Notifications » et un bouton « Clear all » (visible si
history.count > 0) - Une liste des notifications avec horodatage, nom de l’application et bouton de suppression individuelle
L’historique est alimenté dans le gestionnaire onNotification :
history.insert(0, {
summary: n.summary,
body: n.body,
appName: n.appName,
urgency: n.urgency,
time: Qt.formatDateTime(new Date(), "hh:mm")
})
Communication IPC pour le contrôle
Un IpcHandler est créé pour permettre le contrôle depuis la ligne de commande ou un raccourci clavier :
IpcHandler {
target: "notifications"
functions: [
IpcFunction { name: "toggle"; resultType: IpcResultType.Void; body: { root.centerOpen = !root.centerOpen; } },
IpcFunction { name: "show"; resultType: IpcResultType.Void; body: { root.centerOpen = true; } },
IpcFunction { name: "hide"; resultType: IpcResultType.Void; body: { root.centerOpen = false; } }
]
}
L’intervenant utilise ensuite qs-p notifications.qml && qs-p notifications.qml ipc-call notifications toggle pour tester.
Intégration avec le gestionnaire de fenêtres
Le tutoriel se termine par l’intégration dans Hyprland avec un bind super + N pour basculer le centre de notifications. L’intervenant mentionne que les OSD volume et luminosité feront l’objet d’une future vidéo.
CONCEPTS CLÉS
- QuickShell : Toolkit basé sur QML pour créer des composants de shell de bureau (widgets, écrans de verrouillage, lanceurs, OSD)
- QML : Langage déclaratif pour interfaces utilisateur, similaire à JavaScript/JSON
- NotificationServer : Implémentation QuickShell de la spécification freedesktop.org pour les notifications
- ExclusionMode : Propriété QuickShell qui détermine si une fenêtre réserve de l’espace sur le bureau (Ignore = ne réserve pas)
- IPC Handler : Mécanisme QuickShell pour exposer des fonctions appelables depuis la ligne de commande ou des raccourcis
- Delegate : Modèle QML pour générer des éléments à partir d’une liste de données
CONCLUSION
Ce tutoriel montre comment construire un système de notifications complet et moderne avec QuickShell, en seulement 200 lignes de code QML/JavaScript. L’approche modulaire (fichier de configuration centralisé, séparation démon/popup/centre) permet une maintenance aisée et une intégration fluide dans n’importe quel environnement de bureau. La puissance de QuickShell réside dans sa capacité à créer des composants système réactifs et personnalisables, tout en restant léger et performant.