Créez votre barre d'état i3/sway en bash et python

21 juin 2020 · 5 min de lecture

i3 est un gestionnaire de fenêtres sur Linux. Il gère les fenêtres par onglet, en pile, et en mosaïque (tiling). L’avantage est que vous ne perdez plus de temps à organiser vos fenêtres avec la souris. Avec i3 la disposition est automatique. Les fenêtres s’ouvrent en occupant l’espace disponible. Par des raccourcis claviers personnalisables, on peut les déplacer, les afficher en plein écran, les agencer horizontalement ou verticalement. Cela s’avère bien plus pratique et rapide que la souris.

Un autre avantage est que la barre d’état est une simple ligne de texte entièrement configurable. Plus besoin d’extensions comme sur Gnome ou KDE qui ne répondent pas toujours à votre besoin.

Vous voulez une barre de menu qui affiche le cours de quelques crypto-monnaies ? un bouton pour activer/désactiver le VPN ? afficher la météo ? afficher votre adresse IP publique ? rien de plus simple avec un peu de bash et de python. Voici comment procéder.

En bas de cet article se trouve le lien vers un dépôt Github avec le code source de tous les widgets présentés dans la barre ci-dessous.

i3 status

Voici une mise en situation :

i3 status

i3 et dérivés

Très rapidement, sachez que i3 sur GitHub est un projet relativement ancien mais toujours actif. Le système est léger et performant. i3-gaps est un “fork” qui permet de créer un espacement entre les fenêtres pour un effet visuel (gap). Il existe aussi Sway qui fonctionne avec Wayland (le successeur du serveur graphique X11). Mais il ne supporte pas les cartes graphiques NVIDIA.

Les scripts présentés ici fonctionneront sur ces trois gestionnaires de fenêtres.

i3status

La barre d’état par défaut est i3status. Un simple fichier de configuration permet d’afficher la date et l’heure, la mémoire utilisée, l’espace disque occupé, le niveau de la batterie et d’autres informations utiles.

Des alternatives plus évoluées existent : i3pystatus, goi3bar, i3status-rust… mais pourquoi utiliser un framework lourd et compliqué quand on peut le faire soi-même ?

Le protocole i3bar est bien documenté. Il suffit de produire un fichier JSON en sortie standard et de lire en entrée les évènements (clic sur un élément de la barre).

Afficher la date et l’heure

Dans le fichier /home/votre-pseudo/.config/i3/config modifiez la ligne status_command pour exécuter votre script bash :

bar {
  status_command exec /home/votre-pseudo/.config/i3status/mybar.sh
}

Un exemple basique de ce script bash est donné à l’adresse suivante : https://github.com/i3/i3/blob/next/contrib/trivial-bar-script.sh. Utilisons ce modèle pour créer le fichier /home/votre-pseudo/.config/i3status/mybar.sh :

# Send the header so that i3bar knows we want to use JSON:
echo '{ "version": 1 }'

# Begin the endless array.
echo '['

# We send an empty first array of blocks to make the loop simpler:
echo '[]'

# Now send blocks with information forever:
while :;
do
  echo ",[{\"name\":\"id_time\",\"full_text\":\"$(date)\"}]"
  sleep 1
done

La boucle while infinie va appeler toutes les secondes la commande système date pour afficher la date et l’heure. Vous pouvez changer la valeur sleep pour rafraichir par exemple toutes les 10 secondes. Rechargez la configuration i3 avec le raccourci clavier WIN+SHIFT+R. Votre barre d’état ressemble maintenant à :

i3 status date

Gestion des clics

Créons tout d’abord un petit script bash nommé par exemple /home/votre-pseudo/.config/i3status/click_time.sh. Il sera appelé lors d’un clic sur la zone date/heure de la barre d’état :

#!/bin/sh
cal -y          # affiche le calendrier de l'année
read -n 1 -r -s # attend une touche clavier pour quitter le terminal

