BugFix: Hover Fix

This commit is contained in:
Hariharan Mudaliar 2026-03-15 13:00:29 +05:30
commit d172b88349
No known key found for this signature in database
GPG key ID: 025583EB0BE5640E

View file

@ -150,6 +150,7 @@ struct ContentView: View {
@State private var hoverClickMonitor: Any?
@State private var hoverClickLocalMonitor: Any?
@State private var stickyTerminalClickMonitor: Any?
@State private var hiddenEdgeHoverPollingTask: Task<Void, Never>?
@State private var gestureProgress: CGFloat = .zero
@State private var skipGestureActiveDirection: MusicManager.SkipDirection?
@ -286,6 +287,13 @@ struct ContentView: View {
hideNonNotchUntilHover && isNonNotchScreen && vm.notchState == .closed && !isSneakPeekVisibleOnCurrentScreen
}
/// Whether the fallback top-edge hover detector should run.
/// This is only needed when the notch is fully hidden off-screen and
/// regular `.onHover` hit-testing may not trigger reliably.
private var shouldUseHiddenEdgeHoverPolling: Bool {
shouldHideUntilHover && !lockScreenManager.isLocked
}
/// Pill shape for Dynamic Island mode with animated corner radius transitions.
private var currentPillShape: DynamicIslandPillShape {
let radius: CGFloat
@ -535,6 +543,7 @@ struct ContentView: View {
clearMusicControlVisibilityDeadline()
}
enqueueMusicControlWindowSync(forceRefresh: true)
startHiddenEdgeHoverPolling()
}
.onChange(of: vm.notchState) { _, state in
if state == .open {
@ -626,6 +635,7 @@ struct ContentView: View {
hoverTask?.cancel()
stopHoverClickMonitor()
removeStickyTerminalClickMonitor()
stopHiddenEdgeHoverPolling()
cancelMusicControlWindowSync()
hideMusicControlWindow()
cancelMusicControlVisibilityTimer()
@ -1563,6 +1573,48 @@ struct ContentView: View {
}
}
private func hiddenHoverActivationContainsMouse(_ location: NSPoint = NSEvent.mouseLocation) -> Bool {
guard let screen = NSScreen.screens.first(where: { $0.localizedName == currentScreenName }) else {
return false
}
let horizontalPadding: CGFloat = 8
let activationWidth = vm.closedNotchSize.width + horizontalPadding * 2
let activationHeight = max(vm.closedNotchSize.height + zeroHeightHoverPadding, 14)
let activationRect = CGRect(
x: screen.frame.midX - activationWidth / 2,
y: screen.frame.maxY - activationHeight,
width: activationWidth,
height: activationHeight
)
return activationRect.contains(location)
}
private func startHiddenEdgeHoverPolling() {
guard hiddenEdgeHoverPollingTask == nil else { return }
hiddenEdgeHoverPollingTask = Task { @MainActor in
while !Task.isCancelled {
if self.shouldUseHiddenEdgeHoverPolling {
let hovering = self.hiddenHoverActivationContainsMouse()
if hovering != self.isHovering {
self.handleHover(hovering)
}
}
try? await Task.sleep(for: .milliseconds(50))
}
self.hiddenEdgeHoverPollingTask = nil
}
}
private func stopHiddenEdgeHoverPolling() {
hiddenEdgeHoverPollingTask?.cancel()
hiddenEdgeHoverPollingTask = nil
}
private func startHoverClickMonitor() {
guard hoverClickMonitor == nil else { return }