From 1e04332deb4cabd3239df90107d9b0ad0ae64805 Mon Sep 17 00:00:00 2001 From: wangfei Date: Thu, 10 Oct 2024 14:00:37 +0800 Subject: [PATCH] chore: add some interfaces about personalization add some interfaces about personalization Log: --- debian/control | 2 +- include/kernel/dplatformtheme.h | 4 + src/CMakeLists.txt | 6 +- src/kernel/dplatformhandle.cpp | 62 +-- src/kernel/dplatformtheme.cpp | 64 +++- src/wayland/dcontextshellwindow.cpp | 90 ----- src/wayland/dcontextshellwindow.h | 34 -- .../personalizationwaylandclientextension.cpp | 358 ++++++++++++++++++ .../personalizationwaylandclientextension.h | 141 +++++++ .../treeland-personalization-manager-v1.xml | 218 ----------- ...waylandpersonalizationshellintegration.cpp | 66 ---- ...waylandpersonalizationshellintegration_p.h | 46 --- .../qwaylandwindowcontextshellsurface.cpp | 43 --- .../qwaylandwindowcontextshellsurface_p.h | 29 -- tests/src/ut_dplatformtheme.cpp | 1 + 15 files changed, 603 insertions(+), 561 deletions(-) delete mode 100644 src/wayland/dcontextshellwindow.cpp delete mode 100644 src/wayland/dcontextshellwindow.h create mode 100644 src/wayland/personalizationwaylandclientextension.cpp create mode 100644 src/wayland/personalizationwaylandclientextension.h delete mode 100644 src/wayland/protocol/treeland-personalization-manager-v1.xml delete mode 100644 src/wayland/qwaylandpersonalizationshellintegration.cpp delete mode 100644 src/wayland/qwaylandpersonalizationshellintegration_p.h delete mode 100644 src/wayland/qwaylandwindowcontextshellsurface.cpp delete mode 100644 src/wayland/qwaylandwindowcontextshellsurface_p.h diff --git a/debian/control b/debian/control index 7a1b3d87..8096f9e7 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Build-Depends: debhelper-compat (= 12), pkg-config, qtbase5-private-dev, qtbase5-dev-tools, doxygen, graphviz, qttools5-dev, libdtkcore-dev, librsvg2-dev, libfreeimage-dev, libraw-dev, libgtest-dev, libgmock-dev, libqt5xdg-dev, libqt5xdgiconloader-dev, cmake, qt5-image-formats-plugins, libqt5waylandclient5-dev, - extra-cmake-modules, qtwayland5-dev-tools, qtwayland5-private-dev, libkf5wayland-dev + extra-cmake-modules, qtwayland5-dev-tools, qtwayland5-private-dev, libkf5wayland-dev, treeland-protocols Standards-Version: 3.9.8 Package: libdtkgui5 diff --git a/include/kernel/dplatformtheme.h b/include/kernel/dplatformtheme.h index d3e5edb9..d55245d9 100644 --- a/include/kernel/dplatformtheme.h +++ b/include/kernel/dplatformtheme.h @@ -28,6 +28,7 @@ class DPlatformTheme : public DNativeSettings Q_PROPERTY(QByteArray themeName READ themeName WRITE setThemeName NOTIFY themeNameChanged) Q_PROPERTY(QByteArray iconThemeName READ iconThemeName WRITE setIconThemeName NOTIFY iconThemeNameChanged) Q_PROPERTY(QByteArray soundThemeName READ soundThemeName WRITE setSoundThemeName NOTIFY soundThemeNameChanged) + Q_PROPERTY(QByteArray cursorThemeName READ cursorThemeName WRITE setCursorThemeName NOTIFY cursorThemeNameChanged) // Font Q_PROPERTY(QByteArray fontName READ fontName WRITE setFontName NOTIFY fontNameChanged) Q_PROPERTY(QByteArray monoFontName READ monoFontName WRITE setMonoFontName NOTIFY monoFontNameChanged) @@ -94,6 +95,7 @@ class DPlatformTheme : public DNativeSettings QByteArray themeName() const; QByteArray iconThemeName() const; QByteArray soundThemeName() const; + QByteArray cursorThemeName() const; QByteArray fontName() const; QByteArray monoFontName() const; @@ -147,6 +149,7 @@ public Q_SLOTS: void setThemeName(const QByteArray &themeName); void setIconThemeName(const QByteArray &iconThemeName); void setSoundThemeName(const QByteArray &soundThemeName); + void setCursorThemeName(const QByteArray &cursorThemeName); void setFontName(const QByteArray &fontName); void setMonoFontName(const QByteArray &monoFontName); void setFontPointSize(qreal fontPointSize); @@ -196,6 +199,7 @@ public Q_SLOTS: void themeNameChanged(QByteArray themeName); void iconThemeNameChanged(QByteArray iconThemeName); void soundThemeNameChanged(QByteArray soundThemeName); + void cursorThemeNameChanged(QByteArray cursorThemeName); void fontNameChanged(QByteArray fontName); void monoFontNameChanged(QByteArray monoFontName); void fontPointSizeChanged(qreal fontPointSize); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0524e988..808a3a83 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,8 @@ else() find_package(Qt5 REQUIRED COMPONENTS WaylandClient XkbCommonSupport) endif() +find_package(TreeLandProtocols REQUIRED) + add_library(${LIB_NAME} SHARED) include(dbus/dbus.cmake) @@ -14,7 +16,7 @@ include(util/util.cmake) if("${QT_VERSION_MAJOR}" STREQUAL "6") qt6_generate_wayland_protocol_client_sources(${LIB_NAME} FILES - ${CMAKE_CURRENT_SOURCE_DIR}/wayland/protocol/treeland-personalization-manager-v1.xml + ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-personalization-manager-v1.xml ) else() # ECM setup @@ -23,7 +25,7 @@ else() set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${ECM_MODULE_PATH}") find_package(QtWaylandScanner) ecm_add_qtwayland_client_protocol(${LIB_NAME} - PROTOCOL ${CMAKE_CURRENT_SOURCE_DIR}/wayland/protocol/treeland-personalization-manager-v1.xml + PROTOCOL ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-personalization-manager-v1.xml BASENAME treeland-personalization-manager-v1 ) target_sources(${LIB_NAME} PRIVATE diff --git a/src/kernel/dplatformhandle.cpp b/src/kernel/dplatformhandle.cpp index 280a929f..cfe7680a 100644 --- a/src/kernel/dplatformhandle.cpp +++ b/src/kernel/dplatformhandle.cpp @@ -6,7 +6,7 @@ #include "dplatformhandle.h" #include "dplatformtheme.h" #include "dwindowmanagerhelper.h" -#include "wayland/dcontextshellwindow.h" +#include "wayland/personalizationwaylandclientextension.h" #include #include @@ -100,7 +100,7 @@ static void setWindowProperty(QWindow *window, const char *name, const QVariant static bool isTreeLand() { return qEnvironmentVariable("DDE_CURRENT_COMPOSITOR") == "TreeLand"; -}; +} /*! \class Dtk::Gui::DPlatformHandle @@ -629,31 +629,29 @@ class Q_DECL_HIDDEN CreatorWindowEventFile : public QObject { } if (auto *w = qobject_cast(watched); w && isTreeLand()) { - if(DContextShellWindow *window = DContextShellWindow::get(qobject_cast(watched))) { - bool is_mouse_move = event->type() == QEvent::MouseMove && static_cast(event)->buttons() == Qt::LeftButton; + bool is_mouse_move = event->type() == QEvent::MouseMove && static_cast(event)->buttons() == Qt::LeftButton; - if (event->type() == QEvent::MouseButtonRelease) { - m_windowMoving = false; - } + if (event->type() == QEvent::MouseButtonRelease) { + m_windowMoving = false; + } - // workaround for kwin: Qt receives no release event when kwin finishes MOVE operation, - // which makes app hang in windowMoving state. when a press happens, there's no sense of - // keeping the moving state, we can just reset ti back to normal. - if (event->type() == QEvent::MouseButtonPress) { - m_windowMoving = false; - } + // workaround for kwin: Qt receives no release event when kwin finishes MOVE operation, + // which makes app hang in windowMoving state. when a press happens, there's no sense of + // keeping the moving state, we can just reset ti back to normal. + if (event->type() == QEvent::MouseButtonPress) { + m_windowMoving = false; + } + + // FIXME: We need to check whether the event is accepted. + // Only when the upper control does not accept the event, + // the window should be moved through the window. + // But every event here has been accepted. I don't know what happened. + if (is_mouse_move && w->geometry().contains(static_cast(event)->globalPos())) { + if (!m_windowMoving && PersonalizationManager::instance()->noTitlebar()) { + m_windowMoving = true; - // FIXME: We need to check whether the event is accepted. - // Only when the upper control does not accept the event, - // the window should be moved through the window. - // But every event here has been accepted. I don't know what happened. - if (is_mouse_move && w->geometry().contains(static_cast(event)->globalPos())) { - if (!m_windowMoving && window->noTitlebar()) { - m_windowMoving = true; - - event->accept(); - static_cast(w->handle())->startSystemMove(); - } + event->accept(); + static_cast(w->handle())->startSystemMove(); } } } @@ -683,10 +681,7 @@ bool DPlatformHandle::setEnabledNoTitlebarForWindow(QWindow *window, bool enable return false; if (window && isTreeLand()) { - DContextShellWindow *contextWindow = DContextShellWindow::get(window); - if (contextWindow->noTitlebar() == enable) - return true; - contextWindow->setNoTitlebar(enable); + PersonalizationManager::instance()->setNoTitlebar(window, enable); window->installEventFilter(new CreatorWindowEventFile(window)); return true; } @@ -1109,7 +1104,8 @@ void DPlatformHandle::setDisableWindowOverrideCursor(QWindow *window, bool disab int DPlatformHandle::windowRadius() const { - return m_window->property(_windowRadius).toInt(); + return isTreeLand() ? PersonalizationManager::instance()->windowRadius() : + m_window->property(_windowRadius).toInt(); } int DPlatformHandle::borderWidth() const @@ -1209,8 +1205,12 @@ WId DPlatformHandle::windowLeader() void DPlatformHandle::setWindowRadius(int windowRadius) { - setWindowProperty(m_window, _windowRadius, windowRadius); - resolve(m_window, PropRole::WindowRadius); + if (isTreeLand()) { + PersonalizationManager::instance()->setWindowRadius(m_window, windowRadius); + } else { + setWindowProperty(m_window, _windowRadius, windowRadius); + resolve(m_window, PropRole::WindowRadius); + } } void DPlatformHandle::setBorderWidth(int borderWidth) diff --git a/src/kernel/dplatformtheme.cpp b/src/kernel/dplatformtheme.cpp index 10a17871..0b302dec 100644 --- a/src/kernel/dplatformtheme.cpp +++ b/src/kernel/dplatformtheme.cpp @@ -4,6 +4,7 @@ #include "dplatformtheme.h" #include "private/dplatformtheme_p.h" +#include "wayland/personalizationwaylandclientextension.h" #include #include @@ -14,6 +15,11 @@ DGUI_BEGIN_NAMESPACE +static bool isTreeLand() +{ + return qEnvironmentVariable("DDE_CURRENT_COMPOSITOR") == "TreeLand"; +} + // "/deepin/palette" 为调色板属性的存储位置 // 在x11平台下,将使用_DEEPIN_PALETTE作为存储调色板数据的窗口属性 DPlatformThemePrivate::DPlatformThemePrivate(Dtk::Gui::DPlatformTheme *qq) @@ -387,6 +393,10 @@ int DPlatformTheme::dndDragThreshold() const int DPlatformTheme::windowRadius() const { + if (isTreeLand()) { + return PersonalizationManager::instance()->windowRadius(); + } + return windowRadius(-1); } @@ -414,6 +424,10 @@ QByteArray DPlatformTheme::themeName() const QByteArray DPlatformTheme::iconThemeName() const { + if (isTreeLand()) { + return PersonalizationManager::instance()->iconTheme().toLatin1(); + } + FETCH_PROPERTY("Net/IconThemeName", iconThemeName) return value.toByteArray(); @@ -426,8 +440,23 @@ QByteArray DPlatformTheme::soundThemeName() const return value.toByteArray(); } +QByteArray DPlatformTheme::cursorThemeName() const +{ + if (isTreeLand()) { + return PersonalizationManager::instance()->cursorTheme().toLatin1(); + } + + FETCH_PROPERTY("Gtk/CursorThemeName", cursorThemeName) + + return value.toByteArray(); +} + QByteArray DPlatformTheme::fontName() const { + if (isTreeLand()) { + return PersonalizationManager::instance()->fontName().toLatin1(); + } + FETCH_PROPERTY("Qt/FontName", fontName) return value.toByteArray(); @@ -435,6 +464,10 @@ QByteArray DPlatformTheme::fontName() const QByteArray DPlatformTheme::monoFontName() const { + if (isTreeLand()) { + return PersonalizationManager::instance()->monoFontName().toLatin1(); + } + FETCH_PROPERTY("Qt/MonoFontName", monoFontName) return value.toByteArray(); @@ -697,6 +730,11 @@ void DPlatformTheme::setThemeName(const QByteArray &themeName) void DPlatformTheme::setIconThemeName(const QByteArray &iconThemeName) { + if (isTreeLand()) { + PersonalizationManager::instance()->setIconTheme(iconThemeName); + return; + } + D_D(DPlatformTheme); d->theme->setSetting("Net/IconThemeName", iconThemeName); @@ -709,8 +747,24 @@ void DPlatformTheme::setSoundThemeName(const QByteArray &soundThemeName) d->theme->setSetting("Net/SoundThemeName", soundThemeName); } +void DPlatformTheme::setCursorThemeName(const QByteArray &cursorThemeName) +{ + if (isTreeLand()) { + PersonalizationManager::instance()->setCursorTheme(cursorThemeName); + return; + } + + D_D(DPlatformTheme); + + d->theme->setSetting("Gtk/CursorThemeName", cursorThemeName); +} + void DPlatformTheme::setFontName(const QByteArray &fontName) { + if (isTreeLand()) { + PersonalizationManager::instance()->setFontName(fontName); + return; + } D_D(DPlatformTheme); d->theme->setSetting("Qt/FontName", fontName); @@ -718,6 +772,10 @@ void DPlatformTheme::setFontName(const QByteArray &fontName) void DPlatformTheme::setMonoFontName(const QByteArray &monoFontName) { + if (isTreeLand()) { + PersonalizationManager::instance()->setMonoFontName(monoFontName); + return; + } D_D(DPlatformTheme); d->theme->setSetting("Qt/MonoFontName", monoFontName); @@ -895,8 +953,12 @@ void DPlatformTheme::setDotsPerInch(const QString &screenName, int dpi) void DPlatformTheme::setWindowRadius(int windowRadius) { - D_D(DPlatformTheme); + if (isTreeLand()) { + PersonalizationManager::instance()->setWindowRadius(windowRadius); + return; + } + D_D(DPlatformTheme); d->theme->setSetting("DTK/WindowRadius", windowRadius); } diff --git a/src/wayland/dcontextshellwindow.cpp b/src/wayland/dcontextshellwindow.cpp deleted file mode 100644 index e22bf9ea..00000000 --- a/src/wayland/dcontextshellwindow.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "dcontextshellwindow.h" - -#include "qwaylandpersonalizationshellintegration_p.h" - -#include - -DGUI_BEGIN_NAMESPACE -class DContextShellWindowPrivate -{ -public: - explicit DContextShellWindowPrivate(QWindow *window) - : parentWindow(window) - { - } - - QWindow *parentWindow = nullptr; - bool noTitlebar = false; -}; - -bool DContextShellWindow::noTitlebar() -{ - return d->noTitlebar; -} - -void DContextShellWindow::setNoTitlebar(bool value) -{ - if (value == d->noTitlebar) { - return; - } - d->noTitlebar = value; - Q_EMIT noTitlebarChanged(); -} - -static QMap s_map; - -DContextShellWindow::~DContextShellWindow() -{ - s_map.remove(d->parentWindow); -} - -DContextShellWindow::DContextShellWindow(QWindow *window) - : QObject(window) - , d(new DContextShellWindowPrivate(window)) -{ - s_map.insert(window, this); - window->create(); - auto waylandWindow = dynamic_cast(window->handle()); - if (waylandWindow) { - static QWaylandPersonalizationShellIntegration *shellIntegration = nullptr; - if (!shellIntegration) { - shellIntegration = new QWaylandPersonalizationShellIntegration(); - if (!shellIntegration->initialize(waylandWindow->display())) { - delete shellIntegration; - shellIntegration = nullptr; - qWarning() << "failed to init dlayershell intergration"; - return; - } - } -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - shellIntegration->createShellSurface(waylandWindow); -#else - waylandWindow->setShellIntegration(shellIntegration); -#endif - } else { - qWarning() << "not a wayland window, will not create zwlr_layer_surface"; - } -} - -DContextShellWindow *DContextShellWindow::get(QWindow *window) -{ - auto dlayerShellWindow = s_map.value(window); - if (dlayerShellWindow) { - return dlayerShellWindow; - } - return new DContextShellWindow(window); -} - -DContextShellWindow *DContextShellWindow::qmlAttachedProperties(QObject *object) -{ - auto window = qobject_cast(object); - if (window) - return get(window); - qWarning() << "not a qwindow unable to create DContextShellWindow"; - return nullptr; -} -DGUI_END_NAMESPACE diff --git a/src/wayland/dcontextshellwindow.h b/src/wayland/dcontextshellwindow.h deleted file mode 100644 index 8cb8bc79..00000000 --- a/src/wayland/dcontextshellwindow.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#pragma once - -#include -#include - -DGUI_BEGIN_NAMESPACE -class DContextShellWindowPrivate; - -class DContextShellWindow : public QObject -{ - Q_OBJECT - Q_PROPERTY(int noTitlebar READ noTitlebar WRITE setNoTitlebar NOTIFY noTitlebarChanged) - -public: - ~DContextShellWindow() override; - - bool noTitlebar(); - void setNoTitlebar(bool value); - - static DContextShellWindow *get(QWindow *window); - static DContextShellWindow *qmlAttachedProperties(QObject *object); - -Q_SIGNALS: - void noTitlebarChanged(); - -private: - DContextShellWindow(QWindow *window); - QScopedPointer d; -}; -DGUI_END_NAMESPACE diff --git a/src/wayland/personalizationwaylandclientextension.cpp b/src/wayland/personalizationwaylandclientextension.cpp new file mode 100644 index 00000000..05ac9186 --- /dev/null +++ b/src/wayland/personalizationwaylandclientextension.cpp @@ -0,0 +1,358 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "personalizationwaylandclientextension.h" + +#include +#include +#include +#include +#include +#include +#include + +DGUI_BEGIN_NAMESPACE + +class PersonalizationManager_: public PersonalizationManager {}; +Q_GLOBAL_STATIC(PersonalizationManager_, personalizationManager) + +PersonalizationManager::PersonalizationManager() + : QWaylandClientExtensionTemplate(1) +{ + if (QGuiApplication::platformName() == QLatin1String("wayland")) { + QtWaylandClient::QWaylandIntegration *waylandIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + if (!waylandIntegration) { + qWarning() << "waylandIntegration is nullptr!!!"; + return; + } + m_waylandDisplay = waylandIntegration->display(); + if (!m_waylandDisplay) { + qWarning() << "waylandDisplay is nullptr!!!"; + return; + } + addListener(); + } + + auto appearanceContext = get_appearance_context(); + if (!appearanceContext) { + qWarning() << "appearanceContext is nullptr!!!"; + return; + } + m_appearanceContext.reset(new PersonalizationAppearanceContext(appearanceContext)); +} + +PersonalizationManager *PersonalizationManager::instance() +{ + return personalizationManager; +} + +int PersonalizationManager::windowRadius() const +{ + if (m_appearanceContext.isNull()) { + return 0; + } + return m_appearanceContext->windowRadius(); +} + +void PersonalizationManager::setWindowRadius(int radius) +{ + if (m_appearanceContext.isNull()) { + return; + } + m_appearanceContext->setWindowRadius(radius); +} + +QString PersonalizationManager::fontName() const +{ + if (m_appearanceContext.isNull()) { + return QString(); + } + return m_appearanceContext->fontName(); +} + +void PersonalizationManager::setFontName(const QString& fontName) +{ + if (m_appearanceContext.isNull()) { + return; + } + m_appearanceContext->setFontName(fontName); +} + +QString PersonalizationManager::monoFontName() const +{ + if (m_appearanceContext.isNull()) { + return QString(); + } + return m_appearanceContext->monoFontName(); +} + +void PersonalizationManager::setMonoFontName(const QString& monoFontName) +{ + if (m_appearanceContext.isNull()) { + return; + } + m_appearanceContext->setMonoFontName(monoFontName); +} + +QString PersonalizationManager::cursorTheme() const +{ + if (m_appearanceContext.isNull()) { + return QString(); + } + return m_appearanceContext->cursorTheme(); +} + +void PersonalizationManager::setCursorTheme(const QString& cursorTheme) +{ + if (m_appearanceContext.isNull()) { + return; + } + m_appearanceContext->setCursorTheme(cursorTheme); +} + +QString PersonalizationManager::iconTheme() const +{ + if (m_appearanceContext.isNull()) { + return QString(); + } + return m_appearanceContext->iconTheme(); +} + +void PersonalizationManager::setIconTheme(const QString& iconTheme) +{ + if (m_appearanceContext.isNull()) { + return; + } + m_appearanceContext->setIconTheme(iconTheme); +} + +PersonalizationWindowContext *PersonalizationManager::getWindowContext(QWindow *window) +{ + if (!window) { + qWarning() << "window is nullptr!!!"; + return nullptr; + } + auto waylandWindow = dynamic_cast(window->handle()); + if (!waylandWindow) { + qWarning() << "waylandWindow is nullptr!!!"; + return nullptr; + } + auto surface = waylandWindow->waylandSurface()->object(); + if (!surface) { + qWarning() << "waylandSurface is nullptr!!!"; + return nullptr; + } + auto context = get_window_context(surface); + if (m_windowContext.isNull()) { + m_windowContext.reset(new PersonalizationWindowContext(context)); + } + return m_windowContext.data(); +} + +void PersonalizationManager::addListener() +{ + m_waylandDisplay->addRegistryListener(&handleListenerGlobal, this); +} + +void PersonalizationManager::removeListener() +{ + m_waylandDisplay->removeListener(&handleListenerGlobal, this); +} + +void PersonalizationManager::handleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) +{ + if (interface == treeland_personalization_manager_v1_interface.name) { + PersonalizationManager *integration = static_cast(data); + if (!integration) { + qWarning() << "integration is nullptr!!!"; + return; + } + + integration->init(registry, id, version); + } +} + +bool PersonalizationManager::noTitlebar() +{ + return m_windowContext->noTitlebar(); +} + +void PersonalizationManager::setNoTitlebar(QWindow *window, bool enable) +{ + auto windowContext = this->getWindowContext(window); + if (!windowContext) { + qWarning() << "windowContext is nullptr!"; + return; + } + windowContext->setNoTitlebar(enable); +} + +void PersonalizationManager::setWindowRadius(QWindow *window, int radius) +{ + auto windowContext = this->getWindowContext(window); + if (!windowContext) { + return; + } + windowContext->setWindowRadius(radius); +} + +PersonalizationWindowContext::PersonalizationWindowContext(struct ::treeland_personalization_window_context_v1 *context) + : QWaylandClientExtensionTemplate(1) + , QtWayland::treeland_personalization_window_context_v1(context) +{ +} + +bool PersonalizationWindowContext::noTitlebar() const +{ + return m_noTitlebar; +} + +void PersonalizationWindowContext::setNoTitlebar(bool enable) +{ + if (m_noTitlebar == enable) { + return; + } + + m_noTitlebar = enable; + set_no_titlebar(m_noTitlebar ? enable_mode::enable_mode_enable : enable_mode::enable_mode_disable); +} + +int PersonalizationWindowContext::windowRadius() +{ + return m_windowRadius; +} + +void PersonalizationWindowContext::setWindowRadius(int radius) +{ + if (m_windowRadius == radius) { + return; + } + + m_windowRadius = radius; + set_round_corner_radius(radius); +} + +PersonalizationAppearanceContext::PersonalizationAppearanceContext(struct ::treeland_personalization_appearance_context_v1 *context) + : QWaylandClientExtensionTemplate(1) + , QtWayland::treeland_personalization_appearance_context_v1(context) +{ + get_round_corner_radius(); + get_font(); + get_monospace_font(); + get_cursor_theme(); + get_icon_theme(); +} + +int PersonalizationAppearanceContext::windowRadius() const +{ + return m_windowRadius; +} + +void PersonalizationAppearanceContext::setWindowRadius(int radius) +{ + if (m_windowRadius == radius) { + return; + } + + m_windowRadius = radius; + set_round_corner_radius(radius); +} + +QString PersonalizationAppearanceContext::fontName() const +{ + return m_fontName; +} + +void PersonalizationAppearanceContext::setFontName(const QString& fontName) +{ + if (m_fontName == fontName) { + return; + } + + m_fontName = fontName; + set_font(fontName); +} + +QString PersonalizationAppearanceContext::monoFontName() const +{ + return m_monoFontName; +} + +void PersonalizationAppearanceContext::setMonoFontName(const QString& fontName) +{ + if (m_monoFontName == fontName) { + return; + } + + m_monoFontName = fontName; + set_monospace_font(fontName); +} + +QString PersonalizationAppearanceContext::cursorTheme() const +{ + return m_cursorTheme; +} + +void PersonalizationAppearanceContext::setCursorTheme(const QString& cursorTheme) +{ + if (m_cursorTheme == cursorTheme) { + return; + } + + m_cursorTheme = cursorTheme; + set_cursor_theme(cursorTheme); +} + +QString PersonalizationAppearanceContext::iconTheme() const +{ + return m_iconTheme; +} + +void PersonalizationAppearanceContext::setIconTheme(const QString& iconTheme) +{ + if (m_iconTheme == iconTheme) { + return; + } + + m_iconTheme = iconTheme; + set_cursor_theme(iconTheme); +} + +void PersonalizationAppearanceContext::treeland_personalization_appearance_context_v1_round_corner_radius(int32_t radius) +{ + m_windowRadius = radius; +} + +void PersonalizationAppearanceContext::treeland_personalization_appearance_context_v1_font(const QString &font_name) +{ + m_fontName = font_name; +} + +void PersonalizationAppearanceContext::treeland_personalization_appearance_context_v1_monospace_font(const QString &font_name) +{ + m_monoFontName = font_name; +} + +void PersonalizationAppearanceContext::treeland_personalization_appearance_context_v1_cursor_theme(const QString &theme_name) +{ + m_cursorTheme = theme_name; +} + +void PersonalizationAppearanceContext::treeland_personalization_appearance_context_v1_icon_theme(const QString &theme_name) +{ + m_iconTheme = theme_name; +} + +PersonalizationWallpaperContext::PersonalizationWallpaperContext(struct ::treeland_personalization_wallpaper_context_v1 *context) + : QWaylandClientExtensionTemplate(1) + , QtWayland::treeland_personalization_wallpaper_context_v1(context) +{ +} + +PersonalizationCursorContext::PersonalizationCursorContext(struct ::treeland_personalization_cursor_context_v1 *context) + : QWaylandClientExtensionTemplate(1) + , QtWayland::treeland_personalization_cursor_context_v1(context) +{ +} +DGUI_END_NAMESPACE diff --git a/src/wayland/personalizationwaylandclientextension.h b/src/wayland/personalizationwaylandclientextension.h new file mode 100644 index 00000000..89942318 --- /dev/null +++ b/src/wayland/personalizationwaylandclientextension.h @@ -0,0 +1,141 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include + +#include "qwayland-treeland-personalization-manager-v1.h" + +#include +#include +#include + +DGUI_BEGIN_NAMESPACE +class PersonalizationWindowContext; +class PersonalizationAppearanceContext; + +class PersonalizationManager: public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_manager_v1 +{ + Q_OBJECT +public: + static PersonalizationManager *instance(); + + bool noTitlebar(); + void setNoTitlebar(QWindow *window, bool enable); + + void setWindowRadius(QWindow *window, int radius); + + int windowRadius() const; + void setWindowRadius(int radius); + + QString fontName() const; + void setFontName(const QString& fontName); + + QString monoFontName() const; + void setMonoFontName(const QString& monoFontName); + + QString cursorTheme() const; + void setCursorTheme(const QString& cursorTheme); + + QString iconTheme() const; + void setIconTheme(const QString& iconTheme); + +protected: + explicit PersonalizationManager(); + +private: + void addListener(); + void removeListener(); + PersonalizationWindowContext *getWindowContext(QWindow *window); + + static void handleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); + +private: + QScopedPointer m_windowContext; + QScopedPointer m_appearanceContext; + QtWaylandClient::QWaylandDisplay *m_waylandDisplay= nullptr; +}; + +class PersonalizationWindowContext : public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_window_context_v1 +{ + Q_OBJECT +public: + explicit PersonalizationWindowContext(struct ::treeland_personalization_window_context_v1 *context); + + bool noTitlebar() const; + void setNoTitlebar(bool enable); + + int windowRadius(); + void setWindowRadius(int radius); + +private: + bool m_noTitlebar; + int m_windowRadius; +}; + +class PersonalizationAppearanceContext : public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_appearance_context_v1 +{ + Q_OBJECT + Q_PROPERTY(int windowRadius READ windowRadius WRITE setWindowRadius) + Q_PROPERTY(QString fontName READ fontName WRITE setFontName) + Q_PROPERTY(QString monoFontName READ monoFontName WRITE setMonoFontName) + Q_PROPERTY(QString cursorTheme READ cursorTheme WRITE setCursorTheme) + Q_PROPERTY(QString iconTheme READ iconTheme WRITE setIconTheme) + +public: + explicit PersonalizationAppearanceContext(struct ::treeland_personalization_appearance_context_v1 *context); + + int windowRadius() const; + void setWindowRadius(int radius); + + QString fontName() const; + void setFontName(const QString& fontName); + + QString monoFontName() const; + void setMonoFontName(const QString& monoFontName); + + QString cursorTheme() const; + void setCursorTheme(const QString& cursorTheme); + + QString iconTheme() const; + void setIconTheme(const QString& iconTheme); + +protected: + virtual void treeland_personalization_appearance_context_v1_round_corner_radius(int32_t radius); + virtual void treeland_personalization_appearance_context_v1_font(const QString &font_name); + virtual void treeland_personalization_appearance_context_v1_monospace_font(const QString &font_name); + virtual void treeland_personalization_appearance_context_v1_cursor_theme(const QString &theme_name); + virtual void treeland_personalization_appearance_context_v1_icon_theme(const QString &theme_name); + +private: + int m_windowRadius; + QString m_fontName; + QString m_monoFontName; + QString m_cursorTheme; + QString m_iconTheme; +}; + +class PersonalizationWallpaperContext : public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_wallpaper_context_v1 +{ + Q_OBJECT +public: + explicit PersonalizationWallpaperContext(struct ::treeland_personalization_wallpaper_context_v1 *context); + + +}; + +class PersonalizationCursorContext : public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_cursor_context_v1 +{ + Q_OBJECT +public: + explicit PersonalizationCursorContext(struct ::treeland_personalization_cursor_context_v1 *context); + +}; + +DGUI_END_NAMESPACE diff --git a/src/wayland/protocol/treeland-personalization-manager-v1.xml b/src/wayland/protocol/treeland-personalization-manager-v1.xml deleted file mode 100644 index 8d754ef2..00000000 --- a/src/wayland/protocol/treeland-personalization-manager-v1.xml +++ /dev/null @@ -1,218 +0,0 @@ - - - - SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. - - SPDX-License-Identifier: LGPL-3.0-or-later - - - - 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. - - - - Window blend mode defines how compositor composite window's surface over other surfaces. - - - - - - - - Set window background blend mode - - - - - - This request will set window round corner radius, invoking this request means user want to - manage window round corner radius by itself. If not invoked, window round corner radius will - be decided by compositor. - - - - - - Set window shadow's radius, offset and color, invoking this request indicates that client want to manage - the window shadow by itself. If not invoked, window shadow will be decided by the compositor - - - - - - - - - - - - Set window border width and color - - - - - - - - - - Set window enable mode - - - - - - - Set if system titlebar is enabled - - - - - - Destroy the context object. - - - - diff --git a/src/wayland/qwaylandpersonalizationshellintegration.cpp b/src/wayland/qwaylandpersonalizationshellintegration.cpp deleted file mode 100644 index b0d26553..00000000 --- a/src/wayland/qwaylandpersonalizationshellintegration.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "qwaylandpersonalizationshellintegration_p.h" -#include "qwaylandwindowcontextshellsurface_p.h" -#include "wayland-treeland-personalization-manager-v1-client-protocol.h" - -DGUI_BEGIN_NAMESPACE -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -QWaylandPersonalizationShellIntegration::QWaylandPersonalizationShellIntegration() - : QWaylandShellIntegration() - -#else -QWaylandPersonalizationShellIntegration::QWaylandPersonalizationShellIntegration() - : QWaylandShellIntegrationTemplate(4) -#endif -{ -} - -QWaylandPersonalizationShellIntegration::~QWaylandPersonalizationShellIntegration() -{ - if (object() - && treeland_personalization_manager_v1_get_version(object()) - >= TREELAND_PERSONALIZATION_MANAGER_V1_GET_WINDOW_CONTEXT_SINCE_VERSION) { - treeland_personalization_manager_v1_destroy(object()); - } -} - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -bool QWaylandPersonalizationShellIntegration::initialize(QtWaylandClient::QWaylandDisplay *display) -{ - QWaylandShellIntegration::initialize(display); - display->addRegistryListener(registryPluginManager, this); - return m_manager != nullptr; -} - -struct personalization_window_context_v1 * -QWaylandPersonalizationShellIntegration::get_window_context(struct ::wl_surface *surface) -{ - return m_manager->get_window_context(surface); -} -#endif - -QtWaylandClient::QWaylandShellSurface *QWaylandPersonalizationShellIntegration::createShellSurface( - QtWaylandClient::QWaylandWindow *window) -{ - return new QWaylandWindowContextSurface(this, window); -} - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -void QWaylandPersonalizationShellIntegration::registryPluginManager(void *data, - struct wl_registry *registry, - uint32_t id, - const QString &interface, - uint32_t version) -{ - QWaylandPersonalizationShellIntegration *shell = - static_cast(data); - if (interface == treeland_personalization_manager_v1_interface.name) { - shell->m_manager.reset( - new QtWayland::treeland_personalization_manager_v1(registry, id, version)); - } -} -#endif -DGUI_END_NAMESPACE diff --git a/src/wayland/qwaylandpersonalizationshellintegration_p.h b/src/wayland/qwaylandpersonalizationshellintegration_p.h deleted file mode 100644 index 83cc6a93..00000000 --- a/src/wayland/qwaylandpersonalizationshellintegration_p.h +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#pragma once - -#include -#include -#include - -DGUI_BEGIN_NAMESPACE -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -class QWaylandWindowContextSurface; -class QWaylandPersonalizationShellIntegration : public QtWaylandClient::QWaylandShellIntegration -#else -class QWaylandPersonalizationShellIntegration - : public QtWaylandClient::QWaylandShellIntegrationTemplate< - QWaylandPersonalizationShellIntegration>, - public QtWayland::treeland_personalization_manager_v1 -#endif -{ -public: - QWaylandPersonalizationShellIntegration(); - ~QWaylandPersonalizationShellIntegration() override; - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - bool initialize(QtWaylandClient::QWaylandDisplay *display) override; - struct personalization_window_context_v1 *get_window_context(struct ::wl_surface *surface); - - struct treeland_personalization_manager_v1 *object() { return m_manager->object(); } -#endif - - QtWaylandClient::QWaylandShellSurface *createShellSurface( - QtWaylandClient::QWaylandWindow *window) override; - -private: -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - static void registryPluginManager(void *data, - struct wl_registry *registry, - uint32_t id, - const QString &interface, - uint32_t version); - QScopedPointer m_manager; -#endif -}; -DGUI_END_NAMESPACE diff --git a/src/wayland/qwaylandwindowcontextshellsurface.cpp b/src/wayland/qwaylandwindowcontextshellsurface.cpp deleted file mode 100644 index d29aa056..00000000 --- a/src/wayland/qwaylandwindowcontextshellsurface.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "dcontextshellwindow.h" -#include "qwaylandwindowcontextshellsurface_p.h" -#include "wayland/qwaylandpersonalizationshellintegration_p.h" - -#include -#include - -Q_LOGGING_CATEGORY(layershellsurface, "dde.shell.layershell.surface") - -DGUI_BEGIN_NAMESPACE -QWaylandWindowContextSurface::QWaylandWindowContextSurface( - QWaylandPersonalizationShellIntegration *shell, QtWaylandClient::QWaylandWindow *window) - : QtWaylandClient::QWaylandShellSurface(window) - , QtWayland::personalization_window_context_v1() - , m_dcontextShellWindow(DContextShellWindow::get(window->window())) -{ - init(shell->get_window_context(window->waylandSurface()->object())); - auto onNoTitlebarChanged = [this, window] { - if (m_dcontextShellWindow->noTitlebar()) { - set_no_titlebar(PERSONALIZATION_WINDOW_CONTEXT_V1_ENABLE_MODE_ENABLE); - } else { - set_no_titlebar(PERSONALIZATION_WINDOW_CONTEXT_V1_ENABLE_MODE_DISABLE); - } - window->waylandSurface()->commit(); - }; - - connect(m_dcontextShellWindow, - &DContextShellWindow::noTitlebarChanged, - this, - onNoTitlebarChanged); - - onNoTitlebarChanged(); -} - -QWaylandWindowContextSurface::~QWaylandWindowContextSurface() -{ - destroy(); -} -DGUI_END_NAMESPACE diff --git a/src/wayland/qwaylandwindowcontextshellsurface_p.h b/src/wayland/qwaylandwindowcontextshellsurface_p.h deleted file mode 100644 index 109e5119..00000000 --- a/src/wayland/qwaylandwindowcontextshellsurface_p.h +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#pragma once - -#include "dcontextshellwindow.h" - -#include -#include -#include - -#include - -DGUI_BEGIN_NAMESPACE -class QWaylandPersonalizationShellIntegration; -class QWaylandWindowContextSurface : public QtWaylandClient::QWaylandShellSurface, - public QtWayland::personalization_window_context_v1 -{ - Q_OBJECT -public: - QWaylandWindowContextSurface(QWaylandPersonalizationShellIntegration *shell, - QtWaylandClient::QWaylandWindow *window); - ~QWaylandWindowContextSurface() override; - -private: - DContextShellWindow *m_dcontextShellWindow; -}; -DGUI_END_NAMESPACE diff --git a/tests/src/ut_dplatformtheme.cpp b/tests/src/ut_dplatformtheme.cpp index 07cd234e..e0d2f5b1 100644 --- a/tests/src/ut_dplatformtheme.cpp +++ b/tests/src/ut_dplatformtheme.cpp @@ -87,6 +87,7 @@ TEST_F(TDPlatformTheme, testSetFunction) ASSERT_EQ_BY_VALUE(setDndDragThreshold, dndDragThreshold, TEST_DATA); ASSERT_EQ_BY_NAME(setThemeName, themeName, "Theme"); ASSERT_EQ_BY_NAME(setIconThemeName, iconThemeName, "Icon"); + ASSERT_EQ_BY_NAME(setCursorThemeName, cursorThemeName, "Cursor"); ASSERT_EQ_BY_NAME(setSoundThemeName, soundThemeName, "Sound"); ASSERT_EQ_BY_NAME(setFontName, fontName, "Font"); ASSERT_EQ_BY_NAME(setMonoFontName, monoFontName, "MonoFont");