Gestionnaire de fonds d'écran multiplateforme en C++20 : Architecture et intégration système
L'utilitaire CLI Rwal gère les fonds d'écran sous KDE, GNOME, et est prévu pour Windows. Un élément clé est l'interface IWallpaperSetter, implémentant le modèle Adapter. Cela isole la logique métier des spécificités des environnements de bureau, minimisant les #ifdef.
// src/wallpaper/IWallpaperSetter.hpp
class IWallpaperSetter {
public:
virtual ~IWallpaperSetter() = default;
virtual bool setWallpaper(const std::string& path) = 0;
};
Une fabrique détecte l'environnement à l'exécution et retourne l'implémentation appropriée. Ajouter le support d'un nouvel environnement de bureau ne nécessite qu'une nouvelle classe dérivée.
Intégration avec KDE Plasma via D-Bus
KDE nécessite une interaction avec org.kde.plasmashell. L'implémentation KdeSetter envoie un script JavaScript pour appliquer les fonds d'écran à tous les bureaux.
// Extrait simplifié de src/wallpaper/KdeSetter.cpp
QDBusInterface remoteApp("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell");
QString script = QString(
"var allDesktops = desktops();"
"for (var i = 0; i < allDesktops.length; i++) {"
" var d = allDesktops[i];"
" d.wallpaperPlugin = 'org.kde.image';"
" d.currentConfigGroup = Array('Wallpapers', 'org.kde.image', 'General');"
" d.writeConfig('Image', 'file://%1');"
"}"
).arg(QString::fromStdString(path));
remoteApp.call("evaluateScript", script);
Le script configure dynamiquement wallpaperPlugin et Image pour les paramètres de chaque bureau. La gestion des erreurs D-Bus est implémentée via QDBusError.
GNOME : GSettings et modes de thème
Pour GNOME, gsettings est utilisé via QProcess. Il prend en compte picture-uri-dark et picture-uri pour les thèmes sombre/clair.
// De src/wallpaper/GnomeSetter.cpp
QProcess::execute("gsettings", {
"set", "org.gnome.desktop.background", "picture-uri-dark",
QString("file://%1").arg(QString::fromStdString(path))
});
Le code vérifie la disponibilité de gsettings et utilise en secours une copie directe vers ~/.config. Cela assure la stabilité dans les conteneurs.
Couche réseau : Wrapper RAII pour libcurl
Le téléchargement d'images est implémenté via CurlWrapper avec RAII. std::unique_ptr avec un destructeur personnalisé garantit le nettoyage.
// src/net/CurlWrapper.hpp
using CurlPtr = std::unique_ptr<CURL, void(*)(CURL*)>;
// Implémentation
CurlWrapper::CurlWrapper() : curl_(curl_easy_init(), curl_easy_cleanup) {
if (!curl_) throw std::runtime_error("Échec de l'initialisation de CURL");
}
La classe encapsule CURLOPT_USERAGENT, CURLOPT_TIMEOUT et les rappels de progression. Le téléchargement en mémoire utilise CURLOPT_WRITEFUNCTION.
CMake : Build modulaire C++20
Le projet nécessite C++20 pour std::jthread et std::format prévu. CMake trouve Qt5 DBus, CURL, nlohmann_json.
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets)
find_package(CURL REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
add_subdirectory(src/wallpaper)
target_link_libraries(${PROJECT_NAME} PRIVATE wallpaper_lib Qt5::DBus CURL::libcurl nlohmann_json::nlohmann_json)
Éviter Docker simplifie l'accès au D-Bus de l'hôte. La liaison statique de CURL minimise les dépendances.
Asynchronie avec std::jthread
Le téléchargement d'images 4K bloquait l'interface utilisateur. La solution est std::jthread de C++20 :
- Auto-join en sortie de portée.
- stop_token pour l'annulation des opérations.
- Compatibilité co_await avec les coroutines.
std::jthread loader(& {
// Chargement avec vérification de stoken.stop_requested()
});
Compatibilité cross-compilateur : GCC 11+ et Clang 14+ avec -fcoroutines.
Points clés
- Modèle Adapter permet d'ajouter le support d'un environnement de bureau en 15 minutes sans refactorisation du cœur.
- RAII pour libcurl évite les fuites de mémoire dans les chemins d'exception.
std::jthreadrésout les blocages de l'interface utilisateur pendant les opérations réseau.- CMake modulaire assure des builds portables.
- Scripting D-Bus est la seule méthode fiable pour Plasma.
Décisions architecturales et analyse
L'analyse statique avec clang-tidy a révélé des signaux Qt avec des risques d'utilisation après libération. Les ADR documentent le choix de D-Bus plutôt que l'édition directe des configurations.
Plans de développement :
- WinAPI Windows
SystemParametersInfoW. QtNetworkouboost::asiopour l'asynchronie.- Optimisation du parsing JSON pour des réponses de 100 Mo+.
Le projet démontre la programmation système en C++20 pour développeurs intermédiaires : des interfaces aux coroutines.
— Editorial Team
Aucun commentaire pour le moment.