Skip to content

Commit 0c4074e

Browse files
committed
refactor(notification): move bubble overlay logic to QML delegate
1. Remove level property and overlay count tracking from BubbleItem and BubbleModel 2. Introduce BubbleDelegate.qml with visual folding effects (scale, y-offset, opacity) based on index 3. Simplify BubbleModel to use m_maxKeep limit instead of separate display/overlay counts 4. Add remove and removeDisplaced transitions for smooth disappearance animations 5. Consolidate NormalBubble.qml and OverlayBubble.qml into single Bubble.qml component 6. Add delayed hide (500ms) in BubblePanel to allow QML animations to complete Log: Refactor notification bubble system to handle overlay visual effects in QML instead of C++ model refactor(notification): 将气泡折叠逻辑移至 QML 代理组件 1. 移除 BubbleItem 和 BubbleModel 中的 level 属性及折叠计数追踪 2. 新增 BubbleDelegate.qml,根据索引实现视觉折叠效果(缩放、Y 偏移、透明度) 3. 简化 BubbleModel,使用 m_maxKeep 限制替代分离的显示/折叠计数 4. 添加 remove 和 removeDisplaced 过渡动画实现平滑消失效果 5. 合并 NormalBubble.qml 和 OverlayBubble.qml 为单一 Bubble.qml 组件 6. BubblePanel 添加 500ms 延迟隐藏,确保 QML 动画播放完成 Log: 重构通知气泡系统,将折叠视觉效果从 C++ 模型移至 QML 处理 PMS: BUG-355029
1 parent ac054d1 commit 0c4074e

16 files changed

Lines changed: 267 additions & 191 deletions

frame/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ target_link_directories(dde-shell-frame INTERFACE
118118

119119
if (BUILD_WITH_X11)
120120
target_compile_definitions(dde-shell-frame PRIVATE BUILD_WITH_X11)
121-
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb-ewmh xcb-icccm xtst x11)
121+
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb-ewmh xcb-icccm xtst xcb-shape x11)
122122
target_sources(dde-shell-frame PRIVATE layershell/x11dlayershellemulation.h layershell/x11dlayershellemulation.cpp)
123123
target_link_libraries(dde-shell-frame PRIVATE PkgConfig::XCB)
124124
endif(BUILD_WITH_X11)

frame/layershell/dlayershellwindow.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DLayerShellWindowPrivate
4343
int preferredWidth = -1;
4444
int preferredHeight = -1;
4545
bool closeOnDismissed = true;
46+
QRegion inputRegion;
4647
};
4748

4849
void DLayerShellWindow::setAnchors(DLayerShellWindow::Anchors anchors)
@@ -192,6 +193,29 @@ int DLayerShellWindow::preferredHeight() const
192193
return d->preferredHeight;
193194
}
194195

