Get A List Of Open/Running Apps That Have Windows On A Mac With Swift
Notes
- This is the first way I got this to work. Wouldn't surprise me to find there's a more straight forward way.
-
This calls the
runningApps()
function a lot. Would probably be better to memoize that.
import SwiftUI
import CoreGraphics
struct PotentialApp: Identifiable, Hashable {
let app: NSRunningApplication
let id: pid_t
}
struct ContentView: View {
@State private var selectedAppPid = pid_t()
func runningApps() -> [PotentialApp] {
let kCGNullWindowID: UInt32 = 0
guard let windows = CGWindowListCopyWindowInfo([.optionOnScreenOnly], kCGNullWindowID) as NSArray? as? [[String: AnyObject]] else {
return []
}
var filteredWindows: [pid_t] = []
windows.forEach {
let ownerPid = $0[kCGWindowOwnerPID as String] as! pid_t
let ownerName = $0[kCGWindowOwnerName as String] as! String
if ownerName != "Dock" && ownerName != "Window Server" {
if !filteredWindows.contains(ownerPid) {
filteredWindows.append(ownerPid)
}
}
}
let baseApps = NSWorkspace.shared.runningApplications
let initialFilteredApps = baseApps.filter {checkApp in
filteredWindows.contains(checkApp.processIdentifier)
}
.sorted(by: {
$0.localizedName?.lowercased() ?? "unknown name" < $1.localizedName?.lowercased() ?? "unknown name"})
.map{ PotentialApp(app: $0, id: $0.processIdentifier)}
return initialFilteredApps
}
func selectedAppName() -> String? {
guard let selectedAppIndex = runningApps().firstIndex(where: { $0.app.processIdentifier == selectedAppPid })
else {
return Optional.none
}
return runningApps()[selectedAppIndex].app.localizedName
}
var body: some View {
VStack {
List(runningApps(), selection: $selectedAppPid) {
Text($0.app.localizedName ?? "unknown name")
}
Divider()
Text("Selected App: \(selectedAppName() ?? "tbd")")
}
}
}
#Preview {
ContentView()
}
-- end of line --