feat: improve quality of thumbnails and performance

This commit is contained in:
lwouis committed 2025-01-02 19:28:34 +01:00
1 parent b51ff6583d
commit a138a922ef
6 files changed
+29 -15

No files matched your search

+11
View File
@@ -199,6 +199,17 @@ extension DispatchQoS {
}
}
extension NSImageView {
func setSize(_ size: NSSize) {
frame.size = size
// TODO: NSImageView does some internal magic, and ends up with constraints. We need to add our own to force its size
// We can't update .image.size because we share the image between multiple NSImageViews
// I wish there was a better way to only set the frame.size
addOrUpdateConstraint(widthAnchor, size.width)
addOrUpdateConstraint(heightAnchor, size.height)
}
}
extension NSImage {
// NSImage(named) caches/reuses NSImage objects; we force separate instances of images by using copy()
static func initCopy(_ name: String) -> NSImage {
+5 -3
View File
@@ -7,6 +7,7 @@ class Window {
var creationOrder = Int.zero
var title: String!
var thumbnail: NSImage?
var thumbnailFullSize: NSSize?
var icon: NSImage? { get { application.icon } }
var shouldShowTheUser = true
var isTabbed: Bool = false
@@ -98,6 +99,7 @@ class Window {
func refreshThumbnail(_ screenshot: NSImage?) {
thumbnail = screenshot
thumbnailFullSize = screenshot?.size
if App.app.appIsBeingUsed && shouldShowTheUser {
if let index = (Windows.list.firstIndex { $0.cgWindowId == cgWindowId }) {
let view = ThumbnailsView.recycledViews[index]
@@ -111,9 +113,9 @@ class Window {
}
}
func getPreview() -> NSImage? {
if let cgImage = cgWindowId?.screenshot(true) {
return NSImage.fromCgImage(cgImage)
func getPreview() -> (NSImage, NSSize)? {
if let thumbnail = thumbnail, let thumbnailFullSize = thumbnailFullSize {
return (thumbnail, thumbnailFullSize)
}
return nil
}
+2 -2
View File
@@ -153,14 +153,14 @@ class Windows {
App.app.appIsBeingUsed && App.app.thumbnailsPanel.isKeyWindow,
let window = focusedWindow(),
let id = window.cgWindowId,
let preview = window.getPreview(),
let (preview, previewSize) = window.getPreview(),
let position = window.position,
let size = window.size
else {
App.app.previewPanel.orderOut(nil)
return
}
App.app.previewPanel.show(id, preview, position, size)
App.app.previewPanel.show(id, preview, previewSize, position, size)
}
static func voiceOverWindow(_ windowIndex: Int = focusedWindowIndex) {
+1 -1
View File
@@ -252,7 +252,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
func refreshOpenUi(_ windowsToScreenshot: [Window], skipUpdatesBeforeShowing: Bool = false, onlyUpdateScreenshots: Bool = false) {
if !Appearance.hideThumbnails && !windowsToScreenshot.isEmpty {
Windows.refreshThumbnails(windowsToScreenshot, false, onlyUpdateScreenshots)
Windows.refreshThumbnails(windowsToScreenshot, true, onlyUpdateScreenshots)
return
}
guard appIsBeingUsed else { return }
+2 -1
View File
@@ -25,9 +25,10 @@ class PreviewPanel: NSPanel {
setAccessibilitySubrole(.unknown)
}
func show(_ id: CGWindowID, _ preview: NSImage, _ position: CGPoint, _ size: CGSize) {
func show(_ id: CGWindowID, _ preview: NSImage, _ previewSize: NSSize, _ position: CGPoint, _ size: CGSize) {
if id != currentId {
previewView.image = preview
previewView.image!.size = previewSize
var frame = NSRect(origin: position, size: size)
// Flip Y coordinate from Quartz (0,0 at bottom-left) to Cocoa coordinates (0,0 at top-left)
// Always use the primary screen as reference since all coordinates are relative to it
+8 -8
View File
@@ -159,11 +159,14 @@ class ThumbnailView: FlippedView {
private func setupSharedSubiews() {
let shadow = ThumbnailView.makeShadow(Appearance.imageShadowColor)
thumbnail.imageScaling = .scaleProportionallyUpOrDown
thumbnail.shadow = shadow
windowlessIcon.translatesAutoresizingMaskIntoConstraints = false
windowlessIcon.imageScaling = .scaleProportionallyUpOrDown
windowlessIcon.toolTip = ThumbnailView.noOpenWindowToolTip
windowlessIcon.shadow = shadow
appIcon.translatesAutoresizingMaskIntoConstraints = false
appIcon.imageScaling = .scaleProportionallyUpOrDown
appIcon.shadow = shadow
appIcon.setSubviewAbove(dockLabelIcon)
label.fixHeight()
@@ -340,8 +343,8 @@ class ThumbnailView: FlippedView {
if appIconChanged || dockLabelChanged {
setAccessibilityHelp(getAccessibilityHelp(element.application.runningApplication.localizedName, element.dockLabel))
}
if element.isWindowlessApp {
windowlessIcon.image = appIcon.image!.copy() as? NSImage
if element.isWindowlessApp && windowlessIcon.image != element.icon {
windowlessIcon.image = element.icon
}
windowControlIcons.forEach { $0.window_ = element }
showOrHideWindowControls(false)
@@ -353,19 +356,16 @@ class ThumbnailView: FlippedView {
if Preferences.appearanceStyle == .thumbnails {
if !thumbnail.isHidden {
let thumbnailSize = ThumbnailView.thumbnailSize(thumbnail.image, screen, false)
thumbnail.image?.size = thumbnailSize
thumbnail.frame.size = thumbnailSize
thumbnail.setSize(thumbnailSize)
}
if !windowlessIcon.isHidden {
let windowlessIconSize = ThumbnailView.thumbnailSize(windowlessIcon.image, screen, true)
windowlessIcon.image!.size = windowlessIconSize
windowlessIcon.frame.size = windowlessIconSize
windowlessIcon.setSize(windowlessIconSize)
}
}
setFrameWidthHeight(screen, newHeight)
let appIconSize = ThumbnailView.iconSize(screen)
appIcon.image?.size = appIconSize
appIcon.frame.size = appIconSize
appIcon.setSize(appIconSize)
if Preferences.appearanceStyle == .appIcons {
vStackView.frame.size = NSSize(width: frame.width, height: appIcon.frame.height + Appearance.edgeInsetsSize * 2)
hStackView.frame.size = NSSize(width: appIcon.frame.width, height: appIcon.frame.height)