diff --git a/DockDoor/Utilities/WindowUtil.swift b/DockDoor/Utilities/WindowUtil.swift index 7776572b..c1f2364e 100644 --- a/DockDoor/Utilities/WindowUtil.swift +++ b/DockDoor/Utilities/WindowUtil.swift @@ -76,9 +76,10 @@ final class WindowUtil { // Configure the stream to capture only the window content config.scalesToFit = false + config.backgroundColor = .clear config.ignoreGlobalClipDisplay = true config.ignoreShadowsDisplay = true - config.shouldBeOpaque = true + config.shouldBeOpaque = false if #available(macOS 14.2, *) { config.includeChildWindows = false } config.width = Int(window.frame.width) config.height = Int(window.frame.height) diff --git a/DockDoor/Views/Hover Window/HoverWindow.swift b/DockDoor/Views/Hover Window/HoverWindow.swift index 14a8d46c..8b4cb630 100644 --- a/DockDoor/Views/Hover Window/HoverWindow.swift +++ b/DockDoor/Views/Hover Window/HoverWindow.swift @@ -264,6 +264,8 @@ struct HoverView: View { let dockPosition: DockPosition let bestGuessMonitor: NSScreen + @Default(.uniformCardRadius) var uniformCardRadius + @State private var showWindows: Bool = false @State private var hasAppeared: Bool = false @State private var appIcon: NSImage? = nil @@ -304,7 +306,7 @@ struct HoverView: View { ForEach(activeWindows.indices, id: \.self) { index in WindowPreview(windowInfo: activeWindows[index], onTap: onWindowTap, index: index, dockPosition: dockPosition, maxWindowDimension: maxWindowDimension, - bestGuessMonitor: bestGuessMonitor) + bestGuessMonitor: bestGuessMonitor, uniformCardRadius: uniformCardRadius) .id("\(appName)-\(index)") } } @@ -401,7 +403,8 @@ struct HoverView: View { index: index, dockPosition: dockPosition, maxWindowDimension: maxWindowDimension, - bestGuessMonitor: bestGuessMonitor + bestGuessMonitor: bestGuessMonitor, + uniformCardRadius: true // force it to be rounded, since these have no image previews ) } } diff --git a/DockDoor/Views/Hover Window/WindowPreview.swift b/DockDoor/Views/Hover Window/WindowPreview.swift index 61127cb2..155c8ffc 100644 --- a/DockDoor/Views/Hover Window/WindowPreview.swift +++ b/DockDoor/Views/Hover Window/WindowPreview.swift @@ -16,6 +16,7 @@ struct WindowPreview: View { let dockPosition: DockPosition let maxWindowDimension: CGPoint let bestGuessMonitor: NSScreen + let uniformCardRadius: Bool @State private var isHovering = false @State private var isHoveringOverTabMenu = false @@ -43,6 +44,16 @@ struct WindowPreview: View { return CGSize(width: targetWidth, height: targetHeight) } + private func fluidGradient() -> some View { + FluidGradient( + blobs: [.purple, .blue, .green, .yellow, .red, .purple].shuffled(), + highlights: [.red, .orange, .pink, .blue, .purple].shuffled(), + speed: 0.45, + blur: 0.75 + ) + .opacity(0.125) + } + private func windowContent(isMinimized: Bool, isHidden: Bool, isSelected: Bool) -> some View { Group { if isMinimized || isHidden { @@ -72,17 +83,12 @@ struct WindowPreview: View { .padding() .frame(width: width) .frame(height: 60) + .overlay { if isSelected { fluidGradient() }} } else if let cgImage = windowInfo.image { - Image(decorative: cgImage, scale: 1.0) - .resizable() - .aspectRatio(contentMode: .fill) + let image = Image(decorative: cgImage, scale: 1.0).resizable().aspectRatio(contentMode: .fill) + image.overlay(!isSelected ? nil : fluidGradient().mask(image)) } } - .overlay { if isSelected { FluidGradient(blobs: [.purple, .blue, .green, .yellow, .red, .purple].shuffled(), - highlights: [.red, .orange, .pink, .blue, .purple].shuffled(), - speed: 0.45, - blur: 0.75).opacity(0.125) - }} .frame(width: isMinimized || isHidden ? nil : calculatedSize.width, height: isMinimized || isHidden ? nil : calculatedSize.height, alignment: .center) @@ -97,12 +103,12 @@ struct WindowPreview: View { VStack(spacing: 0) { windowContent(isMinimized: windowInfo.isMinimized, isHidden: windowInfo.isHidden, isSelected: selected) .overlay { Color.white.opacity(isHoveringOverTabMenu ? 0.1 : 0) } - .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) .shadow(radius: selected || isHoveringOverTabMenu ? 0 : 3) .background { RoundedRectangle(cornerRadius: 6, style: .continuous) .fill(Color.clear.shadow(.drop(color: .black.opacity(selected ? 0.35 : 0.25), radius: selected ? 12 : 8, y: selected ? 6 : 4))) } + .clipShape(uniformCardRadius ? AnyShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) : AnyShape(Rectangle())) } .overlay(alignment: .bottomLeading) { if selected, let windowTitle = windowInfo.window?.title, !windowTitle.isEmpty, windowTitle != windowInfo.appName { @@ -195,7 +201,7 @@ struct WindowPreview: View { .contentShape(Rectangle()) .onHover { over in withAnimation(.snappy(duration: 0.175)) { - if !CurrentWindow.shared.showingTabMenu { + if (!CurrentWindow.shared.showingTabMenu) { isHovering = over } else { isHoveringOverTabMenu = over @@ -203,9 +209,9 @@ struct WindowPreview: View { } } .onTapGesture { - if windowInfo.isMinimized { + if (windowInfo.isMinimized) { WindowUtil.toggleMinimize(windowInfo: windowInfo) - } else if windowInfo.isHidden { + } else if (windowInfo.isHidden) { WindowUtil.toggleHidden(windowInfo: windowInfo) } else { WindowUtil.bringWindowToFront(windowInfo: windowInfo) diff --git a/DockDoor/Views/Settings/SettingsView.swift b/DockDoor/Views/Settings/SettingsView.swift index 729f2f64..afefcd76 100644 --- a/DockDoor/Views/Settings/SettingsView.swift +++ b/DockDoor/Views/Settings/SettingsView.swift @@ -14,6 +14,7 @@ struct SettingsView: View { @Default(.screenCaptureCacheLifespan) var screenCaptureCacheLifespan @Default(.showAnimations) var showAnimations @Default(.showMenuBarIcon) var showMenuBarIcon + @Default(.uniformCardRadius) var uniformCardRadius var body: some View { VStack(alignment: .leading, spacing: 10) { @@ -31,6 +32,10 @@ struct SettingsView: View { Text("Enable Hover Window Sliding Animation") }) + Toggle(isOn: $uniformCardRadius, label: { + Text("Use Uniform Image Preview Radius") + }) + Toggle(isOn: $showMenuBarIcon, label: { Text("Show Menu Bar Icon") }) diff --git a/DockDoor/consts.swift b/DockDoor/consts.swift index 62e434d0..bd55d0bc 100644 --- a/DockDoor/consts.swift +++ b/DockDoor/consts.swift @@ -18,7 +18,10 @@ extension Defaults.Keys { static let sizingMultiplier = Key("sizingMultiplier") { 3 } static let windowPadding = Key("windowPadding") { 0 } static let openDelay = Key("openDelay") { 0 } + static let screenCaptureCacheLifespan = Key("screenCaptureCacheLifespan") { 60 } + static let uniformCardRadius = Key("uniformCardRadius") { true } + static let showAnimations = Key("showAnimations") { true } static let enableWindowSwitcher = Key("enableWindowSwitcher"){ true } static let showMenuBarIcon = Key("showMenuBarIcon", default: true)