Window Key Switcher : anatomie d’un rabbit hole avec Claude Code
Laisse-moi te raconter le jour où j’ai enfin essayé Claude Code et où je me suis enfoncé dans un rabbit hole jusqu’à créer Window Key Switcher, une extension GNOME Shell pour piloter mes fenêtres au clavier.
Chaque section a son raccourci. Appuie sur 1 à 7 pour sauter directement à l’une d’elles, ou (0) pour toutes les voir.
Salut Claude Code
Depuis que les LLM et les agents de code sont apparus il y a quelques années, je suis resté assez sceptique. La hype autour de l’IA, avec ses grandes déclarations sur le remplacement pur et simple des développeurs et ses promesses d’applications créées en un claquement de doigts, m’a fait lever les yeux au ciel un paquet de fois, surtout quand on parlait de code frontend et d’accessibilité. J’ai hésité longtemps avant de me lancer, mais comme tout bon ingénieur, je ne peux pas avoir un avis tranché sans l’appuyer sur de l’expérience et du vécu. J’avais besoin d’apprendre et de comprendre ce que ces outils savent faire et ne savent pas faire, et c’est pas évident vu la vitesse à laquelle ça bouge en permanence. Parfois j’étais déçu, parfois j’étais impressionné, mais aucun des outils que j’ai testés n’a vraiment fait tilt au point de me faire reconsidérer complètement ma façon de travailler.
Aucun, jusqu’à ce que j’essaie Claude Code.
Je crois que ça tient au fait que Claude Code s’utilise dans un terminal. Avec les forks de VS Code comme Cursor ou Windsurf, je dois ouvrir un projet et là, mon cerveau se dit automatiquement « je suis dans un IDE, je suis censé demander à l’agent d’écrire du code ». Avec Claude Code (et ses concurrents comme Gemini CLI, Open Code ou Codex), mon cerveau se dit « je suis dans un terminal, je peux faire tout ce que je veux sur ma machine ». Dans son article Claude Code is My Computer, Peter Steinberger décrit quelque chose de très proche du déclic que j’ai eu récemment. Cerise sur le gâteau, Claude Code se branche sur WebStorm, donc je peux continuer à utiliser l’IDE que j’adore et que je maîtrise très bien.

Niveau -1 L’achat de nouveaux écrans
La plupart du temps, quand je bosse chez moi ou dans mon espace de coworking, j’utilise deux écrans. J’ai mon IDE sur l’écran du laptop et mon navigateur sur un écran de bureau posé au-dessus. Dès que j’ai besoin de mon terminal, un seul raccourci l’affiche ou le masque, sur l’écran où se trouve la souris. Je travaille comme ça depuis des années !
À force d’utiliser Claude Code, j’ai commencé à mener plusieurs choses de front, avec plusieurs onglets de terminal ouverts en parallèle. Passer de l’un à l’autre était tellement pénible que ça a réveillé une vieille envie : passer à quatre écrans. Mon raisonnement était simple, et peut-être un peu bête : avec plus de surface d’affichage, je pourrais voir plusieurs fenêtres de terminal en même temps et surveiller chaque session Claude Code, tout en gardant mon navigateur et mon IDE sous les yeux.
C’est comme ça que je me suis convaincu d’acheter deux écrans portables USB-C de 15 pouces reconditionnés. Ils sont légers, je peux les emmener partout. J’ai testé de les mettre à la verticale, ce que je n’avais jamais vraiment fait avant. Mais maintenant que j’avais toutes ces fenêtres de terminal, j’avais très envie de pouvoir les découper verticalement et horizontalement.
Niveau -2 La quête du terminal parfait
D’abord, j’ai réessayé tmux. Ce n’était pas ma première tentative, mais comme la fois d’avant, je n’ai pas accroché aux raccourcis. Ils sont trop bizarres et trop compliqués pour moi. De plus, je n’ai pas besoin du système de sessions, et le support de la souris ne marche pas vraiment en natif.
Je suis donc parti à la recherche d’un nouveau terminal. J’utilisais xfce-terminal depuis mon époque XFCE et je l’avais gardé après être revenu à GNOME. C’est là que je suis tombé sur Ghostty. Il découpe ses fenêtres nativement, avec des raccourcis clavier pour « split left » ou « split down », parfait pour mon usage.
Je l’utilise depuis quelques jours et je ne reviendrai pas à xfce-terminal.
Au passage, Ghostty se configure avec un fichier, sans interface graphique ni assistant. Aucun problème, j’ai demandé à Claude Code de :
- chercher ma palette de couleurs personnalisée de xfce-terminal sur ma machine (aucune idée de l’endroit où elle est rangée)
- lancer
ghostty +show-config --default --docspour récupérer la liste des options et leur documentation - se servir de cette sortie pour me poser des questions, comme une sorte d’assistant de configuration
- écrire le fichier de configuration à ma place
Le seul problème que j’ai avec Ghostty pour l’instant, c’est l’absence de support Linux (avec X11) pour le mode « dropdown », qu’ils appellent « quick-terminal ». Comme je le disais plus haut, je suis accro au fait d’avoir un seul raccourci pour afficher et masquer mon terminal sur la moitié haute de mon écran, ou en plein écran parfois.

