// // DesktopIconManager.swift // ScreenShot // // Created by [Your Name/AI] on [Current Date]. // Copyright © 2025 [Your Name/AI]. All rights reserved. // import Foundation import ScreenCaptureKit @available(macOS 12.3, *) class DesktopIconManager { static let shared = DesktopIconManager() private init() { // Private constructor for singleton } func logFinderWindowDetails(windows: [SCWindow]) { NSLog("🕵️‍♂️ DesktopIconManager: Logging details for Finder windows...") let finderWindows = windows.filter { $0.owningApplication?.bundleIdentifier == "com.apple.finder" } if finderWindows.isEmpty { NSLog("🕵️‍♂️ No Finder windows found in the provided list.") return } NSLog("🕵️‍♂️ Found \(finderWindows.count) Finder windows:") for (index, window) in finderWindows.enumerated() { let appName = window.owningApplication?.applicationName ?? "Unknown" let bundleID = window.owningApplication?.bundleIdentifier ?? "Unknown" NSLog(" --------------------------------------------------") NSLog(" 🕵️‍♂️ Finder Window [\(index)] Details:") NSLog(" --------------------------------------------------") NSLog(" Title: '\(window.title ?? "N/A")'") NSLog(" App Name: \(appName)") NSLog(" Bundle ID: \(bundleID)") NSLog(" Window ID: \(window.windowID)") NSLog(" Layer: \(window.windowLayer)") NSLog(" Frame (SCK Coords): \(NSStringFromRect(window.frame))") NSLog(" Is OnScreen: \(window.isOnScreen)") if #available(macOS 13.1, *) { NSLog(" Is Active: \(window.isActive)") } else { NSLog(" Is Active: (N/A on this macOS version)") } NSLog(" --------------------------------------------------") } } /// Checks if desktop icon hiding is currently enabled in user settings /// - Returns: true if desktop icons should be hidden during screenshots func isDesktopIconHidingEnabled() -> Bool { return SettingsManager.shared.hideDesktopIconsDuringScreenshot } /// Checks if desktop widget hiding is currently enabled in user settings /// - Returns: true if desktop widgets should be hidden during screenshots func isDesktopWidgetHidingEnabled() -> Bool { return SettingsManager.shared.hideDesktopWidgetsDuringScreenshot } /// Detects desktop widgets from available windows /// This function identifies widgets based on various criteria such as bundle identifiers and window characteristics /// - Parameter windows: Array of SCWindow objects to analyze /// - Returns: Array of SCWindow objects that are likely desktop widgets func detectDesktopWidgets(from windows: [SCWindow]) -> [SCWindow] { guard isDesktopWidgetHidingEnabled() else { NSLog("🔄 DesktopIconManager: Widget hiding is disabled, returning empty array") return [] } NSLog("🔍 DesktopIconManager: Starting widget detection...") var potentialWidgets: [SCWindow] = [] // Known widget bundle identifiers (based on research) let knownWidgetBundleIdentifiers = [ "com.apple.controlcenter", "com.apple.notificationcenter", "com.apple.dashboard", "com.apple.widget", "com.apple.WidgetKit", "com.apple.widgets" ] // Widget-like window characteristics let widgetWindowTitles = [ "Widget", "Dashboard", "Control Center", "Notification", "Today" ] for window in windows { let bundleId = window.owningApplication?.bundleIdentifier ?? "" let appName = window.owningApplication?.applicationName ?? "" let windowTitle = window.title ?? "" let windowLayer = window.windowLayer var isWidget = false var detectionReason = "" // Check 1: Known widget bundle identifiers if knownWidgetBundleIdentifiers.contains(where: { bundleId.contains($0) }) { isWidget = true detectionReason = "Known widget bundle ID: \(bundleId)" } // Check 2: Widget-like window titles if !isWidget && widgetWindowTitles.contains(where: { windowTitle.contains($0) }) { isWidget = true detectionReason = "Widget-like window title: '\(windowTitle)'" } // Check 3: Window layer characteristics (widgets often appear on specific layers) // Widgets may appear on desktop-level layers (often higher than normal windows) if !isWidget && windowLayer > 25 && windowLayer < 1000 { // Additional checks for this layer range if appName.lowercased().contains("widget") || bundleId.lowercased().contains("widget") || windowTitle.lowercased().contains("widget") { isWidget = true detectionReason = "High window layer (\(windowLayer)) with widget-related naming" } } // Check 4: Window size characteristics (many widgets are small, square-ish windows) let frame = window.frame if !isWidget && frame.width > 0 && frame.height > 0 { let aspectRatio = frame.width / frame.height let area = frame.width * frame.height // Small to medium sized windows with square-ish aspect ratios if area < 50000 && aspectRatio >= 0.5 && aspectRatio <= 2.0 { if bundleId.contains("apple") && ( windowTitle.isEmpty || windowTitle.count < 3 || bundleId.contains("notification") || bundleId.contains("control") ) { isWidget = true detectionReason = "Small Apple window with widget characteristics (area: \(Int(area)), ratio: \(String(format: "%.2f", aspectRatio)))" } } } if isWidget { potentialWidgets.append(window) NSLog("📱 Widget detected: \(detectionReason)") NSLog(" App: \(appName) (\(bundleId))") NSLog(" Title: '\(windowTitle)'") NSLog(" Layer: \(windowLayer)") NSLog(" Frame: \(NSStringFromRect(frame))") } } NSLog("🔍 DesktopIconManager: Found \(potentialWidgets.count) potential desktop widgets") return potentialWidgets } /// Legacy placeholder for future window filtering functionality /// Note: The main desktop icon filtering logic is now handled in ScreenCaptureKitProvider.getDesktopIconWindows() /// which respects the hideDesktopIconsDuringScreenshot setting from SettingsManager func shouldExcludeWindowForDesktopIconHiding(_ window: SCWindow) -> Bool { // Desktop icon filtering is now handled in ScreenCaptureKitProvider.getDesktopIconWindows() // This method is kept for potential future advanced filtering logic return false } /// Determines if a window should be excluded for widget hiding /// - Parameter window: The window to check /// - Returns: true if the window should be excluded (i.e., it's a widget and widget hiding is enabled) func shouldExcludeWindowForWidgetHiding(_ window: SCWindow) -> Bool { guard isDesktopWidgetHidingEnabled() else { return false } // Use the widget detection logic to determine if this single window is a widget let widgets = detectDesktopWidgets(from: [window]) return !widgets.isEmpty } }