diff --git a/Sources/AppBundle/command/impl/MoveWorkspaceToMonitorCommand.swift b/Sources/AppBundle/command/impl/MoveWorkspaceToMonitorCommand.swift index 38a7fa66..dc3b9000 100644 --- a/Sources/AppBundle/command/impl/MoveWorkspaceToMonitorCommand.swift +++ b/Sources/AppBundle/command/impl/MoveWorkspaceToMonitorCommand.swift @@ -9,20 +9,28 @@ struct MoveWorkspaceToMonitorCommand: Command { guard let target = args.resolveTargetOrReportError(env, io) else { return false } let focusedWorkspace = target.workspace let prevMonitor = focusedWorkspace.workspaceMonitor - let sortedMonitors = sortedMonitors - guard let index = sortedMonitors.firstIndex(where: { $0.rect.topLeftCorner == prevMonitor.rect.topLeftCorner }) else { return false } - let targetMonitor = args.wrapAround - ? sortedMonitors.get(wrappingIndex: args.target.val == .next ? index + 1 : index - 1) - : sortedMonitors.getOrNil(atIndex: args.target.val == .next ? index + 1 : index - 1) - guard let targetMonitor else { return false } - if targetMonitor.setActiveWorkspace(focusedWorkspace) { - let stubWorkspace = getStubWorkspace(for: prevMonitor) - check(prevMonitor.setActiveWorkspace(stubWorkspace), - "getStubWorkspace generated incompatible stub workspace (\(stubWorkspace)) for the monitor (\(prevMonitor)") - return true - } else { - return io.err("Can't move workspace '\(focusedWorkspace.name)' to monitor '\(targetMonitor.name)'. workspace-to-monitor-force-assignment doesn't allow it") + switch args.target.val.resolve( + target.workspace.workspaceMonitor, wrapAround: args.wrapAround) + { + case .success(let targetMonitor): + if targetMonitor.monitorId == prevMonitor.monitorId { + return true + } + if targetMonitor.setActiveWorkspace(focusedWorkspace) { + let stubWorkspace = getStubWorkspace(for: prevMonitor) + check( + prevMonitor.setActiveWorkspace(stubWorkspace), + "getStubWorkspace generated incompatible stub workspace (\(stubWorkspace)) for the monitor (\(prevMonitor)" + ) + return true + } else { + return io.err( + "Can't move workspace '\(focusedWorkspace.name)' to monitor '\(targetMonitor.name)'. workspace-to-monitor-force-assignment doesn't allow it" + ) + } + case .failure(let msg): + return io.err(msg) } } } diff --git a/Sources/Cli/subcommandDescriptionsGenerated.swift b/Sources/Cli/subcommandDescriptionsGenerated.swift index b27b3d5e..98f6139b 100644 --- a/Sources/Cli/subcommandDescriptionsGenerated.swift +++ b/Sources/Cli/subcommandDescriptionsGenerated.swift @@ -26,7 +26,7 @@ let subcommandDescriptions = [ [" move-mouse", "Move mouse to the requested position"], [" move-node-to-monitor", "Move window to monitor targeted by relative direction, by order, or by pattern"], [" move-node-to-workspace", "Move the focused window to the specified workspace"], - [" move-workspace-to-monitor", "Move the focused workspace to the next or previous monitor."], + [" move-workspace-to-monitor", "Move workspace to monitor targeted by relative direction, by order, or by pattern."], [" move", "Move the focused window in the given direction"], [" reload-config", "Reload currently active config"], [" resize", "Resize the focused window"], diff --git a/Sources/Common/cmdArgs/cmdArgsManifest.swift b/Sources/Common/cmdArgs/cmdArgsManifest.swift index 39c342b3..6cb8d324 100644 --- a/Sources/Common/cmdArgs/cmdArgsManifest.swift +++ b/Sources/Common/cmdArgs/cmdArgsManifest.swift @@ -99,7 +99,7 @@ func initSubcommands() -> [String: any SubCommandParserProtocol] { case .moveNodeToWorkspace: result[kind.rawValue] = SubCommandParser(parseMoveNodeToWorkspaceCmdArgs) case .moveWorkspaceToMonitor: - result[kind.rawValue] = SubCommandParser(MoveWorkspaceToMonitorCmdArgs.init) + result[kind.rawValue] = SubCommandParser(parseWorkspaceToMonitorCmdArgs) // deprecated result["move-workspace-to-display"] = SubCommandParser(MoveWorkspaceToMonitorCmdArgs.init) case .reloadConfig: diff --git a/Sources/Common/cmdArgs/impl/MoveWorkpsaceToMonitorCmdArgs.swift b/Sources/Common/cmdArgs/impl/MoveWorkpsaceToMonitorCmdArgs.swift index 6307d75b..a6d61870 100644 --- a/Sources/Common/cmdArgs/impl/MoveWorkpsaceToMonitorCmdArgs.swift +++ b/Sources/Common/cmdArgs/impl/MoveWorkpsaceToMonitorCmdArgs.swift @@ -9,18 +9,23 @@ public struct MoveWorkspaceToMonitorCmdArgs: CmdArgs { "--wrap-around": trueBoolFlag(\.wrapAround), "--workspace": optionalWorkspaceFlag(), ], - arguments: [newArgParser(\.target, parseMonitorTarget, mandatoryArgPlaceholder: "(next|prev)")] + arguments: [ + newArgParser( + \.target, parseTarget, + mandatoryArgPlaceholder: "(left|down|up|right|next|prev|)"), + ] ) public var windowId: UInt32? public var workspaceName: WorkspaceName? public var wrapAround: Bool = false - public var target: Lateinit = .uninitialized - public enum MonitorTarget: String, CaseIterable { - case next, prev - } + public var target: Lateinit = .uninitialized } - -private func parseMonitorTarget(arg: String, nextArgs: inout [String]) -> Parsed { - parseEnum(arg, MoveWorkspaceToMonitorCmdArgs.MonitorTarget.self) +public func parseWorkspaceToMonitorCmdArgs(_ args: [String]) -> ParsedCmd< + MoveWorkspaceToMonitorCmdArgs +> { + parseSpecificCmdArgs(MoveWorkspaceToMonitorCmdArgs(rawArgs: args), args) + .filter("--wrap-around is incompatible with argument") { + $0.wrapAround.implies(!$0.target.val.isPatterns) + } } diff --git a/Sources/Common/cmdHelpGenerated.swift b/Sources/Common/cmdHelpGenerated.swift index 295327b2..b9b6b944 100644 --- a/Sources/Common/cmdHelpGenerated.swift +++ b/Sources/Common/cmdHelpGenerated.swift @@ -106,7 +106,8 @@ let move_node_to_workspace_help_generated = """ [--window-id ] """ let move_workspace_to_monitor_help_generated = """ - USAGE: move-workspace-to-monitor [-h|--help] [--workspace ] [--wrap-around] (next|prev) + USAGE: move-workspace-to-monitor [-h|--help] [--workspace ] [--wrap-around] (left|down|up|right|next|prev) + OR: move-workspace-to-monitor [-h|--help] [--workspace ] ... """ let move_help_generated = """ USAGE: move [-h|--help] [--window-id ] (left|down|up|right) diff --git a/docs/aerospace-move-workspace-to-monitor.adoc b/docs/aerospace-move-workspace-to-monitor.adoc index 23e4fa36..114c2f45 100644 --- a/docs/aerospace-move-workspace-to-monitor.adoc +++ b/docs/aerospace-move-workspace-to-monitor.adoc @@ -2,14 +2,15 @@ include::util/man-attributes.adoc[] :manname: aerospace-move-workspace-to-monitor // tag::purpose[] -:manpurpose: Move the focused workspace to the next or previous monitor. +:manpurpose: Move workspace to monitor targeted by relative direction, by order, or by pattern. // end::purpose[] // =========================================================== Synopsis == Synopsis [verse] // tag::synopsis[] -aerospace move-workspace-to-monitor [-h|--help] [--workspace ] [--wrap-around] (next|prev) +aerospace move-workspace-to-monitor [-h|--help] [--workspace ] [--wrap-around] (left|down|up|right|next|prev) +aerospace move-workspace-to-monitor [-h|--help] [--workspace ] ... // end::synopsis[] @@ -34,10 +35,17 @@ include::./util/workspace-flag-desc.adoc[] // =========================================================== Arguments include::./util/conditional-arguments-header.adoc[] +(left|down|up|right):: +Move workspace to monitor in direction relative to the focused monitor + (next|prev):: Move the workspace to next or prev monitor. 'next' or 'prev' monitor is calculated relative to the monitor `` currently belongs to. +:: +Find the first monitor pattern in the list that doesn't describe the current monitor and move the workspace to the appropriate monitor. +Monitor pattern is the same as in `workspace-to-monitor-force-assignment` config option + // end::body[] // =========================================================== Footer