🎉 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.
This commit is contained in:
186
ShotScreen/Sources/DesktopIconManager.swift
Normal file
186
ShotScreen/Sources/DesktopIconManager.swift
Normal file
@@ -0,0 +1,186 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user