diff --git a/docs/docs/customize/snippets.md b/docs/docs/customize/snippets.md index 77ff74871..1fa02ef33 100644 --- a/docs/docs/customize/snippets.md +++ b/docs/docs/customize/snippets.md @@ -44,3 +44,31 @@ context.CommandManager.Add( callback: () => context.WorkspaceManager.ActivateAdjacent(skipActive: true) ); ``` + +## Move a window to a specific monitor + +The following command can be used to move the active window to a specific monitor. The index of the monitor is zero-based, so the primary monitor is index 0, the second monitor is index 1, and so on. + +```csharp +context.CommandManager.Add("move_window_to_monitor_2", "Move window to monitor 2", () => +{ + context.Store.Dispatch(new MoveWindowToMonitorIndexTransform(1)); +}); +``` + +## Move a window to a specific workspace + +The following command can be used to move the active window to a specific workspace. The index of the workspace is zero-based. + +```csharp +Guid? browserWorkspaceId = context.WorkspaceManager.Add("Browser workspace"); +context.CommandManager.Add("move_window_to_browser_workspace", "Move window to browser workspace", () => +{ + // This `if` statement protects against workspaces being created with no layout engines. + if (browserWorkspaceId is Guid workspaceId) + { + // This defaults to the active window, but you can also pass in a specific window as the second argument to the transform. + context.Store.Dispatch(new MoveWindowToWorkspaceTransform(workspaceId)); + } +}); +``` diff --git a/src/Whim.Tests/Store/MapSector/Transforms/InitializeWorkspacesTransformTests.cs b/src/Whim.Tests/Store/MapSector/Transforms/InitializeWorkspacesTransformTests.cs index 3cc341eaa..096ee9c91 100644 --- a/src/Whim.Tests/Store/MapSector/Transforms/InitializeWorkspacesTransformTests.cs +++ b/src/Whim.Tests/Store/MapSector/Transforms/InitializeWorkspacesTransformTests.cs @@ -112,8 +112,9 @@ private static void Setup_UserCreatedWorkspaces(MutableRootSector root) { root.WorkspaceSector.WorkspacesToCreate = [ - new WorkspaceToCreate(BrowserWorkspaceName, null), + new WorkspaceToCreate(Guid.NewGuid(), BrowserWorkspaceName, null), new WorkspaceToCreate( + Guid.NewGuid(), CodeWorkspaceName, new List() { diff --git a/src/Whim.Tests/Store/MonitorSector/Transforms/MonitorsChangedTransformTests.cs b/src/Whim.Tests/Store/MonitorSector/Transforms/MonitorsChangedTransformTests.cs index 752f820f7..57a1f7843 100644 --- a/src/Whim.Tests/Store/MonitorSector/Transforms/MonitorsChangedTransformTests.cs +++ b/src/Whim.Tests/Store/MonitorSector/Transforms/MonitorsChangedTransformTests.cs @@ -93,17 +93,17 @@ private static IWorkspace[] SetupAddWorkspaces(IContext ctx, MutableRootSector r _ => { AddWorkspaceToManager(ctx, rootSector, workspace1); - return workspace1; + return workspace1.Id; }, _ => { AddWorkspaceToManager(ctx, rootSector, workspace2); - return workspace2; + return workspace2.Id; }, _ => { AddWorkspaceToManager(ctx, rootSector, workspace3); - return workspace3; + return workspace3.Id; } ); rootSector.WorkspaceSector.HasInitialized = true; diff --git a/src/Whim.Tests/Store/WorkspaceSector/Transforms/AddWorkspaceTransformTests.cs b/src/Whim.Tests/Store/WorkspaceSector/Transforms/AddWorkspaceTransformTests.cs index 0b80c0262..06feeb44a 100644 --- a/src/Whim.Tests/Store/WorkspaceSector/Transforms/AddWorkspaceTransformTests.cs +++ b/src/Whim.Tests/Store/WorkspaceSector/Transforms/AddWorkspaceTransformTests.cs @@ -13,11 +13,10 @@ internal void SectorNotInitialized(IContext ctx, MutableRootSector root) AddWorkspaceTransform sut = new(name, createLeafLayoutEngines); // When we execute the transform - Result result = ctx.Store.Dispatch(sut); + Result result = ctx.Store.Dispatch(sut); // Then we get null, and the workspace is added to the workspaces to create Assert.True(result.IsSuccessful); - Assert.Null(result.Value); Assert.Single(root.WorkspaceSector.WorkspacesToCreate); Assert.Equal(name, root.WorkspaceSector.WorkspacesToCreate[0].Name); @@ -36,7 +35,7 @@ internal void NoEngineCreators(IContext ctx, MutableRootSector root) AddWorkspaceTransform sut = new(name); // When we execute the transform - Result result = ctx.Store.Dispatch(sut); + Result result = ctx.Store.Dispatch(sut); // Then we get an error Assert.False(result.IsSuccessful); @@ -59,7 +58,7 @@ internal void Success(IContext ctx, MutableRootSector root, ILayoutEngine engine AddWorkspaceTransform sut = new(name, createLeafLayoutEngines); // When we execute the transform - Result? result = null; + Result? result = null; var raisedEvent = Assert.Raises( h => ctx.Store.WorkspaceEvents.WorkspaceAdded += h, h => ctx.Store.WorkspaceEvents.WorkspaceAdded -= h, @@ -69,7 +68,7 @@ internal void Success(IContext ctx, MutableRootSector root, ILayoutEngine engine // Then we get the created workspace Assert.True(result!.Value.IsSuccessful); - IWorkspace? workspace = result!.Value.Value; + IWorkspace workspace = root.WorkspaceSector.Workspaces[result!.Value.Value]; Assert.NotNull(workspace); Assert.Single(root.WorkspaceSector.Workspaces); Assert.Single(root.WorkspaceSector.WorkspaceOrder); @@ -98,7 +97,7 @@ internal void Success_UseDefaults(IContext ctx, MutableRootSector root) AddWorkspaceTransform sut = new(); // When we execute the transform - Result? result = null; + Result? result = null; var raisedEvent = Assert.Raises( h => ctx.Store.WorkspaceEvents.WorkspaceAdded += h, h => ctx.Store.WorkspaceEvents.WorkspaceAdded -= h, @@ -108,7 +107,7 @@ internal void Success_UseDefaults(IContext ctx, MutableRootSector root) // Then we get the created workspace Assert.True(result!.Value.IsSuccessful); - IWorkspace? workspace = result!.Value.Value; + IWorkspace workspace = root.WorkspaceSector.Workspaces[result!.Value.Value]; Assert.NotNull(workspace); Assert.Single(root.WorkspaceSector.Workspaces); Assert.Single(root.WorkspaceSector.WorkspaceOrder); diff --git a/src/Whim/Store/MonitorSector/Transforms/MonitorsChangedTransform.cs b/src/Whim/Store/MonitorSector/Transforms/MonitorsChangedTransform.cs index 71f3b3b5a..888497d0e 100644 --- a/src/Whim/Store/MonitorSector/Transforms/MonitorsChangedTransform.cs +++ b/src/Whim/Store/MonitorSector/Transforms/MonitorsChangedTransform.cs @@ -149,11 +149,11 @@ List removedMonitors // If there's no workspace, create one. if (workspaceId == default) { - if (ctx.WorkspaceManager.Add() is IWorkspace newWorkspace) + if (ctx.WorkspaceManager.Add() is WorkspaceId newWorkspaceId) { mapSector.MonitorWorkspaceMap = mapSector.MonitorWorkspaceMap.SetItem( monitor.Handle, - newWorkspace.Id + newWorkspaceId ); } else diff --git a/src/Whim/Store/WorkspaceSector/Transforms/AddWorkspaceTransform.cs b/src/Whim/Store/WorkspaceSector/Transforms/AddWorkspaceTransform.cs index c68ec6bd0..ac632b18c 100644 --- a/src/Whim/Store/WorkspaceSector/Transforms/AddWorkspaceTransform.cs +++ b/src/Whim/Store/WorkspaceSector/Transforms/AddWorkspaceTransform.cs @@ -15,30 +15,35 @@ namespace Whim; /// The layout engines to add to the workspace. Defaults to , which will /// use the function. /// +/// +/// The ID of the workspace. Defaults to . +/// public record AddWorkspaceTransform( string? Name = null, - IEnumerable? CreateLeafLayoutEngines = null -) : Transform + IEnumerable? CreateLeafLayoutEngines = null, + WorkspaceId WorkspaceId = default +) : Transform { - internal override Result Execute( + internal override Result Execute( IContext ctx, IInternalContext internalCtx, MutableRootSector mutableRootSector ) { WorkspaceSector sector = mutableRootSector.WorkspaceSector; + WorkspaceId id = WorkspaceId == default ? WorkspaceId.NewGuid() : WorkspaceId; if (!sector.HasInitialized) { - sector.WorkspacesToCreate = sector.WorkspacesToCreate.Add(new(Name, CreateLeafLayoutEngines)); - return null; + sector.WorkspacesToCreate = sector.WorkspacesToCreate.Add(new(id, Name, CreateLeafLayoutEngines)); + return id; } CreateLeafLayoutEngine[] engineCreators = CreateLeafLayoutEngines?.ToArray() ?? sector.CreateLayoutEngines(); if (engineCreators.Length == 0) { - return Result.FromException(new WhimException("No engine creators were provided")); + return Result.FromException(new WhimException("No engine creators were provided")); } // Create the layout engines. @@ -58,7 +63,7 @@ MutableRootSector mutableRootSector } Workspace workspace = - new(ctx, WorkspaceId.NewGuid()) + new(ctx, id) { BackingName = Name ?? $"Workspace {sector.Workspaces.Count + 1}", LayoutEngines = layoutEnginesBuilder.ToImmutable() @@ -67,6 +72,6 @@ MutableRootSector mutableRootSector sector.WorkspaceOrder = sector.WorkspaceOrder.Add(workspace.Id); sector.QueueEvent(new WorkspaceAddedEventArgs() { Workspace = workspace }); - return workspace; + return id; } } diff --git a/src/Whim/Store/WorkspaceSector/Transforms/InitializeWorkspacesTransform.cs b/src/Whim/Store/WorkspaceSector/Transforms/InitializeWorkspacesTransform.cs index 252066a43..efd8a9598 100644 --- a/src/Whim/Store/WorkspaceSector/Transforms/InitializeWorkspacesTransform.cs +++ b/src/Whim/Store/WorkspaceSector/Transforms/InitializeWorkspacesTransform.cs @@ -27,7 +27,7 @@ private static void CreatePreInitializationWorkspaces(IContext ctx, MutableRootS workspaceSector.HasInitialized = true; foreach (WorkspaceToCreate w in workspaceSector.WorkspacesToCreate) { - ctx.Store.Dispatch(new AddWorkspaceTransform(w.Name, w.CreateLeafLayoutEngines)); + ctx.Store.Dispatch(new AddWorkspaceTransform(w.Name, w.CreateLeafLayoutEngines, w.WorkspaceId)); } workspaceSector.WorkspacesToCreate = workspaceSector.WorkspacesToCreate.Clear(); diff --git a/src/Whim/Store/WorkspaceSector/WorkspaceSector.cs b/src/Whim/Store/WorkspaceSector/WorkspaceSector.cs index c834f1d4d..b0463ba4f 100644 --- a/src/Whim/Store/WorkspaceSector/WorkspaceSector.cs +++ b/src/Whim/Store/WorkspaceSector/WorkspaceSector.cs @@ -3,9 +3,14 @@ namespace Whim; /// /// A workspace's name and layout engines. /// +/// /// /// -internal record WorkspaceToCreate(string? Name, IEnumerable? CreateLeafLayoutEngines); +internal record WorkspaceToCreate( + WorkspaceId WorkspaceId, + string? Name, + IEnumerable? CreateLeafLayoutEngines +); internal class WorkspaceSector(IContext ctx, IInternalContext internalCtx) : SectorBase, diff --git a/src/Whim/Workspace/IWorkspaceManager.cs b/src/Whim/Workspace/IWorkspaceManager.cs index 17ea1f5d5..77cac21d3 100644 --- a/src/Whim/Workspace/IWorkspaceManager.cs +++ b/src/Whim/Workspace/IWorkspaceManager.cs @@ -82,11 +82,11 @@ public interface IWorkspaceManager : IEnumerable, IDisposable /// /// /// - /// Otherwise, returns the created workspace. + /// Otherwise, returns the ID of the created workspace. /// /// /// - IWorkspace? Add(string? name = null, IEnumerable? createLayoutEngines = null); + WorkspaceId? Add(string? name = null, IEnumerable? createLayoutEngines = null); /// /// Whether the manager contains the given workspace. diff --git a/src/Whim/Workspace/WorkspaceManager.cs b/src/Whim/Workspace/WorkspaceManager.cs index e3aea9ae3..36e3984fc 100644 --- a/src/Whim/Workspace/WorkspaceManager.cs +++ b/src/Whim/Workspace/WorkspaceManager.cs @@ -37,8 +37,10 @@ public IWorkspace ActiveWorkspace } } - public IWorkspace? Add(string? name = null, IEnumerable? createLayoutEngines = null) => - _context.Store.Dispatch(new AddWorkspaceTransform(name, createLayoutEngines)).ValueOrDefault; + public WorkspaceId? Add(string? name = null, IEnumerable? createLayoutEngines = null) => + _context.Store.Dispatch(new AddWorkspaceTransform(name, createLayoutEngines)).TryGet(out WorkspaceId id) + ? id + : null; public void AddProxyLayoutEngine(ProxyLayoutEngineCreator proxyLayoutEngineCreator) => _context.Store.Dispatch(new AddProxyLayoutEngineTransform(proxyLayoutEngineCreator));