diff --git a/mac/VibeTunnel/Core/Services/WindowTracker.swift b/mac/VibeTunnel/Core/Services/WindowTracker.swift index 691ae43d..dc9dd7ea 100644 --- a/mac/VibeTunnel/Core/Services/WindowTracker.swift +++ b/mac/VibeTunnel/Core/Services/WindowTracker.swift @@ -225,14 +225,14 @@ final class WindowTracker { } } - /// Focuses an iTerm2 window/tab. + /// Focuses an iTerm2 window. private func focusiTerm2Window(_ windowInfo: WindowInfo) { - if let tabID = windowInfo.tabID { - // Use tab ID for focusing + if let windowID = windowInfo.tabID { + // Use window ID for focusing (stored in tabID for consistency) let script = """ tell application "iTerm2" activate - tell tab id "\(tabID)" + tell window id "\(windowID)" select end tell end tell @@ -240,9 +240,9 @@ final class WindowTracker { do { try AppleScriptExecutor.shared.execute(script) - logger.info("Focused iTerm2 tab using ID") + logger.info("Focused iTerm2 window using ID") } catch { - logger.error("Failed to focus iTerm2 tab: \(error)") + logger.error("Failed to focus iTerm2 window: \(error)") focusWindowUsingAccessibility(windowInfo) } } else { @@ -299,7 +299,7 @@ final class WindowTracker { let activeSessionIDs = Set(sessions.map { $0.id }) sessionWindowMap = sessionWindowMap.filter { activeSessionIDs.contains($0.key) } - logger.debug("Updated window tracker: \(self.sessionWindowMap.count) active windows") + //logger.debug("Updated window tracker: \(self.sessionWindowMap.count) active windows") } } @@ -346,4 +346,4 @@ final class WindowTracker { AccessibilityPermissionManager.shared.requestPermission() } } -} \ No newline at end of file +} diff --git a/mac/VibeTunnel/Utilities/TerminalLauncher.swift b/mac/VibeTunnel/Utilities/TerminalLauncher.swift index 488d0123..c8fb6e6c 100644 --- a/mac/VibeTunnel/Utilities/TerminalLauncher.swift +++ b/mac/VibeTunnel/Utilities/TerminalLauncher.swift @@ -143,11 +143,32 @@ enum Terminal: String, CaseIterable { // For all other terminals, use clipboard approach for reliability // This avoids issues with special characters and long commands // Note: The command is already copied to clipboard before this script runs + + // Special handling for iTerm2 to ensure new window (not tab) + if self == .iTerm2 { + return """ + tell application "\(processName)" + activate + tell application "System Events" + -- Create new window (Cmd+Shift+N for iTerm2) + keystroke "n" using {command down, shift down} + delay 0.5 + -- Paste command from clipboard + keystroke "v" using {command down} + delay 0.1 + -- Execute the command + key code 36 + end tell + end tell + """ + } + + // For other terminals, Cmd+N typically creates a new window return """ tell application "\(processName)" activate tell application "System Events" - -- Create new window/tab + -- Create new window keystroke "n" using {command down} delay 0.5 -- Paste command from clipboard @@ -399,8 +420,10 @@ final class TerminalLauncher { tabReference = "tab id \(components[1]) of window id \(components[0])" } } else if config.terminal == .iTerm2 { - // iTerm2 returns tab ID - tabID = result.trimmingCharacters(in: .whitespacesAndNewlines) + // iTerm2 returns window ID + let windowIDString = result.trimmingCharacters(in: .whitespacesAndNewlines) + // For iTerm2, we store the window ID as tabID for consistency + tabID = windowIDString } } else { // For non-Terminal.app terminals, copy command to clipboard first @@ -555,16 +578,15 @@ final class TerminalLauncher { """ case .iTerm2: - // iTerm2 script that returns tab info + // iTerm2 script that returns window info return """ tell application "iTerm2" - tell current window - set newTab to (create tab with default profile) - tell current session of newTab - write text "\(config.appleScriptEscapedCommand)" - end tell - return id of newTab + activate + set newWindow to (create window with default profile) + tell current session of newWindow + write text "\(config.appleScriptEscapedCommand)" end tell + return id of newWindow end tell """