83 lines
4.3 KiB
Python
83 lines
4.3 KiB
Python
#!/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')
|