Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout engine YAML config #1035

Merged
merged 34 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e0b1d60
Port over SliceLayoutEngine fixes
dalyIsaac Sep 27, 2024
effc408
Bump coverage
dalyIsaac Sep 27, 2024
ea96281
Change timeout
dalyIsaac Sep 27, 2024
02eec8f
More coverage
dalyIsaac Sep 27, 2024
284548a
Renamed types to `type`
dalyIsaac Sep 19, 2024
9154e80
Separate out layout engines
dalyIsaac Sep 19, 2024
14cdfa0
Add LayoutEngineBase inheritance
dalyIsaac Sep 24, 2024
6e1b696
Only write if the previous item didn't fail
dalyIsaac Sep 24, 2024
d9e63b8
Remove `LayoutEngineBase`
dalyIsaac Sep 24, 2024
d5e74da
Add parsing
dalyIsaac Sep 24, 2024
06ad458
Fix existing tests
dalyIsaac Sep 24, 2024
f2a0dc3
Load the Tree and Slice layouts
dalyIsaac Sep 25, 2024
f5f8af1
Move LayoutEngine loading
dalyIsaac Sep 25, 2024
46cd2f9
Support a wider range of variants
dalyIsaac Sep 25, 2024
5caa355
Better coverage for columns and rows
dalyIsaac Sep 26, 2024
db6c34a
Fix build
dalyIsaac Sep 26, 2024
d22eaba
SliceLayoutEngine YAML tests
dalyIsaac Sep 27, 2024
07bb351
Remove irritating analyzer rule
dalyIsaac Sep 28, 2024
df6c066
Slice coverage
dalyIsaac Sep 28, 2024
16fca54
Reorganized into folders
dalyIsaac Sep 28, 2024
56a6152
Actually fix slice coverage
dalyIsaac Sep 28, 2024
d19ed23
TreeLayoutEngine tests
dalyIsaac Sep 28, 2024
f3c8e97
Merge remote-tracking branch 'origin/main' into 1032-workspaces-yaml-…
dalyIsaac Oct 1, 2024
0fee15a
Clean up from merge
dalyIsaac Oct 1, 2024
6efa537
Fix SliceLayouts
dalyIsaac Oct 1, 2024
4a48413
Somewhat fix tree
dalyIsaac Oct 1, 2024
484c063
Fix tree test
dalyIsaac Oct 1, 2024
1e7304d
Merge remote-tracking branch 'origin/main' into 1032-workspaces-yaml-…
dalyIsaac Oct 2, 2024
d26a7e5
FocusLayoutEngine config
dalyIsaac Oct 2, 2024
c208618
Remove unnecessary validation
dalyIsaac Oct 2, 2024
dd2e6b9
Plugin loading tests
dalyIsaac Oct 2, 2024
1a014a6
Update docs for changed `type`s
dalyIsaac Oct 4, 2024
50d3113
Cursory docs
dalyIsaac Oct 4, 2024
ded5a46
Merge branch 'main' into 1032-workspaces-yaml-config
dalyIsaac Oct 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,23 @@
"tools": {
"xamlstyler.console": {
"version": "3.2404.2",
"commands": [
"xstyler"
],
"commands": ["xstyler"],
"rollForward": false
},
"csharpier": {
"version": "0.29.2",
"commands": [
"dotnet-csharpier"
],
"commands": ["dotnet-csharpier"],
"rollForward": false
},
"docfx": {
"version": "2.77.0",
"commands": [
"docfx"
],
"commands": ["docfx"],
"rollForward": false
},
"corvus.json.jsonschema.typegeneratortool": {
"version": "3.1.1",
"commands": [
"generatejsonschematypes"
],
"commands": ["generatejsonschematypes"],
"rollForward": false
}
}
}
}
65 changes: 55 additions & 10 deletions docs/docs/customize/yaml.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# YAML Configuration (WIP)

