QFreeRDP platform QPA

Premier billet de 2026, je vous souhaite tous mes meilleurs vœux pour cette nouvelle année.
Dans ce billet, je vais parler d'un vieux projet que je trouve très intéressant et qui n'a pas perdu une ride depuis ses plus de 10 ans d'existence: qfreerdp_platform. J'ai fait quelques amélioration intéressantes sur ce projet récemment, et je vais donc en parler un peu.
Fonctionnement interne de Qt

Le framework Qt fonctionne avec une abstraction de la plateforme sur laquelle il tourne: en gros on a des classes indépendantes qui implémentent les widgets, le scripting QML, le rendu, etc. Mais toute la partie qui doit vraiment interagir avec le système, comme par exemple envoyer du contenu à la carte graphique ou bien collecter les signaux des périphériques d'entrée (clavier, souris ou touchscreen), est implémentée par des QPA (Qt Platform Abstraction). Par exemple, quand on lance une application Qt sous Linux, il va y avoir un système d'heuristique qui va soit charger le QPA pour X11 (xcb) ou bien le QPA wayland.
J'en parlais déjà en 2013 dans ce billet, une chose intéressante est qu'on peut forcer le QPA qui va être utilisé par une application, celà se
fait en passant le paramètre -platform <nom du qpa> lors de l'appel du programme Qt (c'est pour ça qu'il
faut passer les paramètres de ligne de commande à la QApplication, c'est pour que Qt puisse sélectionner
les arguments qui lui sont destinés). La chose vraiment surprenante est que le programme Qt sans recompilation
peut tourner à la fois sous X11 et Wayland, ou bien sur un QPA qu'on lui dit d'utiliser...
qfreerdp_platform
Et c'est là qu'intervient ce projet qfreerdp_platform, il s'agit d'un QPA qui permet de publier son application Qt en RDP.
Par exemple, on prend mainapplication, un des programmes d'exemple de Qt, si on le lance en local on obtient ceci:
Mais une fois qfreerdp_platform compilé et installé on peut aussi lancer:
$ ./mainapplication -platform freerdp
Et désormais dans une autre console, si on lance (pas de login / mot de passe / domaine):
$ xfreerdp3 /v:127.0.0.1 /u: /p: /d: /cert:ignore
On obtient cette fenêtre de connexion à distance:
Donc sauf pour le thème, on a la même application qu'on peut utiliser en RDP. Je sais que certain s'en servent par exemple pour faire tourner une application sur un mobile, mais faire les tests à distance. On bénéficie donc de l'application Qt qui va avoir toutes les interactions avec les couches logicielles du mobile, mais on peut tester tranquillement sur son PC plutôt que d'avoir à tout le temps basculer entre le mobile et le desktop.
Dernières améliorations
Depuis un petit bout de temps, le projet utilise meson comme système de build à la
place de l'infâme qmake: tout le monde déteste cmake, mais qmake est encore pire !
Le clipboard est implémenté, donc on a la synchronization du presse-papier entre le local (la machine qui fait tourner le client RDP) et le distant (l'application Qt).
On m'a aussi fait travailler dernièrement sur un système de fenêtrage minimal pour qfreerdp_platform. Le QPA est aussi
responsable de l'interaction avec un éventuel gestionnaire de fenêtres, donc quand il s'agit du QPA xcb pour X11, il va faire
ce qu'il faut avec le serveur X11 et le gestionnaire de fenêtres pour décorer les fenêtres Qt (idem avec le QPA wayland).
Mais dans le cas de qfreerdp_platform, c'est à nous de faire cette gestion des fenêtres: dessiner des bordures, mettre un bouton
pour pouvoir fermer la fenêtre, gérer le focus, le déplacement et le redimensionnement des fenêtres, etc. Après ces développements
on a un gestionnaire de fenêtre basique mais fonctionnel.
En RDP on dispose d'une fonctionnalité qui permet de redimensionner sa fenêtre RDP, j'en avait déjà parlé dans ce billet là et
celui-ci. En gros quand on redimensionne la fenêtre coté client, celui-ci envoit des notifications de modification de taille
des moniteurs. Et donc aussi étrange que celà puisse paraître pour implémenter ce redimensionnment
dynamique, j'ai dû implémenté le support des multiples écrans dans qfreerdp_platform. Et donc avec cette pull request,
on dispose du support multi-écrans: l'application Qt "voit" les moniteurs envoyés par le client
et peut agir en conséquence. Par exemple, pour ne pas mettre une fenêtre à cheval sur deux écrans, ou
quand on demande à passer plein écran, c'est mettre en grand sur l'écran courant.
Conclusion

Ce petit projet est vraiment plein de potentiel, par exemple on peut aussi ne pas avoir la partie listener RDP, et directement
passer au QPA la socket de connection du client RDP (on fait un socketpair et on forke/exec l'application Qt). Dans un scenario
de serveur RDP, ça peut permettre au serveur d'avoir le contenu RDP généré directement par une application Qt qu'on aura développé
sur son poste de travail. Sans faire des commandes RDP à la main
comme le font plein de projets, coucou Xrdp ou redemption.
J'ai aussi sous le coude le support de GL pour Qt en utilisant les DRI rendernodes, sur un serveur ayant une carte graphique supportée ça peut permettre d'utiliser toute la puissance de Qt notamment le QML (cf les applications d'exemples de Qt avec les moteurs de gestion de particules, etc.).
Franchement c'est tellement bien qu'il ne vous reste plus qu'à l'essayer !