mirror of
https://github.com/lwouis/alt-tab-macos.git
synced 2026-05-24 11:20:36 +00:00
fix: rare crash when scrolling some settings window views
This commit is contained in:
@@ -6,38 +6,32 @@ class ForwardingVerticalScrollView: NSScrollView {
|
||||
}
|
||||
|
||||
override func scrollWheel(with event: NSEvent) {
|
||||
let before = contentView.bounds.origin
|
||||
super.scrollWheel(with: event)
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self, self.shouldForwardToParent(event, before) else { return }
|
||||
self.parentScrollView()?.scrollWheel(with: event)
|
||||
guard isVerticalScroll(event) else {
|
||||
super.scrollWheel(with: event)
|
||||
return
|
||||
}
|
||||
let bounds = contentView.bounds
|
||||
let y = bounds.origin.y
|
||||
// Ask AppKit for the actual valid scroll range (accounts for headers, insets, etc.)
|
||||
let minY = contentView.constrainBoundsRect(NSRect(x: bounds.origin.x, y: -1e9, width: bounds.width, height: bounds.height)).origin.y
|
||||
let maxY = contentView.constrainBoundsRect(NSRect(x: bounds.origin.x, y: 1e9, width: bounds.width, height: bounds.height)).origin.y
|
||||
let canScrollUp = y > minY + 0.5
|
||||
let canScrollDown = y < maxY - 0.5
|
||||
// scrollingDeltaY > 0 → scroll up (y decreases); < 0 → scroll down (y increases)
|
||||
let wantsUp = event.scrollingDeltaY > 0
|
||||
let wantsDown = event.scrollingDeltaY < 0
|
||||
let shouldForward = (wantsUp && !canScrollUp) || (wantsDown && !canScrollDown)
|
||||
if shouldForward {
|
||||
parentScrollView()?.scrollWheel(with: event)
|
||||
} else {
|
||||
super.scrollWheel(with: event)
|
||||
}
|
||||
}
|
||||
|
||||
private func shouldForwardToParent(_ event: NSEvent, _ before: CGPoint) -> Bool {
|
||||
guard isVerticalScroll(event) else { return false }
|
||||
guard abs(contentView.bounds.origin.y - before.y) < 0.01 else { return false }
|
||||
return isAtVerticalBoundary(event)
|
||||
}
|
||||
|
||||
private func isVerticalScroll(_ event: NSEvent) -> Bool {
|
||||
abs(event.scrollingDeltaY) > abs(event.scrollingDeltaX) && abs(event.scrollingDeltaY) > 0.1
|
||||
}
|
||||
|
||||
private func isAtVerticalBoundary(_ event: NSEvent) -> Bool {
|
||||
guard let content = documentView else { return false }
|
||||
let visible = contentView.documentVisibleRect
|
||||
let dy = normalizedVerticalDelta(event)
|
||||
if dy > 0 { return visible.minY <= content.bounds.minY + 0.5 }
|
||||
if dy < 0 { return visible.maxY >= content.bounds.maxY - 0.5 }
|
||||
return false
|
||||
}
|
||||
|
||||
private func normalizedVerticalDelta(_ event: NSEvent) -> CGFloat {
|
||||
let delta = event.hasPreciseScrollingDeltas ? event.scrollingDeltaY : event.deltaY
|
||||
return event.isDirectionInvertedFromDevice ? -delta : delta
|
||||
}
|
||||
|
||||
private func parentScrollView() -> NSScrollView? {
|
||||
var parent = superview
|
||||
while let view = parent {
|
||||
|
||||
@@ -135,6 +135,7 @@ class ExceptionsView: ForwardingVerticalScrollView {
|
||||
borderType = .noBorder
|
||||
hasHorizontalScroller = false
|
||||
hasVerticalScroller = true
|
||||
verticalScrollElasticity = .none
|
||||
usesPredominantAxisScrolling = true
|
||||
documentView = TableView(nil)
|
||||
fit(width, height)
|
||||
|
||||
@@ -299,6 +299,7 @@ class ControlsTab {
|
||||
rowsScrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||
rowsScrollView.drawsBackground = false
|
||||
rowsScrollView.hasVerticalScroller = true
|
||||
rowsScrollView.verticalScrollElasticity = .none
|
||||
rowsScrollView.hasHorizontalScroller = false
|
||||
rowsScrollView.scrollerStyle = .overlay
|
||||
rowsScrollView.usesPredominantAxisScrolling = true
|
||||
|
||||
Reference in New Issue
Block a user