196+
void DLayerShellWindow::setInputRegion(const QRegion &region)
197+
{
198+
if (d->inputRegion != region) {
199+
d->inputRegion = region;
200+
Q_EMIT inputRegionChanged();
201+
}
202+
}
203+
204+
void DLayerShellWindow::resetInputRegion()
205+
{
206+
setInputRegion(QRegion());
207+
}
208+
209+
QRegion DLayerShellWindow::inputRegion() const
210+
{
211+
return d->inputRegion;
212+
}
213+
214+
void DLayerShellWindow::setInputRegionRect(int x, int y, int width, int height)
215+
{
216+
setInputRegion(QRegion(x, y, width, height));
217+
}
218+
195219
bool DLayerShellWindow::closeOnDismissed() const
196220
{
197221
return d->closeOnDismissed;

frame/layershell/dlayershellwindow.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class DS_SHARE DLayerShellWindow : public QObject
3030
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
3131
Q_PROPERTY(int preferredWidth READ preferredWidth WRITE setPreferredWidth RESET resetPreferredWidth NOTIFY geometryHintsChanged)
3232
Q_PROPERTY(int preferredHeight READ preferredHeight WRITE setPreferredHeight RESET resetPreferredHeight NOTIFY geometryHintsChanged)
33+
Q_PROPERTY(QRegion inputRegion READ inputRegion WRITE setInputRegion RESET resetInputRegion NOTIFY inputRegionChanged)
3334

3435
Q_PROPERTY(bool closeOnDismissed READ closeOnDismissed WRITE setCloseOnDismissed)
3536

@@ -121,6 +122,12 @@ class DS_SHARE DLayerShellWindow : public QObject
121122
void resetPreferredHeight();
122123
int preferredHeight() const;
123124

125+
void setInputRegion(const QRegion &region);
126+
void resetInputRegion();
127+
QRegion inputRegion() const;
128+
129+
Q_INVOKABLE void setInputRegionRect(int x, int y, int width, int height);
130+
124131
/**
125132
* Sets a string based identifier for this window.
126133
* This may be used by a compositor to determine stacking
@@ -156,6 +163,7 @@ class DS_SHARE DLayerShellWindow : public QObject
156163
void layerChanged();
157164
void scopeChanged();
158165
void geometryHintsChanged();
166+
void inputRegionChanged();
159167

160168
private:
161169
DLayerShellWindow(QWindow* window);

frame/layershell/qwaylandlayershellsurface.cpp

Lines changed: 8 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

@@ -75,6 +75,13 @@ QWaylandLayerShellSurface::QWaylandLayerShellSurface(QtWayland::zwlr_layer_shell
7575
window->waylandSurface()->commit();
7676
});
7777

78+
auto applyInputRegion = [this, window]() {
79+
window->window()->setMask(m_dlayerShellWindow->inputRegion());
80+
window->waylandSurface()->commit();
81+
};
82+
83+
connect(m_dlayerShellWindow, &DLayerShellWindow::inputRegionChanged, this, applyInputRegion);
84+
7885
calcAndSetRequestSize(window->surfaceSize());
7986

8087
if (m_requestSize.isValid()) {

frame/layershell/x11dlayershellemulation.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <xcb/xcb.h>
1818
#include <xcb/xcb_ewmh.h>
1919
#include <xcb/xcb_icccm.h>
20+
#include <xcb/shape.h>
2021

2122
DS_BEGIN_NAMESPACE
2223

@@ -71,6 +72,9 @@ LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent)
7172
onScopeChanged();
7273
connect(m_dlayerShellWindow, &DLayerShellWindow::scopeChanged, this, &LayerShellEmulation::onScopeChanged);
7374

75+
onInputRegionChanged();
76+
connect(m_dlayerShellWindow, &DLayerShellWindow::inputRegionChanged, this, &LayerShellEmulation::onInputRegionChanged);
77+
7478
// connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::keyboardInteractivityChanged, this, &LayerShellEmulation::onKeyboardInteractivityChanged);
7579
}
7680

@@ -321,6 +325,41 @@ void LayerShellEmulation::onScopeChanged()
321325
qCDebug(layershell) << "Set WM_CLASS for window" << m_window->winId() << " wm_class:" << wmClassData;
322326
}
323327

328+
void LayerShellEmulation::onInputRegionChanged()
329+
{
330+
auto *x11Application = qGuiApp->nativeInterface<QNativeInterface::QX11Application>();
331+
if (!x11Application || !m_window->winId() || !m_dlayerShellWindow) {
332+
return;
333+
}
334+
335+
if (m_dlayerShellWindow->inputRegion().isNull()) {
336+
// Reset input region (no shape constraint)
337+
xcb_shape_mask(x11Application->connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, m_window->winId(), 0, 0, XCB_NONE);
338+
xcb_flush(x11Application->connection());
339+
return;
340+
}
341+
342+
QRegion region = m_dlayerShellWindow->inputRegion();
343+
qreal scaleFactor = qGuiApp->devicePixelRatio();
344+
345+
QVector<xcb_rectangle_t> rects;
346+
for (const QRect &r : region) {
347+
xcb_rectangle_t rect;
348+
rect.x = r.x() * scaleFactor;
349+
rect.y = r.y() * scaleFactor;
350+
rect.width = r.width() * scaleFactor;
351+
rect.height = r.height() * scaleFactor;
352+
rects.append(rect);
353+
}
354+
355+
// Set the input shape via XCB
356+
// If rects vector is empty, the window will become completely transparent to input clicks (unclickable)
357+
xcb_shape_rectangles(x11Application->connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT,
358+
XCB_CLIP_ORDERING_UNSORTED, m_window->winId(), 0, 0,
359+
rects.size(), rects.data());
360+
xcb_flush(x11Application->connection());
361+
}
362+
324363
// void X11Emulation::onKeyboardInteractivityChanged()
325364
// {
326365
// // kwin no implentation on wayland

frame/layershell/x11dlayershellemulation.h

Lines changed: 2 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,7 @@ private slots:
2828
void onPositionChanged();
2929
void onExclusionZoneChanged();
3030
void onScopeChanged();
31+
void onInputRegionChanged();
3132
// void onKeyboardInteractivityChanged();
3233

3334
private:

panels/notification/bubble/bubbleitem.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -282,19 +282,6 @@ void BubbleItem::updateActions()
282282
m_actions = array;
283283
}
284284

285-
int BubbleItem::level() const
286-
{
287-
return m_level;
288-
}
289-
290-
void BubbleItem::setLevel(int level)
291-
{
292-
if (m_level == level)
293-
return;
294-
295-
m_level = level;
296-
emit levelChanged();
297-
}
298285

299286
QString BubbleItem::timeTip() const
300287
{

panels/notification/bubble/bubbleitem.h

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

@@ -39,8 +39,6 @@ class BubbleItem : public QObject
3939
QVariantList actions() const;
4040
void updateActions();
4141

42-
int level() const;
43-
void setLevel(int level);
4442

4543
QString timeTip() const;
4644
void setTimeTip(const QString &timeTip);
@@ -51,15 +49,13 @@ class BubbleItem : public QObject
5149
bool isValid() const;
5250

5351
signals:
54-
void levelChanged();
5552
void timeTipChanged();
5653

5754
private:
5855
QString displayText() const;
5956

6057
private:
6158
NotifyEntity m_entity;
62-
int m_level = 0;
6359
int m_urgency = NotifyEntity::Normal;
6460
QString m_timeTip;
6561
bool m_enablePreview = true;

0 commit comments

Comments
 (0)