diff --git a/src/AeroSpaceApp.swift b/src/AeroSpaceApp.swift index c8079788..f8e2084b 100644 --- a/src/AeroSpaceApp.swift +++ b/src/AeroSpaceApp.swift @@ -46,7 +46,7 @@ struct AeroSpaceApp: App { Text("Workspaces:") ForEach(Workspace.all) { workspace in Button { - WorkspaceCommand.switchToWorkspace(workspace) + Task { await WorkspaceCommand(workspaceName: workspace.name).run() } } label: { Toggle(isOn: workspace.name == viewModel.focusedWorkspaceTrayText ? Binding(get: { true }, set: { _, _ in }) diff --git a/src/command/CloseAllWindowsButCurrentCommand.swift b/src/command/CloseAllWindowsButCurrentCommand.swift index c5b6aaef..e52f0ad8 100644 --- a/src/command/CloseAllWindowsButCurrentCommand.swift +++ b/src/command/CloseAllWindowsButCurrentCommand.swift @@ -1,5 +1,5 @@ class CloseAllWindowsButCurrentCommand: Command { - func run() { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) // todo } diff --git a/src/command/Command.swift b/src/command/Command.swift index b6a733d8..48db2b35 100644 --- a/src/command/Command.swift +++ b/src/command/Command.swift @@ -1,4 +1,13 @@ protocol Command { @MainActor - func run() async + func runWithoutRefresh() async +} + +extension Command { + @MainActor + func run() async { + refresh() + await runWithoutRefresh() + refresh(startSession: false) + } } diff --git a/src/command/CompositeCommand.swift b/src/command/CompositeCommand.swift index 89b08d52..0de5afc1 100644 --- a/src/command/CompositeCommand.swift +++ b/src/command/CompositeCommand.swift @@ -1,10 +1,10 @@ struct CompositeCommand: Command { let subCommands: [Command] - func run() async { + func runWithoutRefresh() async { precondition(Thread.current.isMainThread) for command in subCommands { - await command.run() + await command.runWithoutRefresh() } } } diff --git a/src/command/ExecAndForgetCommand.swift b/src/command/ExecAndForgetCommand.swift index ae32c53c..24310c76 100644 --- a/src/command/ExecAndForgetCommand.swift +++ b/src/command/ExecAndForgetCommand.swift @@ -1,7 +1,7 @@ struct ExecAndForgetCommand: Command { let bashCommand: String - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) try! Process.run(URL(filePath: "/bin/bash"), arguments: ["-c", bashCommand]) } diff --git a/src/command/ExecAndWaitCommand.swift b/src/command/ExecAndWaitCommand.swift index 09c3a52e..5fcf66a8 100644 --- a/src/command/ExecAndWaitCommand.swift +++ b/src/command/ExecAndWaitCommand.swift @@ -1,7 +1,7 @@ struct ExecAndWaitCommand: Command { let bashCommand: String - func run() async { + func runWithoutRefresh() async { precondition(Thread.current.isMainThread) await withCheckedContinuation { (continuation: CheckedContinuation<(), Never>) in let process = Process() diff --git a/src/command/FocusCommand.swift b/src/command/FocusCommand.swift index 9c9b0a16..f3480823 100644 --- a/src/command/FocusCommand.swift +++ b/src/command/FocusCommand.swift @@ -10,7 +10,7 @@ struct FocusCommand: Command { //case next, prev } - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) guard let currentWindow = focusedWindow ?? Workspace.focused.mruWindows.mostRecent else { return } if let direction = direction.cardinalOrNil { diff --git a/src/command/LayoutCommand.swift b/src/command/LayoutCommand.swift index bb5a28ec..a5589d69 100644 --- a/src/command/LayoutCommand.swift +++ b/src/command/LayoutCommand.swift @@ -15,7 +15,7 @@ struct LayoutCommand: Command { self.toggleBetween = toggleBetween } - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) guard let window = focusedWindow ?? Workspace.focused.mruWindows.mostRecent else { return } let targetLayout = toggleBetween.firstIndex(of: window.verboseLayout) @@ -23,7 +23,6 @@ struct LayoutCommand: Command { if let parent = window.parent as? TilingContainer { parent.layout = targetLayout?.simpleLayout ?? errorT("TODO") parent.orientation = targetLayout?.orientation ?? errorT("TODO") - refresh() } else { precondition(window.parent is Workspace) // todo diff --git a/src/command/ModeCommand.swift b/src/command/ModeCommand.swift index 11abee45..38b95721 100644 --- a/src/command/ModeCommand.swift +++ b/src/command/ModeCommand.swift @@ -1,7 +1,7 @@ struct ModeCommand: Command { let idToActivate: String - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) for (modeId, mode) in config.modes { if modeId == idToActivate { diff --git a/src/command/MoveThroughCommand.swift b/src/command/MoveThroughCommand.swift index 98d8f281..c5695815 100644 --- a/src/command/MoveThroughCommand.swift +++ b/src/command/MoveThroughCommand.swift @@ -5,7 +5,7 @@ struct MoveThroughCommand: Command { case left, down, up, right } - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) } diff --git a/src/command/ReloadConfigCommand.swift b/src/command/ReloadConfigCommand.swift index fa42b1ad..1d678201 100644 --- a/src/command/ReloadConfigCommand.swift +++ b/src/command/ReloadConfigCommand.swift @@ -1,5 +1,5 @@ struct ReloadConfigCommand: Command { - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) reloadConfig() refresh() diff --git a/src/command/WorkspaceBackAndForth.swift b/src/command/WorkspaceBackAndForth.swift index ba601bb8..fae4c531 100644 --- a/src/command/WorkspaceBackAndForth.swift +++ b/src/command/WorkspaceBackAndForth.swift @@ -1,5 +1,5 @@ struct WorkspaceBackAndForth: Command { - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) // todo } diff --git a/src/command/WorkspaceCommand.swift b/src/command/WorkspaceCommand.swift index 284d4b11..ed1b5ae7 100644 --- a/src/command/WorkspaceCommand.swift +++ b/src/command/WorkspaceCommand.swift @@ -1,14 +1,10 @@ struct WorkspaceCommand : Command { let workspaceName: String - func run() async { + func runWithoutRefresh() { precondition(Thread.current.isMainThread) - WorkspaceCommand.switchToWorkspace(Workspace.get(byName: workspaceName)) - } - - static func switchToWorkspace(_ workspace: Workspace) { + let workspace = Workspace.get(byName: workspaceName) debug("Switch to workspace: \(workspace.name)") - refresh() if let window = workspace.mruWindows.mostRecent ?? workspace.anyLeafWindowRecursive { // switch to not empty workspace window.focus() // The switching itself will be done by refreshWorkspaces and layoutWorkspaces later in refresh @@ -19,12 +15,15 @@ struct WorkspaceCommand : Command { if let focusedMonitor = NSScreen.focusedMonitorOrNilIfDesktop ?? NSScreen.main?.monitor { focusedMonitor.setActiveWorkspace(workspace) } - defocusAllWindows() + WorkspaceCommand.defocusAllWindows() } - refresh(startSession: false) debug("End switch to workspace: \(workspace.name)") } + static func switchToWorkspace(_ workspace: Workspace) async { + await WorkspaceCommand(workspaceName: workspace.name).run() + } + private static func defocusAllWindows() { // Since AeroSpace doesn't show any windows, focusing AeroSpace defocuses all windows let current = NSRunningApplication.current