From 64040bccb9081fe8a211793a1e4af49956a96a43 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Tue, 6 Jan 2026 22:16:57 -0500 Subject: [PATCH] Clipboard: rounded corners are back --- Modules/Panels/Launcher/ClipboardPreview.qml | 7 ++-- Modules/Panels/Launcher/Launcher.qml | 2 +- Shaders/frag/rounded_image.frag | 33 ++++++++++++++----- Shaders/qsb/rounded_image.frag.qsb | Bin 3924 -> 4415 bytes 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Modules/Panels/Launcher/ClipboardPreview.qml b/Modules/Panels/Launcher/ClipboardPreview.qml index c87bc23c8..4723b080d 100644 --- a/Modules/Panels/Launcher/ClipboardPreview.qml +++ b/Modules/Panels/Launcher/ClipboardPreview.qml @@ -117,12 +117,13 @@ Item { spacing: Style.marginS visible: isImageContent && !loadingFullContent && imageDataUrl !== "" - Image { + NImageRounded { id: previewImage Layout.fillWidth: true Layout.fillHeight: true - source: imageDataUrl - fillMode: Image.PreserveAspectFit + radius: Style.marginS + imagePath: imageDataUrl + imageFillMode: Image.PreserveAspectFit } NDivider { diff --git a/Modules/Panels/Launcher/Launcher.qml b/Modules/Panels/Launcher/Launcher.qml index 1a9b2b207..97ff34440 100644 --- a/Modules/Panels/Launcher/Launcher.qml +++ b/Modules/Panels/Launcher/Launcher.qml @@ -981,7 +981,7 @@ SmartPanel { id: imagePreview anchors.fill: parent visible: modelData.isImage && !modelData.displayString - radius: Style.radiusM + radius: Style.radiusXS // Use provider's image revision for reactive updates readonly property int _rev: modelData.provider && modelData.provider.imageRevision ? modelData.provider.imageRevision : 0 diff --git a/Shaders/frag/rounded_image.frag b/Shaders/frag/rounded_image.frag index cf9fde018..796e0b3ee 100644 --- a/Shaders/frag/rounded_image.frag +++ b/Shaders/frag/rounded_image.frag @@ -35,13 +35,6 @@ void main() { // Work in pixel space for accurate rounded rectangle calculation vec2 pixelPos = qt_TexCoord0 * itemSize; - // Calculate distance to rounded rectangle edge (in pixels) - vec2 centerOffset = pixelPos - itemSize * 0.5; - float distance = roundedBoxSDF(centerOffset, itemSize * 0.5, cornerRadius); - - // Create smooth alpha mask for edge with anti-aliasing - float alpha = 1.0 - smoothstep(-0.5, 0.5, distance); - // Calculate UV coordinates based on fill mode vec2 imageUV = qt_TexCoord0; @@ -54,21 +47,38 @@ void main() { // Image.TileHorizontally = 5 // Image.Pad = 6 + // Default: rounded corners on full item + vec2 roundedSize = itemSize; + vec2 roundedCenter = itemSize * 0.5; + if (fillMode == 1) { // PreserveAspectFit float itemAspect = itemSize.x / itemSize.y; float sourceAspect = sourceSize.x / sourceSize.y; + // Calculate actual displayed image size and position + vec2 displayedSize; + vec2 offset; + if (sourceAspect > itemAspect) { // Image is wider than item, letterbox top/bottom + displayedSize = vec2(itemSize.x, itemSize.x / sourceAspect); + offset = vec2(0.0, (itemSize.y - displayedSize.y) * 0.5); imageUV.y = (qt_TexCoord0.y - 0.5) * (sourceAspect / itemAspect) + 0.5; } else { // Image is taller than item, letterbox left/right + displayedSize = vec2(itemSize.y * sourceAspect, itemSize.y); + offset = vec2((itemSize.x - displayedSize.x) * 0.5, 0.0); imageUV.x = (qt_TexCoord0.x - 0.5) * (itemAspect / sourceAspect) + 0.5; } + // Apply rounded corners to displayed image bounds + roundedSize = displayedSize; + roundedCenter = offset + displayedSize * 0.5; + // Make letterbox area transparent if (imageUV.x < 0.0 || imageUV.x > 1.0 || imageUV.y < 0.0 || imageUV.y > 1.0) { - alpha = 0.0; + fragColor = vec4(0.0); + return; } } else if (fillMode == 2) { // PreserveAspectCrop float itemAspect = itemSize.x / itemSize.y; @@ -84,6 +94,13 @@ void main() { } // For Stretch (0) or other modes, use qt_TexCoord0 as-is + // Calculate distance to rounded rectangle edge using the correct bounds + vec2 centerOffset = pixelPos - roundedCenter; + float distance = roundedBoxSDF(centerOffset, roundedSize * 0.5, cornerRadius); + + // Create smooth alpha mask for edge with anti-aliasing + float alpha = 1.0 - smoothstep(-0.5, 0.5, distance); + // Sample the texture vec4 color = texture(source, imageUV); diff --git a/Shaders/qsb/rounded_image.frag.qsb b/Shaders/qsb/rounded_image.frag.qsb index c6144553479a353f56108091482bd8b0cd0969ef..4439aec97663393b50aaef53b32f1151227792b6 100644 GIT binary patch literal 4415 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 literal 3924 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