OsaNotch transforme l'encoche du MacBook en petite île dynamique. Au survol, elle s'ouvre avec une animation à ressort et regroupe la musique et ses paroles, une étagère de fichiers, les réglages système et toutes les apps OsaLabs. Au centre, une mascotte qui suit ton curseur des yeux.
SwiftSwiftUIAppKitWebKitIOKitEventKitAccessibility API
45commits en 5 jours
4 379lignes de Swift
23fichiers source
2versions : Electron, puis natif
01Le point de départ
« L'encoche, c'est 3 cm de vide en plein milieu de l'écran. Je voulais qu'elle serve à quelque chose. »
Sur un MacBook récent, l'encoche de la caméra mange le centre de la barre des menus. Des apps comme NotchNook ont montré qu'on pouvait en faire une zone utile, mais je voulais la mienne : connectée à mes propres outils, et avec un peu de personnalité.
Le premier prototype, le matin du 7 octobre, était une app Electron : une fenêtre transparente plein écran qui dessinait dans la bande de l'encoche. Ça marchait, mais l'interrogation de macOS par osascript s'accumulait et l'app pesait lourd pour ce qu'elle faisait. Le soir même, j'ai tout réécrit en Swift natif.
02En images
À quoi ça ressemble.
La bannière du projet, avec la mascotte dans son encoche.
notch.osalabs.fr
Le site de téléchargement, qui sert aussi les mises à jour automatiques.
03Comment ça marche
Sous le capot.
OsaNotch est une seule app SwiftUI qui va chercher ses données à plein d'endroits de macOS, sans jamais faire de polling lourd.
1
Une fenêtre au-dessus de la barre des menus
Un NSPanel sans bordure, placé juste au-dessus du niveau de la barre des menus. Hors de l'île, les clics passent au travers.
2
Un survol qui réveille tout
Un moniteur global d'événements détecte la souris près de l'encoche. L'île s'ouvre avec un ressort SwiftUI, et la mascotte, dessinée dans un Canvas, se réveille.
3
Les vraies données du Mac
Musique via AppleScript, pochettes via l'API iTunes, paroles via LRCLIB, batterie via IOKit, agenda via EventKit, luminosité via DisplayServices.
4
Un HUD qui remplace celui de macOS
Un CGEventTap intercepte les touches volume et luminosité : les gros carrés gris disparaissent, une barre fine glisse sous l'encoche.
5
Les apps OsaLabs embarquées
Une WKWebView invisible charge les pages « pont » d'OsaDrop, OsaCast et OsaParty. Le notch utilise donc exactement le même moteur WebRTC que les sites.
✦À toi de jouer
Survole l'encoche
Une reproduction de l'île. Une visite guidée tourne toute seule ; prends la main quand tu veux : survole l'encoche, change d'onglet, glisse un fichier dessus ou touche au volume.
!Les défis
Ce qui a résisté.
Dessiner au-dessus de la barre des menus
ProblèmeUne fenêtre classique passe sous la barre des menus, et une fenêtre trop haute vole le focus des autres apps.
SolutionJ'ai testé plusieurs niveaux de fenêtre (pleine largeur, économiseur d'écran…) avant de retenir mainMenuWindow + 3, avec acceptsFirstMouse pour que le premier clic réagisse.
Ne jamais bloquer le Mac
ProblèmeUne fenêtre posée au-dessus de tout qui garde le focus peut rendre l'ordinateur inutilisable.
SolutionUn correctif prioritaire : Échap referme toujours l'île, plus aucun vol de focus en boucle, et les clics traversent tout ce qui n'est pas l'île.
Savoir quand une IA a fini, sans API
ProblèmeLire la barre d'état des outils donnait des faux positifs, et le scan figeait l'interface.
SolutionDétection par signaux propres à une génération en cours, confirmée par 3 relevés de suite (6 s), et scan déplacé sur un thread d'arrière-plan.
Réutiliser plutôt que réécrire
ProblèmeMa première version native d'OsaCast utilisait une autre bibliothèque WebRTC et ne parlait pas au site.
SolutionUne page « pont » chargée dans une WebView : un seul moteur pour le web et le Mac, donc tout est interopérable.
⏱Journal de bord
Comment c'est arrivé.
Prototype Electron
Overlay transparent avec de vraies données : musique, pochette, batteries, agenda.
La mascotte prend vie
Yeux qui suivent le curseur, respiration, clignements, émotions.
Réécriture en Swift natif
NSPanel dans l'encoche, mascotte dessinée en Canvas SwiftUI.
Correctif anti-blocage
Échap referme toujours, plus de vol de focus.
Moteur OsaDrop unifié
Pont WebRTC natif via une WebView qui réutilise le site.
HUD volume & luminosité
Une barre blanche sous l'encoche, l'affichage natif supprimé.
Paroles animées
Lecteur compact avec défilement des paroles façon Apple Music.
Mises à jour automatiques
L'app lit un manifeste sur mon serveur et se met à jour en un clic.
Étagère & installateur
Presse-papier de fichiers, mode cinéma OsaCast, icône et DMG.
Pont OsaParty
Le notch envoie la position de lecture au salon web pour synchroniser les paroles.
OsaDrop aligné sur le site
Codes à 6 caractères dans le notch : un fichier envoyé depuis le site arrive enfin dans le notch.
→Et ensuite
La suite du projet.
Notariser l'app auprès d'Apple pour supprimer le « clic droit → Ouvrir » au premier lancement.
Rendre les modules activables un par un dans les réglages.
Ouvrir une petite API locale pour que d'autres outils puissent afficher leurs notifications dans l'île.
Astuce : les flèches ←→ de ton clavier passent d'un projet à l'autre.