Files
shotscreen/ShotScreen/Sources/DesktopIconManager.swift
Nick Roodenrijs 0dabed11d2 🎉 ShotScreen v1.0 - Initial Release
🚀 First official release of ShotScreen with complete feature set:

 Core Features:
- Advanced screenshot capture system
- Multi-monitor support
- Professional UI/UX design
- Automated update system with Sparkle
- Apple notarized & code signed

🛠 Technical Excellence:
- Native Swift macOS application
- Professional build & deployment pipeline
- Comprehensive error handling
- Memory optimized performance

📦 Distribution Ready:
- Professional DMG packaging
- Apple notarization complete
- No security warnings for users
- Ready for public distribution

This is the foundation release that establishes ShotScreen as a premium screenshot tool for macOS.
2025-06-28 16:15:15 +02:00

186 lines
8.0 KiB
Swift

//
// 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
}
}