From d015a41f5be5ae69af9fa887d28a39e0b4c06a9d Mon Sep 17 00:00:00 2001 From: tsic404 Date: Fri, 10 Nov 2023 13:59:52 +0800 Subject: [PATCH] fix: layershell wrap bugs 1. waylandSurafce not update after layershell perproty changed, because not commit changed, so now manually call waylandSurface()->commit() 2. x11emulation not make window keep in center, can not get window size in qml before when init, but now connectted widthChanged and heightChanged. 3. unable to anchor three sides, beacause wayland when setSize QSize::isEmpty get a unexpected result when width or height is 0, x11 not modify window size reason as above 2. log: fix above bugs --- example/panel-example/package/main.qml | 3 +- frame/layershell/dlayershellwindow.cpp | 4 +- .../layershell/qwaylandlayershellsurface.cpp | 19 ++++--- frame/layershell/x11dlayershellemulation.cpp | 56 +++++++++++-------- frame/layershell/x11dlayershellemulation.h | 9 +-- 5 files changed, 54 insertions(+), 37 deletions(-) diff --git a/example/panel-example/package/main.qml b/example/panel-example/package/main.qml index 4489d62dc..b4efde878 100644 --- a/example/panel-example/package/main.qml +++ b/example/panel-example/package/main.qml @@ -11,9 +11,8 @@ import org.deepin.ds 1.0 Window { id: root visible: true - width: Screen.width height: 200 - DLayerShellWindow.anchors: DLayerShellWindow.AnchorBottom + DLayerShellWindow.anchors: DLayerShellWindow.AnchorBottom | DLayerShellWindow.AnchorLeft | DLayerShellWindow.AnchorRight Repeater { anchors.fill: parent diff --git a/frame/layershell/dlayershellwindow.cpp b/frame/layershell/dlayershellwindow.cpp index d607cfdc7..ffc8fc65f 100644 --- a/frame/layershell/dlayershellwindow.cpp +++ b/frame/layershell/dlayershellwindow.cpp @@ -31,9 +31,9 @@ class DLayerShellWindowPrivate QWindow* parentWindow; QString scope = QStringLiteral("window"); - DLayerShellWindow::Anchors anchors = {DLayerShellWindow::AnchorTop | DLayerShellWindow::AnchorBottom | DLayerShellWindow::AnchorLeft | DLayerShellWindow::AnchorRight}; + DLayerShellWindow::Anchors anchors = {DLayerShellWindow::AnchorNone}; int32_t exclusionZone = 0; - DLayerShellWindow::KeyboardInteractivity keyboardInteractivity = DLayerShellWindow::KeyboardInteractivityExclusive; + DLayerShellWindow::KeyboardInteractivity keyboardInteractivity = DLayerShellWindow::KeyboardInteractivityNone; DLayerShellWindow::Layer layer = DLayerShellWindow::LayerTop; int leftMargin = 0; int rightMargin = 0; diff --git a/frame/layershell/qwaylandlayershellsurface.cpp b/frame/layershell/qwaylandlayershellsurface.cpp index b148d8d64..4f4b1b6f3 100644 --- a/frame/layershell/qwaylandlayershellsurface.cpp +++ b/frame/layershell/qwaylandlayershellsurface.cpp @@ -38,18 +38,21 @@ QWaylandLayeShellSurface::QWaylandLayeShellSurface(QtWayland::zwlr_layer_shell_v init(shell->get_layer_surface(window->waylandSurface()->object(), output, m_dlayerShellWindow->layer(), m_dlayerShellWindow->scope())); set_layer(m_dlayerShellWindow->layer()); - connect(m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this, [this](){ + connect(m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this, [this, window](){ set_layer(m_dlayerShellWindow->layer()); + window->waylandSurface()->commit(); }); set_anchor(m_dlayerShellWindow->anchors()); - connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this,[this](){ + connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this,[this, window](){ set_anchor(m_dlayerShellWindow->anchors()); + window->waylandSurface()->commit(); }); set_exclusive_zone(m_dlayerShellWindow->exclusionZone()); - connect(m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this,[this](){ + connect(m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this,[this, window](){ set_exclusive_zone(m_dlayerShellWindow->exclusionZone()); + window->waylandSurface()->commit(); }); set_margin(m_dlayerShellWindow->topMargin(), m_dlayerShellWindow->rightMargin(), m_dlayerShellWindow->bottomMargin(), m_dlayerShellWindow->leftMargin()); @@ -58,8 +61,9 @@ QWaylandLayeShellSurface::QWaylandLayeShellSurface(QtWayland::zwlr_layer_shell_v }); set_keyboard_interactivity(m_dlayerShellWindow->keyboardInteractivity()); - connect(m_dlayerShellWindow, &DLayerShellWindow::keyboardInteractivityChanged, this, [this](){ + connect(m_dlayerShellWindow, &DLayerShellWindow::keyboardInteractivityChanged, this, [this, window](){ set_keyboard_interactivity(m_dlayerShellWindow->keyboardInteractivity()); + window->waylandSurface()->commit(); }); @@ -73,7 +77,7 @@ QWaylandLayeShellSurface::QWaylandLayeShellSurface(QtWayland::zwlr_layer_shell_v size.setHeight(0); } - if (size.isValid() && !size.isEmpty()) { + if (size.isValid()) { set_size(size.width(), size.height()); } } @@ -111,8 +115,9 @@ void QWaylandLayeShellSurface::applyConfigure() void QWaylandLayeShellSurface::setWindowGeometry(const QRect &geometry) { - const bool horizontallyConstrained = m_dlayerShellWindow->anchors() & (DLayerShellWindow::AnchorLeft & DLayerShellWindow::AnchorRight); - const bool verticallyConstrained = m_dlayerShellWindow->anchors() & (DLayerShellWindow::AnchorTop & DLayerShellWindow::AnchorBottom); + auto anchors = m_dlayerShellWindow->anchors(); + const bool horizontallyConstrained =(anchors & (DLayerShellWindow::AnchorLeft | DLayerShellWindow::AnchorRight)) == (DLayerShellWindow::AnchorLeft | DLayerShellWindow::AnchorRight); + const bool verticallyConstrained = (anchors & (DLayerShellWindow::AnchorTop | DLayerShellWindow::AnchorBottom)) == (DLayerShellWindow::AnchorTop | DLayerShellWindow::AnchorBottom); QSize size = geometry.size(); if (horizontallyConstrained) { diff --git a/frame/layershell/x11dlayershellemulation.cpp b/frame/layershell/x11dlayershellemulation.cpp index a20b5a24c..2df3f73a4 100644 --- a/frame/layershell/x11dlayershellemulation.cpp +++ b/frame/layershell/x11dlayershellemulation.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "dlayershellwindow.h" +#include "dsglobal.h" #include "x11dlayershellemulation.h" #include @@ -16,22 +17,24 @@ #include #include +DS_BEGIN_NAMESPACE + LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent) : QObject(parent) , m_window(window) - , m_dlayerShellWindow(DS_NAMESPACE::DLayerShellWindow::get(m_window)) + , m_dlayerShellWindow(DLayerShellWindow::get(m_window)) { m_window->setFlag(Qt::FramelessWindowHint); onLayerChanged(); - connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::layerChanged, this, &LayerShellEmulation::onLayerChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this, &LayerShellEmulation::onLayerChanged); onPositionChanged(); - connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onPositionChanged); - connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::marginsChanged, this, &LayerShellEmulation::onPositionChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onPositionChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this, &LayerShellEmulation::onPositionChanged); onExclusionZoneChanged(); - connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onExclusionZoneChanged); - connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::exclusionZoneChanged, this, &LayerShellEmulation::onExclusionZoneChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onExclusionZoneChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this, &LayerShellEmulation::onExclusionZoneChanged); // qml height or wdth may update later, need to update anchor postion and exclusion zone connect(m_window, &QWindow::widthChanged, this, &LayerShellEmulation::onExclusionZoneChanged); @@ -56,23 +59,23 @@ void LayerShellEmulation::onLayerChanged() { auto xcbWindow = dynamic_cast(m_window->handle()); switch (m_dlayerShellWindow->layer()) { - case DS_NAMESPACE::DLayerShellWindow::LayerBackground: { + case DLayerShellWindow::LayerBackground: { m_window->setFlags(m_window->flags() & ~Qt::WindowStaysOnBottomHint); xcbWindow->setWindowType(QNativeInterface::Private::QXcbWindow::Desktop); break; } - case DS_NAMESPACE::DLayerShellWindow::LayerButtom: { + case DLayerShellWindow::LayerButtom: { //use Normal type will influenced by exclusionZone xcbWindow->setWindowType(QNativeInterface::Private::QXcbWindow::Normal); m_window->setFlags(Qt::WindowStaysOnBottomHint); break; } - case DS_NAMESPACE::DLayerShellWindow::LayerTop: { + case DLayerShellWindow::LayerTop: { m_window->setFlags(m_window->flags() & ~Qt::WindowStaysOnBottomHint); xcbWindow->setWindowType(QNativeInterface::Private::QXcbWindow::Dock); break; } - case DS_NAMESPACE::DLayerShellWindow::LayerOverlay: { + case DLayerShellWindow::LayerOverlay: { // on deepin Notification will be influenced by exclusionZone, // while plasma works all right, maybe deepin kwin bug? // FIXME: fix above @@ -86,25 +89,33 @@ void LayerShellEmulation::onLayerChanged() void LayerShellEmulation::onPositionChanged() { auto anchors = m_dlayerShellWindow->anchors(); - auto x = m_window->x(), y = m_window->y(); auto screen = m_window->screen(); - if (anchors & DS_NAMESPACE::DLayerShellWindow::AnchorRight) { + auto x = (screen->geometry().right() - m_window->width()) / 2; + auto y = (screen->geometry().height() - m_window->height()) / 2; + if (anchors & DLayerShellWindow::AnchorRight) { x = (screen->geometry().right() - m_window->width() - m_dlayerShellWindow->rightMargin()); } - if (anchors & DS_NAMESPACE::DLayerShellWindow::AnchorBottom) { + if (anchors & DLayerShellWindow::AnchorBottom) { y = (screen->geometry().bottom() - m_window->height() - m_dlayerShellWindow->bottomMargin()); } - if (anchors & DS_NAMESPACE::DLayerShellWindow::AnchorLeft) { + if (anchors & DLayerShellWindow::AnchorLeft) { x = (screen->geometry().left() + m_dlayerShellWindow->leftMargin()); } - if (anchors & DS_NAMESPACE::DLayerShellWindow::AnchorTop) { + if (anchors & DLayerShellWindow::AnchorTop) { y = (screen->geometry().top() + m_dlayerShellWindow->topMargin()); } - if (anchors == DS_NAMESPACE::DLayerShellWindow::AnchorNone) { - x = (screen->geometry().right() - m_window->width()) / 2; - y = (screen->geometry().height() - m_window->height()) / 2; + const bool horizontallyConstrained =(anchors & (DLayerShellWindow::AnchorLeft | DLayerShellWindow::AnchorRight)) == (DLayerShellWindow::AnchorLeft | DLayerShellWindow::AnchorRight); + const bool verticallyConstrained = (anchors & (DLayerShellWindow::AnchorTop | DLayerShellWindow::AnchorBottom)) == (DLayerShellWindow::AnchorTop | DLayerShellWindow::AnchorBottom); + + if (horizontallyConstrained) { + x = (screen->geometry().left()); + m_window->setWidth(screen->geometry().width()); + } + if (verticallyConstrained) { + y = (screen->geometry().top()); + m_window->setHeight(screen->geometry().height()); } m_window->setX(x), m_window->setY(y); } @@ -122,19 +133,19 @@ void LayerShellEmulation::onExclusionZoneChanged() xcb_ewmh_wm_strut_partial_t strut_partial; memset(&strut_partial, 0, sizeof(xcb_ewmh_wm_strut_partial_t)); auto anchors = m_dlayerShellWindow->anchors(); - if ((anchors == DS_NAMESPACE::DLayerShellWindow::AnchorLeft) || (anchors ^ DS_NAMESPACE::DLayerShellWindow::AnchorLeft) == (DS_NAMESPACE::DLayerShellWindow::AnchorTop | DS_NAMESPACE::DLayerShellWindow::AnchorBottom)) { + if ((anchors == DLayerShellWindow::AnchorLeft) || (anchors ^ DLayerShellWindow::AnchorLeft) == (DLayerShellWindow::AnchorTop | DLayerShellWindow::AnchorBottom)) { strut_partial.left = m_dlayerShellWindow->exclusionZone() * scaleFactor; strut_partial.left_start_y = m_window->y(); strut_partial.left_end_y = m_window->y() + m_window->height(); - } else if ((anchors == DS_NAMESPACE::DLayerShellWindow::AnchorRight) || (anchors ^ DS_NAMESPACE::DLayerShellWindow::AnchorRight) == (DS_NAMESPACE::DLayerShellWindow::AnchorTop | DS_NAMESPACE::DLayerShellWindow::AnchorBottom)) { + } else if ((anchors == DLayerShellWindow::AnchorRight) || (anchors ^ DLayerShellWindow::AnchorRight) == (DLayerShellWindow::AnchorTop | DLayerShellWindow::AnchorBottom)) { strut_partial.right = m_dlayerShellWindow->exclusionZone() * scaleFactor; strut_partial.right_start_y = m_window->y(); strut_partial.right_end_y = m_window->y() + m_window->height(); - } else if ((anchors == DS_NAMESPACE::DLayerShellWindow::AnchorTop) || (anchors ^ DS_NAMESPACE::DLayerShellWindow::AnchorTop) == (DS_NAMESPACE::DLayerShellWindow::AnchorLeft | DS_NAMESPACE::DLayerShellWindow::AnchorRight)) { + } else if ((anchors == DLayerShellWindow::AnchorTop) || (anchors ^ DLayerShellWindow::AnchorTop) == (DLayerShellWindow::AnchorLeft | DLayerShellWindow::AnchorRight)) { strut_partial.top = m_dlayerShellWindow->exclusionZone() * scaleFactor; strut_partial.top_start_x = m_window->x(); strut_partial.top_end_x = m_window->x() + m_window->width(); - } else if ((anchors == DS_NAMESPACE::DLayerShellWindow::AnchorBottom) || (anchors ^ DS_NAMESPACE::DLayerShellWindow::AnchorBottom) == (DS_NAMESPACE::DLayerShellWindow::AnchorLeft | DS_NAMESPACE::DLayerShellWindow::AnchorRight)) { + } else if ((anchors == DLayerShellWindow::AnchorBottom) || (anchors ^ DLayerShellWindow::AnchorBottom) == (DLayerShellWindow::AnchorLeft | DLayerShellWindow::AnchorRight)) { strut_partial.bottom = m_dlayerShellWindow->exclusionZone() * scaleFactor; strut_partial.bottom_start_x = m_window->x(); strut_partial.bottom_end_x = m_window->x() + m_window->width(); @@ -147,3 +158,4 @@ void LayerShellEmulation::onExclusionZoneChanged() // { // // kwin no implentation on wayland // } +DS_END_NAMESPACE diff --git a/frame/layershell/x11dlayershellemulation.h b/frame/layershell/x11dlayershellemulation.h index 484071549..718a4da42 100644 --- a/frame/layershell/x11dlayershellemulation.h +++ b/frame/layershell/x11dlayershellemulation.h @@ -4,17 +4,17 @@ #pragma once +#include "dsglobal.h" #include "dlayershellwindow.h" + #include #include -#include -#include #include #include class xcb_connection_t; - +DS_BEGIN_NAMESPACE class LayerShellEmulation : public QObject { Q_OBJECT @@ -30,5 +30,6 @@ private slots: private: QWindow* m_window; - DS_NAMESPACE::DLayerShellWindow* m_dlayerShellWindow; + DLayerShellWindow* m_dlayerShellWindow; }; +DS_END_NAMESPACE