diff --git a/frame/qml/PanelPopup.qml b/frame/qml/PanelPopup.qml index c417f0532..33b132533 100644 --- a/frame/qml/PanelPopup.qml +++ b/frame/qml/PanelPopup.qml @@ -16,6 +16,10 @@ Item { property int popupY: 0 property bool readyBinding: false property bool openPending: false + property bool contentReady: true + property bool contentOpenPending: false + property bool revealAfterRender: false + property bool revealPending: false property bool grabInactivePending: false property int grabInactiveTimeout: 200 // WM_NAME, used for kwin. @@ -54,6 +58,12 @@ Item { if (!popupWindow) return + if (!contentReady) { + contentOpenPending = true + return + } + contentOpenPending = false + // The popup is being displayed. If you click on other plugin at this time, // the popup content of the previous plugin will be displayed first, // and the wrong popup size will cause the window size to change and flicker. @@ -84,11 +94,16 @@ Item { function close() { openPending = false + contentOpenPending = false + revealPending = false grabInactivePending = false grabInactiveTimer.stop() if (!popupWindow) return + if (popupWindow.currentItem === control) + popupWindow.opacity = 1 + // avoid to closing window by other PanelPopup. if (!readyBinding) return @@ -97,6 +112,16 @@ Item { popupWindow.currentItem = null } + onContentReadyChanged: { + if (!contentReady || !contentOpenPending) + return + + Qt.callLater(function () { + if (contentReady && contentOpenPending) + control.open() + }) + } + function finalizeOpen() { if (!popupWindow || !openPending || !readyBinding || popupWindow.currentItem !== control) @@ -104,8 +129,16 @@ Item { openPending = false popupWindow.title = windowTitle + revealPending = revealAfterRender + // popupWindow is shared by all PanelPopup instances. Always initialize + // its opacity so a popup cannot inherit an interrupted reveal state. + popupWindow.opacity = revealPending ? 0 : 1 popupWindow.show() - popupWindow.requestActivate() + if (revealPending) { + popupWindow.update() + } else { + popupWindow.requestActivate() + } } Timer { @@ -156,6 +189,16 @@ Item { control.finalizeOpen() } + function onFrameSwapped() + { + if (!control.revealPending || !popupWindow || popupWindow.currentItem !== control) + return + + control.revealPending = false + popupWindow.opacity = 1 + popupWindow.requestActivate() + } + function onX11FocusOutByGrab() { if (!popupWindow || !readyBinding || !popup.visible || popupWindow.currentItem !== control) { diff --git a/panels/dock/ShellSurfaceItemProxy.qml b/panels/dock/ShellSurfaceItemProxy.qml index e55eaea63..f73180a75 100644 --- a/panels/dock/ShellSurfaceItemProxy.qml +++ b/panels/dock/ShellSurfaceItemProxy.qml @@ -18,6 +18,7 @@ Item { property bool pressed: tapHandler.pressed property int cursorShape: Qt.ArrowCursor property alias shellSurfaceItem: impl + readonly property bool hasSurfaceContent: impl.surface ? impl.surface.hasContent : false implicitWidth: shellSurface ? shellSurface.width : 16 implicitHeight: shellSurface ? shellSurface.height : 16 diff --git a/panels/dock/dockpositioner.cpp b/panels/dock/dockpositioner.cpp index 231a881e6..e1b8bc5d4 100644 --- a/panels/dock/dockpositioner.cpp +++ b/panels/dock/dockpositioner.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024-2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -36,7 +36,10 @@ DockPositioner::DockPositioner(DPanel *panel, QObject *parent) Q_ASSERT(m_panel); connect(m_panel, SIGNAL(positionChanged(Position)), this, SLOT(update())); connect(m_panel, SIGNAL(geometryChanged(QRect)), this, SLOT(update())); - connect(this, &DockPositioner::boundingChanged, this, &DockPositioner::update); + // The popup may be opened in the same event-loop turn as its anchor is + // assigned. Calculate anchor changes immediately so its first frame does + // not use the default (0, 0) position. + connect(this, &DockPositioner::boundingChanged, this, &DockPositioner::updatePosition); } DockPositioner::~DockPositioner() diff --git a/panels/dock/tray/TrayItemSurfacePopup.qml b/panels/dock/tray/TrayItemSurfacePopup.qml index c3cfbcdc2..4c5616650 100644 --- a/panels/dock/tray/TrayItemSurfacePopup.qml +++ b/panels/dock/tray/TrayItemSurfacePopup.qml @@ -33,6 +33,8 @@ Item { height: popupContent.height popupX: DockPanelPositioner.x popupY: DockPanelPositioner.y + contentReady: popupContent.hasSurfaceContent + revealAfterRender: true Item { anchors.fill: parent