From 54349062e59333479b032bb9700ac2a55597ce48 Mon Sep 17 00:00:00 2001 From: pengwenhao Date: Thu, 13 Jun 2024 10:24:04 +0800 Subject: [PATCH] feat: wallpaper usage treeland personalization manager protocol Signed-off-by: pengwenhao --- misc/dde.portal | 2 +- .../treeland-personalization-manager-v1.xml | 188 ++++++++++++++++++ src/CMakeLists.txt | 9 + src/access.cpp | 59 ++++++ src/access.h | 27 +++ src/account.h | 5 +- src/ddesktopportal.cpp | 2 + src/ddesktopportal.h | 2 + src/personalization_manager_client.cpp | 43 ++++ src/personalization_manager_client.h | 45 +++++ src/wallpaper.cpp | 67 ++++++- src/wallpaper.h | 28 ++- 12 files changed, 466 insertions(+), 11 deletions(-) create mode 100644 protocol/treeland-personalization-manager-v1.xml create mode 100644 src/access.cpp create mode 100644 src/access.h create mode 100644 src/personalization_manager_client.cpp create mode 100644 src/personalization_manager_client.h diff --git a/misc/dde.portal b/misc/dde.portal index d273c0d..25d7070 100644 --- a/misc/dde.portal +++ b/misc/dde.portal @@ -1,4 +1,4 @@ [portal] DBusName=org.freedesktop.impl.portal.desktop.dde -Interfaces=org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Notification;org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.Wallpaper;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.RemoteDesktop +Interfaces=org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Notification;org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.Wallpaper;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.RemoteDesktop;org.freedesktop.impl.portal.Access UseIn=DDE diff --git a/protocol/treeland-personalization-manager-v1.xml b/protocol/treeland-personalization-manager-v1.xml new file mode 100644 index 0000000..0f235ac --- /dev/null +++ b/protocol/treeland-personalization-manager-v1.xml @@ -0,0 +1,188 @@ + + + + Copyright © 2023 Uniontech + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This interface allows a client to customized display effects. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + set window background, shadow based on context + + + + + + + custom user wallpaper + + + + + + custom user cursor + + + + + + + This interface allows a client personalization wallpaper. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + get the current user's wallpaper + + + + + Destroy the context object. + + + + + Send this signal after getting the user's wallpaper. + + + + + + + This interface allows a client personalization cursor. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + + + + + + + + + + + + + + if only one commit fails validation, the commit will fail + + + + + Destroy the context object. + + + + + Send this signal after commit cursor configure. + + + + + + Send this signal after system cursor theme changed. + + + + + + Send this signal after system cursor size changed. + + + + + + + This interface allows a client personalization window. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + This will instruct the compositor how to set the background + for the window, desktop. + + + + + + + + Destroy the context object. + + + + + + Destroy the context object. + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 65f8d5f..b0e47a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,6 +52,8 @@ set(SRC iteminfo.cpp account.h account.cpp + access.cpp + access.h globalshortcut.h globalshortcut.cpp lockdown.h @@ -63,11 +65,18 @@ set(SRC dbushelpers.h utils.h utils.cpp + personalization_manager_client.h + personalization_manager_client.cpp ) add_executable(${PROJECT_NAME} ${SRC}) +qt6_generate_wayland_protocol_client_sources(${PROJECT_NAME} + FILES + ${CMAKE_SOURCE_DIR}/protocol/treeland-personalization-manager-v1.xml +) + target_link_libraries(${PROJECT_NAME} PUBLIC Qt::Core Qt::Widgets diff --git a/src/access.cpp b/src/access.cpp new file mode 100644 index 0000000..4379ad6 --- /dev/null +++ b/src/access.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2024 Wenhao Peng . +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "access.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +Q_LOGGING_CATEGORY(XdgDestkopDDEAccess, "xdg-dde-access") + +AccessPortal::AccessPortal(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + qCDebug(XdgDestkopDDEAccess) << "access init"; +} + +uint AccessPortal::AccessDialog( + const QDBusObjectPath &handle, const QString &app_id, const QString &parent_window, const QString &title, + const QString &subtitle, const QString &body, const QVariantMap &options, QVariantMap &results) +{ + qCDebug(XdgDestkopDDEAccess) << "request for access dialog"; + + QMessageBox access_dialog; + + if (options.contains(QStringLiteral("modal"))) { + access_dialog.setModal(options.value(QStringLiteral("modal")).toBool()); + } + + QPushButton *rejectButton = nullptr; + if (options.contains(QStringLiteral("deny_label"))) { + rejectButton = access_dialog.addButton(options.value(QStringLiteral("deny_label")).toString(), QMessageBox::RejectRole); + } + + + QPushButton *allowButton = nullptr; + if (options.contains(QStringLiteral("grant_label"))) { + allowButton = access_dialog.addButton(options.value(QStringLiteral("grant_label")).toString(), QMessageBox::AcceptRole); + } + + access_dialog.setWindowTitle(title); + access_dialog.setText(body); + access_dialog.exec(); + + uint respnse = 2; + if (access_dialog.clickedButton() == (QAbstractButton*)rejectButton) { + respnse = 0; + } else if (access_dialog.clickedButton() == (QAbstractButton*)allowButton) { + respnse = 1; + } + + return respnse; +} diff --git a/src/access.h b/src/access.h new file mode 100644 index 0000000..2857065 --- /dev/null +++ b/src/access.h @@ -0,0 +1,27 @@ +// Copyright (C) 2024 pengwenhao . +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#pragma once + +#include +#include + +class AccessPortal : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.impl.portal.Access") + +public: + explicit AccessPortal(QObject *parent); + ~AccessPortal() = default; + +public slots: + uint AccessDialog(const QDBusObjectPath &handle, + const QString &app_id, + const QString &parent_window, + const QString &title, + const QString &subtitle, + const QString &body, + const QVariantMap &options, + QVariantMap &results); +}; diff --git a/src/account.h b/src/account.h index b822c78..214953e 100644 --- a/src/account.h +++ b/src/account.h @@ -1,6 +1,5 @@ -// SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 Wenhao Peng . +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #pragma once diff --git a/src/ddesktopportal.cpp b/src/ddesktopportal.cpp index 30952f0..1c2f373 100644 --- a/src/ddesktopportal.cpp +++ b/src/ddesktopportal.cpp @@ -16,6 +16,7 @@ #include "filechooser.h" #include "wallpaper.h" #include "notification.h" +#include "access.h" DDesktopPortal::DDesktopPortal(QObject *parent) : QObject(parent) @@ -23,6 +24,7 @@ DDesktopPortal::DDesktopPortal(QObject *parent) , m_fileChooser(new FileChooserPortal(this)) , m_wallpaper(new WallPaperPortal(this)) , m_notification(new NotificationPortal(this)) + , m_access(new AccessPortal(this)) { const QByteArray &xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toUpper(); if (xdgCurrentDesktop == "DDE" || xdgCurrentDesktop == "DEEPIN") { diff --git a/src/ddesktopportal.h b/src/ddesktopportal.h index 9ada16d..addf1cf 100644 --- a/src/ddesktopportal.h +++ b/src/ddesktopportal.h @@ -19,6 +19,7 @@ class WallPaperPortal; class NotificationPortal; class FileChooserPortal; class AppChooserPortal; +class AccessPortal; class DDesktopPortal : public QObject, public QDBusContext { @@ -41,4 +42,5 @@ class DDesktopPortal : public QObject, public QDBusContext SecretPortal *m_secret = nullptr; WallPaperPortal *const m_wallpaper; NotificationPortal *const m_notification; + AccessPortal *const m_access; }; diff --git a/src/personalization_manager_client.cpp b/src/personalization_manager_client.cpp new file mode 100644 index 0000000..b288251 --- /dev/null +++ b/src/personalization_manager_client.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2024 Wenhao Peng . +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "personalization_manager_client.h" + +#include + +PersonalizationManager::PersonalizationManager() + : QWaylandClientExtensionTemplate(1) +{ + connect(this, + &PersonalizationManager::activeChanged, + this, + &PersonalizationManager::onActiveChanged); +} + +PersonalizationManager::~PersonalizationManager() +{ + +} + +void PersonalizationManager::onActiveChanged() +{ + if (!isActive()) + return; + + if (!m_wallpaperContext) { + m_wallpaperContext = new PersonalizationWallpaper(get_wallpaper_context()); + } +} + +PersonalizationWallpaper::PersonalizationWallpaper( + struct ::personalization_wallpaper_context_v1 *object) + : QWaylandClientExtensionTemplate(1) + , QtWayland::personalization_wallpaper_context_v1(object) +{ +} + +void PersonalizationWallpaper::personalization_wallpaper_context_v1_metadata( + const QString &metadata) +{ + Q_EMIT metadataChanged(metadata); +} diff --git a/src/personalization_manager_client.h b/src/personalization_manager_client.h new file mode 100644 index 0000000..1882353 --- /dev/null +++ b/src/personalization_manager_client.h @@ -0,0 +1,45 @@ +// Copyright (C) 2024 Wenhao Peng . +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qwayland-treeland-personalization-manager-v1.h" + +#include +#include + +class PersonalizationWallpaper; +class PersonalizationManager : public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_manager_v1 +{ + Q_OBJECT +public: + explicit PersonalizationManager(); + ~PersonalizationManager(); + void onActiveChanged(); + + PersonalizationWallpaper *wallpaper() { return m_wallpaperContext; } + +private: + PersonalizationWallpaper *m_wallpaperContext = nullptr; +}; + +class PersonalizationWindow : public QWaylandClientExtensionTemplate, + public QtWayland::personalization_window_context_v1 +{ + Q_OBJECT +public: + explicit PersonalizationWindow(struct ::personalization_window_context_v1 *object); +}; + +class PersonalizationWallpaper : public QWaylandClientExtensionTemplate, + public QtWayland::personalization_wallpaper_context_v1 +{ + Q_OBJECT +public: + explicit PersonalizationWallpaper(struct ::personalization_wallpaper_context_v1 *object); + +signals: + void metadataChanged(const QString &meta); + +protected: + void personalization_wallpaper_context_v1_metadata(const QString &metadata) override; +}; diff --git a/src/wallpaper.cpp b/src/wallpaper.cpp index 60388d7..4146323 100644 --- a/src/wallpaper.cpp +++ b/src/wallpaper.cpp @@ -1,9 +1,11 @@ -// SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 pengwenhao . +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #include "wallpaper.h" +#include "personalization_manager_client.h" +#include #include #include #include @@ -14,15 +16,33 @@ Q_LOGGING_CATEGORY(XdgDesktopDDEWallpaper, "xdg-dde-wallpaper") WallPaperPortal::WallPaperPortal(QObject *parent) : QDBusAbstractAdaptor(parent) + , m_personalizationManager(new PersonalizationManager) { qCDebug(XdgDesktopDDEWallpaper) << "WallPaper init"; } +WallPaperPortal::~WallPaperPortal() +{ + if (m_personalizationManager) { + delete m_personalizationManager; + m_personalizationManager = nullptr; + } +} + uint WallPaperPortal::SetWallpaperURI(const QDBusObjectPath &handle, const QString &app_id, const QString &parent_window, const QString &uri, const QVariantMap &options) +{ + return set_Treeland_WallpaperURI(handle, app_id, parent_window, uri, options); +} + +uint WallPaperPortal::set_V20_WallpaperURI(const QDBusObjectPath &handle, + const QString &app_id, + const QString &parent_window, + const QString &uri, + const QVariantMap &options) { // TODO: 未处理options,仅实现设置主屏壁纸 // options.value("show-preview").toBool(); // whether to show a preview of the picture. Note that the portal may decide to show a preview even if this option is not set @@ -54,3 +74,44 @@ uint WallPaperPortal::SetWallpaperURI(const QDBusObjectPath &handle, return 1; } + +uint WallPaperPortal::set_Treeland_WallpaperURI(const QDBusObjectPath &handle, + const QString &app_id, + const QString &parent_window, + const QString &uri, + const QVariantMap &options) +{ + if (!m_personalizationManager) + return 1; + + auto wallpaper = m_personalizationManager->wallpaper(); + if (!wallpaper) + return 1; + + QFile file(uri); + if (file.open(QIODevice::ReadOnly)) { + wallpaper->set_on(setOn2Int(options)); + wallpaper->set_fd(file.handle(), ""); + wallpaper->commit(); + } + + return 1; +} + +uint32_t WallPaperPortal::setOn2Int(const QVariantMap &options) +{ + QString set_on = options.value("set-on").toString(); + uint32_t op = 0; + if (set_on == "background") + op = personalization_wallpaper_context_v1_options::PERSONALIZATION_WALLPAPER_CONTEXT_V1_OPTIONS_BACKGROUND; + else if (set_on == "lockscreen") + op = personalization_wallpaper_context_v1_options::PERSONALIZATION_WALLPAPER_CONTEXT_V1_OPTIONS_LOCKSCREEN; + else if (set_on == "both") + op = personalization_wallpaper_context_v1_options::PERSONALIZATION_WALLPAPER_CONTEXT_V1_OPTIONS_LOCKSCREEN | + personalization_wallpaper_context_v1_options::PERSONALIZATION_WALLPAPER_CONTEXT_V1_OPTIONS_BACKGROUND; + + if (options.value("show-preview").toBool()) + op = op | personalization_wallpaper_context_v1_options::PERSONALIZATION_WALLPAPER_CONTEXT_V1_OPTIONS_PREVIEW; + + return op; +} diff --git a/src/wallpaper.h b/src/wallpaper.h index 31f0ed4..864e503 100644 --- a/src/wallpaper.h +++ b/src/wallpaper.h @@ -1,6 +1,6 @@ -// SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 pengwenhao . +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #pragma once @@ -8,6 +8,8 @@ #include #include +class PersonalizationManager; + class WallPaperPortal : public QDBusAbstractAdaptor { Q_OBJECT @@ -15,7 +17,7 @@ class WallPaperPortal : public QDBusAbstractAdaptor public: explicit WallPaperPortal(QObject *parent); - ~WallPaperPortal() = default; + ~WallPaperPortal(); public slots: uint SetWallpaperURI(const QDBusObjectPath &handle, @@ -23,4 +25,22 @@ public slots: const QString &parent_window, const QString &uri, const QVariantMap &options); + +private: + uint set_V20_WallpaperURI(const QDBusObjectPath &handle, + const QString &app_id, + const QString &parent_window, + const QString &uri, + const QVariantMap &options); + + uint set_Treeland_WallpaperURI(const QDBusObjectPath &handle, + const QString &app_id, + const QString &parent_window, + const QString &uri, + const QVariantMap &options); + + uint32_t setOn2Int(const QVariantMap &options); + +private: + PersonalizationManager *m_personalizationManager = nullptr; };