From a7d021d2327fad9e6e0cce034e8aaf36d3e56a3e 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: --- src/CMakeLists.txt | 6 +- src/kernel/dplatformhandle.cpp | 49 ++-- .../personalizationwaylandclientextension.cpp | 107 +++++++++ .../personalizationwaylandclientextension.h | 79 +++++++ .../treeland-personalization-manager-v1.xml | 218 ------------------ ...waylandpersonalizationshellintegration.cpp | 2 +- ...waylandpersonalizationshellintegration_p.h | 2 +- .../qwaylandwindowcontextshellsurface.cpp | 8 +- .../qwaylandwindowcontextshellsurface_p.h | 2 +- 9 files changed, 219 insertions(+), 254 deletions(-) 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 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..7b00c650 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 @@ -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(enable, window); window->installEventFilter(new CreatorWindowEventFile(window)); return true; } diff --git a/src/wayland/personalizationwaylandclientextension.cpp b/src/wayland/personalizationwaylandclientextension.cpp new file mode 100644 index 00000000..2568d137 --- /dev/null +++ b/src/wayland/personalizationwaylandclientextension.cpp @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "personalizationwaylandclientextension.h" +#include "qwayland-treeland-personalization-manager-v1.h" + +#include +#include +#include + +DGUI_BEGIN_NAMESPACE + +class PersonalizationManager_: public PersonalizationManager {}; +Q_GLOBAL_STATIC(PersonalizationManager_, personalizationManager) + +PersonalizationManager::PersonalizationManager() + : QWaylandClientExtensionTemplate(1) +{ +} + +PersonalizationManager *PersonalizationManager::instance() +{ + return personalizationManager; +} + +PersonalizationWindowContext *PersonalizationManager::getWindowContext(QWindow *window) +{ + Q_ASSERT(!isActive()); + + if (!window) { + return nullptr; + } + window->create(); + auto waylandWindow = dynamic_cast(window->handle()); + if (!waylandWindow) { + return nullptr; + } + auto surface = waylandWindow->waylandSurface()->object(); + auto context = get_window_context(surface); + if (m_windowContext.isNull()) { + m_windowContext.reset(new PersonalizationWindowContext(context)); + } + return m_windowContext.data(); +} + + +bool PersonalizationManager::noTitlebar() +{ + return m_windowContext->noTitlebar(); +} + +void PersonalizationManager::setNoTitlebar(bool enable, QWindow *window) +{ + connect(this, &PersonalizationManager::activeChanged, [this, enable, window]{ + if (!isActive()) { + return ; + } + + auto windowContext = this->getWindowContext(window); + if (!windowContext) { + return; + } + windowContext->setNoTitlebar(enable); + }); +} + +PersonalizationWindowContext::PersonalizationWindowContext(struct ::treeland_personalization_window_context_v1 *context) + : QWaylandClientExtensionTemplate(1) + , QtWayland::treeland_personalization_window_context_v1(context) +{ +} + + +bool PersonalizationWindowContext::noTitlebar() +{ + 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); +} + +PersonalizationAppearanceContext::PersonalizationAppearanceContext(struct ::treeland_personalization_appearance_context_v1 *context) + : QWaylandClientExtensionTemplate(1) + , QtWayland::treeland_personalization_appearance_context_v1(context) +{ +} + +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..782d1457 --- /dev/null +++ b/src/wayland/personalizationwaylandclientextension.h @@ -0,0 +1,79 @@ +// 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 PersonalizationManager: public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_manager_v1 +{ + Q_OBJECT +public: + static PersonalizationManager *instance(); + + bool noTitlebar(); + void setNoTitlebar(bool enable, QWindow *window); + +protected: + explicit PersonalizationManager(); + +private: + PersonalizationWindowContext *getWindowContext(QWindow *window); + +private: + QScopedPointer m_windowContext; +}; + +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(); + void setNoTitlebar(bool enable); + +private: + bool m_noTitlebar; +}; + + +class PersonalizationAppearanceContext : public QWaylandClientExtensionTemplate, + public QtWayland::treeland_personalization_appearance_context_v1 +{ + Q_OBJECT +public: + explicit PersonalizationAppearanceContext(struct ::treeland_personalization_appearance_context_v1 *context); + +}; + +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 index b0d26553..819d69ed 100644 --- a/src/wayland/qwaylandpersonalizationshellintegration.cpp +++ b/src/wayland/qwaylandpersonalizationshellintegration.cpp @@ -35,7 +35,7 @@ bool QWaylandPersonalizationShellIntegration::initialize(QtWaylandClient::QWayla return m_manager != nullptr; } -struct personalization_window_context_v1 * +struct treeland_personalization_window_context_v1 * QWaylandPersonalizationShellIntegration::get_window_context(struct ::wl_surface *surface) { return m_manager->get_window_context(surface); diff --git a/src/wayland/qwaylandpersonalizationshellintegration_p.h b/src/wayland/qwaylandpersonalizationshellintegration_p.h index 83cc6a93..18b2903a 100644 --- a/src/wayland/qwaylandpersonalizationshellintegration_p.h +++ b/src/wayland/qwaylandpersonalizationshellintegration_p.h @@ -25,7 +25,7 @@ class QWaylandPersonalizationShellIntegration #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_window_context_v1 *get_window_context(struct ::wl_surface *surface); struct treeland_personalization_manager_v1 *object() { return m_manager->object(); } #endif diff --git a/src/wayland/qwaylandwindowcontextshellsurface.cpp b/src/wayland/qwaylandwindowcontextshellsurface.cpp index d29aa056..93a88b31 100644 --- a/src/wayland/qwaylandwindowcontextshellsurface.cpp +++ b/src/wayland/qwaylandwindowcontextshellsurface.cpp @@ -9,21 +9,21 @@ #include #include -Q_LOGGING_CATEGORY(layershellsurface, "dde.shell.layershell.surface") +// 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() + , QtWayland::treeland_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); + set_no_titlebar(TREELAND_PERSONALIZATION_WINDOW_CONTEXT_V1_ENABLE_MODE_ENABLE ); } else { - set_no_titlebar(PERSONALIZATION_WINDOW_CONTEXT_V1_ENABLE_MODE_DISABLE); + set_no_titlebar(TREELAND_PERSONALIZATION_WINDOW_CONTEXT_V1_ENABLE_MODE_DISABLE ); } window->waylandSurface()->commit(); }; diff --git a/src/wayland/qwaylandwindowcontextshellsurface_p.h b/src/wayland/qwaylandwindowcontextshellsurface_p.h index 109e5119..2ade92e4 100644 --- a/src/wayland/qwaylandwindowcontextshellsurface_p.h +++ b/src/wayland/qwaylandwindowcontextshellsurface_p.h @@ -15,7 +15,7 @@ DGUI_BEGIN_NAMESPACE class QWaylandPersonalizationShellIntegration; class QWaylandWindowContextSurface : public QtWaylandClient::QWaylandShellSurface, - public QtWayland::personalization_window_context_v1 + public QtWayland::treeland_personalization_window_context_v1 { Q_OBJECT public: