From 5817801537632caa83d57bf0e3049f0197c6f2b3 Mon Sep 17 00:00:00 2001 From: Yutao Meng Date: Wed, 11 Dec 2024 17:02:55 +0800 Subject: [PATCH] fix: Changing screen layout might make dock exclusion zone incorrect Changing screen layout may not change the geometry of the screen binded to dock. (For example, the screen stay on top or left without resolution changed) So, connect slot to all screens instead. pms: BUG-292677 Log: Changing screen layout might make dock exclusion zone incorrect --- frame/layershell/x11dlayershellemulation.cpp | 53 +++++++++++--------- frame/layershell/x11dlayershellemulation.h | 3 ++ 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/frame/layershell/x11dlayershellemulation.cpp b/frame/layershell/x11dlayershellemulation.cpp index 2de1e1d83..622c3043e 100644 --- a/frame/layershell/x11dlayershellemulation.cpp +++ b/frame/layershell/x11dlayershellemulation.cpp @@ -30,36 +30,39 @@ LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent) connect(m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this, &LayerShellEmulation::onLayerChanged); onPositionChanged(); - connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onPositionChanged); - connect(m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this, &LayerShellEmulation::onPositionChanged); + m_positionChangedTimer.setSingleShot(true); + m_positionChangedTimer.setInterval(100); + connect(&m_positionChangedTimer, &QTimer::timeout, this, &LayerShellEmulation::onPositionChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); + connect(m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); onExclusionZoneChanged(); - connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onExclusionZoneChanged); - connect(m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this, &LayerShellEmulation::onExclusionZoneChanged); + m_exclusionZoneChangedTimer.setSingleShot(true); + m_exclusionZoneChangedTimer.setInterval(100); + connect(&m_exclusionZoneChangedTimer, &QTimer::timeout, this, &LayerShellEmulation::onExclusionZoneChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, &m_exclusionZoneChangedTimer, static_cast(&QTimer::start)); + connect(m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, &m_exclusionZoneChangedTimer, static_cast(&QTimer::start)); // qml height or width may update later, need to update anchor postion and exclusion zone - connect(m_window, &QWindow::widthChanged, this, &LayerShellEmulation::onExclusionZoneChanged); - connect(m_window, &QWindow::widthChanged, this, &LayerShellEmulation::onPositionChanged); - // (x,y) wasn't set correctly by xcb_configure_window, TODO using EventFilter to update positions. - connect(m_window, &QWindow::xChanged, this, &LayerShellEmulation::onPositionChanged); - connect(m_window, &QWindow::yChanged, this, &LayerShellEmulation::onPositionChanged); - - connect(m_window, &QWindow::heightChanged, this, &LayerShellEmulation::onExclusionZoneChanged); - connect(m_window, &QWindow::heightChanged, this, &LayerShellEmulation::onPositionChanged); - - auto screen = m_window->screen(); - connect(screen, &QScreen::geometryChanged, this, &LayerShellEmulation::onPositionChanged); - connect(screen, &QScreen::geometryChanged, this, &LayerShellEmulation::onExclusionZoneChanged); - connect(qApp, &QGuiApplication::primaryScreenChanged, this, &LayerShellEmulation::onExclusionZoneChanged); + connect(m_window, &QWindow::widthChanged, &m_exclusionZoneChangedTimer, static_cast(&QTimer::start)); + connect(m_window, &QWindow::widthChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); + connect(m_window, &QWindow::heightChanged, &m_exclusionZoneChangedTimer, static_cast(&QTimer::start)); + connect(m_window, &QWindow::heightChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); + connect(m_window, &QWindow::xChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); + connect(m_window, &QWindow::yChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); + + for (auto screen : qApp->screens()) { + connect(screen, &QScreen::geometryChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); + connect(screen, &QScreen::geometryChanged, &m_exclusionZoneChangedTimer, static_cast(&QTimer::start)); + } + connect(qApp, &QGuiApplication::screenAdded, this, [this] (const QScreen *newScreen) { + connect(newScreen, &QScreen::geometryChanged, &m_positionChangedTimer, static_cast(&QTimer::start)); + connect(newScreen, &QScreen::geometryChanged, &m_exclusionZoneChangedTimer, static_cast(&QTimer::start)); + }); + connect(qApp, &QGuiApplication::primaryScreenChanged, &m_exclusionZoneChangedTimer, static_cast(&QTimer::start)); connect(m_window, &QWindow::screenChanged, this, [this](QScreen *nowScreen){ - for (auto screen : qApp->screens()) { - screen->disconnect(this); - } - - connect(nowScreen, &QScreen::geometryChanged, this, &LayerShellEmulation::onPositionChanged); - connect(nowScreen, &QScreen::geometryChanged, this, &LayerShellEmulation::onExclusionZoneChanged); - onPositionChanged(); - QMetaObject::invokeMethod(this, &LayerShellEmulation::onExclusionZoneChanged, Qt::QueuedConnection); + m_positionChangedTimer.start(); + m_exclusionZoneChangedTimer.start(); }); // connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::keyboardInteractivityChanged, this, &LayerShellEmulation::onKeyboardInteractivityChanged); diff --git a/frame/layershell/x11dlayershellemulation.h b/frame/layershell/x11dlayershellemulation.h index 718a4da42..91436df49 100644 --- a/frame/layershell/x11dlayershellemulation.h +++ b/frame/layershell/x11dlayershellemulation.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -31,5 +32,7 @@ private slots: private: QWindow* m_window; DLayerShellWindow* m_dlayerShellWindow; + QTimer m_positionChangedTimer; + QTimer m_exclusionZoneChangedTimer; }; DS_END_NAMESPACE