diff --git a/frame/layershell/dlayershellwindow.cpp b/frame/layershell/dlayershellwindow.cpp index 25a184c9c..3149e005c 100644 --- a/frame/layershell/dlayershellwindow.cpp +++ b/frame/layershell/dlayershellwindow.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later #include "dsglobal.h" @@ -40,6 +40,8 @@ class DLayerShellWindowPrivate int topMargin = 0; int bottomMargin = 0; DLayerShellWindow::ScreenConfiguration screenConfiguration = DLayerShellWindow::ScreenFromQWindow; + int preferredWidth = -1; + int preferredHeight = -1; bool closeOnDismissed = true; }; @@ -154,6 +156,42 @@ void DLayerShellWindow::setScreenConfiguration(DLayerShellWindow::ScreenConfigur } } +void DLayerShellWindow::setPreferredWidth(int width) +{ + if (width != d->preferredWidth) { + d->preferredWidth = width; + Q_EMIT geometryHintsChanged(); + } +} + +void DLayerShellWindow::resetPreferredWidth() +{ + setPreferredWidth(-1); +} + +int DLayerShellWindow::preferredWidth() const +{ + return d->preferredWidth; +} + +void DLayerShellWindow::setPreferredHeight(int height) +{ + if (height != d->preferredHeight) { + d->preferredHeight = height; + Q_EMIT geometryHintsChanged(); + } +} + +void DLayerShellWindow::resetPreferredHeight() +{ + setPreferredHeight(-1); +} + +int DLayerShellWindow::preferredHeight() const +{ + return d->preferredHeight; +} + bool DLayerShellWindow::closeOnDismissed() const { return d->closeOnDismissed; diff --git a/frame/layershell/dlayershellwindow.h b/frame/layershell/dlayershellwindow.h index c62497357..1b77ac777 100644 --- a/frame/layershell/dlayershellwindow.h +++ b/frame/layershell/dlayershellwindow.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -28,6 +28,8 @@ class DS_SHARE DLayerShellWindow : public QObject Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged) Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged) Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration) + Q_PROPERTY(int preferredWidth READ preferredWidth WRITE setPreferredWidth RESET resetPreferredWidth NOTIFY geometryHintsChanged) + Q_PROPERTY(int preferredHeight READ preferredHeight WRITE setPreferredHeight RESET resetPreferredHeight NOTIFY geometryHintsChanged) Q_PROPERTY(bool closeOnDismissed READ closeOnDismissed WRITE setCloseOnDismissed) @@ -111,6 +113,14 @@ class DS_SHARE DLayerShellWindow : public QObject void setScreenConfiguration(ScreenConfiguration screenConfiguration); ScreenConfiguration screenConfiguration() const; + void setPreferredWidth(int width); + void resetPreferredWidth(); + int preferredWidth() const; + + void setPreferredHeight(int height); + void resetPreferredHeight(); + int preferredHeight() const; + /** * Sets a string based identifier for this window. * This may be used by a compositor to determine stacking @@ -145,6 +155,7 @@ class DS_SHARE DLayerShellWindow : public QObject void keyboardInteractivityChanged(); void layerChanged(); void scopeChanged(); + void geometryHintsChanged(); private: DLayerShellWindow(QWindow* window); diff --git a/frame/layershell/x11dlayershellemulation.cpp b/frame/layershell/x11dlayershellemulation.cpp index c38280967..c7ae84ce4 100644 --- a/frame/layershell/x11dlayershellemulation.cpp +++ b/frame/layershell/x11dlayershellemulation.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -33,6 +33,7 @@ LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent) onPositionChanged(); connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onPositionChanged); connect(m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this, &LayerShellEmulation::onPositionChanged); + connect(m_dlayerShellWindow, &DLayerShellWindow::geometryHintsChanged, this, &LayerShellEmulation::onPositionChanged); onExclusionZoneChanged(); m_exclusionZoneChangedTimer.setSingleShot(true); @@ -117,17 +118,30 @@ void LayerShellEmulation::onPositionChanged() { auto anchors = m_dlayerShellWindow->anchors(); auto screen = m_window->screen(); + if (!screen) { + return; + } + + int targetWidth = m_window->width(); + int targetHeight = m_window->height(); + if (m_dlayerShellWindow->preferredWidth() > 0) { + targetWidth = m_dlayerShellWindow->preferredWidth(); + } + if (m_dlayerShellWindow->preferredHeight() > 0) { + targetHeight = m_dlayerShellWindow->preferredHeight(); + } + auto screenRect = screen->geometry(); - auto x = screenRect.left() + (screenRect.width() - m_window->width()) / 2; - auto y = screenRect.top() + (screenRect.height() - m_window->height()) / 2; + auto x = screenRect.left() + (screenRect.width() - targetWidth) / 2; + auto y = screenRect.top() + (screenRect.height() - targetHeight) / 2; if (anchors & DLayerShellWindow::AnchorRight) { // https://doc.qt.io/qt-6/qrect.html#right - x = (screen->geometry().right() + 1 - m_window->width() - m_dlayerShellWindow->rightMargin()); + x = (screen->geometry().right() + 1 - targetWidth - m_dlayerShellWindow->rightMargin()); } if (anchors & DLayerShellWindow::AnchorBottom) { // https://doc.qt.io/qt-6/qrect.html#bottom - y = (screen->geometry().bottom() + 1 - m_window->height() - m_dlayerShellWindow->bottomMargin()); + y = (screen->geometry().bottom() + 1 - targetHeight - m_dlayerShellWindow->bottomMargin()); } if (anchors & DLayerShellWindow::AnchorLeft) { x = (screen->geometry().left() + m_dlayerShellWindow->leftMargin()); @@ -136,7 +150,7 @@ void LayerShellEmulation::onPositionChanged() y = (screen->geometry().top() + m_dlayerShellWindow->topMargin()); } - QRect rect(x, y, m_window->width(), m_window->height()); + QRect rect(x, y, targetWidth, targetHeight); const bool horizontallyConstrained = anchors.testFlags({DLayerShellWindow::AnchorLeft, DLayerShellWindow::AnchorRight}); const bool verticallyConstrained = anchors.testFlags({DLayerShellWindow::AnchorTop, DLayerShellWindow::AnchorBottom}); @@ -150,7 +164,9 @@ void LayerShellEmulation::onPositionChanged() rect.setHeight(screen->geometry().height() - m_dlayerShellWindow->topMargin() - m_dlayerShellWindow->bottomMargin()); } - m_window->setGeometry(rect); + if (m_window->geometry() != rect) { + m_window->setGeometry(rect); + } } /** diff --git a/panels/notification/bubble/package/main.qml b/panels/notification/bubble/package/main.qml index d25dabf91..18dd17787 100644 --- a/panels/notification/bubble/package/main.qml +++ b/panels/notification/bubble/package/main.qml @@ -68,8 +68,8 @@ Window { } visible: Applet.visible - width: 390 - height: Math.max(10, bubbleView.height + bubbleView.anchors.topMargin + bubbleView.anchors.bottomMargin) + DLayerShellWindow.preferredWidth: 390 + DLayerShellWindow.preferredHeight: Math.max(10, bubbleView.height + bubbleView.anchors.topMargin + bubbleView.anchors.bottomMargin) DLayerShellWindow.layer: DLayerShellWindow.LayerOverlay DLayerShellWindow.anchors: DLayerShellWindow.AnchorBottom | DLayerShellWindow.AnchorRight DLayerShellWindow.topMargin: windowMargin(0) @@ -107,27 +107,27 @@ Window { verticalLayoutDirection: ListView.BottomToTop add: Transition { id: addTrans - // Before starting the new animation, forcibly complete the previous notification bubble's animation - ScriptAction { - script: { - // Only handle the previous notification bubble (at index count - 1); no need to iterate through all of them - if (bubbleView.count > 1) { - let prevItem = bubbleView.itemAtIndex(bubbleView.count - 2) - if (prevItem) { - // Directly set x to 0 to forcibly complete the animation - prevItem.x = 0 - } - } - } - } - XAnimator { + PropertyAnimation { target: addTrans.ViewTransition.item + properties: "x" from: addTrans.ViewTransition.item.width to: 0 duration: 600 easing.type: Easing.OutExpo } } + + addDisplaced: Transition { + id: addDisplacedTrans + PropertyAnimation { + target: addDisplacedTrans.ViewTransition.item + properties: "x" + to: 0 + duration: 600 + easing.type: Easing.OutExpo + } + } + delegate: Bubble { width: 360 bubble: model