Blog

Configuration dynamique des écrans sous GNU/Linux

J’utilise régulièrement différentes configurations d’écrans sur mon ordinateur portable tournant sur GNU/Linux, en fonction de l’endroit où je me trouve et de ce que j’y fais. Notamment, je passe quotidiennement de la configuration double écran utilisée à mon domicile (où mon portable est constamment branché à un écran externe) à la configuration simple écran utilisée sur mon lieu de travail. De plus, occasionnellement (mais assez souvent), lors d’un séminaire ou d’un cours, je suis amené à brancher un vidéoprojecteur avec lequel j’utilise selon les situations plusieurs configurations.

Cette note explique le dispositif que j’ai progressivement mis en place pour gérer ces changements réguliers de configuration. L’objectif (atteint) était de pouvoir changer de configuration d’écran

Les différentes configurations

J’utilise XrandR pour configurer dynamiquement mes écrans. Une « configuration d’écran » n’est donc, en définitive, qu’une ligne de commande invoquant xrandr(1) avec les bonnes options.

Voici les différentes configurations que j’utilise 1 :

Nom Commande Description
default
$ xrandr --fb 1600x900 \
  --output LVDS1 --mode 1600x900 --primary \
  --output VGA1  --off
Écran interne seulement
beamer
$ xrandr --fb 1600x900 \
  --output LVDS1 --mode 1600x900 --primary \
  --output VGA1  --mode  800x600 --pos 800x150
Mode pour les présentations Beamer
extern
$ xrandr --fb 1024x768 \
  --output LVDS1 --off \
  --output VGA1  --mode 1024x768
Écran externe seulement
same
$ xrandr --fb 800x600 \
  --output LVDS1 --mode 800x600 \
  --output VGA1  --mode 800x600 --same-as LVDS1
Deux écrans affichant la même image
side
$ xrandr \
  --output LVDS1 --mode 800x600 \
  --output VGA1  --mode 800x600 --right-of LVDS1
Deux écrans affichant un « bureau étendu »
home
xrandr --fb 3520x1080 \
  --output LVDS1 --pos 0x0    --mode 1600x900 \
  --output VGA1  --pos 1600x0 --mode 1920x1080 --primary
Variante de la configuration side adaptée à un écran externe de 22”

Le script xdisplay

Comme il n’est évidemment pas question de saisir intégralement les commandes ci-dessus chaque fois que je désire changer de configuration, j’ai écrit un script shell appelé xdisplay.

xdisplay.sh (text/x-shellscript, 2.0K)

Les configurations ne sont pas codées directement dans le script mais dans des fichiers situés dans $XDG_CONFIG_HOME/xdisplay/ ; chaque fichier décrit une configuration et porte le nom de cette configuration. Par exemple, la configuration default est enregistrée dans un fichier default contenant le code suivant :

#!/bin/sh
# internal screen only
xrandr --fb 1600x900 \
  --output LVDS1 --mode 1600x900 --primary \
  --output VGA1 --off

La seconde ligne est une description succinte de la configuration, utilisée par xdisplay lorsqu’il liste les différentes configurations disponibles (option -l, --list).

Appelé avec un argument (autre qu’une option), xdisplay cherche dans $XDG_CONFIG_HOME/xdisplay un fichier dont le nom correspond à l’argument. Si un tel fichier existe, il est sourcé pour exécuter le code qu’il contient et donc appliquer la configuration.

Appelé sans argument, xdisplay applique automatiquement la configuration qui suit immédiatement la configuration courante. Appeler xdisplay sans argument plusieurs fois permet donc de boucler à travers les configurations disponibles. (C’est là toute la logique nécessaire à l’implémentation du comportement de la combinaison Fn+F7 ; il suffit désormais de faire en sorte qu’un appui sur cette combinaison de touches appelle xdisplay sans argument.)

Intégration dans Awesome

L’intégration dans le gestionnaire de fenêtres Awesome consiste en deux choses :

La figure ci-dessous présente le résultat de cette intégration. En haut à gauche, le widget indiquant la configuration courante (ici, default) ; en haut à droite, le menu de sélection des configurations ; en bas, les icônes représentant les différentes configurations.

Configuration dynamique des écrans sous Awesome

Pour arriver à ce résultat, un objet Lua spécifique, appelé ScreenInfo, est chargé d’encapsuler les appels au script xdisplay et de créer le widget et le menu associé. Cet objet est défini dans un module Lua helpers.2

helpers.lua (text/plain, 4.2K)

Dans le fichier de configuration de Awesome, il faut inclure ce module et instancier un objet ScreenInfo :

require("helpers")
screen_info = ScreenInfo:new()

Le widget affichant la configuration actuelle peut alors être ajouté à la wibox d’Awesome (ici, entre l’horloge et la layoutbox) :

mywibox[s].widgets = {
    ...
    mylayoutbox[s],
    screen_info.widget,
    mytextclock,
    ...
}

Reste enfin à ajouter un key binding pour la combinaison Fn+F7 (la fonction cycle() de l’objet ScreenInfo encapsule un appel sans argument à xdisplay) :

globalkeys = awful.util.table.join(
    ...
    awful.key({ }, "XF86Display", function() screen_info:cycle() end),
    ...
)

Conclusion

En partant des lignes de commande invoquant xrandr, le dispositif décrit ici, centré sur le script shell xdisplay, permet une gestion souple et pratique des configurations d’écran.

Ajouter une nouvelle configuration à celles déjà définies consiste à créer un nouveau fichier dans $XDG_CONFIG_HOME/xdisplay/ décrivant la configuration voulue. Par exemple, si l’on voulait ajouter une configuration similaire à side mais avec l’écran externe placé à gauche de l’écran interne (appelons-là lside), on ajouterait un fichier $XDG_CONFIG_HOME/xdisplay/lside contenant le code suivant :

#!/bin/sh
# wide-desktop with external screen on the left
xrandr \
  --output LVDS1 --mode 800x600 \
  --output VGA1  --mode 800x600 --left-of LVDS1

Pour l’intégration dans Awesome, on ajoutera également un fichier lside.png représentant cette configuration dans le dossier $XDG_DATA_HOME/awesome/icons/.

  1. Dans les commandes xrandr, LVDS1 désigne l’écran interne de mon portable, et VGA1 désigne la sortie VGA et l’écran externe qui y est éventuellement connecté.
  2. Ce module définit également d’autres objets auxiliaires que j’utilise dans ma configuration d’Awesome.