diff --git a/docs/configure/core/workspaces.md b/docs/configure/core/workspaces.md index 565f64ff8..d3c875e21 100644 --- a/docs/configure/core/workspaces.md +++ b/docs/configure/core/workspaces.md @@ -27,6 +27,13 @@ workspaces: ## Sticky Workspaces -Sticky workspaces are being worked on in [this GitHub issue](https://github.com/dalyIsaac/Whim/issues/660). +Sticky workspaces can only be displayed on specific monitors. To create a sticky workspace, specify the monitor indices when creating the workspace: -👷🏗️🚧 +```yaml +workspaces: + entries: + - name: Browser + monitors: [0, 1] +``` + +Here, the workspace can only be displayed on the first and second monitors (0-based index). For more on the ordering of monitors monitors, see the [Monitors](monitors.md) page. diff --git a/docs/script/core/workspaces.md b/docs/script/core/workspaces.md index 5772eca55..436273ccc 100644 --- a/docs/script/core/workspaces.md +++ b/docs/script/core/workspaces.md @@ -71,7 +71,7 @@ Guid stickyWorkspaceId = context.Store.Dispatch( ); ``` -The workspace will only be displayed on the first and second monitors (0-based index). For more on monitors, see the [Monitors](./monitors.md) page. +Here, the workspace can only be displayed on the first and second monitors (0-based index). For more on the ordering of monitors monitors, see the [Monitors](monitors.md) page. ## Example Command diff --git a/src/Whim.Yaml.Tests/YamlLoader/YamlLoader_LoadWorkspacesTests.cs b/src/Whim.Yaml.Tests/YamlLoader/YamlLoader_LoadWorkspacesTests.cs index 5d8dc65bd..bde4617c4 100644 --- a/src/Whim.Yaml.Tests/YamlLoader/YamlLoader_LoadWorkspacesTests.cs +++ b/src/Whim.Yaml.Tests/YamlLoader/YamlLoader_LoadWorkspacesTests.cs @@ -1,5 +1,6 @@ using System.Collections.Immutable; using FluentAssertions; +using NSubstitute; using Whim.SliceLayout; using Whim.TestUtils; using Xunit; @@ -149,4 +150,72 @@ public void Load_NoWorkspaces(string config, bool isYaml, IContext ctx) IWorkspace[] workspaces = YamlLoaderTestUtils.GetWorkspaces(ctx)!; Assert.Empty(workspaces); } + + public static TheoryData WorkspacesMonitorConfig => + new() + { + { + """ + workspaces: + entries: + - name: workspace1 + monitors: [0, 1] + - name: workspace2 + monitors: [2] + - name: workspace3 + monitors: [] + """, + true + }, + { + """ + { + "workspaces": { + "entries": [ + { + "name": "workspace1", + "monitors": [0, 1] + }, + { + "name": "workspace2", + "monitors": [2] + }, + { + "name": "workspace3", + "monitors": [] + } + ] + } + } + """, + false + }, + }; + + [Theory, MemberAutoSubstituteData(nameof(WorkspacesMonitorConfig))] + internal void Load_WorkspacesWithMonitors(string config, bool isYaml, IContext ctx) + { + // Given a valid config with workspaces and monitor indices + YamlLoaderTestUtils.SetupFileConfig(ctx, config, isYaml); + + // When loading the workspaces + bool result = YamlLoader.Load(ctx, showErrorWindow: false); + + // Then the workspaces and monitor indices are loaded correctly + Assert.True(result); + + // Verify the expected transforms were executed + var received = ctx.Store.ReceivedCalls().ToArray(); + Assert.Equal(3, received.Length); + + // Verify the monitor indices. + AddWorkspaceTransform[] transforms = received + .Select(c => c.GetArguments()[0]) + .OfType() + .ToArray(); + + transforms[0].MonitorIndices.Should().BeEquivalentTo([0, 1]); + transforms[1].MonitorIndices.Should().BeEquivalentTo([2]); + transforms[2].MonitorIndices.Should().BeEmpty(); + } } diff --git a/src/Whim.Yaml/YamlLoader.cs b/src/Whim.Yaml/YamlLoader.cs index b874a8ae9..0d8e6c468 100644 --- a/src/Whim.Yaml/YamlLoader.cs +++ b/src/Whim.Yaml/YamlLoader.cs @@ -129,12 +129,23 @@ private static void UpdateWorkspaces(IContext ctx, Schema schema) string workspaceName = (string)workspace.Name; CreateLeafLayoutEngine[]? engines = null; + List? monitorIndices = null; + if (workspace.LayoutEngines.Entries.AsOptional() is Schema.RequiredEntries.RequiredTypeArray definedEngines) { engines = YamlLayoutEngineLoader.GetCreateLeafLayoutEngines(ctx, [.. definedEngines]); } - ctx.Store.Dispatch(new AddWorkspaceTransform(workspaceName, engines)); + if (workspace.Monitors.AsOptional() is Schema.RequiredName.MonitorsEntityArray definedMonitorIndices) + { + monitorIndices = []; + foreach (var monitorIndex in definedMonitorIndices) + { + monitorIndices.Add((int)monitorIndex); + } + } + + ctx.Store.Dispatch(new AddWorkspaceTransform(workspaceName, engines, MonitorIndices: monitorIndices)); } } diff --git a/src/Whim.Yaml/schema.json b/src/Whim.Yaml/schema.json index 301a31c26..84c8ab63c 100644 --- a/src/Whim.Yaml/schema.json +++ b/src/Whim.Yaml/schema.json @@ -128,6 +128,14 @@ "layout_engines": { "$ref": "#/$defs/LayoutEngineList", "description": "The layout engines to use for the workspace. If not specified, the layout engines in `layout_engines` will be used." + }, + "monitors": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "description": "The monitors which this workspace is restricted to. This is a 0-indexed list of monitor indices - see https://dalyisaac.github.io/Whim/configure/core/monitors.html. If not specified, this workspace will be available on all monitors." } } },