|
|
|
@ -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 |
|
|
|
|