From 3d827c306a780ae4d4a25dcf9c37dc207608c106 Mon Sep 17 00:00:00 2001 From: Jis G Jacob Date: Thu, 12 Mar 2026 22:57:27 +0530 Subject: [PATCH] Atoll: Fix Timers LS Widget overlapping Music Player Signed-off-by: Jis G Jacob --- .../managers/LockScreenPanelManager.swift | 14 +++++++++++++- .../LockScreenTimerWidgetManager.swift | 13 ++++--------- .../LockScreenWidgetPreviewManager.swift | 19 +++++++++---------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/DynamicIsland/managers/LockScreenPanelManager.swift b/DynamicIsland/managers/LockScreenPanelManager.swift index 3dbe0c8..5c5dfa7 100644 --- a/DynamicIsland/managers/LockScreenPanelManager.swift +++ b/DynamicIsland/managers/LockScreenPanelManager.swift @@ -202,6 +202,11 @@ class LockScreenPanelManager { currentAdditionalHeight = additionalHeight } + func notifyTimerWidgetFrameChanged(animated: Bool) { + guard panelWindow?.isVisible == true || panelAnimator.isPresented else { return } + applyOffsetAdjustment(animated: animated) + } + func applyOffsetAdjustment(animated: Bool = true) { guard let screen = currentScreen() else { return } let screenFrame = screen.frame @@ -266,7 +271,14 @@ class LockScreenPanelManager { let defaultLowering: CGFloat = -28 let userOffset = CGFloat(Defaults[.lockScreenMusicVerticalOffset]) let clampedOffset = min(max(userOffset, -160), 160) - let originY = baseOriginY + defaultLowering + clampedOffset + var originY = baseOriginY + defaultLowering + clampedOffset + + if let timerFrame = LockScreenTimerWidgetPanelManager.shared.latestFrame { + let maxAllowedTop = timerFrame.minY - 12 + let maxOriginY = maxAllowedTop - collapsedSize.height + originY = min(originY, maxOriginY) + } + return NSRect(x: originX, y: originY, width: collapsedSize.width, height: collapsedSize.height) } diff --git a/DynamicIsland/managers/LockScreenTimerWidgetManager.swift b/DynamicIsland/managers/LockScreenTimerWidgetManager.swift index ff672f4..0337d89 100644 --- a/DynamicIsland/managers/LockScreenTimerWidgetManager.swift +++ b/DynamicIsland/managers/LockScreenTimerWidgetManager.swift @@ -156,6 +156,7 @@ final class LockScreenTimerWidgetPanelManager { hideTask?.cancel() hideTask = nil animator.isPresented = true + LockScreenPanelManager.shared.notifyTimerWidgetFrameChanged(animated: false) LockScreenReminderWidgetPanelManager.shared.refreshPosition(animated: true) } @@ -169,6 +170,7 @@ final class LockScreenTimerWidgetPanelManager { window.orderOut(nil) hideTask = nil latestFrame = nil + LockScreenPanelManager.shared.notifyTimerWidgetFrameChanged(animated: true) LockScreenReminderWidgetPanelManager.shared.refreshPosition(animated: true) return } @@ -179,6 +181,7 @@ final class LockScreenTimerWidgetPanelManager { window?.orderOut(nil) self?.hideTask = nil self?.latestFrame = nil + LockScreenPanelManager.shared.notifyTimerWidgetFrameChanged(animated: true) LockScreenReminderWidgetPanelManager.shared.refreshPosition(animated: true) } } @@ -264,19 +267,11 @@ final class LockScreenTimerWidgetPanelManager { let size = LockScreenTimerWidget.preferredSize let originX = screen.frame.midX - (size.width / 2) let defaultLowering: CGFloat = -18 - var baseY = screen.frame.midY + 24 + defaultLowering - - if let musicFrame = LockScreenPanelManager.shared.latestFrame { - baseY = musicFrame.maxY + 28 + defaultLowering - } + let baseY = screen.frame.midY + 24 + defaultLowering let offset = CGFloat(clampedTimerOffset()) var originY = baseY + offset - if let musicFrame = LockScreenPanelManager.shared.latestFrame { - originY = max(originY, musicFrame.maxY + 12) - } - if let weatherFrame = LockScreenWeatherPanelManager.shared.latestFrame { originY = min(originY, weatherFrame.minY - size.height - 20) } else { diff --git a/DynamicIsland/managers/LockScreenWidgetPreviewManager.swift b/DynamicIsland/managers/LockScreenWidgetPreviewManager.swift index f5fc25d..9ac2c2a 100644 --- a/DynamicIsland/managers/LockScreenWidgetPreviewManager.swift +++ b/DynamicIsland/managers/LockScreenWidgetPreviewManager.swift @@ -444,7 +444,14 @@ private struct LockScreenPreviewScene: View { let defaultLowering: CGFloat = -28 let userOffset = CGFloat(Defaults[.lockScreenMusicVerticalOffset]) let clampedOffset = min(max(userOffset, -160), 160) - let originY = baseOriginY + defaultLowering + clampedOffset + var originY = baseOriginY + defaultLowering + clampedOffset + + if showsTimer { + let maxAllowedTop = timerFrame.minY - 12 + let maxOriginY = maxAllowedTop - size.height + originY = min(originY, maxOriginY) + } + return CGRect(x: originX, y: originY, width: size.width, height: size.height) } @@ -453,19 +460,11 @@ private struct LockScreenPreviewScene: View { let screenFrame = CGRect(origin: .zero, size: screenSize) let originX = screenFrame.midX - (size.width / 2) let defaultLowering: CGFloat = -18 - var baseY = screenFrame.midY + 24 + defaultLowering - - if showsMediaPanel { - baseY = mediaFrame.maxY + 28 + defaultLowering - } + let baseY = screenFrame.midY + 24 + defaultLowering let offset = CGFloat(min(max(Defaults[.lockScreenTimerVerticalOffset], -160), 160)) var originY = baseY + offset - if showsMediaPanel { - originY = max(originY, mediaFrame.maxY + 12) - } - if showsWeather { originY = min(originY, weatherFrame.minY - size.height - 20) } else {