Whim is in the process of adding YAML configuration support - this is being tracked in [#1009](https://github.com/dalyIsaac/Whim/issues/1009). This has been implemented in the `Whim.Yaml` plugin.
Whim is in the process of adding YAML configuration support - this is being tracked in [#1009](https://github.com/dalyIsaac/Whim/issues/1009). This has been implemented in the `Whim.Yaml` plugin, and may have breaking changes in the future.

## Setup

Expand Down Expand Up @@ -46,6 +46,51 @@ To use the schema in your JSON file, add the following line at the top of your f
}
```

## Layout Engines

The layout engines configuration has a list of layout engines that you can use to customize the layout of your windows. These apply to all workspaces, unless overridden by workspace-specific configuration.

### Layout Engines Example

```yaml
layout_engines:
entries:
- type: TreeLayoutEngine
initial_direction: right

- type: SliceLayoutEngine
variant:
type: row

- type: SliceLayoutEngine
variant:
type: column

- type: SliceLayoutEngine
variant:
type: primary_stack

- type: SliceLayoutEngine
variant:
type: secondary_primary_stack

- type: SliceLayoutEngine
variant:
type: multi_column_stack
columns: [2, 1, 0]

- type: SliceLayoutEngine
variant:
type: secondary_primary_stack
primary_capacity: 1
secondary_capacity: 2

- type: FocusLayoutEngine
maximize: false
```

TODO: Add layout engine descriptions

## Keybinds

The keybinds configuration has a list of bindings that you can use to bind commands to key combinations.
Expand Down Expand Up @@ -129,7 +174,7 @@ For example, to filter out Chromium windows with the class `Chrome_WidgetWin_1`,
```yaml
filters:
entries:
- filter_type: window_class
- type: window_class
value: Chrome_WidgetWin_1
```

Expand All @@ -140,7 +185,7 @@ For example, to filter out windows with the process file name `explorer.exe`, ad
```yaml
filters:
entries:
- filter_type: process_file_name
- type: process_file_name
value: explorer.exe
```

Expand All @@ -151,7 +196,7 @@ For example, to filter out windows with the title `Untitled - Notepad`, add the
```yaml
filters:
entries:
- filter_type: title
- type: title
value: Untitled - Notepad
```

Expand All @@ -162,7 +207,7 @@ For example, to filter out windows with the title that matches the regex `^Untit
```yaml
filters:
entries:
- filter_type: title_regex
- type: title_regex
value: ^Untitled - Notepad$
```

Expand All @@ -182,7 +227,7 @@ The available routing behaviors are:

### Custom Routing Behavior

You can also define custom routing behavior by specifying a list of routing entries. Each routing entry has a `router_type`, `value`, and `workspace_name`.
You can also define custom routing behavior by specifying a list of routing entries. Each routing entry has a `type`, `value`, and `workspace_name`.

The available router types are:

Expand All @@ -198,7 +243,7 @@ For example, to route Chromium windows with the class `Chrome_WidgetWin_1` to th
```yaml
routers:
entries:
- router_type: window_class
- type: window_class
value: Chrome_WidgetWin_1
workspace_name: web
```
Expand All @@ -210,7 +255,7 @@ For example, to route windows with the process file name `explorer.exe` to the w
```yaml
routers:
entries:
- router_type: process_file_name
- type: process_file_name
value: explorer.exe
workspace_name: file_explorer
```
Expand All @@ -222,7 +267,7 @@ For example, to route windows with the title `Untitled - Notepad` to the workspa
```yaml
routers:
entries:
- router_type: title
- type: title
value: Untitled - Notepad
workspace_name: notepad
```
Expand All @@ -234,7 +279,7 @@ For example, to route windows with the title that matches the regex `^Untitled -
```yaml
routers:
entries:
- router_type: title_regex
- type: title_regex
value: ^Untitled - Notepad$
workspace_name: notepad
```
Expand Down
2 changes: 1 addition & 1 deletion scripts/Generate-SourceFromSchema.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ dotnet tool run generatejsonschematypes `
--outputPath $outputPath

# If not in CI, write metadata file
if ($null -eq $env:CI) {
if ($LASTEXITCODE -eq 0 -and $null -eq $env:CI) {
Write-Host "Writing metadata file..."
@{ gitRef = $gitSha; lastWriteTime = $now } | ConvertTo-Json | Set-Content $metadataPath
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using FluentAssertions;
using NSubstitute;
using Whim.TestUtils;
Expand Down Expand Up @@ -65,6 +66,7 @@ public void Count(int windowCount, int minimizedWindowCount, IContext ctx, Slice
}

[Theory, AutoSubstituteData]
[SuppressMessage("Maintainability", "CA1508:Avoid dead conditional code")]
public void Equals_Null(IContext ctx, SliceLayoutPlugin plugin)
{
// Given
Expand Down
2 changes: 2 additions & 0 deletions src/Whim.SliceLayout.Tests/SliceLayoutsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Whim.SliceLayout.Tests;

// NOTE: We deliberately use FluentAssertions to deeply compare the objects, instead of comparing
// the properties one by one, or comparing by reference.
public class SliceLayoutsTests
{
[Theory, AutoSubstituteData]
Expand Down
154 changes: 154 additions & 0 deletions src/Whim.Yaml.Tests/Layouts/YamlLayoutEngineLoaderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using FluentAssertions;
using NSubstitute;
using Whim.TestUtils;
using Xunit;

namespace Whim.Yaml.Tests;

public class YamlLayoutEngineLoaderTests
{
public static TheoryData<string, bool, bool> FocusLayoutEngineConfig =>
new()
{
{
"""
layout_engines:
entries:
- type: FocusLayoutEngine
""",
false,
true
},
{
"""
{
"layout_engines": {
"entries": [
{
"type": "FocusLayoutEngine"
}
]
}
}
""",
false,
false
},
{
"""
layout_engines:
entries:
- type: FocusLayoutEngine
maximize: true
""",
true,
true
},
{
"""
{
"layout_engines": {
"entries": [
{
"type": "FocusLayoutEngine",
"maximize": true
}
]
}
}
""",
true,
false
},
{
"""
layout_engines:
entries:
- type: FocusLayoutEngine
maximize: false
""",
false,
true
},
{
"""
{
"layout_engines": {
"entries": [
{
"type": "FocusLayoutEngine",
"maximize": false
}
]
}
}
""",
false,
false
},
};

[Theory, MemberAutoSubstituteData<YamlLoaderCustomization>(nameof(FocusLayoutEngineConfig))]
public void Load_FocusLayoutEngine(string config, bool maximize, bool isYaml, IContext ctx)
{
// Given a valid config with FocusLayoutEngine set
ctx.PluginManager.LoadedPlugins.Returns([]);
YamlLoaderTestUtils.SetupFileConfig(ctx, config, isYaml);

// When loading the layout engine
bool result = YamlLoader.Load(ctx);

// Then the layout engine is loaded
Assert.True(result);

ILayoutEngine[] engines = YamlLoaderTestUtils.GetLayoutEngines(ctx);
Assert.Single(engines);
engines[0].Should().BeEquivalentTo(new FocusLayoutEngine(engines[0].Identity, maximize));
}

public static TheoryData<string, bool> InvalidFocusLayoutEngineConfig =>
new()
{
{
"""
layout_engines:
entries:
- type: FocusLayoutEngine
maximize: "bob"
""",
true
},
{
"""
{
"layout_engines": {
"entries": [
{
"type": "FocusLayoutEngine",
"maximize": "bob"
}
]
}
}
""",
false
},
};

[Theory, MemberAutoSubstituteData<YamlLoaderCustomization>(nameof(InvalidFocusLayoutEngineConfig))]
public void Load_InvalidFocusLayoutEngine(string config, bool isYaml, IContext ctx)
{
// Given an invalid config with FocusLayoutEngine set
ctx.PluginManager.LoadedPlugins.Returns([]);
YamlLoaderTestUtils.SetupFileConfig(ctx, config, isYaml);

// When loading the layout engine
bool result = YamlLoader.Load(ctx);

// Then the layout engine is not loaded
Assert.True(result);

ILayoutEngine[] engines = YamlLoaderTestUtils.GetLayoutEngines(ctx);
Assert.Empty(engines);
}
}
Loading