Skip to content

Commit

Permalink
Always expose the workspace id when adding a workspace (#977)
Browse files Browse the repository at this point in the history
Previously, `context.WorkspaceManager.Add()` would return `null` in the csx. This was because it would only return `IWorkspace` once Whim had completed initialization.

Now, `context.WorkspaceManager.Add()` will return the `Guid` of the workspace that was added. This allows you to utilize the workspace id when setting up commands or other functionality that requires the workspace id.
  • Loading branch information
dalyIsaac authored Aug 16, 2024
1 parent f497291 commit 895c46d
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 27 deletions.
28 changes: 28 additions & 0 deletions docs/docs/customize/snippets.md
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
});
```
Original file line number Diff line number Diff line change
Expand Up @@ -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<CreateLeafLayoutEngine>()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ internal void SectorNotInitialized(IContext ctx, MutableRootSector root)
AddWorkspaceTransform sut = new(name, createLeafLayoutEngines);

// When we execute the transform
Result<IWorkspace?> result = ctx.Store.Dispatch(sut);
Result<Guid> 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);
Expand All @@ -36,7 +35,7 @@ internal void NoEngineCreators(IContext ctx, MutableRootSector root)
AddWorkspaceTransform sut = new(name);

// When we execute the transform
Result<IWorkspace?> result = ctx.Store.Dispatch(sut);
Result<Guid> result = ctx.Store.Dispatch(sut);

// Then we get an error
Assert.False(result.IsSuccessful);
Expand All @@ -59,7 +58,7 @@ internal void Success(IContext ctx, MutableRootSector root, ILayoutEngine engine
AddWorkspaceTransform sut = new(name, createLeafLayoutEngines);

// When we execute the transform
Result<IWorkspace?>? result = null;
Result<Guid>? result = null;
var raisedEvent = Assert.Raises<WorkspaceAddedEventArgs>(
h => ctx.Store.WorkspaceEvents.WorkspaceAdded += h,
h => ctx.Store.WorkspaceEvents.WorkspaceAdded -= h,
Expand All @@ -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);
Expand Down Expand Up @@ -98,7 +97,7 @@ internal void Success_UseDefaults(IContext ctx, MutableRootSector root)
AddWorkspaceTransform sut = new();

// When we execute the transform
Result<IWorkspace?>? result = null;
Result<Guid>? result = null;
var raisedEvent = Assert.Raises<WorkspaceAddedEventArgs>(
h => ctx.Store.WorkspaceEvents.WorkspaceAdded += h,
h => ctx.Store.WorkspaceEvents.WorkspaceAdded -= h,
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ List<IMonitor> 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
Expand Down
21 changes: 13 additions & 8 deletions src/Whim/Store/WorkspaceSector/Transforms/AddWorkspaceTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,35 @@ namespace Whim;
/// The layout engines to add to the workspace. Defaults to <see langword="null"/>, which will
/// use the <see cref="WorkspaceSector.CreateLayoutEngines"/> function.
/// </param>
/// <param name="WorkspaceId">
/// The ID of the workspace. Defaults to <see cref="WorkspaceId.NewGuid"/>.
/// </param>
public record AddWorkspaceTransform(
string? Name = null,
IEnumerable<CreateLeafLayoutEngine>? CreateLeafLayoutEngines = null
) : Transform<IWorkspace?>
IEnumerable<CreateLeafLayoutEngine>? CreateLeafLayoutEngines = null,
WorkspaceId WorkspaceId = default
) : Transform<WorkspaceId>
{
internal override Result<IWorkspace?> Execute(
internal override Result<WorkspaceId> 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<IWorkspace?>(new WhimException("No engine creators were provided"));
return Result.FromException<WorkspaceId>(new WhimException("No engine creators were provided"));
}

// Create the layout engines.
Expand All @@ -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()
Expand All @@ -67,6 +72,6 @@ MutableRootSector mutableRootSector
sector.WorkspaceOrder = sector.WorkspaceOrder.Add(workspace.Id);
sector.QueueEvent(new WorkspaceAddedEventArgs() { Workspace = workspace });

return workspace;
return id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
7 changes: 6 additions & 1 deletion src/Whim/Store/WorkspaceSector/WorkspaceSector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ namespace Whim;
/// <summary>
/// A workspace's name and layout engines.
/// </summary>
/// <param name="WorkspaceId"></param>
/// <param name="Name"></param>
/// <param name="CreateLeafLayoutEngines"></param>
internal record WorkspaceToCreate(string? Name, IEnumerable<CreateLeafLayoutEngine>? CreateLeafLayoutEngines);
internal record WorkspaceToCreate(
WorkspaceId WorkspaceId,
string? Name,
IEnumerable<CreateLeafLayoutEngine>? CreateLeafLayoutEngines
);

internal class WorkspaceSector(IContext ctx, IInternalContext internalCtx)
: SectorBase,
Expand Down
4 changes: 2 additions & 2 deletions src/Whim/Workspace/IWorkspaceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ public interface IWorkspaceManager : IEnumerable<IWorkspace>, IDisposable
/// </description>
/// </item>
/// <item>
/// <description>Otherwise, returns the created workspace.</description>
/// <description>Otherwise, returns the ID of the created workspace.</description>
/// </item>
/// </list>
/// </returns>
IWorkspace? Add(string? name = null, IEnumerable<CreateLeafLayoutEngine>? createLayoutEngines = null);
WorkspaceId? Add(string? name = null, IEnumerable<CreateLeafLayoutEngine>? createLayoutEngines = null);

/// <summary>
/// Whether the manager contains the given workspace.
Expand Down
6 changes: 4 additions & 2 deletions src/Whim/Workspace/WorkspaceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ public IWorkspace ActiveWorkspace
}
}

public IWorkspace? Add(string? name = null, IEnumerable<CreateLeafLayoutEngine>? createLayoutEngines = null) =>
_context.Store.Dispatch(new AddWorkspaceTransform(name, createLayoutEngines)).ValueOrDefault;
public WorkspaceId? Add(string? name = null, IEnumerable<CreateLeafLayoutEngine>? 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));
Expand Down

0 comments on commit 895c46d

Please sign in to comment.