Merge pull request #14156 from bjarneo/fix/image-picker-hidpi

Keep image picker previews sharp on HiDPI displays
This commit is contained in:
bjarneo authored and GitHub committed 2026-10-03 18:25:39 +02:00
commit 8e02fc84f5
2 files changed
+21 -5

No files matched your search

+6 -4
View File
@@ -603,13 +603,15 @@ Item {
Image {
id: image
anchors.fill: parent
// Even an uncached 6K wallpaper decodes at card size, off the
// GUI thread. Departing cards release their images instead of
// retaining every preview visited in a large collection.
// Decode at the expanded card's physical size, off the GUI
// thread. Keep that size during navigation to avoid reloads.
// Departing cards release their images instead of retaining
// every preview visited in a large collection.
// Queue the selected preview first; neighbors must not delay
// the image the user opened the picker to see.
source: (item.selected || root.neighborImagesEnabled) && item.thumbnailPath ? Util.fileUrl(item.thumbnailPath) : ""
sourceSize: Qt.size(root.expandedWidth, root.expandedHeight)
sourceSize.width: Math.ceil(root.expandedWidth * Screen.devicePixelRatio)
sourceSize.height: Math.ceil(root.expandedHeight * Screen.devicePixelRatio)
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: false
+15 -1
View File
@@ -151,10 +151,24 @@ assert(
)
assert(
/model: visibleImages/.test(imagePickerQml) &&
/sourceSize: Qt\.size\(root\.expandedWidth, root\.expandedHeight\)/.test(imagePickerQml) &&
/asynchronous: true\s*cache: false/.test(imagePickerQml),
'image picker renders its window with bounded asynchronous decoding'
)
const sourceWidth = imagePickerQml.match(/sourceSize\.width: ([^\n]+)/)[1]
const sourceHeight = imagePickerQml.match(/sourceSize\.height: ([^\n]+)/)[1]
const decodeSize = new Function('root', 'Screen', `return [${sourceWidth}, ${sourceHeight}]`)
for (const [scale, expected] of [
[1, [768, 475]],
[1.25, [960, 594]],
[1.5, [1152, 713]],
[2, [1536, 950]]
]) {
assertDeepEqual(
decodeSize({ expandedWidth: 768, expandedHeight: 475 }, { devicePixelRatio: scale }),
expected,
`image picker decodes enough physical pixels at ${scale}x display scale`
)
}
assert(
imagePickerQml.includes('(item.selected || root.neighborImagesEnabled)') &&
/onStatusChanged: if \(item.selected && \(status === Image.Ready \|\| status === Image.Error\)\) root.neighborImagesEnabled = true/.test(imagePickerQml),