Skip to content

Commit 9ea5674

Browse files
committed
fix: fix notification bubble animation glitch
1. Replaced the previous complex ScriptAction with a simpler PropertyAnimation for the add transition 2. Added a new addDisplaced transition to handle displaced items when new notifications are added 3. Removed the manual script that forced previous bubble animations to complete, which was causing visual glitches 4. Now uses standard Qt Quick transitions for smoother and more reliable animation behavior fix: 修复通知气泡动画显示问题 1. 将之前复杂的 ScriptAction 替换为更简单的 PropertyAnimation 来处理添加 动画 2. 新增 addDisplaced 过渡动画来处理新通知添加时其他气泡的位移 3. 移除了强制完成前一个气泡动画的手动脚本,该脚本会导致视觉故障 4. 现在使用标准的 Qt Quick 过渡动画来实现更平滑可靠的动画效果 PMS: BUG-355029
1 parent 1824886 commit 9ea5674

4 files changed

Lines changed: 92 additions & 25 deletions

File tree

frame/layershell/dlayershellwindow.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44
#include "dsglobal.h"
@@ -40,6 +40,8 @@ class DLayerShellWindowPrivate
4040
int topMargin = 0;
4141
int bottomMargin = 0;
4242
DLayerShellWindow::ScreenConfiguration screenConfiguration = DLayerShellWindow::ScreenFromQWindow;
43+
int preferredWidth = -1;
44+
int preferredHeight = -1;
4345
bool closeOnDismissed = true;
4446
};
4547

@@ -154,6 +156,42 @@ void DLayerShellWindow::setScreenConfiguration(DLayerShellWindow::ScreenConfigur
154156
}
155157
}
156158

159+
void DLayerShellWindow::setPreferredWidth(int width)
160+
{
161+
if (width != d->preferredWidth) {
162+
d->preferredWidth = width;
163+
Q_EMIT geometryHintsChanged();
164+
}
165+
}
166+
167+
void DLayerShellWindow::resetPreferredWidth()
168+
{
169+
setPreferredWidth(-1);
170+
}
171+
172+
int DLayerShellWindow::preferredWidth() const
173+
{
174+
return d->preferredWidth;
175+
}
176+
177+
void DLayerShellWindow::setPreferredHeight(int height)
178+
{
179+
if (height != d->preferredHeight) {
180+
d->preferredHeight = height;
181+
Q_EMIT geometryHintsChanged();
182+
}
183+
}
184+
185+
void DLayerShellWindow::resetPreferredHeight()
186+
{
187+
setPreferredHeight(-1);
188+
}
189+
190+
int DLayerShellWindow::preferredHeight() const
191+
{
192+
return d->preferredHeight;
193+
}
194+
157195
bool DLayerShellWindow::closeOnDismissed() const
158196
{
159197
return d->closeOnDismissed;

frame/layershell/dlayershellwindow.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -28,6 +28,8 @@ class DS_SHARE DLayerShellWindow : public QObject
2828
Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged)
2929
Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged)
3030
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
31+
Q_PROPERTY(int preferredWidth READ preferredWidth WRITE setPreferredWidth RESET resetPreferredWidth NOTIFY geometryHintsChanged)
32+
Q_PROPERTY(int preferredHeight READ preferredHeight WRITE setPreferredHeight RESET resetPreferredHeight NOTIFY geometryHintsChanged)
3133

3234
Q_PROPERTY(bool closeOnDismissed READ closeOnDismissed WRITE setCloseOnDismissed)
3335

@@ -111,6 +113,14 @@ class DS_SHARE DLayerShellWindow : public QObject
111113
void setScreenConfiguration(ScreenConfiguration screenConfiguration);
112114
ScreenConfiguration screenConfiguration() const;
113115

