From b1a9d7912e7da800702f42484dd96f159b80be55 Mon Sep 17 00:00:00 2001 From: Scott Jones Date: Fri, 24 Jul 2026 11:47:53 -0400 Subject: [PATCH] Give notification popups a fixed-size surface to stop resize scaling The popups used one Wayland layer surface per output sized to their content (implicitWidth/Height bound to the toast column), so every time a toast was added or removed the surface resized. During that resize the compositor briefly scaled a stale buffer, stretching or squishing the cards mid- transition -- worst with only one or two toasts, where each resize is a larger relative change. Make the surface full-screen and fixed, like the OSD overlay, so adding or removing a toast only changes the content inside it and the surface never resizes. Mask the input region to the toast column so the otherwise- invisible full-screen overlay stays click-through. Co-Authored-By: Claude Opus 4.8 (1M context) --- shell/plugins/notifications/Service.qml | 29 +++++++++++++------------ 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/shell/plugins/notifications/Service.qml b/shell/plugins/notifications/Service.qml index a2f0fcea..10840cf3 100644 --- a/shell/plugins/notifications/Service.qml +++ b/shell/plugins/notifications/Service.qml @@ -787,26 +787,27 @@ Item { readonly property var popupPlacement: NotificationLogic.popupPlacement( service.barPosition, service.barClearance, Style.gapsOut) - anchors { - top: popupWindow.popupPlacement.anchors.top - bottom: popupWindow.popupPlacement.anchors.bottom - left: popupWindow.popupPlacement.anchors.left - right: popupWindow.popupPlacement.anchors.right - } - margins { - top: popupWindow.popupPlacement.margins.top - bottom: popupWindow.popupPlacement.margins.bottom - left: popupWindow.popupPlacement.margins.left - right: popupWindow.popupPlacement.margins.right - } + // Full-screen, fixed-size surface (like the OSD overlay). Adding or + // removing a toast changes only the content inside; the Wayland surface + // never resizes, so the compositor can't briefly scale a stale buffer -- + // which is what stretched/squished the cards during count changes. + anchors { top: true; bottom: true; left: true; right: true } - implicitWidth: popupColumn.implicitWidth - implicitHeight: popupColumn.implicitHeight + // Keep the surface click-through except over the toast column, so the + // rest of the (invisible) full-screen overlay never eats input. + mask: Region { + x: popupColumn.x + y: popupColumn.y + width: popupColumn.width + height: popupColumn.height + } ColumnLayout { id: popupColumn anchors.right: parent.right anchors.top: parent.top + anchors.topMargin: popupWindow.popupPlacement.margins.top + anchors.rightMargin: popupWindow.popupPlacement.margins.right spacing: Style.space(8) Repeater {