From c7d49d375aac508b59b56124925cf38523a4e774 Mon Sep 17 00:00:00 2001 From: zhaoyingzhen Date: Thu, 26 Mar 2026 15:29:26 +0800 Subject: [PATCH] fix: resolve abnormal compositor window size due to popup panel height change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactored the QML bindings handling the width and height of the popup window. By introducing requestedWidth and requestedHeight and explicitly passing them to the native window bounds via setWindowGeometry, we prevent uncoordinated and recurrent Wayland resize events from corrupting the compositor window geometries during dynamic plugin panel dimension adjustments. 修复:解决因弹出面板尺寸变化导致顶层合成器显示窗口大小异常的缺陷 重构了处理弹出面板宽高的 QML 绑定逻辑。通过引入 requestedWidth 和 requestedHeight 参数,并通过 setWindowGeometry 显式设置底层原 生窗口状态,可以避免在插件动态调整面板尺寸时,高频和未协调的 Wayland 尺寸挂载事件破坏合成器渲染的窗口几何形状。 Log: resolve abnormal compositor window size due to popup panel height change Pms: BUG-307129 BUG-336777 --- frame/popupwindow.cpp | 5 +++++ frame/popupwindow.h | 2 ++ frame/qml/PanelPopup.qml | 4 ++-- frame/qml/PanelPopupWindow.qml | 26 +++++++++++++++++++------- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/frame/popupwindow.cpp b/frame/popupwindow.cpp index a7425f9b9..2732c914e 100644 --- a/frame/popupwindow.cpp +++ b/frame/popupwindow.cpp @@ -32,6 +32,11 @@ PopupWindow::PopupWindow(QWindow *parent) }); } +void PopupWindow::setWindowGeometry(int px, int py, int pw, int ph) +{ + this->setGeometry(px, py, pw, ph); +} + void PopupWindow::mouseReleaseEvent(QMouseEvent *event) { QQuickApplicationWindow::mouseReleaseEvent(event); diff --git a/frame/popupwindow.h b/frame/popupwindow.h index 5c9925446..8a6eb2f54 100644 --- a/frame/popupwindow.h +++ b/frame/popupwindow.h @@ -17,7 +17,9 @@ class PopupWindow : public QQuickApplicationWindow public: PopupWindow(QWindow *parent = nullptr); + bool x11GrabFocusTransition() const { return m_x11GrabFocusTransition; } + Q_INVOKABLE void setWindowGeometry(int px, int py, int pw, int ph); protected: void mouseReleaseEvent(QMouseEvent *event) override; diff --git a/frame/qml/PanelPopup.qml b/frame/qml/PanelPopup.qml index b01c69b82..b0bdb8995 100644 --- a/frame/qml/PanelPopup.qml +++ b/frame/qml/PanelPopup.qml @@ -24,12 +24,12 @@ Item { Binding { when: readyBinding - target: popupWindow; property: "width" + target: popupWindow; property: "requestedWidth" value: popup.width } Binding { when: readyBinding - target: popupWindow; property: "height" + target: popupWindow; property: "requestedHeight" value: popup.height } Binding { diff --git a/frame/qml/PanelPopupWindow.qml b/frame/qml/PanelPopupWindow.qml index c4404dfa0..4de58dd69 100644 --- a/frame/qml/PanelPopupWindow.qml +++ b/frame/qml/PanelPopupWindow.qml @@ -15,14 +15,18 @@ PopupWindow { property real yOffset: 0 property int margins: 10 property Item currentItem + property int requestedWidth: 10 + property int requestedHeight: 10 signal requestUpdateGeometry() signal updateGeometryFinished() // order to update screen and (x,y) property var updateGeometryer : function updateGeometry() { - if (root.width <= 10 || root.height <= 10) { - return + if (root.requestedWidth <= 10 || root.requestedHeight <= 10) { + root.width = root.requestedWidth; + root.height = root.requestedHeight; + return; } if (!root.transientParent) return @@ -33,9 +37,11 @@ PopupWindow { let bounding = Qt.rect(root.screen.virtualX + margins, root.screen.virtualY + margins, root.screen.width - margins * 2, root.screen.height - margins * 2) let pos = Qt.point(transientParent ? transientParent.x + xOffset : xOffset, - transientParent ? transientParent.y + yOffset : YOffset) - x = selectValue(pos.x, bounding.left, bounding.right - root.width) - y = selectValue(pos.y, bounding.top, bounding.bottom - root.height) + transientParent ? transientParent.y + yOffset : yOffset) + let newX = selectValue(pos.x, bounding.left, bounding.right - root.requestedWidth) + let newY = selectValue(pos.y, bounding.top, bounding.bottom - root.requestedHeight) + + root.setWindowGeometry(newX, newY, root.requestedWidth, root.requestedHeight) } function selectValue(value, min, max) { @@ -84,6 +90,8 @@ PopupWindow { if(root.visible) return currentItem = null + root.requestedWidth = 10 + root.requestedHeight = 10 root.width = 10 root.height = 10 DS.closeChildrenWindows(root) @@ -117,8 +125,12 @@ PopupWindow { } } - onHeightChanged: requestUpdateGeometry() - onWidthChanged: requestUpdateGeometry() + onRequestedHeightChanged: { + requestUpdateGeometry() + } + onRequestedWidthChanged: { + requestUpdateGeometry() + } onXOffsetChanged: requestUpdateGeometry() onYOffsetChanged: requestUpdateGeometry()