116+
void setPreferredWidth(int width);
117+
void resetPreferredWidth();
118+
int preferredWidth() const;
119+
120+
void setPreferredHeight(int height);
121+
void resetPreferredHeight();
122+
int preferredHeight() const;
123+
114124
/**
115125
* Sets a string based identifier for this window.
116126
* This may be used by a compositor to determine stacking
@@ -145,6 +155,7 @@ class DS_SHARE DLayerShellWindow : public QObject
145155
void keyboardInteractivityChanged();
146156
void layerChanged();
147157
void scopeChanged();
158+
void geometryHintsChanged();
148159

149160
private:
150161
DLayerShellWindow(QWindow* window);

frame/layershell/x11dlayershellemulation.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -33,6 +33,7 @@ LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent)
3333
onPositionChanged();
3434
connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this, &LayerShellEmulation::onPositionChanged);
3535
connect(m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this, &LayerShellEmulation::onPositionChanged);
36+
connect(m_dlayerShellWindow, &DLayerShellWindow::geometryHintsChanged, this, &LayerShellEmulation::onPositionChanged);
3637

3738
onExclusionZoneChanged();
3839
m_exclusionZoneChangedTimer.setSingleShot(true);
@@ -117,17 +118,30 @@ void LayerShellEmulation::onPositionChanged()
117118
{
118119
auto anchors = m_dlayerShellWindow->anchors();
119120
auto screen = m_window->screen();
121+
if (!screen) {
122+
return;
123+
}
124+
125+
int targetWidth = m_window->width();
126+
int targetHeight = m_window->height();
127+
if (m_dlayerShellWindow->preferredWidth() > 0) {
128+
targetWidth = m_dlayerShellWindow->preferredWidth();
129+
}
130+
if (m_dlayerShellWindow->preferredHeight() > 0) {
131+
targetHeight = m_dlayerShellWindow->preferredHeight();
132+
}
133+
120134
auto screenRect = screen->geometry();
121-
auto x = screenRect.left() + (screenRect.width() - m_window->width()) / 2;
122-
auto y = screenRect.top() + (screenRect.height() - m_window->height()) / 2;
135+
auto x = screenRect.left() + (screenRect.width() - targetWidth) / 2;
136+
auto y = screenRect.top() + (screenRect.height() - targetHeight) / 2;
123137
if (anchors & DLayerShellWindow::AnchorRight) {
124138
// https://doc.qt.io/qt-6/qrect.html#right
125-
x = (screen->geometry().right() + 1 - m_window->width() - m_dlayerShellWindow->rightMargin());
139+
x = (screen->geometry().right() + 1 - targetWidth - m_dlayerShellWindow->rightMargin());
126140
}
127141

128142
if (anchors & DLayerShellWindow::AnchorBottom) {
129143
// https://doc.qt.io/qt-6/qrect.html#bottom
130-
y = (screen->geometry().bottom() + 1 - m_window->height() - m_dlayerShellWindow->bottomMargin());
144+
y = (screen->geometry().bottom() + 1 - targetHeight - m_dlayerShellWindow->bottomMargin());
131145
}
132146
if (anchors & DLayerShellWindow::AnchorLeft) {
133147
x = (screen->geometry().left() + m_dlayerShellWindow->leftMargin());
@@ -136,7 +150,7 @@ void LayerShellEmulation::onPositionChanged()
136150
y = (screen->geometry().top() + m_dlayerShellWindow->topMargin());
137151
}
138152

139-
QRect rect(x, y, m_window->width(), m_window->height());
153+
QRect rect(x, y, targetWidth, targetHeight);
140154

141155
const bool horizontallyConstrained = anchors.testFlags({DLayerShellWindow::AnchorLeft, DLayerShellWindow::AnchorRight});
142156
const bool verticallyConstrained = anchors.testFlags({DLayerShellWindow::AnchorTop, DLayerShellWindow::AnchorBottom});
@@ -150,7 +164,11 @@ void LayerShellEmulation::onPositionChanged()
150164
rect.setHeight(screen->geometry().height() - m_dlayerShellWindow->topMargin() - m_dlayerShellWindow->bottomMargin());
151165
}
152166

153-
m_window->setGeometry(rect);
167+
if (m_window->geometry() != rect) {
168+
169+
m_window->setGeometry(rect);
170+
171+
}
154172
}
155173

156174
/**

panels/notification/bubble/package/main.qml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ Window {
6868
}
6969

7070
visible: Applet.visible
71-
width: 390
72-
height: Math.max(10, bubbleView.height + bubbleView.anchors.topMargin + bubbleView.anchors.bottomMargin)
71+
DLayerShellWindow.preferredWidth: 390
72+
DLayerShellWindow.preferredHeight: Math.max(10, bubbleView.height + bubbleView.anchors.topMargin + bubbleView.anchors.bottomMargin)
7373
DLayerShellWindow.layer: DLayerShellWindow.LayerOverlay
7474
DLayerShellWindow.anchors: DLayerShellWindow.AnchorBottom | DLayerShellWindow.AnchorRight
7575
DLayerShellWindow.topMargin: windowMargin(0)
@@ -107,27 +107,27 @@ Window {
107107
verticalLayoutDirection: ListView.BottomToTop
108108
add: Transition {
109109
id: addTrans
110-
// Before starting the new animation, forcibly complete the previous notification bubble's animation
111-
ScriptAction {
112-
script: {
113-
// Only handle the previous notification bubble (at index count - 1); no need to iterate through all of them
114-
if (bubbleView.count > 1) {
115-
let prevItem = bubbleView.itemAtIndex(bubbleView.count - 2)
116-
if (prevItem) {
117-
// Directly set x to 0 to forcibly complete the animation
118-
prevItem.x = 0
119-
}
120-
}
121-
}
122-
}
123-
XAnimator {
110+
PropertyAnimation {
124111
target: addTrans.ViewTransition.item
112+
properties: "x"
125113
from: addTrans.ViewTransition.item.width
126114
to: 0
127115
duration: 600
128116
easing.type: Easing.OutExpo
129117
}
130118
}
119+
120+
addDisplaced: Transition {
121+
id: addDisplacedTrans
122+
PropertyAnimation {
123+
target: addDisplacedTrans.ViewTransition.item
124+
properties: "x"
125+
to: 0
126+
duration: 600
127+
easing.type: Easing.OutExpo
128+
}
129+
}
130+
131131
delegate: Bubble {
132132
width: 360
133133
bubble: model

0 commit comments

Comments
 (0)