diff --git a/src/api-wrappers/HelperExtensions.swift b/src/api-wrappers/HelperExtensions.swift index f40bb301..0f289482 100644 --- a/src/api-wrappers/HelperExtensions.swift +++ b/src/api-wrappers/HelperExtensions.swift @@ -2,6 +2,24 @@ import Cocoa import Darwin import Carbon.HIToolbox.Events +class NoAnimationDelegate: NSObject, CALayerDelegate { + static let shared = NoAnimationDelegate() + func action(for layer: CALayer, forKey event: String) -> (any CAAction)? { NSNull() } +} + +func noAnimation(_ make: () -> T) -> T { + let layer = make() + layer.delegate = NoAnimationDelegate.shared + return layer +} + +func caTransaction(_ body: () -> Void) { + CATransaction.begin() + defer { CATransaction.commit() } + CATransaction.setDisableActions(true) + body() +} + extension NSAppearance { func getThemeName() -> AppearanceThemePreference { if #available(macOS 10.14, *) { diff --git a/src/ui/generic-components/LightImageView.swift b/src/ui/generic-components/LightImageView.swift index de7eee4d..f7f7a493 100644 --- a/src/ui/generic-components/LightImageView.swift +++ b/src/ui/generic-components/LightImageView.swift @@ -22,13 +22,7 @@ class LightImageView: NSView { layer!.minificationFilter = .trilinear layer!.minificationFilterBias = 0.0 layer!.shouldRasterize = false - // disable implicit animations - layer!.actions = [ - "contents": NSNull(), - "bounds": NSNull(), - "position": NSNull(), - "contentsScale": NSNull() - ] + layer!.delegate = NoAnimationDelegate.shared layerContentsRedrawPolicy = .never setupOutlineLayer() setupHandRaisedLayer() diff --git a/src/ui/main-window/ThumbnailView.swift b/src/ui/main-window/ThumbnailView.swift index 16e4258a..8fd1ac7e 100644 --- a/src/ui/main-window/ThumbnailView.swift +++ b/src/ui/main-window/ThumbnailView.swift @@ -146,8 +146,6 @@ class ThumbnailView: FlippedView { let shouldShow = shouldShowWindowControls && !Preferences.hideColoredCircles && !Appearance.hideThumbnails guard isShowingWindowControls != shouldShow else { return } isShowingWindowControls = shouldShow - CATransaction.begin() - CATransaction.setDisableActions(true) for icon in windowControlIcons { let shouldHide = !shouldShow || (icon.type == .quit && !(window_?.application.canBeQuit() ?? true)) @@ -159,7 +157,6 @@ class ThumbnailView: FlippedView { icon.needsDisplay = true } } - CATransaction.commit() } diff --git a/src/ui/main-window/ThumbnailsPanel.swift b/src/ui/main-window/ThumbnailsPanel.swift index 7a7c1faa..05d7b94a 100644 --- a/src/ui/main-window/ThumbnailsPanel.swift +++ b/src/ui/main-window/ThumbnailsPanel.swift @@ -33,14 +33,13 @@ class ThumbnailsPanel: NSPanel { } func updateContents() { - CATransaction.begin() - defer { CATransaction.commit() } - CATransaction.setDisableActions(true) - thumbnailsView.updateItemsAndLayout() - guard App.app.appIsBeingUsed else { return } - setContentSize(thumbnailsView.contentView.frame.size) - guard App.app.appIsBeingUsed else { return } - NSScreen.preferred.repositionPanel(self) + caTransaction { + thumbnailsView.updateItemsAndLayout() + guard App.app.appIsBeingUsed else { return } + setContentSize(thumbnailsView.contentView.frame.size) + guard App.app.appIsBeingUsed else { return } + NSScreen.preferred.repositionPanel(self) + } } override func orderOut(_ sender: Any?) { diff --git a/src/ui/main-window/ThumbnailsView.swift b/src/ui/main-window/ThumbnailsView.swift index 6e893998..d7b6f8ec 100644 --- a/src/ui/main-window/ThumbnailsView.swift +++ b/src/ui/main-window/ThumbnailsView.swift @@ -291,8 +291,10 @@ class ScrollView: NSScrollView { } override func mouseExited(with event: NSEvent) { - previousTarget = nil - resetHoveredWindow() + caTransaction { + previousTarget = nil + resetHoveredWindow() + } } override func mouseMoved(with event: NSEvent) { @@ -300,16 +302,15 @@ class ScrollView: NSScrollView { let location = documentView.convert(App.app.thumbnailsPanel.mouseLocationOutsideOfEventStream, from: nil) let newTarget = findTarget(location) guard newTarget !== previousTarget else { return } - CATransaction.begin() - CATransaction.setDisableActions(true) - if let newTarget { - previousTarget?.showOrHideWindowControls(false) - newTarget.mouseMoved() - } else { - resetHoveredWindow() + caTransaction { + if let newTarget { + previousTarget?.showOrHideWindowControls(false) + newTarget.mouseMoved() + } else { + resetHoveredWindow() + } + previousTarget = newTarget } - previousTarget = newTarget - CATransaction.commit() } private func findTarget(_ location: NSPoint) -> ThumbnailView? {