#!/usr/bin/env python3 """Fix OrionToolbar service visibility and foreground activation, preserving other UI.""" from pathlib import Path from datetime import datetime import shutil root = Path.cwd() controller = root / 'OrionToolbar/OrionVMController.swift' view = root / 'OrionToolbar/OrionMenuView.swift' if not controller.exists() or not view.exists(): raise SystemExit('Run from the OrionToolbar project root. No changes made.') c = controller.read_text() v = view.read_text() def swap(src, old, new, count, label): found = src.count(old) if found != count: raise ValueError(f'{label}: expected {count} matches, found {found}') return src.replace(old, new) try: # Keep both the startup and timer paths checking actual services. c = swap(c, 'await discoverVMs()\n await refreshAll()', 'await discoverVMs()\n await refreshAll()\n await refreshServiceAvailability()', 2, 'initial refresh') c = swap(c, 'await self.discoverVMs(); await self.refreshAll()', 'await self.discoverVMs(); await self.refreshAll(); await self.refreshServiceAvailability()', 1, 'timer refresh') # Use the observed probe results, never just the existence of settings. v = swap(v, 'if !server.host.isEmpty && !server.sshUser.isEmpty {', 'if !server.host.isEmpty && !server.sshUser.isEmpty && vm.reachableSSH.contains(server.id) {', 2, 'SSH visibility') v = swap(v, 'if !server.host.isEmpty && server.mailpitPort != nil {', 'if !server.host.isEmpty && server.mailpitPort != nil && vm.reachableMailpit.contains(server.id) {', 2, 'Mailpit visibility') # Hide the menu bar panel *before* launching other apps. Activate the target # again shortly afterwards to prevent the menu-bar panel stealing focus. c = swap(c, ' func openSSH(_ s: ServerDefinition) {', ' func openSSH(_ s: ServerDefinition) {\n NSApp.hide(nil)', 1, 'SSH panel dismissal') old = ''' NSWorkspace.shared.open([scriptURL], withApplicationAt: terminalURL, configuration: configuration) { _, error in Task { @MainActor in if let error { self.lastError = "Could not open Terminal: \\(error.localizedDescription)" } } }''' new = ''' NSWorkspace.shared.open([scriptURL], withApplicationAt: terminalURL, configuration: configuration) { application, error in Task { @MainActor in if let error { self.lastError = "Could not open Terminal: \\(error.localizedDescription)" } else { DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) { application?.activate(options: [.activateAllWindows]) } } } }''' c = swap(c, old, new, 1, 'Terminal foreground') old = ' func openMailpit(_ s: ServerDefinition) { if let p = s.mailpitPort, let url = URL(string: "http://\\(s.host):\\(p)") { NSWorkspace.shared.open(url) } }' new = ''' func openMailpit(_ s: ServerDefinition) { guard let p = s.mailpitPort, let url = URL(string: "http://\\(s.host):\\(p)") else { return } NSApp.hide(nil) let browserURL = NSWorkspace.shared.urlForApplication(toOpen: url) NSWorkspace.shared.open(url) if let browserURL { DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { let browser = NSWorkspace.shared.runningApplications.first { $0.bundleURL == browserURL } browser?.activate(options: [.activateAllWindows]) } } }''' c = swap(c, old, new, 1, 'browser foreground') except ValueError as error: raise SystemExit(f'Patch not applied: {error}. No files changed.') stamp = datetime.now().strftime('%Y%m%d-%H%M%S') for path, updated in ((controller, c), (view, v)): backup = root / 'backups' / f'services-focus-{stamp}' / path.relative_to(root) backup.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(path, backup) path.write_text(updated) print(f'Updated: {path.relative_to(root)}; backup: {backup.relative_to(root)}') print('Done. Build using: /bin/zsh scripts/build.sh --launch')