From b22d4a42d91dfb6316328ca767a85396dcce33f2 Mon Sep 17 00:00:00 2001 From: deepin-ci-robot Date: Thu, 28 Nov 2024 06:52:27 +0000 Subject: [PATCH] sync: from linuxdeepin/dtkgui Synchronize source files from linuxdeepin/dtkgui. Source-pull-request: https://github.com/linuxdeepin/dtkgui/pull/258 --- src/kernel/dplatformhandle.cpp | 38 +- src/plugins/dplatformwindowinterface.cpp | 214 +++++ .../dtreelandplatformwindowinterface.cpp | 82 +- .../dtreelandplatformwindowinterface.h | 28 +- .../dtreelandplatformwindowinterface_p.h | 32 + .../xcb/dxcbplatformwindowinterface.cpp | 767 ++++++++++++++++++ .../xcb/dxcbplatformwindowinterface.h | 98 +++ .../xcb/dxcbplatformwindowinterface_p.h | 22 + src/private/dplatformwindowinterface_p.h | 100 +++ src/private/dplatformwindowinterface_p_p.h | 30 + src/private/private.cmake | 1 + 11 files changed, 1357 insertions(+), 55 deletions(-) create mode 100644 src/plugins/dplatformwindowinterface.cpp create mode 100644 src/plugins/platform/treeland/dtreelandplatformwindowinterface_p.h create mode 100644 src/plugins/platform/xcb/dxcbplatformwindowinterface.cpp create mode 100644 src/plugins/platform/xcb/dxcbplatformwindowinterface.h create mode 100644 src/plugins/platform/xcb/dxcbplatformwindowinterface_p.h create mode 100644 src/private/dplatformwindowinterface_p.h create mode 100644 src/private/dplatformwindowinterface_p_p.h diff --git a/src/kernel/dplatformhandle.cpp b/src/kernel/dplatformhandle.cpp index d21fbd9..221c5e5 100644 --- a/src/kernel/dplatformhandle.cpp +++ b/src/kernel/dplatformhandle.cpp @@ -8,6 +8,11 @@ #include "dplatformtheme.h" #include "dwindowmanagerhelper.h" +#include "private/dplatformwindowinterface_p.h" +#include +#ifndef DTK_DISABLE_XCB +#include "plugins/platform/xcb/dxcbplatformwindowinterface.h" +#endif #ifndef DTK_DISABLE_TREELAND #include "plugins/platform/treeland/dtreelandplatformwindowinterface.h" #endif @@ -104,19 +109,17 @@ static void setWindowProperty(QWindow *window, const char *name, const QVariant reinterpret_cast(setWindowProperty)(window, name, value); } -#ifndef DTK_DISABLE_TREELAND -static QHash g_platformThemeMap; +static QHash g_platformThemeMap; -static DTreeLandPlatformWindowInterface *dPlatformWindowInterfaceByWindow(QWindow * window) +static DPlatformWindowInterface *dPlatformWindowInterfaceByWindow(QWindow *window) { for (auto it = g_platformThemeMap.cbegin(); it != g_platformThemeMap.cend(); ++it) { - if (it.value()->getWindow() == window) { + if (it.value()->window() == window) { return it.value(); } } return nullptr; } -#endif /*! \class Dtk::Gui::DPlatformHandle @@ -394,6 +397,13 @@ static DTreeLandPlatformWindowInterface *dPlatformWindowInterfaceByWindow(QWindo 竖直方向的圆角半径 */ +static DPlatformWindowInterfaceFactory::HelperCreator OutsideWindowInterfaceCreator = nullptr; + +void DPlatformWindowInterfaceFactory::registerInterface(HelperCreator creator) +{ + OutsideWindowInterfaceCreator = creator; +} + /*! \brief DPlatformHandle::DPlatformHandle 将 \a window 对象传递给 enableDXcbForWindow @@ -405,11 +415,21 @@ DPlatformHandle::DPlatformHandle(QWindow *window, QObject *parent) : QObject(parent) , m_window(window) { + if (OutsideWindowInterfaceCreator) { + g_platformThemeMap.insert(this, OutsideWindowInterfaceCreator(window, this)); + } else { +#ifndef DTK_DISABLE_XCB + if (DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsXWindowPlatform)) { + g_platformThemeMap.insert(this, new DXCBPlatformWindowInterface(window, this, parent)); + } +#endif + #ifndef DTK_DISABLE_TREELAND - if (DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsWaylandPlatform)) { - g_platformThemeMap.insert(this, new DTreeLandPlatformWindowInterface(nullptr, window)); - } + if (DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsWaylandPlatform)) { + g_platformThemeMap.insert(this, new DTreeLandPlatformWindowInterface(window, this, parent)); + } #endif + } enableDXcbForWindow(window); @@ -418,11 +438,9 @@ DPlatformHandle::DPlatformHandle(QWindow *window, QObject *parent) DPlatformHandle::~DPlatformHandle() { -#ifndef DTK_DISABLE_TREELAND if (auto item = g_platformThemeMap.take(this)) { item->deleteLater(); } -#endif } /*! diff --git a/src/plugins/dplatformwindowinterface.cpp b/src/plugins/dplatformwindowinterface.cpp new file mode 100644 index 0000000..faf0a33 --- /dev/null +++ b/src/plugins/dplatformwindowinterface.cpp @@ -0,0 +1,214 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "dplatformhandle.h" +#include "private/dplatformwindowinterface_p.h" +#include "private/dplatformwindowinterface_p_p.h" +#include "dtkgui_global.h" +#include +#include + +DGUI_BEGIN_NAMESPACE + +DPlatformWindowInterfacePrivate::DPlatformWindowInterfacePrivate(DPlatformWindowInterface *qq) + : DObjectPrivate(qq) +{ +} + +DPlatformWindowInterface::DPlatformWindowInterface(QWindow *window, DPlatformHandle *platformHandle, QObject *parent) + :DPlatformWindowInterface(*new DPlatformWindowInterfacePrivate(this), window, platformHandle, parent) +{ +} + +DPlatformWindowInterface::~DPlatformWindowInterface() +{ +} + +QWindow *DPlatformWindowInterface::window() const +{ + D_DC(DPlatformWindowInterface); + + return d->m_window; +} + +bool DPlatformWindowInterface::isEnabledNoTitlebar() const +{ + return {}; +} + +bool DPlatformWindowInterface::setEnabledNoTitlebar(bool enable) +{ + return {}; +} + +bool DPlatformWindowInterface::setWindowBlurAreaByWM(const QVector &area) +{ + return {}; +} + +bool DPlatformWindowInterface::setWindowBlurAreaByWM(const QList &paths) +{ + return {}; +} + +int DPlatformWindowInterface::windowRadius() const +{ + return {}; +} + +void DPlatformWindowInterface::setWindowRadius(int windowRadius) +{ +} + +int DPlatformWindowInterface::borderWidth() const +{ + return {}; +} + +void DPlatformWindowInterface::setBorderWidth(int borderWidth) +{ +} + +QColor DPlatformWindowInterface::borderColor() const +{ + return {}; +} + +void DPlatformWindowInterface::setBorderColor(const QColor &borderColor) +{ +} + +int DPlatformWindowInterface::shadowRadius() const +{ + return {}; +} + +void DPlatformWindowInterface::setShadowRadius(int shadowRadius) +{ +} + +QPoint DPlatformWindowInterface::shadowOffset() const +{ + return {}; +} + +void DPlatformWindowInterface::setShadowOffset(const QPoint &shadowOffset) +{ +} + +QColor DPlatformWindowInterface::shadowColor() const +{ + return {}; +} + +void DPlatformWindowInterface::setShadowColor(const QColor &shadowColor) +{ +} + +DPlatformHandle::EffectScene DPlatformWindowInterface::windowEffect() +{ + return {}; +} + +void DPlatformWindowInterface::setWindowEffect(DPlatformHandle::EffectScenes effectScene) +{ +} + +DPlatformHandle::EffectType DPlatformWindowInterface::windowStartUpEffect() +{ + return {}; +} + +void DPlatformWindowInterface::setWindowStartUpEffect(DPlatformHandle::EffectTypes effectType) +{ +} + +QPainterPath DPlatformWindowInterface::clipPath() const +{ + return {}; +} + +void DPlatformWindowInterface::setClipPath(const QPainterPath &clipPath) +{ +} + +QRegion DPlatformWindowInterface::frameMask() const +{ + return {}; +} + +void DPlatformWindowInterface::setFrameMask(const QRegion &frameMask) +{ +} + +QMargins DPlatformWindowInterface::frameMargins() const +{ + return {}; +} + +bool DPlatformWindowInterface::translucentBackground() const +{ + return {}; +} + +void DPlatformWindowInterface::setTranslucentBackground(bool translucentBackground) +{ +} + +bool DPlatformWindowInterface::enableSystemResize() const +{ + return {}; +} + +void DPlatformWindowInterface::setEnableSystemResize(bool enableSystemResize) +{ +} + +bool DPlatformWindowInterface::enableSystemMove() const +{ + return {}; +} + +void DPlatformWindowInterface::setEnableSystemMove(bool enableSystemMove) +{ +} + +bool DPlatformWindowInterface::enableBlurWindow() const +{ + return {}; +} + +void DPlatformWindowInterface::setEnableBlurWindow(bool enableBlurWindow) +{ +} + +bool DPlatformWindowInterface::autoInputMaskByClipPath() const +{ + return {}; +} + +void DPlatformWindowInterface::setAutoInputMaskByClipPath(bool autoInputMaskByClipPath) +{ +} + +WId DPlatformWindowInterface::realWindowId() const +{ + return {}; +} + +WId DPlatformWindowInterface::windowLeader() +{ + return {}; +} + +DPlatformWindowInterface::DPlatformWindowInterface(DPlatformWindowInterfacePrivate &dd, QWindow *window, DPlatformHandle *platformHandle, QObject *parent) + : QObject(parent) + , DObject(dd) +{ + d_func()->m_window = window; + d_func()->m_platformHandle = platformHandle; +} + +DGUI_END_NAMESPACE + diff --git a/src/plugins/platform/treeland/dtreelandplatformwindowinterface.cpp b/src/plugins/platform/treeland/dtreelandplatformwindowinterface.cpp index 1e9034d..bee7204 100644 --- a/src/plugins/platform/treeland/dtreelandplatformwindowinterface.cpp +++ b/src/plugins/platform/treeland/dtreelandplatformwindowinterface.cpp @@ -2,18 +2,19 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later + +#include "dtkgui_global.h" #define protected public #include #undef protected #include "dtreelandplatformwindowinterface.h" -#include "dtreelandplatformwindowinterface.h" -#include "dtreelandplatforminterface.h" +#include "dtreelandplatformwindowinterface_p.h" + #include #include #include -#include "personalizationwaylandclientextension.h" #include #include "dvtablehook.h" @@ -22,6 +23,7 @@ #include #include + DCORE_USE_NAMESPACE class MoveWindowHelper : public QObject @@ -164,14 +166,22 @@ class Q_DECL_HIDDEN WindowEventFilter : public QObject { DTreeLandPlatformWindowInterface *m_interface; }; -DTreeLandPlatformWindowInterface::DTreeLandPlatformWindowInterface(QObject *parent, QWindow *window) - : QObject(parent) - , m_window(window) +DGUI_BEGIN_NAMESPACE + +DTreeLandPlatformWindowInterfacePrivate::DTreeLandPlatformWindowInterfacePrivate(DTreeLandPlatformWindowInterface *qq) + : DPlatformWindowInterfacePrivate(qq) +{ +} + +DTreeLandPlatformWindowInterface::DTreeLandPlatformWindowInterface(QWindow *window, DPlatformHandle *platformHandle, QObject *parent) + : DPlatformWindowInterface(*new DTreeLandPlatformWindowInterfacePrivate(this), window, platformHandle, parent) { - m_manager = PersonalizationManager::instance(); - m_window->installEventFilter(new WindowEventFilter(this, this)); - connect(m_manager, &PersonalizationManager::activeChanged, this, [this](){ - if (m_manager->isActive()) { + D_D(DTreeLandPlatformWindowInterface); + + d->m_manager = PersonalizationManager::instance(); + d->m_window->installEventFilter(new WindowEventFilter(this, this)); + connect(d->m_manager, &PersonalizationManager::activeChanged, this, [this, d](){ + if (d->m_manager->isActive()) { handlePendingTasks(); } }); @@ -188,18 +198,20 @@ DTreeLandPlatformWindowInterface::~DTreeLandPlatformWindowInterface() PersonalizationWindowContext *DTreeLandPlatformWindowInterface::getWindowContext() { - if (!m_manager->isSupported()) { + D_D(DTreeLandPlatformWindowInterface); + + if (!d->m_manager->isSupported()) { return nullptr; } - if (!m_window) { + if (!d->m_window) { qWarning() << "window is nullptr!!!"; return nullptr; } - if (m_windowContext) { - return m_windowContext; + if (d->m_windowContext) { + return d->m_windowContext; } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - auto waylandWindow = m_window->nativeInterface(); + auto waylandWindow = d->m_window->nativeInterface(); #else auto waylandWindow = dynamic_cast(m_window->handle()); #endif @@ -217,37 +229,43 @@ PersonalizationWindowContext *DTreeLandPlatformWindowInterface::getWindowContext return nullptr; } - if (!m_windowContext) { - m_windowContext = new PersonalizationWindowContext(m_manager->get_window_context(surface)); + if (!d->m_windowContext) { + d->m_windowContext = new PersonalizationWindowContext(d->m_manager->get_window_context(surface)); } - connect(m_window, &QWindow::visibleChanged, m_windowContext, [this](bool visible){ + connect(d->m_window, &QWindow::visibleChanged, d->m_windowContext, [this, d](bool visible){ if (!visible) { - m_windowContext->deleteLater(); - m_windowContext = nullptr; + d->m_windowContext->deleteLater(); + d->m_windowContext = nullptr; } }); - return m_windowContext; + return d->m_windowContext; } void DTreeLandPlatformWindowInterface::handlePendingTasks() { - while (!m_pendingTasks.isEmpty()) { - auto handleFunc = m_pendingTasks.dequeue(); + D_D(DTreeLandPlatformWindowInterface); + + while (!d->m_pendingTasks.isEmpty()) { + auto handleFunc = d->m_pendingTasks.dequeue(); handleFunc(); } } bool DTreeLandPlatformWindowInterface::setEnabledNoTitlebar(bool enable) { - m_isNoTitlebar = enable; + D_D(DTreeLandPlatformWindowInterface); + + d->m_isNoTitlebar = enable; doSetEnabledNoTitlebar(); return true; } void DTreeLandPlatformWindowInterface::setEnableBlurWindow(bool enable) { + D_D(DTreeLandPlatformWindowInterface); + auto handleFunc = [this, enable](){ auto windowContext = getWindowContext(); if (!windowContext) { @@ -256,27 +274,31 @@ void DTreeLandPlatformWindowInterface::setEnableBlurWindow(bool enable) } windowContext->set_blend_mode(enable ? PersonalizationWindowContext::blend_mode_blur : PersonalizationWindowContext::blend_mode_transparent); }; - if (m_manager->isActive()) { + if (d->m_manager->isActive()) { handleFunc(); } else { - m_pendingTasks.enqueue(handleFunc); + d->m_pendingTasks.enqueue(handleFunc); } } void DTreeLandPlatformWindowInterface::doSetEnabledNoTitlebar() { - auto handleFunc = [this](){ + D_D(DTreeLandPlatformWindowInterface); + + auto handleFunc = [this, d](){ auto windowContext = getWindowContext(); if (!windowContext) { qWarning() << "windowContext is nullptr!"; return false; } - windowContext->set_titlebar(m_isNoTitlebar ? PersonalizationWindowContext::enable_mode_disable : PersonalizationWindowContext::enable_mode_enable); + windowContext->set_titlebar(d->m_isNoTitlebar ? PersonalizationWindowContext::enable_mode_disable : PersonalizationWindowContext::enable_mode_enable); return true; }; - if (m_manager->isActive()) { + if (d->m_manager->isActive()) { handleFunc(); } else { - m_pendingTasks.enqueue(handleFunc); + d->m_pendingTasks.enqueue(handleFunc); } } + +DGUI_END_NAMESPACE diff --git a/src/plugins/platform/treeland/dtreelandplatformwindowinterface.h b/src/plugins/platform/treeland/dtreelandplatformwindowinterface.h index a6e1f46..02a52bb 100644 --- a/src/plugins/platform/treeland/dtreelandplatformwindowinterface.h +++ b/src/plugins/platform/treeland/dtreelandplatformwindowinterface.h @@ -6,31 +6,29 @@ #define DTREELANDPLATFORMWINDOWINTERFACE_H #include "dtkgui_global.h" -#include "dtreelandplatforminterface.h" -#include +#include "private/dplatformwindowinterface_p.h" -DGUI_USE_NAMESPACE -class DTreeLandPlatformWindowInterface : public QObject +DGUI_BEGIN_NAMESPACE + +class PersonalizationWindowContext; +class DTreeLandPlatformWindowInterfacePrivate; +class DTreeLandPlatformWindowInterface : public DPlatformWindowInterface { Q_OBJECT + D_DECLARE_PRIVATE(DTreeLandPlatformWindowInterface) public: - explicit DTreeLandPlatformWindowInterface(QObject *parent = nullptr, QWindow *window = nullptr); + explicit DTreeLandPlatformWindowInterface(QWindow *window, DPlatformHandle *platformHandle, QObject *parent = nullptr); ~DTreeLandPlatformWindowInterface(); - bool setEnabledNoTitlebar(bool enable); - void setEnableBlurWindow(bool enable); + + bool setEnabledNoTitlebar(bool enable) override; + void setEnableBlurWindow(bool enable) override; + void doSetEnabledNoTitlebar(); - [[nodiscard]]QWindow *getWindow() const { return m_window; } private: PersonalizationWindowContext *getWindowContext(); void handlePendingTasks(); - -private: - QWindow *m_window = nullptr; - QQueue> m_pendingTasks; - PersonalizationManager *m_manager = nullptr; - PersonalizationWindowContext *m_windowContext = nullptr; - bool m_isNoTitlebar = true; }; +DGUI_END_NAMESPACE #endif // DTREELANDPLATFORMWINDOWINTERFACE_H diff --git a/src/plugins/platform/treeland/dtreelandplatformwindowinterface_p.h b/src/plugins/platform/treeland/dtreelandplatformwindowinterface_p.h new file mode 100644 index 0000000..84cb3db --- /dev/null +++ b/src/plugins/platform/treeland/dtreelandplatformwindowinterface_p.h @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DTREELANDPLATFORMINTERFACE_P_H +#define DTREELANDPLATFORMINTERFACE_P_H + +#include "dplatformwindowinterface_p_p.h" +#include "dtreelandplatformwindowinterface.h" +#include "personalizationwaylandclientextension.h" + +#include + +DGUI_BEGIN_NAMESPACE + +class DTreeLandPlatformWindowInterfacePrivate : public DPlatformWindowInterfacePrivate +{ +public: + D_DECLARE_PUBLIC(DTreeLandPlatformWindowInterface) + DTreeLandPlatformWindowInterfacePrivate(DTreeLandPlatformWindowInterface *qq); + +public: + QWindow *m_window = nullptr; + QQueue> m_pendingTasks; + PersonalizationManager *m_manager = nullptr; + PersonalizationWindowContext *m_windowContext = nullptr; + bool m_isNoTitlebar = true; +}; + +DGUI_END_NAMESPACE + +#endif // DNATIVESETTINGS_P_H diff --git a/src/plugins/platform/xcb/dxcbplatformwindowinterface.cpp b/src/plugins/platform/xcb/dxcbplatformwindowinterface.cpp new file mode 100644 index 0000000..36caaf4 --- /dev/null +++ b/src/plugins/platform/xcb/dxcbplatformwindowinterface.cpp @@ -0,0 +1,767 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "dguiapplicationhelper.h" +#include "dxcbplatformwindowinterface.h" +#include "dplatformhandle.h" +#include "dplatformwindowinterface_p_p.h" +#include "dxcbplatformwindowinterface_p.h" +#include "dplatformtheme.h" +#include "dwindowmanagerhelper.h" +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +DGUI_BEGIN_NAMESPACE + +#define DXCB_PLUGIN_KEY "dxcb" +#define DXCB_PLUGIN_SYMBOLIC_PROPERTY "_d_isDxcb" + +#define DEFINE_CONST_CHAR(Name) const char _##Name[] = "_d_" #Name + +DEFINE_CONST_CHAR(useDxcb); +DEFINE_CONST_CHAR(redirectContent); +DEFINE_CONST_CHAR(netWmStates); +DEFINE_CONST_CHAR(windowRadius); +DEFINE_CONST_CHAR(borderWidth); +DEFINE_CONST_CHAR(borderColor); +DEFINE_CONST_CHAR(windowEffect); +DEFINE_CONST_CHAR(windowStartUpEffect); +DEFINE_CONST_CHAR(shadowRadius); +DEFINE_CONST_CHAR(shadowOffset); +DEFINE_CONST_CHAR(shadowColor); +DEFINE_CONST_CHAR(clipPath); +DEFINE_CONST_CHAR(frameMask); +DEFINE_CONST_CHAR(frameMargins); +DEFINE_CONST_CHAR(translucentBackground); +DEFINE_CONST_CHAR(enableSystemResize); +DEFINE_CONST_CHAR(enableSystemMove); +DEFINE_CONST_CHAR(enableBlurWindow); +DEFINE_CONST_CHAR(windowBlurAreas); +DEFINE_CONST_CHAR(windowBlurPaths); +DEFINE_CONST_CHAR(windowWallpaperParas); +DEFINE_CONST_CHAR(autoInputMaskByClipPath); + +DEFINE_CONST_CHAR(resolve_mask); +enum PropRole { + WindowRadius, + + // TO BE CONTINUE +}; + +// functions +DEFINE_CONST_CHAR(setWmBlurWindowBackgroundArea); +DEFINE_CONST_CHAR(setWmBlurWindowBackgroundPathList); +DEFINE_CONST_CHAR(setWmBlurWindowBackgroundMaskImage); +DEFINE_CONST_CHAR(setWmWallpaperParameter); +DEFINE_CONST_CHAR(setWindowProperty); +DEFINE_CONST_CHAR(pluginVersion); +DEFINE_CONST_CHAR(disableOverrideCursor); +DEFINE_CONST_CHAR(enableDxcb); +DEFINE_CONST_CHAR(isEnableDxcb); +DEFINE_CONST_CHAR(setEnableNoTitlebar); +DEFINE_CONST_CHAR(isEnableNoTitlebar); +DEFINE_CONST_CHAR(clientLeader); + +static void resolve(QObject *obj, PropRole role) +{ + int mask = obj->property(_resolve_mask).toInt(); + obj->setProperty(_resolve_mask, (mask |= 1 << role)); +} + +static bool resolved(QObject *obj, PropRole role) +{ + int mask = obj->property(_resolve_mask).toInt(); + return mask & (1 << role); +} + +static void setWindowProperty(QWindow *window, const char *name, const QVariant &value) +{ + if (!window) + return; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + static QFunctionPointer setWindowProperty = qApp->platformFunction(_setWindowProperty); +#else + constexpr QFunctionPointer setWindowProperty = nullptr; +#endif + + if (!setWindowProperty) { + window->setProperty(name, value); + + return; + } + + reinterpret_cast(setWindowProperty)(window, name, value); +} + +DXCBPlatformWindowInterfacePrivate::DXCBPlatformWindowInterfacePrivate(DXCBPlatformWindowInterface *qq) + : DPlatformWindowInterfacePrivate(qq) +{ +} + +DXCBPlatformWindowInterface::DXCBPlatformWindowInterface(QWindow *window, DPlatformHandle *platformHandle, QObject *parent) + : DPlatformWindowInterface(*new DXCBPlatformWindowInterfacePrivate(this), window, platformHandle, parent) +{ + D_D(DXCBPlatformWindowInterface); + + /*enableInterfaceForWindow(window);*/ + + window->installEventFilter(this); +} + +DXCBPlatformWindowInterface::~DXCBPlatformWindowInterface() +{ +} + +QString DXCBPlatformWindowInterface::pluginVersion() +{ + QFunctionPointer pv = 0; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + pv = qApp->platformFunction(_pluginVersion); +#endif + + if (Q_UNLIKELY(!pv)) + return QString(); + + return reinterpret_cast(pv)(); +} + +bool DXCBPlatformWindowInterface::isDXcbPlatform() +{ + if (!qApp) + return false; + + static bool _is_dxcb = qApp->platformName() == DXCB_PLUGIN_KEY || qApp->property(DXCB_PLUGIN_SYMBOLIC_PROPERTY).toBool(); + + return _is_dxcb; +} + +void DXCBPlatformWindowInterface::enableDXcb() +{ + D_D(DXCBPlatformWindowInterface); + + // 优先使用窗口管理器中实现的no titlebar接口实现自定义窗口修饰器的效果 + if (setEnabledNoTitlebar(true)) { + return; + } + + if (!isDXcbPlatform()) + return; + + QFunctionPointer enable_dxcb = nullptr; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + enable_dxcb = qApp->platformFunction(_enableDxcb); +#endif + + if (enable_dxcb) { + (*reinterpret_cast(enable_dxcb))(d->m_window); + } else if (d->m_window->handle()) { + Q_ASSERT_X(d->m_window->property(_useDxcb).toBool(), "DXCBPlatformWindowInterfacer:", + "Must be called before window handle has been created. See also QWindow::handle()"); + } else { + d->m_window->setProperty(_useDxcb, true); + } +} + +void DXCBPlatformWindowInterface::enableDXcb(bool redirectContent) +{ + D_D(DXCBPlatformWindowInterface); + + d->m_window->setProperty(_redirectContent, redirectContent); + + enableDXcb(); +} + +bool DXCBPlatformWindowInterface::isEnabledDXcb() +{ + D_D(DXCBPlatformWindowInterface); + + if (isEnabledNoTitlebar()) + return true; + + QFunctionPointer is_enable_dxcb = nullptr; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + is_enable_dxcb = qApp->platformFunction(_isEnableDxcb); +#endif + + if (is_enable_dxcb) { + return (*reinterpret_cast(is_enable_dxcb))(d->m_window); + } + + return d->m_window->property(_useDxcb).toBool(); +} + +static void initWindowRadius(QWindow *window) +{ + if (window->property(_windowRadius).isValid()) + return; + + auto theme = DGuiApplicationHelper::instance()->systemTheme(); + int radius = theme->windowRadius(18); //###(zccrs): 暂时在此处给窗口默认设置为18px的圆角 + + setWindowProperty(window, _windowRadius, radius); + // Qt::UniqueConnection will report a warning + // to `unique connections require a pointer to member function of a QObject subclass`. + const char *uniqueueConnectionFlag("_d_uniqueueConnectionFlag"); + bool connected = window->property(uniqueueConnectionFlag).toBool(); + if (!connected) { + window->setProperty(uniqueueConnectionFlag, true); + window->connect(theme, &DPlatformTheme::windowRadiusChanged, window, [window] (int radius) { + if (!resolved(window, PropRole::WindowRadius)) + setWindowProperty(window, _windowRadius, radius); + }); + } +} + +class Q_DECL_HIDDEN CreatorWindowEventFilter : public QObject { +public: + CreatorWindowEventFilter(QObject *par= nullptr): QObject(par){} + +public: + bool eventFilter(QObject *watched, QEvent *event) override { + if (event->type() == QEvent::PlatformSurface) { + QPlatformSurfaceEvent *se = static_cast(event); + if (se->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) { // 若收到此信号, 则 WinID 已被创建 + auto window = qobject_cast(watched); + initWindowRadius(window); + } + } + return QObject::eventFilter(watched, event); + } +}; + +bool DXCBPlatformWindowInterface::isEnabledNoTitlebar() const +{ + D_DC(DXCBPlatformWindowInterface); + QFunctionPointer is_enable_no_titlebar = nullptr; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + is_enable_no_titlebar = qApp->platformFunction(_isEnableNoTitlebar); +#endif + + if (is_enable_no_titlebar) { + return (*reinterpret_cast(is_enable_no_titlebar))(d->m_window); + } + + return false; +} + +bool DXCBPlatformWindowInterface::setEnabledNoTitlebar(bool enable) +{ + D_D(DXCBPlatformWindowInterface); + auto isDWaylandPlatform = [] { + return qApp->platformName() == "dwayland" || qApp->property("_d_isDwayland").toBool(); + }; + if (!(isDXcbPlatform() || isDWaylandPlatform() || DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsWaylandPlatform))) + return false; + + if (isEnabledNoTitlebar() == enable) + return true; + + QFunctionPointer enable_no_titlear = nullptr; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + enable_no_titlear = qApp->platformFunction(_setEnableNoTitlebar); +#endif + + if (enable_no_titlear) { + bool ok = (*reinterpret_cast(enable_no_titlear))(d->m_window, enable); + if (ok && enable) { + if (d->m_window->handle()) { + initWindowRadius(d->m_window); + } else { + d->m_window->installEventFilter(new CreatorWindowEventFilter(d->m_window)); + } + } + + return ok; + } + + return false; +} + +inline DPlatformHandle::WMBlurArea operator *(const DPlatformHandle::WMBlurArea &area, qreal scale) +{ + if (qFuzzyCompare(scale, 1.0)) + return area; + + DPlatformHandle::WMBlurArea new_area; + + new_area.x = qRound64(area.x * scale); + new_area.y = qRound64(area.y * scale); + new_area.width = qRound64(area.width * scale); + new_area.height = qRound64(area.height * scale); + new_area.xRadius = qRound64(area.xRadius * scale); + new_area.yRaduis = qRound64(area.yRaduis * scale); + + return new_area; +} + +/*! + \brief DXCBPlatformWindowInterface::setWindowBlurAreaByWM + 设置窗口背景的模糊区域,示例: + \code + QWindow w; + QVector area_list; + DXCBPlatformWindowInterface::WMBlurArea area; + + area.x = 50; + area.y = 50; + area.width = 200; + area.height = 200; + area.xRadius = 10; + area.yRaduis = 10; + area_list.append(area); + + DXCBPlatformWindowInterface::setWindowBlurAreaByWM(&w, area_list); + + QSurfaceFormat format = w.format(); + format.setAlphaBufferSize(8); + + w.setFormat(format); + w.resize(300, 300); + w.show(); + + \endcode + \image blur_window_demo1.png + \a window 目标窗口对象 + \a area 模糊区域,此区域范围内的窗口背景将填充为窗口后面内容模糊之后的图像 + \return 如果设置成功则返回 true,否则返回 false + \note 对于需要显示模糊背景的窗口,需要将其 QSurfaceFormat 的 alpha 通道设置为8 + \note 调用此接口设置窗口背景模糊区域后将覆盖之前所设置的区域,包括调用 + setWindowBlurAreaByWM(QWindow *, const QList &) + 所设置的区域 + \note 建议使用 DBlurEffectWidget 实现窗口背景模糊效果 + \note 此功能依赖于窗口管理器的实现,目前仅支持 deepin-wm 和 kwin 这两个窗口管理器 + \sa Dtk::Widget::DBlurEffectWidget + \sa QSurfaceFormat::setAlphaBufferSize + \sa QWindow::setFormat + \sa DWindowManagerHelper::hasBlurWindow + \sa DXCBPlatformWindowInterface::setWindowBlurAreaByWM(QWindow *, const QList &) + */ +bool DXCBPlatformWindowInterface::setWindowBlurArea(const QVector &area) +{ + D_D(DXCBPlatformWindowInterface); + + if (!d->m_window) { + return false; + } + + if (isEnabledDXcb()) { + QVector areas; + for (auto item : area) + areas << item.x << item.y << item.width << item.height << item.xRadius << item.yRaduis; + setWindowProperty(d->m_window, _windowBlurAreas, QVariant::fromValue(areas)); + return true; + } + + QFunctionPointer setWmBlurWindowBackgroundArea = Q_NULLPTR; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + setWmBlurWindowBackgroundArea = qApp->platformFunction(_setWmBlurWindowBackgroundArea); +#endif + + if (!setWmBlurWindowBackgroundArea) { + qWarning("setWindowBlurAreaByWM is not support"); + + return false; + } + + QSurfaceFormat format = d->m_window->format(); + + format.setAlphaBufferSize(8); + d->m_window->setFormat(format); + + const qreal device_ratio = d->m_window->devicePixelRatio(); + + if (qFuzzyCompare(device_ratio, 1.0)) { + return reinterpret_cast&)>(setWmBlurWindowBackgroundArea)(d->m_window->winId(), area); + } + + QVector new_areas; + + new_areas.reserve(area.size()); + + for (const DPlatformHandle::WMBlurArea &a : area) { + new_areas.append(a * device_ratio); + } + + return reinterpret_cast&)>(setWmBlurWindowBackgroundArea)(d->m_window->winId(), new_areas); +} + +inline QPainterPath operator *(const QPainterPath &path, qreal scale) +{ + if (qFuzzyCompare(1.0, scale)) + return path; + + QPainterPath new_path = path; + + for (int i = 0; i < path.elementCount(); ++i) { + const QPainterPath::Element &e = path.elementAt(i); + + new_path.setElementPositionAt(i, qRound(e.x * scale), qRound(e.y * scale)); + } + + return new_path; +} + +bool DXCBPlatformWindowInterface::setWindowBlurArea(const QList &paths) +{ + D_D(DXCBPlatformWindowInterface); + + if (!d->m_window) { + return false; + } + + if (isEnabledDXcb()) { + setWindowProperty(d->m_window, _windowBlurPaths, QVariant::fromValue(paths)); + + return true; + } + + QFunctionPointer setWmBlurWindowBackgroundPathList = Q_NULLPTR; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + setWmBlurWindowBackgroundPathList = qApp->platformFunction(_setWmBlurWindowBackgroundPathList); +#endif + + if (!setWmBlurWindowBackgroundPathList) { + qWarning("setWindowBlurAreaByWM is not support"); + + return false; + } + + QSurfaceFormat format = d->m_window->format(); + + format.setAlphaBufferSize(8); + d->m_window->setFormat(format); + + const qreal device_ratio = d->m_window->devicePixelRatio(); + + if (qFuzzyCompare(device_ratio, 1.0)) { + return reinterpret_cast&)>(setWmBlurWindowBackgroundPathList)(d->m_window->winId(), paths); + } + + QList new_paths; + + new_paths.reserve(paths.size()); + + for (const QPainterPath &p : paths) { + new_paths.append(p * device_ratio); + } + + return reinterpret_cast&)>(setWmBlurWindowBackgroundPathList)(d->m_window->winId(), new_paths); +} + +bool DXCBPlatformWindowInterface::setWindowWallpaperPara(const QRect &area, DPlatformHandle::WallpaperScaleMode sMode, DPlatformHandle::WallpaperFillMode fMode) +{ + D_D(DXCBPlatformWindowInterface); + + if (!d->m_window) { + return false; + } + + QFunctionPointer setWmWallpaperParameter = Q_NULLPTR; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + setWmWallpaperParameter = qApp->platformFunction(_setWmWallpaperParameter); +#endif + + if (!setWmWallpaperParameter) { + qWarning("setWindowWallpaperParaByWM is not support"); + + return false; + } + + QSurfaceFormat format = d->m_window->format(); + + format.setAlphaBufferSize(8); + d->m_window->setFormat(format); + + quint32 bMode = sMode | fMode; + + // 激活 backing store + d->m_window->setProperty("_d_dxcb_wallpaper", QVariant::fromValue(QPair(area, bMode))); + + if (!d->m_window->handle()) { + return true; + } else { + qWarning() << "because the window handle has been created, so 2D mode will have no effect"; + } + + const qreal device_ratio = d->m_window->devicePixelRatio(); + if (qFuzzyCompare(device_ratio, 1.0) || !area.isValid()) { + return reinterpret_cast(setWmWallpaperParameter)(d->m_window->winId(), area, bMode); + } + + QRect new_area(area.x() * device_ratio, + area.y() * device_ratio, + area.width() * device_ratio, + area.height() * device_ratio); + + return reinterpret_cast(setWmWallpaperParameter)(d->m_window->winId(), new_area, bMode); +} + +bool DXCBPlatformWindowInterface::connectWindowManagerChangedSignal(QObject *object, std::function slot) +{ + if (object) { + return QObject::connect(DWindowManagerHelper::instance(), &DWindowManagerHelper::windowManagerChanged, object, slot); + } + + return QObject::connect(DWindowManagerHelper::instance(), &DWindowManagerHelper::windowManagerChanged, slot); +} + +bool DXCBPlatformWindowInterface::connectHasBlurWindowChanged(QObject *object, std::function slot) +{ + if (object) { + return QObject::connect(DWindowManagerHelper::instance(), &DWindowManagerHelper::hasBlurWindowChanged, object, slot); + } + + return QObject::connect(DWindowManagerHelper::instance(), &DWindowManagerHelper::hasBlurWindowChanged, slot); +} + +bool DXCBPlatformWindowInterface::setWindowBlurAreaByWM(const QVector &area) +{ + D_D(DXCBPlatformWindowInterface); + + return setWindowBlurArea(area); +} + +bool DXCBPlatformWindowInterface::setWindowBlurAreaByWM(const QList &paths) +{ + D_D(DXCBPlatformWindowInterface); + + return setWindowBlurArea(paths); +} + +void DXCBPlatformWindowInterface::setDisableWindowOverrideCursor(bool disable) +{ + D_D(DXCBPlatformWindowInterface); + + d->m_window->setProperty(_disableOverrideCursor, disable); +} + +int DXCBPlatformWindowInterface::windowRadius() const +{ + D_DC(DXCBPlatformWindowInterface); + + return d->m_window->property(_windowRadius).toInt(); +} + +void DXCBPlatformWindowInterface::setWindowRadius(int windowRadius) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _windowRadius, windowRadius); + resolve(d->m_window, PropRole::WindowRadius); +} + +int DXCBPlatformWindowInterface::borderWidth() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_borderWidth).toInt(); +} + +void DXCBPlatformWindowInterface::setBorderWidth(int borderWidth) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _borderWidth, borderWidth); +} + +QColor DXCBPlatformWindowInterface::borderColor() const +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property(_borderColor)); +} + +void DXCBPlatformWindowInterface::setBorderColor(const QColor &borderColor) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _borderColor, QVariant::fromValue(borderColor)); +} + +int DXCBPlatformWindowInterface::shadowRadius() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_shadowRadius).toInt(); +} + +void DXCBPlatformWindowInterface::setShadowRadius(int shadowRadius) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _shadowRadius, shadowRadius); +} + +QPoint DXCBPlatformWindowInterface::shadowOffset() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_shadowOffset).toPoint(); +} + +void DXCBPlatformWindowInterface::setShadowOffset(const QPoint &shadowOffset) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _shadowOffset, shadowOffset); +} + +QColor DXCBPlatformWindowInterface::shadowColor() const +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property(_shadowColor)); +} + +void DXCBPlatformWindowInterface::setShadowColor(const QColor &shadowColor) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _shadowColor, QVariant::fromValue(shadowColor)); +} + +DPlatformHandle::EffectScene DXCBPlatformWindowInterface::windowEffect() +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property(_windowEffect)); +} + +void DXCBPlatformWindowInterface::setWindowEffect(DPlatformHandle::EffectScenes effectScene) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _windowEffect, static_cast(effectScene)); +} + +DPlatformHandle::EffectType DXCBPlatformWindowInterface::windowStartUpEffect() +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property(_windowStartUpEffect)); +} + +void DXCBPlatformWindowInterface::setWindowStartUpEffect(DPlatformHandle::EffectTypes effectType) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _windowStartUpEffect, static_cast(effectType)); +} + +QPainterPath DXCBPlatformWindowInterface::clipPath() const +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property(_clipPath)); +} + +void DXCBPlatformWindowInterface::setClipPath(const QPainterPath &clipPath) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _clipPath, QVariant::fromValue(clipPath)); +} + +QRegion DXCBPlatformWindowInterface::frameMask() const +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property(_frameMask)); +} + +void DXCBPlatformWindowInterface::setFrameMask(const QRegion &frameMask) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _frameMask, QVariant::fromValue(frameMask)); +} + +QMargins DXCBPlatformWindowInterface::frameMargins() const +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property(_frameMargins)); +} + +bool DXCBPlatformWindowInterface::translucentBackground() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_translucentBackground).toBool(); +} + +void DXCBPlatformWindowInterface::setTranslucentBackground(bool translucentBackground) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _translucentBackground, translucentBackground); +} + +bool DXCBPlatformWindowInterface::enableSystemResize() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_enableSystemResize).toBool(); +} + +void DXCBPlatformWindowInterface::setEnableSystemResize(bool enableSystemResize) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _enableSystemResize, enableSystemResize); +} + +bool DXCBPlatformWindowInterface::enableSystemMove() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_enableSystemMove).toBool(); +} + +void DXCBPlatformWindowInterface::setEnableSystemMove(bool enableSystemMove) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _enableSystemMove, enableSystemMove); +} + +bool DXCBPlatformWindowInterface::enableBlurWindow() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_enableBlurWindow).toBool(); +} + +void DXCBPlatformWindowInterface::setEnableBlurWindow(bool enableBlurWindow) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _enableBlurWindow, enableBlurWindow); +} + +bool DXCBPlatformWindowInterface::autoInputMaskByClipPath() const +{ + D_DC(DXCBPlatformWindowInterface); + return d->m_window->property(_autoInputMaskByClipPath).toBool(); +} + +void DXCBPlatformWindowInterface::setAutoInputMaskByClipPath(bool autoInputMaskByClipPath) +{ + D_D(DXCBPlatformWindowInterface); + setWindowProperty(d->m_window, _autoInputMaskByClipPath, autoInputMaskByClipPath); +} + +WId DXCBPlatformWindowInterface::realWindowId() const +{ + D_DC(DXCBPlatformWindowInterface); + return qvariant_cast(d->m_window->property("_d_real_content_window")); +} + +WId DXCBPlatformWindowInterface::windowLeader() +{ + QFunctionPointer clientLeader = Q_NULLPTR; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + clientLeader = qApp->platformFunction(_clientLeader); +#endif + + if (!clientLeader) { + return 0; + } + + return reinterpret_cast(clientLeader)(); +} + + +DGUI_END_NAMESPACE diff --git a/src/plugins/platform/xcb/dxcbplatformwindowinterface.h b/src/plugins/platform/xcb/dxcbplatformwindowinterface.h new file mode 100644 index 0000000..a1fea2e --- /dev/null +++ b/src/plugins/platform/xcb/dxcbplatformwindowinterface.h @@ -0,0 +1,98 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DXCBPLATFORMWINDOWINTERFACE_H +#define DXCBPLATFORMWINDOWINTERFACE_H + +#include "private/dplatformwindowinterface_p.h" + +#include + +DGUI_BEGIN_NAMESPACE + +class DXCBPlatformWindowInterfacePrivate; +class DXCBPlatformWindowInterface : public DPlatformWindowInterface +{ + Q_OBJECT + D_DECLARE_PRIVATE(DXCBPlatformWindowInterface) +public: + explicit DXCBPlatformWindowInterface(QWindow *window, DPlatformHandle *platformHandle, QObject *parent); + ~DXCBPlatformWindowInterface(); + + static QString pluginVersion(); + static bool isDXcbPlatform(); + + void enableDXcb(); + void enableDXcb(bool redirectContent); + bool isEnabledDXcb(); + + bool setWindowBlurArea(const QVector &area); + bool setWindowBlurArea(const QList &paths); + bool setWindowWallpaperPara(const QRect &area, DPlatformHandle::WallpaperScaleMode sMode, DPlatformHandle::WallpaperFillMode fMode); + + static bool connectWindowManagerChangedSignal(QObject *object, std::function slot); + static bool connectHasBlurWindowChanged(QObject *object, std::function slot); + + bool setWindowBlurAreaByWM(const QVector &area) override; + bool setWindowBlurAreaByWM(const QList &paths) override; + + void setDisableWindowOverrideCursor(bool disable); + + bool isEnabledNoTitlebar() const override; + bool setEnabledNoTitlebar(bool enable) override; + + int windowRadius() const override; + void setWindowRadius(int windowRadius) override; + + int borderWidth() const override; + void setBorderWidth(int borderWidth) override; + + QColor borderColor() const override; + void setBorderColor(const QColor &borderColor) override; + + int shadowRadius() const override; + void setShadowRadius(int shadowRadius) override; + + QPoint shadowOffset() const override; + void setShadowOffset(const QPoint &shadowOffset) override; + + QColor shadowColor() const override; + void setShadowColor(const QColor &shadowColor) override; + + DPlatformHandle::EffectScene windowEffect() override; + void setWindowEffect(DPlatformHandle::EffectScenes effectScene) override; + + DPlatformHandle::EffectType windowStartUpEffect() override; + void setWindowStartUpEffect(DPlatformHandle::EffectTypes effectType) override; + + QPainterPath clipPath() const override; + void setClipPath(const QPainterPath &clipPath) override; + + QRegion frameMask() const override; + void setFrameMask(const QRegion &frameMask) override; + + QMargins frameMargins() const override; + + bool translucentBackground() const override; + void setTranslucentBackground(bool translucentBackground) override; + + bool enableSystemResize() const override; + void setEnableSystemResize(bool enableSystemResize) override; + + bool enableSystemMove() const override; + void setEnableSystemMove(bool enableSystemMove) override; + + bool enableBlurWindow() const override; + void setEnableBlurWindow(bool enableBlurWindow) override; + + bool autoInputMaskByClipPath() const override; + void setAutoInputMaskByClipPath(bool autoInputMaskByClipPath) override; + + WId realWindowId() const override; + + WId windowLeader() override; +}; + +DGUI_END_NAMESPACE +#endif // DXCBPLATFORMWINDOWINTERFACE_H diff --git a/src/plugins/platform/xcb/dxcbplatformwindowinterface_p.h b/src/plugins/platform/xcb/dxcbplatformwindowinterface_p.h new file mode 100644 index 0000000..f281f53 --- /dev/null +++ b/src/plugins/platform/xcb/dxcbplatformwindowinterface_p.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DXCBPLATFORMINTERFACE_P_H +#define DXCBPLATFORMINTERFACE_P_H + +#include "dplatformwindowinterface_p_p.h" +#include "dxcbplatformwindowinterface.h" + +DGUI_BEGIN_NAMESPACE + +class DXCBPlatformWindowInterfacePrivate : public DPlatformWindowInterfacePrivate +{ +public: + D_DECLARE_PUBLIC(DXCBPlatformWindowInterface) + DXCBPlatformWindowInterfacePrivate(DXCBPlatformWindowInterface *qq); +}; + +DGUI_END_NAMESPACE + +#endif // DNATIVESETTINGS_P_H diff --git a/src/private/dplatformwindowinterface_p.h b/src/private/dplatformwindowinterface_p.h new file mode 100644 index 0000000..0496a5b --- /dev/null +++ b/src/private/dplatformwindowinterface_p.h @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DPLATFORMWINDOWINTERFACE_P_H +#define DPLATFORMWINDOWINTERFACE_P_H + +#include +#include +#include +#include +#include + +#include "dtkgui_global.h" +#include "dplatformhandle.h" + +DGUI_BEGIN_NAMESPACE + +class DPlatformHandle; +class DPlatformWindowInterfacePrivate; +class LIBDTKCORESHARED_EXPORT DPlatformWindowInterface : public QObject, public DCORE_NAMESPACE::DObject +{ + Q_OBJECT + D_DECLARE_PRIVATE(DPlatformWindowInterface) +public: + explicit DPlatformWindowInterface(QWindow *window, DPlatformHandle *platformHandle, QObject *parent=nullptr); + virtual ~DPlatformWindowInterface(); + + QWindow* window() const; + + virtual bool isEnabledNoTitlebar() const; + virtual bool setEnabledNoTitlebar(bool enable); + + virtual bool setWindowBlurAreaByWM(const QVector &area); + virtual bool setWindowBlurAreaByWM(const QList &paths); + + virtual int windowRadius() const; + virtual void setWindowRadius(int windowRadius); + + virtual int borderWidth() const; + virtual void setBorderWidth(int borderWidth); + + virtual QColor borderColor() const; + virtual void setBorderColor(const QColor &borderColor); + + virtual int shadowRadius() const; + virtual void setShadowRadius(int shadowRadius); + + virtual QPoint shadowOffset() const; + virtual void setShadowOffset(const QPoint &shadowOffset); + + virtual QColor shadowColor() const; + virtual void setShadowColor(const QColor &shadowColor); + + virtual DPlatformHandle::EffectScene windowEffect(); + virtual void setWindowEffect(DPlatformHandle::EffectScenes effectScene); + + virtual DPlatformHandle::EffectType windowStartUpEffect(); + virtual void setWindowStartUpEffect(DPlatformHandle::EffectTypes effectType); + + virtual QPainterPath clipPath() const; + virtual void setClipPath(const QPainterPath &clipPath); + + virtual QRegion frameMask() const; + virtual void setFrameMask(const QRegion &frameMask); + + virtual QMargins frameMargins() const; + + virtual bool translucentBackground() const; + virtual void setTranslucentBackground(bool translucentBackground); + + virtual bool enableSystemResize() const; + virtual void setEnableSystemResize(bool enableSystemResize); + + virtual bool enableSystemMove() const; + virtual void setEnableSystemMove(bool enableSystemMove); + + virtual bool enableBlurWindow() const; + virtual void setEnableBlurWindow(bool enableBlurWindow); + + virtual bool autoInputMaskByClipPath() const; + virtual void setAutoInputMaskByClipPath(bool autoInputMaskByClipPath); + + virtual WId realWindowId() const; + + virtual WId windowLeader(); + +protected: + DPlatformWindowInterface(DPlatformWindowInterfacePrivate &dd, QWindow *window, DPlatformHandle *handle, QObject *parent); +}; + +class LIBDTKCORESHARED_EXPORT DPlatformWindowInterfaceFactory { +public: + using HelperCreator = DPlatformWindowInterface * (*)(QWindow *, DPlatformHandle*); + static void registerInterface(HelperCreator creator); +}; + +DGUI_END_NAMESPACE +#endif // DPLATFORMWINDOWINTERFACE_P_H + diff --git a/src/private/dplatformwindowinterface_p_p.h b/src/private/dplatformwindowinterface_p_p.h new file mode 100644 index 0000000..7ac2e91 --- /dev/null +++ b/src/private/dplatformwindowinterface_p_p.h @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DPLATFORMINTERFACE_P_P_H +#define DPLATFORMINTERFACE_P_P_H + +#include "dplatformwindowinterface_p.h" + +#include +#include + +class QWindow; + +DGUI_BEGIN_NAMESPACE + +class DPlatformWindowInterfacePrivate : public DCORE_NAMESPACE::DObjectPrivate +{ + D_DECLARE_PUBLIC(DPlatformWindowInterface) +public: + DPlatformWindowInterfacePrivate(DPlatformWindowInterface *qq); + +public: + QWindow *m_window = nullptr; + DPlatformHandle *m_platformHandle = nullptr; +}; + +DGUI_END_NAMESPACE + +#endif // DNATIVESETTINGS_P_H diff --git a/src/private/private.cmake b/src/private/private.cmake index 6ca2ce9..856e00d 100644 --- a/src/private/private.cmake +++ b/src/private/private.cmake @@ -8,4 +8,5 @@ set(private_SRC ${CMAKE_CURRENT_LIST_DIR}/dtaskbarcontrol_p.h ${CMAKE_CURRENT_LIST_DIR}/dfontmanager_p.h ${CMAKE_CURRENT_LIST_DIR}/dplatforminterface_p.h + ${CMAKE_CURRENT_LIST_DIR}/dplatformwindowinterface_p.h )