Composantes graphiques

Ce module requiert, pour son fonctionnement global, le binding python de la bibliothèque Xlib. Certaines fonctionnalités nécessitent également des programmes tiers, voir ci-dessous.

Les trucs dont le chemin d'accès est de la forme « :X » où X est un nombre correspondent aux différents serveurs graphiques accessibles (TODO fournir une alternative à tout ça pour Wayland). Le chemin particulier $DISPLAY permet de récupérer le serveur graphique actuellement utilisé, à partir de la variable d'environnement du même nom. Chaque serveur graphique possède des enfants :X/keyboard et :X/pointerY (où Y est le numéro de la souris, une seule (de numéro 0) étant gérée pour l'instant mais c'est techniquement faisable d'en mettre plusieurs sous X, il faudra que je creuse ça), ainsi que les différents écrans et les différentes sélections.

Le chemin « :X/window » permet d'obtenir un stuff listant les fenêtres principales actuellement ouvertes (qui ne sont pourtant pas considérées comme des enfants du serveur, car elles possèdent leur propre arbre). Le chemin « :X/input » récupère le clavier et les différents pointeurs, « :X/screen » les différents écrans, et « :X/selection » les différentes sélections.

Actuellement, le serveur graphique n'a pas d'états particuliers, pas de clefs (ça viendra, TODO, par exemple l'identifiant du gestionnaire de fenêtres), mais reconnaît les requêtes « select » (change la variable d'environnement $DISPLAY pour que tous les programmes lancés depuis le programme en cours utilisent ce serveur-ci), et « moveto:X » qui active le bureau virtuel X. D'autres requêtes sont prévues mais pas encore implémentées, comme la possibilité d'ajouter ou de retirer un bureau virtuel, ou de déplacer le viewport.

L'objet control d'un serveur graphique en état de marche possède les attributs « file » (chemin d'accès à la socket), « root » (truc correspondant à la fenêtre racine), « active » (truc correspondant à la fenêtre active), « display » et « screen » (objets Xlib associés au serveur graphique), ainsi qu'une méthode « event » pour faciliter l'envoi d'événements X. Ces attributs ne sont pas disponibles si le serveur graphique n'est présentement pas utilisable.

Fenêtres

Sous X, les fenêtres sont identifiées par un chemin de la forme « :X/Y », où « :X » est le serveur graphique et « Y » le numéro d'identifiant de la fenêtre. On interagira surtout avec les fenêtres principales (celles qui sont décorées et navigables via alt+tab), qui sont accessibles par le stuff particulier « :X/window » (ou « $DISPLAY/window » dans la plupart des cas utiles). Les fenêtres ont leur propre arbre, et il est possible d'accéder aux parents ou aux enfants d'une fenêtre, mais c'est rarement utile en pratique.

Les clefs/valeurs des fenêtres correspondent à ses attributs X, que l'on peut aussi obtenir par exemple avec la commande « xprop ». On récupérera notamment le nom de la fenêtre par les clefs « WM_NAME » ou « _NET_WM_NAME ». Une clef supplémentaire « GEOMETRY » est cependant ajoutée pour fournir de manière facilement utilisable les taille et position actuelles de la fenêtre. Un truc de type fenêtre peut présenter les états et répondre aux requêtes suivantes :

En complément, les requêtes suivantes modifient les attributs de la fenêtre sans être directement liées à un état en particulier :

L'objet control associé à la fenêtre permet d'accéder à l'id de celle-ci ainsi qu'à l'objet Xlib correspondant. Il fournit aussi des méthodes event, setstate et setproperty pour modifier plus facilement les propriétés d'une fenêtre.

Clavier

Le chemin « :X/keyboard » permet d'accéder à un truc correspondant au clavier, qui présente autant que possible des clefs et valeurs suivantes :

Le clavier reconnaît les requêtes « press:X », « release:X » et « toggle:X » où la bibliothèque fera tout son possible pour trouver un numéro de touche à appuyer/relâcher correspondant à la chaîne « X », et une requête « remap:X », permettant de changer la disposition clavier en utilisant les commandes setxkbmap et/ou xmodmap. La chaîne X attendue peut commencer par une dispo clavier à passer à la première commande, par exemple « us » ou « fr oss », et peut se terminer par une série de « [keycode=keysym] » passés ensuite à la seconde pour remapper certaines touches en particulier.

L'icône du clavier est l'icône « keyboard » présente dans le thème, au dessus de laquelle est affichée la valeur qui sera obtenue par les quatre premières touches alphabétiques du clavier, par exemple « AZER » ou « bépo », en fonction de l'état actuel.

L'objet control du clavier est lui-même un objet écoutable, permettant de suivre l'appui sur les touches : les fonctions référencées recevront deux paramètres, le premier correspondant au numéro de la touche, et le second étant un booléen indiquant son nouvel état. Il fournit également une méthode sample permettant d'indiquer les caractères qui seront obtenus lors de l'appui sur une touche (utilisée pour générer l'icône), et des méthodes press, release et toggle, permettant de gérer les touches directement depuis leur numéro, plutôt que par une chaîne de caractère avec les requêtes. De même, demander un entier comme clef renvoie un booléen indiquant si la touche en question est active ou non.

Souris

Le chemin « :X/pointerY » (pour l'instant uniquement « :X/pointer0 ») permet d'accéder à un truc permettant d'interagir avec la souris. Le nom est « pointer » et non pas « mouse » car dans les faits, le pointeur peut être déplacé par autre chose qu'une souris, et le truc essaye d'ailleurs de refléter ça autant que possible. En effet, son icône change en fonction du dernier périphérique à avoir déplacé le pointeur, parmi les images du thème « mouse », « touchpad » ou « tablet ». Une requête « reicon:X » permet de changer l'icône qui sera utilisée si le dernier déplacement a été effectué par le pointeur virtuel.

De façon analogue au clavier, le pointeur possède une clef « buttons » qui indique les numéros des boutons actuellement actifs ; ainsi qu'une clef « position » indiquant la position actuelle du pointeur à l'écran (les clefs « x » et « y » peuvent être utilisées pour obtenir l'une de ces valeurs directement). Les requêtes « press:X », « release:X » et « toggle:X » permettent de simuler l'appui sur des boutons, et on y ajoute les requêtes « moveby:X,Y » et « moveto:X,Y » pour gérer la position.

Le pointeur reconnaît aussi les requêtes « tabletmode:relative » et « tabletmote:absolute » pour régler le mode des éventuelles tablettes graphiques (en utilisant la commande xsetwacom), « cursor:X » pour modifier l'apparence du curseur avec la commande xsetroot (je n'ai pas trouvé comment identifier le curseur actuellement affiché, sinon la clef correspondate serait fournie aussi), et « hide » et « show » pour afficher ou masquer le curseur en utilisant le programme unclutter.

Le pointeur reçoit d'ailleurs l'état « hidden » quand un unclutter est en train de tourner. Il présente également l'état « relative » ou « absolute » quand une tablette a été utilisée pour la dernière fois (qui est également exposée par une clef « mode »), ainsi que l'état « active » si au moins un bouton est enfoncé. Enfin, un état parmi « mouse », « tablet », « touchpad » et « virtual » est ajouté, selon le dernier périphérique utilisé.

Les informations relatives au dernier périphérique utilisé ne sont cependant généralement pas disponibles avec les commandes thing et stuff, dans la mesure où elles nécessitent qu'un évennement X se produise une fois que le « truc » est chargé, afin d'en identifier la cause, ce qui n'est pas évident sur un instantané.

L'objet control du pointeur est également écoutable, avec deux paramètres, pour suivre les actions directement. Il peut s'agir soit d'un numéro de bouton suivi d'un booléen indiquant son nouvel état, soit de deux entiers indiquant la nouvelle position. Les méthodes « moveby », « moveto », « press », « release » et « toggle » peuvent être utilisées de façon analogue aux requêtes correspondantes.

Écrans

L'implémentation actuelle pour les écrans relève plus du test que du code pérenne. En théorie, les écrans devraient être accessibles par des chemins du type « :X/eDP1 » ou autre identifiants utilisés par des programmes comme xrandr. En l'état, un seul écran est reconnu, il permet d'obtenir la luminosité actuelle (TODO : mais la valeur récupérée n'a pas l'air d'être la bonne (la requête indiquant directement une valeur fonctionne bien pour sa part)), le mode (largeur et hauteur en pixels) et les différents choix de modes disponibles.

Les requêtes actuellement reconnues sont « off » (lance xset dpms force off), « light:up » et « light:down » (ou, en plus court, « up » et « down ») pour augmenter ou diminuer la luminosité, et « light:X » où X est un entier entre 0 et 100 pour la fixer à une valeur précise. Il faudrait également ajouter une requête pour changer de mode, des clefs/requêtes pour gérer le gamma, etc.

L'icône d'un écran est une image spéciale affichant un écran plus ou moins intensément jaune en fonction de sa luminosité, ou l'icône « display » du thème actif si l'écran n'a pas de luminosité réglable. Une requête « reicon:X » permet d'y ajouter (ou de la remplacer par dans le second cas) une image arbitraire pour l'identifier s'il y a plusieurs écrans.

Sélections

Les sélections usuelles sont accessibles par « :X/CLIPBOARD » (presse-papier usuel), « :X/PRIMARY » (sélection+clic milieu) et « :X/SECONDARY », mais il est également possible d'en gérer d'autres dont le nom de sélection (après l'identifiant du serveur graphique) commencera toujours par un « _ ».

TODO Code pas encore transféré dans le nouveau dépôt.