From 739e2b8e84aeea541754b6d14b80fcac9ddae5ba Mon Sep 17 00:00:00 2001 From: Ali Alavi Date: Wed, 16 Sep 2026 06:18:34 +0000 Subject: [PATCH] fix: force WindowServer Space transition and AppleScript reopen for windowless Electron processes --- src/VoiceCommandExecutor.swift | 43 ++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/VoiceCommandExecutor.swift b/src/VoiceCommandExecutor.swift index 66ca830..c2e3b1c 100644 --- a/src/VoiceCommandExecutor.swift +++ b/src/VoiceCommandExecutor.swift @@ -417,8 +417,9 @@ public final class VoiceCommandExecutor { // MARK: - Specialized Antigravity Matcher private func matchAntigravity(normalized: String) -> String? { - let hasAnti = normalized.contains("انتی") || normalized.contains("anti") - let hasGravity = normalized.contains("گراویتی") || normalized.contains("گرویتی") || normalized.contains("gravity") + let hasAnti = normalized.contains("انتی") || normalized.contains("anti") || + normalized.contains("on the") || normalized.contains("in the") || normalized.contains("and the") + let hasGravity = normalized.contains("گراویتی") || normalized.contains("گرویتی") || normalized.contains("gravity") || normalized.contains("graphity") guard (hasAnti && hasGravity) || normalized.contains("antigravity") || normalized.contains("انتیگراویتی") || normalized.contains("انتیگرویتی") else { return nil @@ -1113,13 +1114,41 @@ public final class VoiceCommandExecutor { }) if let running = runningApp { - running.activate(options: [.activateIgnoringOtherApps]) - ensureWindowFullScreen(app: running) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { + // Check if app has any open windows + let appElem = AXUIElementCreateApplication(running.processIdentifier) + var winListObj: CFTypeRef? + let hasWindows = (AXUIElementCopyAttributeValue(appElem, kAXWindowsAttribute as CFString, &winListObj) == .success) && + ((winListObj as? [AXUIElement])?.isEmpty == false) + + if hasWindows { + // Force macOS WindowServer to switch Spaces + runAppleScript("tell application \"\(appName)\" to activate") + let task = Process() + task.executableURL = URL(fileURLWithPath: "/usr/bin/open") + task.arguments = ["-a", appName] + try? task.run() + running.activate(options: [.activateIgnoringOtherApps]) - completion?() + ensureWindowFullScreen(app: running) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { + running.activate(options: [.activateIgnoringOtherApps]) + completion?() + } + return + } else { + // Process is lingering with 0 windows! Re-open window via AppleScript & open -a + runAppleScript("tell application \"\(appName)\" to reopen") + runAppleScript("tell application \"\(appName)\" to activate") + let task = Process() + task.executableURL = URL(fileURLWithPath: "/usr/bin/open") + task.arguments = ["-a", appName] + try? task.run() + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.pollAndMakeFullScreen(app: running, targetBid: targetBid, appName: appName, completion: completion) + } + return } - return } // Cold launch if app was closed