mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Merge pull request #298 from Ebullioscopic/bugfix/applemusic
Partial Resolution for Apple Music and Click Open Issues
This commit is contained in:
commit
d7d1d9df83
4 changed files with 115 additions and 35 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,4 +64,5 @@ class DynamicIslandWindow: NSPanel {
|
|||
override var canBecomeMain: Bool {
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue