Skip to content

rolljee/TouchDeck

Repository files navigation

TouchDeck 🎛

Release License: MIT Platform

Un mini "Pock" personnel : un moteur Swift minimal qui affiche ta Touch Bar en permanence, piloté par un simple config.json rechargé à chaud. Toute la logique métier (actions, widgets dynamiques) passe par des commandes shell — donc tu peux tout écrire en Node/JavaScript.

Installation (binaire pré-compilé)

  1. Télécharge TouchDeck-x.y.z.zip depuis les Releases (binaire universel Intel + Apple Silicon).
  2. Dézippe et glisse TouchDeck.app dans /Applications.
  3. L'app n'étant pas notarisée (signature ad-hoc), au premier lancement : clic droit → Ouvrir, ou :
xattr -d com.apple.quarantine /Applications/TouchDeck.app
open /Applications/TouchDeck.app

Pourquoi Swift et pas Electron ?

L'API TouchBar d'Electron ne s'affiche que quand une fenêtre Electron a le focus — impossible d'en faire un outil global. Pock et MTMR utilisent des API privées macOS (DFRFoundation, presentSystemModalTouchBar) pour afficher une barre persistante. TouchDeck reprend exactement cette technique, mais réduit le Swift au strict minimum (~400 lignes) : tu ne touches quasiment que le JSON et tes scripts JS.

Compilation depuis les sources

Prérequis : un Mac avec Touch Bar, Xcode Command Line Tools (xcode-select --install), Node pour les widgets JS (optionnel).

git clone https://github.com/rolljee/TouchDeck.git
cd TouchDeck
make app        # produit TouchDeck.app
# ou juste : make run

Au premier lancement :

  • une icône 🎛 apparaît dans la barre de menus (recharger la config, quitter…) ;
  • un fichier ~/.config/touchdeck/config.json est créé avec une config par défaut ;
  • la Touch Bar s'affiche. Si tu la fermes (bouton ✕), l'icône 🎛 dans le Control Strip la rouvre.

Configuration

Édite ~/.config/touchdeck/config.json — la Touch Bar se met à jour à la sauvegarde (pas besoin de relancer). Voir config.example.json pour un exemple complet.

Types de widgets

button — un bouton qui exécute une commande shell :

{ "type": "button", "label": "🚀 Deploy", "action": "node ~/scripts/deploy.js", "backgroundColor": "#FF5733" }

appSwitcher — les apps ouvertes avec leurs icônes, tap pour basculer (façon Dock de Pock) :

{ "type": "appSwitcher", "width": 320 }

shellLabel — un texte dynamique : le stdout de la commande est affiché, rafraîchi toutes les refreshInterval secondes. C'est ton point d'entrée JavaScript idéal :

{ "type": "shellLabel", "command": "node ~/.config/touchdeck/scripts/status.js", "refreshInterval": 30 }

spacer — espacement : "size" = "small", "large" ou "flexible".

Widgets en JavaScript

Copie scripts/status.js dans ~/.config/touchdeck/scripts/ pour l'exemple fourni (heure + batterie). N'importe quel script qui écrit sur stdout fonctionne : météo, CI, PRs GitHub en attente, etc. Les commandes tournent dans zsh -l, donc ton PATH habituel (node, brew…) est disponible.

Publier une release

Le workflow GitHub Actions (.github/workflows/release.yml) compile un binaire universel, package TouchDeck.app et attache le zip à une Release GitHub à chaque push de tag :

git tag v0.2.0
git push origin v0.2.0

Lancement automatique au login

Avec TouchDeck.app dans /Applications : Réglages Système → Général → Ouverture à la session → ajouter TouchDeck. Sinon, avec le binaire brut, crée ~/Library/LaunchAgents/io.touchdeck.plist :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>io.touchdeck</string>
    <key>ProgramArguments</key>
    <array>
        <string>/CHEMIN/VERS/TouchDeck/.build/release/TouchDeck</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Puis : launchctl load ~/Library/LaunchAgents/io.touchdeck.plist

Comment ça marche (pour comprendre le Swift)

  • main.swift / AppDelegate.swift — app "accessory" (pas d'icône Dock) + menu barre de menus + watcher de config.
  • TouchBarController.swift — construit la NSTouchBar depuis le JSON et la présente en "system modal" via l'API privée presentSystemModalTouchBar, avec une icône dans le Control Strip pour la rouvrir.
  • DFR.swift — charge les fonctions C privées de DFRFoundation à runtime via dlopen/dlsym (évite de linker un framework privé).
  • Sources/TouchBarPrivate/ — déclarations Objective-C des méthodes privées d'AppKit (résolues dynamiquement à runtime).
  • Widgets.swift — app switcher et shell label.
  • Config.swift — modèle JSON + rechargement à chaud (DispatchSource sur le fichier).

Avertissements

  • API privées : non documentées par Apple. Elles fonctionnent sur toutes les versions de macOS supportant la Touch Bar (c'est ce qu'utilisent Pock et MTMR), mais Apple ne garantit rien. Pas de distribution App Store possible.
  • Si la Touch Bar se comporte bizarrement après plusieurs reloads : pkill "Touch Bar agent"; killall ControlStrip la réinitialise.

Pistes d'évolution

Volume/luminosité (nécessite des API privées supplémentaires), widget "shellButton" (label dynamique + action au tap), groupes/pages de widgets, long-press pour actions secondaires, support de SF Symbols (NSImage(systemSymbolName:)).

Inspirations

  • Pock — le Dock dans la Touch Bar
  • MTMR — Touch Bar configurée en JSON (si tu veux du clé-en-main sans compiler)
  • TouchBar Simulator — pour tester sans Touch Bar physique

About

A macos menu bar for mac with touchbar

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors