diff --git a/panels/notification/bubble/bubblemodel.cpp b/panels/notification/bubble/bubblemodel.cpp index 44382c4fe..c9bbee6fb 100644 --- a/panels/notification/bubble/bubblemodel.cpp +++ b/panels/notification/bubble/bubblemodel.cpp @@ -95,15 +95,8 @@ BubbleItem *BubbleModel::replaceBubble(BubbleItem *bubble) const auto replaceIndex = replaceBubbleIndex(bubble); const auto oldBubble = m_bubbles[replaceIndex]; - // Use remove + insert instead of dataChanged to force the view - // to recreate the delegate, so ListView recalculates its height. - beginRemoveRows(QModelIndex(), replaceIndex, replaceIndex); - m_bubbles.removeAt(replaceIndex); - endRemoveRows(); - - beginInsertRows(QModelIndex(), replaceIndex, replaceIndex); - m_bubbles.insert(replaceIndex, bubble); - endInsertRows(); + m_bubbles.replace(replaceIndex, bubble); + Q_EMIT dataChanged(index(replaceIndex), index(replaceIndex)); return oldBubble; } diff --git a/panels/notification/bubble/package/main.qml b/panels/notification/bubble/package/main.qml index e078ac4b6..69c3b0614 100644 --- a/panels/notification/bubble/package/main.qml +++ b/panels/notification/bubble/package/main.qml @@ -103,6 +103,17 @@ Window { bottomMargin: 10 } + // itemGeometryChanged() normally triggers forceLayoutPolish() to + // re-layout with updated height, but it exits early when a transition + // (add/remove/displaced) is running for the first visible item. + // Toggle displayMarginBeginning to force forceLayoutPolish() directly, + // bypassing the transition check. + function requestLayoutFix() { + var m = displayMarginBeginning + displayMarginBeginning = m + 1 + displayMarginBeginning = m + } + function updateInputRegion() { root.DLayerShellWindow.setInputRegionRect( Math.ceil(bubbleView.x), @@ -171,6 +182,14 @@ Window { delegate: BubbleDelegate { maxCount: model.bubbleCount + + onHeightChanged: { + if (index < 0) { + return + } + + bubbleView.requestLayoutFix() + } } } }