From 3bc981bb7eae911dcb63d7bdf262e392f8b580f8 Mon Sep 17 00:00:00 2001 From: 993381 <56956885+993381@users.noreply.github.com> Date: Wed, 30 Mar 2022 13:15:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81wayland=E4=B8=8A?= =?UTF-8?q?=E7=9A=84=E5=88=86=E5=B1=8F=E9=9C=80=E6=B1=82=20(#70)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 支持wayland上的分屏需求 Log: Influence: wayland平台的分屏功能 Co-authored-by: AlexOne --- src/global.cpp | 15 ++++++ src/global.h | 5 ++ src/src.pri | 1 + .../dwayland/dnotitlebarwindowhelper_wl.cpp | 12 ----- wayland/dwayland/dwaylandinterfacehook.cpp | 46 ++++++++++++++++++- wayland/dwayland/dwaylandinterfacehook.h | 5 +- .../wayland-shell/dwaylandshellmanager.cpp | 18 ++++++++ 7 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 src/global.cpp diff --git a/src/global.cpp b/src/global.cpp new file mode 100644 index 00000000..8a9d34ad --- /dev/null +++ b/src/global.cpp @@ -0,0 +1,15 @@ +#include "global.h" +#include +#include + +QWindow * fromQtWinId(WId id) { + QWindow *window = nullptr; + + for (auto win : qApp->allWindows()) { + if (win->winId() == id) { + window = win; + break; + } + } + return window; +}; diff --git a/src/global.h b/src/global.h index 2646a8ed..cec3b880 100644 --- a/src/global.h +++ b/src/global.h @@ -18,6 +18,8 @@ #ifndef GLOBAL_H #define GLOBAL_H +#include + #define MOUSE_MARGINS 10 #define DPP_BEGIN_NAMESPACE namespace deepin_platform_plugin { @@ -116,4 +118,7 @@ enum DeviceType { MouseDevice }; +class QWindow; +QWindow * fromQtWinId(WId id); + #endif // GLOBAL_H diff --git a/src/src.pri b/src/src.pri index 2c71ed6d..e341fb62 100644 --- a/src/src.pri +++ b/src/src.pri @@ -16,6 +16,7 @@ SOURCES += \ $$PWD/dnativesettings.cpp \ $$PWD/dopenglpaintdevice.cpp \ $$PWD/dxcbxsettings.cpp \ + $$PWD/global.cpp \ $$PWD/vtablehook.cpp \ $$PWD/dplatformsettings.cpp \ $$PWD/ddesktopinputselectioncontrol.cpp \ diff --git a/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp b/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp index 03e74c77..7514d066 100644 --- a/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp +++ b/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp @@ -123,18 +123,6 @@ void DNoTitlebarWlWindowHelper::setWindowProperty(QWindow *window, const char *n void DNoTitlebarWlWindowHelper::popupSystemWindowMenu(quintptr wid) { - auto fromQtWinId = [](WId id) { - QWindow *window = nullptr; - - for (auto win : qApp->allWindows()) { - if (win->winId() == id) { - window = win; - break; - } - } - return window; - }; - QWindow *window = fromQtWinId(wid); if(!window || !window->handle()) return; diff --git a/wayland/dwayland/dwaylandinterfacehook.cpp b/wayland/dwayland/dwaylandinterfacehook.cpp index 464a82d9..434cd3d7 100755 --- a/wayland/dwayland/dwaylandinterfacehook.cpp +++ b/wayland/dwayland/dwaylandinterfacehook.cpp @@ -29,6 +29,16 @@ #include #include #include + +#include +#include + +#ifndef QT_DEBUG +Q_LOGGING_CATEGORY(dwli, "dtk.wayland.interface" , QtInfoMsg); +#else +Q_LOGGING_CATEGORY(dwli, "dtk.wayland.interface"); +#endif + DPP_BEGIN_NAMESPACE @@ -85,6 +95,10 @@ static QFunctionPointer getFunction(const QByteArray &function) return reinterpret_cast(&DWaylandInterfaceHook::enableDwayland); } else if (function == isEnableDwayland) { return reinterpret_cast(&DWaylandInterfaceHook::isEnableDwayland); + } else if (function == splitWindowOnScreen) { + return reinterpret_cast(&DWaylandInterfaceHook::splitWindowOnScreen); + } else if (function == supportForSplittingWindow) { + return reinterpret_cast(&DWaylandInterfaceHook::supportForSplittingWindow); } return nullptr; @@ -183,11 +197,11 @@ bool DWaylandInterfaceHook::isEnableNoTitlebar(QWindow *window) return window->property(noTitlebar).toBool(); } -bool DWaylandInterfaceHook::setWindowRadius(QWindow *window, int windowRadius) +bool DWaylandInterfaceHook::setWindowRadius(QWindow *window, int value) { if (!window) return false; - return window->setProperty("_d_windowRadius", QVariant{windowRadius}); + return window->setProperty(windowRadius, QVariant{value}); } void DWaylandInterfaceHook::setWindowProperty(QWindow *window, const char *name, const QVariant &value) @@ -241,6 +255,34 @@ bool DWaylandInterfaceHook::isEnableDwayland(const QWindow *window) return window->property(useDwayland).toBool(); } +void DWaylandInterfaceHook::splitWindowOnScreen(WId wid, quint32 type) +{ + QWindow *window = fromQtWinId(wid); + if(!window || !window->handle()) + return; + // 1 left,2 right,15 fullscreen + if (type == 15) { + if (window->windowStates().testFlag(Qt::WindowMaximized)) { + window->showNormal(); + } else { + window->showMaximized(); + } + } else if (type == 1 || type == 2) { + DNoTitlebarWlWindowHelper::setWindowProperty(window, ::splitWindowOnScreen, type); + } else { + qCWarning(dwli) << "invalid split type: " << type; + } +} + +bool DWaylandInterfaceHook::supportForSplittingWindow(WId wid) +{ + QWindow *window = fromQtWinId(wid); + if(!window || !window->handle()) + return false; + DNoTitlebarWlWindowHelper::setWindowProperty(window, ::supportForSplittingWindow, false); + return window->property(::supportForSplittingWindow).toBool(); +} + DXcbXSettings *DWaylandInterfaceHook::globalSettings() { if (Q_LIKELY(m_xsettings)) { diff --git a/wayland/dwayland/dwaylandinterfacehook.h b/wayland/dwayland/dwaylandinterfacehook.h index d9d26eec..d1fa18b9 100755 --- a/wayland/dwayland/dwaylandinterfacehook.h +++ b/wayland/dwayland/dwaylandinterfacehook.h @@ -21,6 +21,7 @@ #include "global.h" #include +#include QT_BEGIN_NAMESPACE class QObject; @@ -46,11 +47,13 @@ class DWaylandInterfaceHook static void clearNativeSettings(quint32 settingWindow); static bool setEnableNoTitlebar(QWindow *window, bool enable); static bool isEnableNoTitlebar(QWindow *window); - static bool setWindowRadius(QWindow *window, int windowRadius); + static bool setWindowRadius(QWindow *window, int value); static void setWindowProperty(QWindow *window, const char *name, const QVariant &value); static void popupSystemWindowMenu(quintptr wid); static bool enableDwayland(QWindow *window); static bool isEnableDwayland(const QWindow *window); + static void splitWindowOnScreen(WId wid, quint32 type); + static bool supportForSplittingWindow(WId wid); static DXcbXSettings *globalSettings(); private: diff --git a/wayland/wayland-shell/dwaylandshellmanager.cpp b/wayland/wayland-shell/dwaylandshellmanager.cpp index 806b8ee9..b8b976cc 100644 --- a/wayland/wayland-shell/dwaylandshellmanager.cpp +++ b/wayland/wayland-shell/dwaylandshellmanager.cpp @@ -145,6 +145,24 @@ void DWaylandShellManager::sendProperty(QWaylandShellSurface *self, const QStrin else qCWarning(dwlp) << "invalid property" << name << value; } + if (!name.compare(splitWindowOnScreen)) { + using KWayland::Client::DDEShellSurface; + bool ok = false; + qreal leftOrRight = value.toInt(&ok); + if (ok) { + dde_shell_surface->requestSplitWindow((DDEShellSurface::SplitType)leftOrRight); + qCInfo(dwlp) << "requestSplitWindow value: " << leftOrRight; + } else { + qCWarning(dwlp) << "invalid property: " << name << value; + } + self->window()->window()->setProperty(splitWindowOnScreen, 0); + } + if (!name.compare(supportForSplittingWindow)) { + if (self->window() && self->window()->window()) { + self->window()->window()->setProperty(supportForSplittingWindow, dde_shell_surface->isSplitable()); + } + return; + } } // 将popup的窗口设置为tooltop层级, 包括qmenu,combobox弹出窗口