N’oubliez pas de rendre exécutable ce script avec la commande chmod +x click_time.sh.

Modifiez le script précédent mybar.sh de la façon suivante :

echo '{ "version": 1, "click_events":true }'
echo '['
echo '[]'

# lancé dans un processus en arrière plan
(while :;
do
  echo ",[{\"name\":\"id_time\",\"full_text\":\"$(date)\"}]"
  sleep 1
done) &

# Ecoute des évènement en STDIN
while read line;
do
  # echo $line > /tmp/tmp.txt
  # on reçoit en STDIN :
  # {"name":"id_time","button":1,"modifiers":["Mod2"],"x":2982,"y":9,"relative_x":67,"relative_y":9,"width":95,"height":22}

  # DATE click
  if [[ $line == *"name"*"id_time"* ]]; then
    alacritty -e /home/votre-pseudo/.config/i3status/click_time.sh &
  fi  
done

Quelques explications :

  • "click_events":true indique au protocole i3 que nous allons gérer les évènements souris.
  • la boucle principale est alors exécutée en arrière plan pour que la boucle d’écoute de l’entrée standard fonctionne en parallèle.
  • Un exemple du JSON de l’évènement reçu est indiqué en commentaire. Référez-vous à la documentation du protocole i3bar pour plus d’informations.
  • Si l’ID de l’élément cliqué contient id_time, le script click_time.sh est exécuté. Il affiche dans un terminal le calendrier de l’année en cours. alacritty peut être remplacé par le terminal de votre choix.

Démonstration ! un clic sur la date affiche le calendrier annuel :

i3 status date

Afficher le taux d’utilisation du processeur

Et hop, un peu de python dans le fichier /home/votre-pseudo/.config/i3status/cpu.py :

#!/usr/bin/env python3
# installez le paquet "psutil" avec la commande "pip3 install psutil --user"
import psutil
print(psutil.cpu_percent(interval=1), end='')

Ce script affiche par exemple 1.2 si le CPU est occupé à 1.2%.

Revenons au script mybar.sh :

echo '{ "version": 1, "click_events":true }'
echo '['
echo '[]'

# lancé dans un processus en arrière plan
(while :;
do
  echo -n ",["
  echo -n "{\"name\":\"id_cpu\",\"background\":\"#283593\",\"full_text\":\"$(/home/votre-pseudo/.config/i3status/cpu.py)%\"},"
  echo -n "{\"name\":\"id_time\",\"background\":\"#546E7A\",\"full_text\":\"$(date)\"}"
  echo -n "]"
  sleep 1
done) &

# Ecoute des évènement en STDIN
while read line;
do
  # echo $line > /tmp/tmp.txt
  # on reçoit en STDIN :
  # {"name":"id_time","button":1,"modifiers":["Mod2"],"x":2982,"y":9,"relative_x":67,"relative_y":9,"width":95,"height":22}

  # DATE click
  if [[ $line == *"name"*"id_time"* ]]; then
    alacritty -e /home/votre-pseudo/.config/i3status/click_time.sh &

  # CPU click
  elif [[ $line == *"name"*"id_cpu"* ]]; then
    alacritty -e htop &
  fi
done

La barre apparait comme ceci :

i3 status date

Vous avez remarqué qu’une couleur de fond est ajoutée avec la clé background. Lors d’un clic sur l’affichage du CPU, l’utilitaire htop est affiché dans un terminal.

Autres widgets utiles

Normalement, vous avez compris le principe. C’est une manière de procéder mais si vous avez d’autres idées n’hésitez pas à les partager.

Sachez que des icônes peuvent être affichées en utilisant la police Font Awesome.

Je vous partage ma configuration i3 sur Github où vous trouverez également les widgets pour démarrer/arrêter un VPN, afficher la météo, l’adresse IP publique, l’adresse IP locale, l’espace mémoire utilisé, le niveau de la batterie, le volume et le nombre de mises à jour disponibles du système.

PARTAGER

A LIRE EGALEMENT