Merge pull request #298 from Ebullioscopic/bugfix/applemusic

Partial Resolution for Apple Music and Click Open Issues
This commit is contained in:
Hariharan Mudaliar 2026-02-16 15:34:19 +05:30 • committed by GitHub
commit d7d1d9df83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 115 additions and 35 deletions

View file

@ -126,6 +126,7 @@ struct ContentView: View {
@State private var hoverTask: Task<Void, Never>?
@State private var isHovering: Bool = false
@State private var lastHapticTime: Date = Date()
@State private var hoverClickMonitor: Any?
@State private var gestureProgress: CGFloat = .zero
@State private var skipGestureActiveDirection: MusicManager.SkipDirection?
@ -271,6 +272,7 @@ struct ContentView: View {
}
.conditionalModifier(interactionsEnabled) { view in
view
.contentShape(currentNotchShape)
.onHover { hovering in
handleHover(hovering)
}
@ -389,12 +391,13 @@ struct ContentView: View {
// #endif
// .keyboardShortcut("E", modifiers: .command)
}
}
.frame(
maxWidth: dynamicNotchSize.width,
maxHeight: dynamicNotchSize.height + currentShadowPadding,
alignment: .top
)
.frame(
maxWidth: dynamicNotchSize.width,
maxHeight: dynamicNotchSize.height + currentShadowPadding,
alignment: .top
)
.environmentObject(privacyManager)
.onChange(of: dynamicNotchSize) { oldSize, newSize in
guard oldSize != newSize else { return }
@ -424,6 +427,7 @@ struct ContentView: View {
releaseMusicControlWindowUpdates(after: musicControlResumeDelay)
enqueueMusicControlWindowSync(forceRefresh: true, delay: 0.05)
}
}
.onChange(of: musicControlWindowEnabled) { _, enabled in
if enabled {
@ -502,6 +506,7 @@ struct ContentView: View {
}
.onDisappear {
hoverTask?.cancel()
stopHoverClickMonitor()
cancelMusicControlWindowSync()
hideMusicControlWindow()
cancelMusicControlVisibilityTimer()
@ -1430,12 +1435,40 @@ struct ContentView: View {
}
}
private func startHoverClickMonitor() {
guard hoverClickMonitor == nil else { return }
hoverClickMonitor = NSEvent.addGlobalMonitorForEvents(matching: [.leftMouseDown]) { _ in
Task { @MainActor in
guard !lockScreenManager.isLocked else { return }
guard vm.notchState == .closed else { return }
guard isHovering else { return }
if Defaults[.enableHaptics] {
triggerHapticIfAllowed()
}
openNotch()
}
}
}
private func stopHoverClickMonitor() {
if let hoverClickMonitor {
NSEvent.removeMonitor(hoverClickMonitor)
self.hoverClickMonitor = nil
}
}
// MARK: - Hover Management
/// Handle hover state changes with debouncing
private func handleHover(_ hovering: Bool) {
hoverTask?.cancel()
if hovering {
startHoverClickMonitor()
} else {
stopHoverClickMonitor()
}
if hovering {
withAnimation(.bouncy.speed(1.2)) {
isHovering = true

View file

@ -79,6 +79,12 @@ struct DynamicNotchApp: App {
}
}
final class FirstMouseHostingView<Content: View>: NSHostingView<Content> {
override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
true
}
}
extension AppDelegate {
static var shared: AppDelegate? {
NSApplication.shared.delegate as? AppDelegate
@ -223,7 +229,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
window.animationBehavior = .none
window.contentView = NSHostingView(
window.contentView = FirstMouseHostingView(
rootView: ContentView()
.environmentObject(viewModel)
.environmentObject(webcamManager)

View file

@ -145,38 +145,78 @@ class AppleMusicController: MediaControllerProtocol {
}
private func fetchPlaybackInfoAsync() async throws -> NSAppleEventDescriptor? {
let script = """
tell application "Music"
set isRunning to true
try
set playerState to player state is playing
set currentTrackName to name of current track
set currentTrackArtist to artist of current track
set currentTrackAlbum to album of current track
set trackPosition to player position
set trackDuration to duration of current track
set shuffleState to shuffle enabled
set repeatState to song repeat
if repeatState is off then
set repeatValue to 1
else if repeatState is one then
set repeatValue to 2
else if repeatState is all then
set repeatValue to 3
end if
if #available(macOS 26.0, *) {
let script = """
tell application "Music"
try
set artData to data of artwork 1 of current track
on error
set artData to ""
end try
return {playerState, currentTrackName, currentTrackArtist, currentTrackAlbum, trackPosition, trackDuration, shuffleState, repeatValue, artData}
on error
return {false, "Not Playing", "Unknown", "Unknown", 0, 0, false, 0, ""}
end try
end tell
"""
set playerState to player state is playing
set currentTrackName to name of current track
set currentTrackArtist to artist of current track
set currentTrackAlbum to album of current track
set trackPosition to player position
set trackDuration to duration of current track
set shuffleState to shuffle enabled
set repeatState to song repeat
if repeatState is off then
set repeatValue to 1
else if repeatState is one then
set repeatValue to 2
else if repeatState is all then
set repeatValue to 3
end if
return try await AppleScriptHelper.execute(script)
set artData to ""
try
set libraryTrack to first track of playlist "Library" whose name is currentTrackName and artist is currentTrackArtist
set artData to data of artwork 1 of libraryTrack
on error
try
set artData to data of artwork 1 of current track
on error
set artData to ""
end try
end try
return {playerState, currentTrackName, currentTrackArtist, currentTrackAlbum, trackPosition, trackDuration, shuffleState, repeatValue, artData}
on error
return {false, "Not Playing", "Unknown", "Unknown", 0, 0, false, 0, ""}
end try
end tell
"""
return try await AppleScriptHelper.execute(script)
} else {
let script = """
tell application "Music"
set isRunning to true
try
set playerState to player state is playing
set currentTrackName to name of current track
set currentTrackArtist to artist of current track
set currentTrackAlbum to album of current track
set trackPosition to player position
set trackDuration to duration of current track
set shuffleState to shuffle enabled
set repeatState to song repeat
if repeatState is off then
set repeatValue to 1
else if repeatState is one then
set repeatValue to 2
else if repeatState is all then
set repeatValue to 3
end if
try
set artData to data of artwork 1 of current track
on error
set artData to ""
end try
return {playerState, currentTrackName, currentTrackArtist, currentTrackAlbum, trackPosition, trackDuration, shuffleState, repeatValue, artData}
on error
return {false, "Not Playing", "Unknown", "Unknown", 0, 0, false, 0, ""}
end try
end tell
"""
return try await AppleScriptHelper.execute(script)
}
}
}

View file

@ -64,4 +64,5 @@ class DynamicIslandWindow: NSPanel {
override var canBecomeMain: Bool {
true
}
}