Group :: Desktop gráfico/Outros
RPM: deepin-qt5platform-plugins
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: 0001-feat-Support-multi-split-screen-151.patch
Download
Download
From 64a24998869ef3ab6fbc4d2398a17f439dc053c2 Mon Sep 17 00:00:00 2001
From: yeshanshan <yeshanshan@uniontech.com>
Date: Wed, 11 Jan 2023 16:10:20 +0800
Subject: [PATCH] feat: Support multi split screen (#151)
Add function to be compatible with two split screen.
Log: x11和wayland下支持多分屏
Task: https://pms.uniontech.com/task-view-180357.html
Influence: 需要依赖窗管升级,才能实现多分屏效果
Change-Id: I4abd73b8418f280a97caa9d5a46b76454a5d105e
---
src/global.h | 2 ++
wayland/dwayland/dwaylandinterfacehook.cpp | 30 ++++++++++++++++++++++--------
wayland/dwayland/dwaylandinterfacehook.h | 2 ++
wayland/wayland-shell/dwaylandshellmanager.cpp | 26 ++++++++++++++++++++------
xcb/dplatformnativeinterfacehook.cpp | 4 +++-
xcb/utility.h | 2 ++
xcb/utility_x11.cpp | 21 ++++++++++++++++-----
7 files changed, 67 insertions(+), 20 deletions(-)
diff --git a/src/global.h b/src/global.h
index 564ab67..0806a64 100644
--- a/src/global.h
+++ b/src/global.h
@@ -95,4 +95,6 @@ DEFINE_CONST_CHAR(splitWindowOnScreen);
DEFINE_CONST_CHAR(supportForSplittingWindow);
DEFINE_CONST_CHAR(sendEndStartupNotifition);
+DEFINE_CONST_CHAR(splitWindowOnScreenByType);
+DEFINE_CONST_CHAR(supportForSplittingWindowByType);
// others
diff --git a/wayland/dwayland/dwaylandinterfacehook.cpp b/wayland/dwayland/dwaylandinterfacehook.cpp
index b3d31c1..042e836 100755
--- a/wayland/dwayland/dwaylandinterfacehook.cpp
+++ b/wayland/dwayland/dwaylandinterfacehook.cpp
@@ -40,5 +40,7 @@ static QFunctionPointer getFunction(const QByteArray &function)
{isEnableDwayland, reinterpret_cast<QFunctionPointer>(&DWaylandInterfaceHook::isEnableDwayland)},
{splitWindowOnScreen, reinterpret_cast<QFunctionPointer>(&DWaylandInterfaceHook::splitWindowOnScreen)},
- {supportForSplittingWindow, reinterpret_cast<QFunctionPointer>(&DWaylandInterfaceHook::supportForSplittingWindow)}
+ {supportForSplittingWindow, reinterpret_cast<QFunctionPointer>(&DWaylandInterfaceHook::supportForSplittingWindow)},
+ {splitWindowOnScreenByType, reinterpret_cast<QFunctionPointer>(&DWaylandInterfaceHook::splitWindowOnScreenByType)},
+ {supportForSplittingWindowByType, reinterpret_cast<QFunctionPointer>(&DWaylandInterfaceHook::supportForSplittingWindowByType)}
};
return functionCache.value(function);
@@ -150,28 +152,40 @@ bool DWaylandInterfaceHook::isEnableDwayland(const QWindow *window)
void DWaylandInterfaceHook::splitWindowOnScreen(WId wid, quint32 type)
{
+ return splitWindowOnScreenByType(wid, 1, type);
+}
+
+void DWaylandInterfaceHook::splitWindowOnScreenByType(WId wid, quint32 position, quint32 type)
+{
QWindow *window = fromQtWinId(wid);
if(!window || !window->handle())
return;
- // 1 left,2 right,15 fullscreen
- if (type == 15) {
+ // position: 15 not preview
+ if (position == 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;
+ // type 1:two splitting 2:three splitting 4:four splitting
+ // position enum class SplitType in kwin-dev, Left=0x1, Right=0x10, Top=0x100, Bottom=0x1000
+ QVariantList value{position, type};
+ DNoTitlebarWlWindowHelper::setWindowProperty(window, ::splitWindowOnScreen, value);
}
}
bool DWaylandInterfaceHook::supportForSplittingWindow(WId wid)
{
+ return supportForSplittingWindowByType(wid, 1);
+}
+
+// screenSplittingType: 0: can't splitting, 1:two splitting, 2: four splitting(includ three splitting)
+bool DWaylandInterfaceHook::supportForSplittingWindowByType(quint32 wid, quint32 screenSplittingType)
+{
QWindow *window = fromQtWinId(wid);
if(!window || !window->handle())
return false;
- DNoTitlebarWlWindowHelper::requestByWindowProperty(window, ::supportForSplittingWindow);
- return window->property(::supportForSplittingWindow).toBool();
+ DNoTitlebarWlWindowHelper::setWindowProperty(window, ::supportForSplittingWindow, false);
+ return window->property(::supportForSplittingWindow).toInt() >= screenSplittingType;
}
diff --git a/wayland/dwayland/dwaylandinterfacehook.h b/wayland/dwayland/dwaylandinterfacehook.h
index 56f85d2..aed1477 100755
--- a/wayland/dwayland/dwaylandinterfacehook.h
+++ b/wayland/dwayland/dwaylandinterfacehook.h
@@ -44,5 +44,7 @@ public:
static bool isEnableDwayland(const QWindow *window);
static void splitWindowOnScreen(WId wid, quint32 type);
+ static void splitWindowOnScreenByType(WId wid, quint32 position, quint32 type);
static bool supportForSplittingWindow(WId wid);
+ static bool supportForSplittingWindowByType(quint32 wid, quint32 screenSplittingType);
};
diff --git a/wayland/wayland-shell/dwaylandshellmanager.cpp b/wayland/wayland-shell/dwaylandshellmanager.cpp
index beb7801..7d78cda 100644
--- a/wayland/wayland-shell/dwaylandshellmanager.cpp
+++ b/wayland/wayland-shell/dwaylandshellmanager.cpp
@@ -142,4 +142,11 @@ static Region *ensureRegion(QObject *parent = nullptr)
}
+static void checkIsDWayland(const QString &function)
+{
+#ifndef D_DEEPIN_IS_DWAYLAND
+ qCWarning(dwlp) << "This package is not compiled as dwayland, and [" << function << "] not support in this version.";
+#endif
+}
+
DWaylandShellManager::DWaylandShellManager()
: m_registry (new Registry())
@@ -197,16 +204,23 @@ void DWaylandShellManager::sendProperty(QWaylandShellSurface *self, const QStrin
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));
- qCDebug(dwlp) << "requestSplitWindow value: " << leftOrRight;
+ const auto tmp = value.toList();
+ if (tmp.size() >= 2) {
+ const auto &position = tmp[0].toInt();
+ const auto &type = tmp[1].toInt();
+ checkIsDWayland("requestSplitWindow()");
+#ifdef D_DEEPIN_IS_DWAYLAND
+ dde_shell_surface->requestSplitWindow(DDEShellSurface::SplitType(position), DDEShellSurface::SplitMode(type));
+ qCDebug(dwlp) << "requestSplitWindow splitType: " << position << " mode: " << type;
+#endif
} else {
qCWarning(dwlp) << "invalid property: " << name << value;
}
wlWindow->window()->setProperty(splitWindowOnScreen, 0);
}
if (!name.compare(supportForSplittingWindow)) {
- wlWindow->window()->setProperty(supportForSplittingWindow, dde_shell_surface->isSplitable());
+ checkIsDWayland("getSplitable()");
+#ifdef D_DEEPIN_IS_DWAYLAND
+ wlWindow->window()->setProperty(supportForSplittingWindow, dde_shell_surface->getSplitable());
+#endif
return;
}
diff --git a/xcb/dplatformnativeinterfacehook.cpp b/xcb/dplatformnativeinterfacehook.cpp
index fc018dd..d9af2ac 100644
--- a/xcb/dplatformnativeinterfacehook.cpp
+++ b/xcb/dplatformnativeinterfacehook.cpp
@@ -78,5 +78,7 @@ static QFunctionPointer getFunction(const QByteArray &function)
{splitWindowOnScreen, reinterpret_cast<QFunctionPointer>(&Utility::splitWindowOnScreen)},
{supportForSplittingWindow, reinterpret_cast<QFunctionPointer>(&Utility::supportForSplittingWindow)},
- {sendEndStartupNotifition, reinterpret_cast<QFunctionPointer>(&DPlatformIntegration::sendEndStartupNotifition)}
+ {sendEndStartupNotifition, reinterpret_cast<QFunctionPointer>(&DPlatformIntegration::sendEndStartupNotifition)},
+ {splitWindowOnScreenByType, reinterpret_cast<QFunctionPointer>(&Utility::splitWindowOnScreenByType)},
+ {supportForSplittingWindowByType, reinterpret_cast<QFunctionPointer>(&Utility::supportForSplittingWindowByType)}
};
diff --git a/xcb/utility.h b/xcb/utility.h
index e3454cb..f98ddc4 100644
--- a/xcb/utility.h
+++ b/xcb/utility.h
@@ -65,5 +65,7 @@ public:
static void setNoTitlebar(quint32 WId, bool on);
static void splitWindowOnScreen(quint32 WId, quint32 type);
+ static void splitWindowOnScreenByType(quint32 WId, quint32 position, quint32 type);
static bool supportForSplittingWindow(quint32 WId);
+ static bool supportForSplittingWindowByType(quint32 WId, quint32 screenSplittingType);
struct BlurArea {
diff --git a/xcb/utility_x11.cpp b/xcb/utility_x11.cpp
index 48d450b..b8c01c8 100644
--- a/xcb/utility_x11.cpp
+++ b/xcb/utility_x11.cpp
@@ -462,12 +462,18 @@ void Utility::setNoTitlebar(quint32 WId, bool on)
void Utility::splitWindowOnScreen(quint32 WId, quint32 type)
{
+ splitWindowOnScreenByType(WId, type, 1);
+}
+
+void Utility::splitWindowOnScreenByType(quint32 WId, quint32 position, quint32 type)
+{
xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE;
xev.type = internAtom("_DEEPIN_SPLIT_WINDOW", false);
xev.window = WId;
xev.format = 32;
- xev.data.data32[0] = type; /* 1: 左 2: 右 15: 全屏 */
- xev.data.data32[1] = type < 15 ? 1 : 0; /* 1: 左右 0: 全屏 */
+ xev.data.data32[0] = position; /* enum class SplitType in kwin-dev, Left=0x1, Right=0x10, Top=0x100, Bottom=0x1000*/
+ xev.data.data32[1] = position == 15 ? 0 : 1; /* 0: not preview 1: preview*/
+ xev.data.data32[2] = type; /* 1:two splitting 2:three splitting 4:four splitting*/
xcb_send_event(QX11Info::connection(), false, QX11Info::appRootWindow(QX11Info::appScreen()),
@@ -478,12 +484,17 @@ void Utility::splitWindowOnScreen(quint32 WId, quint32 type)
bool Utility::supportForSplittingWindow(quint32 WId)
{
+ return Utility::supportForSplittingWindowByType(WId, 1);
+}
+
+// screenSplittingType: 0: can't splitting, 1:two splitting, 2: four splitting(includ three splitting)
+bool Utility::supportForSplittingWindowByType(quint32 WId, quint32 screenSplittingType)
+{
auto propAtom = internAtom("_DEEPIN_NET_SUPPORTED");
QByteArray data = windowProperty(WId, propAtom, XCB_ATOM_CARDINAL, 4);
- bool supported = false;
if (const char *cdata = data.constData())
- supported = *(reinterpret_cast<const quint8 *>(cdata));
+ return *(reinterpret_cast<const quint8 *>(cdata)) >= screenSplittingType;
- return supported;
+ return false;
}
--
libgit2 1.3.2