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;
};