Niveau -2.5 Le script bash
J’ai passé une soirée à bricoler un script bash pour imiter ce comportement de dropdown avec xdotool.
Là encore, j’ai demandé à Claude Code.
Ça marchait… plus ou moins.
Mais le placement de la fenêtre était bancal.
C’est surtout une limite de ce que xdotool sait faire, comparé à une approche plus précise.
Je suis allé me coucher avec une solution qui fonctionnait, mais qui ne me satisfaisait pas vraiment.
Niveau -3 L’extension GNOME Shell
Le lendemain matin, j’en voulais plus, je voulais une version plus propre et plus puissante de ce script bash. C’est là que j’ai décidé de créer une extension GNOME Shell. J’ai aussi accepté avec une résignation enjouée que j’étais désormais un résident permanent de ce rabbit hole.
J’avais déjà construit une extension pour piloter les fenêtres de mon bureau en HTTP, avec mon outil de slides maison, pour mon talk sur le cache HTTP. Mais en vrai, je n’avais que très peu de connaissances et d’expérience sur les extensions GNOME Shell. À l’époque, j’avais surtout copié et adapté une extension existante trouvée sur GitHub, et je me souviens que parcourir la documentation de l’API était un vrai bazar.
J’ai commencé à décrire mon idée à Claude Code :
- dix raccourcis :
Super + touche-chiffre - associer n’importe quelle application à un chiffre
- appuyer sur le raccourci :
- si l’application n’est pas lancée, la lancer
- si l’application est lancée, donner le focus à sa fenêtre
- si l’application a plusieurs fenêtres ouvertes, donner le focus à la suivante comme le ferait Alt+Tab (ce n’était pas si simple)
- bonus : mettre en évidence la fenêtre qui vient de recevoir le focus
Le premier essai en mode « vibe coding »
J’ai utilisé le « plan mode » pour écrire une liste d’étapes détaillée, avec les détails d’expérience utilisateur et les consignes de structure du code. J’ai fait quelques itérations pour affiner le plan et une fois satisfait, je lui ai dit d’y aller. Claude Code a mis environ 9 minutes pour construire l’extension. Je me disais déjà « super, je l’installe et je passe à un vrai projet ».
Je l’ai installée et ça a planté. Les bases étaient là, mais plusieurs détails ne marchaient pas. En plus, j’avais oublié de lui dire d’utiliser Context7, du coup il visait une vieille version de GNOME Shell et il n’utilisait pas la syntaxe ESM la plus récente.
Les sessions de pair programming
En m’enfonçant encore un peu plus dans ce trou, j’ai décidé de coder l’extension moi-même, avec l’aide de Claude Code bien sûr, mais en profitant de l’occasion pour découvrir l’écosystème des extensions GNOME Shell, que je connaissais mal.
J’avais déjà vécu le même échec du « génère-moi tout d’un coup » sur un autre projet. Mon manque de connaissances et d’expérience sur la stack m’avait empêché de réparer les choses moi-même.
J’ai tout supprimé et j’ai demandé à Claude de démarrer une session de pair programming avec moi. L’idée était d’avancer pas à pas, d’apprendre de nouvelles API et de nouvelles techniques en chemin, et surtout de vérifier que tout marchait avant de passer à l’étape suivante.
On a commencé par créer une extension GNOME Shell toute simple qui écrit « Hello, world! » dans les logs quand on l’active, et cette fois, on a utilisé Context7 !
Pour référence, voici la documentation des extensions GNOME Shell qu’on a utilisée tout au long du développement.
Ensuite, on s’est concentré sur les mouvements de base dont j’avais besoin pour la chorégraphie :
- écouter un raccourci clavier
- lire la configuration des raccourcis clavier
- lister les fenêtres ouvertes
- donner le focus à une fenêtre
- lancer un programme
- mettre une fenêtre en évidence
Pour certains, Claude Code m’a proposé plusieurs options entre lesquelles je devais choisir. Il a trouvé genre 5 façons de lancer une application. Au final, je n’ai pas ouvert la documentation de l’API une seule fois et la plupart du code produit fonctionnait tel quel.
Une fois ces mouvements de base au point, j’aurais pu redonner sa chance à la méthode « génère-moi tout d’un coup ». J’ai préféré continuer à itérer et à apprendre… Ça m’a permis de tester différentes façons d’architecturer le code. Je voulais quelque chose de vraiment propre et bien rangé, et j’ai surtout l’habitude des projets navigateur et Node.js. J’ai aussi pris le temps d’automatiser un peu d’outillage sur le projet.
Voici comment les modules du projet s’assemblent.
Un résultat satisfaisant
Au final, j’ai une extension GNOME Shell qui marche et qui fait exactement ce que je voulais. La première fois que j’ai obtenu un truc qui marche, j’ai souri comme un gamin devant une glace.
Maintenant, je donne le focus à mon terminal avec un seul raccourci. Je n’ai plus vraiment besoin du comportement dropdown. Je n’ai pas besoin de le masquer, j’ai juste besoin de donner le focus à une autre application, mon navigateur ou mon IDE, avec un seul raccourci. Je suis encore dans la phase d’apprentissage de la mémoire musculaire, j’ai d’ailleurs fait quelques Alt+Tab entre mon éditeur markdown et le navigateur en écrivant cet article.
J’ai poussé le code sur GitHub mais à l’heure où j’écris ces lignes, je ne l’ai pas encore publiée sur le site des extensions GNOME. Je veux d’abord prendre le temps de l’utiliser un moment. Si ça te tente, tu peux l’installer en local et la tester, et surtout, fais-moi des retours.
La suite du projet
Je vais voir comment je m’en sers dans différentes situations :
- en déplacement, avec le laptop seul
- en configuration classique, laptop + écran
- en nouvelle méga configuration, laptop + écran + 2 écrans portables verticaux
J’ai aussi quelques idées d’améliorations et de prochaines étapes :
- Essayer d’automatiser des tests et les lancer avec GJS et/ou Node.js, avec des mocks.
- Expérimenter le fait d’avoir la même application sur plusieurs raccourcis. Comme ça, si j’ai 2 fenêtres de terminal, je pourrais donner le focus à celle que je veux avec un seul raccourci. Je ne suis pas sûr d’en avoir vraiment besoin, et je ne sais pas trop comment je l’implémenterais.
- Peaufiner le README et le guide CONTRIBUTING.
- Ce projet m’a donné plein d’idées d’autres extensions, et même l’envie de relancer mon extension Window manager HTTP et de la publier !
Ce que j’ai appris
Comme je le disais, j’ai appris plein de choses sur ce projet :
- Je comprends beaucoup mieux ce que les extensions GNOME Shell peuvent faire ou pas avec leurs API (raccourcis clavier, gestion des fenêtres…).
- Le runtime JavaScript GJS supporte maintenant ESM.
- Fini le
const MyModule = Me.imports.myModuled’un autre âge !
- Fini le
- Des gens ont créé des définitions de types pour GJS et pour les extensions GNOME Shell.
- On ne peut pas importer directement depuis
node_modules, mais on peut bundler son code avant d’installer son extension.
Au final, j’ai surtout architecturé le projet moi-même. La majorité du code a été générée puis retravaillée à mon goût. Claude Code a été un très bon binôme de pair programming et un expert des extensions GNOME Shell qui sait tout, une fois que je lui ai dit d’utiliser Context7 et d’aller regarder quelques dépôts d’extensions sur GitHub.
Je me suis servi de ce projet pour mieux comprendre les LLM et les agents de code.
J’ai essayé de trouver le bon équilibre entre le vibe coding à l’aveugle et taper chaque caractère de mes fichiers .js.
Je pense sincèrement que ma façon de travailler s’est améliorée dans l’histoire.
Les galères en chemin
Ça aurait dû être un projet simple, mais je suis tombé sur quelques difficultés en route :
- Le cycle d’itération est un peu pénible. À chaque fois que je veux tester le code, je dois construire l’extension et recharger GNOME Shell. J’ai l’habitude du live-reload dans le navigateur ou des redémarrages automatiques avec Node.js. Même avec les scripts que j’ai écrits, ça reste douloureux.
- L’écoute des raccourcis clavier est assez limitée, mais j’imagine que c’est pour des raisons de sécurité.
- J’ai dit qu’il existait des définitions de types pour les extensions, mais la plupart des gens s’en servent dans des fichiers
.ts. Je préfère écrire des fichiers.jsavec du JSDoc et vérifier les types avec le CLI TypeScripttsc. Comprendre comment configurer tout ça a été un peu plus dur. - Il m’a fallu du temps pour savoir ce que je voulais vraiment comme comportement de cycle de focus entre les fenêtres.
- J’ai failli tout envoyer valser en réalisant que quelqu’un avait déjà fait une extension très similaire.
- Je ne sais pas comment j’ai pu passer à côté pendant mes premières recherches.
- Je suis content d’avoir construit ma propre solution, elle colle mieux à mon besoin et j’ai beaucoup appris.
Conclusion
Tout ça a commencé par une utilisation plus intensive de Claude Code, et ça m’a mené à acheter des écrans, à changer de terminal, et pour finir à construire une extension GNOME Shell. Ça m’a même poussé à écrire cet article, ce qui est tellement rare que ce blog était presque devenu une blague.
Parfois, les meilleurs projets naissent quand tu grattes là où ça te démange, quand tu t’enfonces dans le trou aussi profond qu’il aille, surtout si tu apprends des choses en chemin.
Window Key Switcher est peut-être une extension toute bête, mais elle règle parfaitement mon besoin très particulier. Et la fabriquer m’a fait découvrir tout un écosystème que je n’avais quasiment jamais exploré. Ça m’a aussi permis de mieux comprendre les LLM et les agents de code.
C’est ça la beauté des side projects : ce n’est jamais seulement une histoire de résultat final.