mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-15 05:12:28 +01:00
A window that opens goes after the focused container. A workspace can now say
another place for its windows: the primary or the secondary tile, before or
after the focused container, the end of the list, or a place by number, counting
from 1. The place is for every window, or for the windows that match a rule on
their program, app id, title or path; the rules are the conditions the ignore
and manage rules are made of, and the first that matches in key order decides. A
place that does not exist, such as the secondary tile of a workspace with one
container, is the default place.
A place is read from a name, a number or text that is a number. The
documentation of the setting shows a number and a map's keys can only be text,
and komorebi for Windows (83c4e11d) reads only text, so the form its own page
shows is refused there.
A place that was reserved with preselect-direction is used before the rules are
asked, and a locked container keeps its index. A workspace whose
window_container_behaviour is Append puts a window in the focused container, and
the rules are not used.
A workspace takes the rules from the key initial_window_placement_rules of its
entry in komorebi.json. The key is in schema.json and so in the typed config
option of the module, and the page docs/initial-window-placement-rules.md says
how to write it. vm-placement opens windows in a headless KWin and checks where
they go, by program, app id and title.
The schema that schemars derives for a place is an object with a Placement or an
Index key, which is not what is read or written, so a check against it refuses a
file that the daemon reads. The schema of PlacementTarget is written by hand
instead: a name, a number, or text that is a number. A file with a place of each
form is checked against schema.json, and the module's config option takes them.
138 lines
4.4 KiB
Nix
138 lines
4.4 KiB
Nix
# `nix-options-validation`: the options `just nixgen` makes from `schema.json`, evaluated against
|
|
# the example configuration, whose JSON is checked against the schema, and against the example
|
|
# file of the docs, and against the places a workspace can give the windows that open, in every
|
|
# form komorebi reads. Run with `nix build -f nix/tests/default.nix`, or as a check of the flake.
|
|
{
|
|
pkgs ? import <nixpkgs> { },
|
|
}:
|
|
let
|
|
lib = pkgs.lib;
|
|
|
|
# the Nix module system uses null for an optional field that is not set, and the schema wants
|
|
# the field to be absent
|
|
filterNulls =
|
|
value:
|
|
if value == null then
|
|
null
|
|
else if builtins.isList value then
|
|
map filterNulls (builtins.filter (x: x != null) value)
|
|
else if builtins.isAttrs value then
|
|
lib.filterAttrs (_n: v: v != null) (builtins.mapAttrs (_n: v: filterNulls v) value)
|
|
else
|
|
value;
|
|
|
|
evaluated =
|
|
(lib.evalModules {
|
|
modules = [
|
|
(import ../komorebi-options.nix)
|
|
(import ./komorebi-example.nix)
|
|
];
|
|
}).config.komorebi;
|
|
|
|
evaluatedJson = pkgs.writeText "komorebi-example-from-nix.json" (
|
|
builtins.toJSON (filterNulls evaluated)
|
|
);
|
|
|
|
# where a workspace puts the windows that open, in each form komorebi reads: a name, a number,
|
|
# text that is a number, and a map of places to rules (whose keys are text)
|
|
placements =
|
|
(lib.evalModules {
|
|
modules = [
|
|
(import ../komorebi-options.nix)
|
|
{
|
|
komorebi.monitors = [
|
|
{
|
|
workspaces = [
|
|
{
|
|
name = "name";
|
|
initial_window_placement_rules = "Primary";
|
|
}
|
|
{
|
|
name = "number";
|
|
initial_window_placement_rules = 3;
|
|
}
|
|
{
|
|
name = "text";
|
|
initial_window_placement_rules = "3";
|
|
}
|
|
{
|
|
name = "map";
|
|
initial_window_placement_rules = {
|
|
Primary = {
|
|
kind = "Exe";
|
|
id = "firefox";
|
|
matching_strategy = "Equals";
|
|
};
|
|
"2" = [
|
|
{
|
|
kind = "Title";
|
|
id = "notes";
|
|
matching_strategy = "StartsWith";
|
|
}
|
|
];
|
|
};
|
|
}
|
|
];
|
|
}
|
|
];
|
|
}
|
|
];
|
|
}).config.komorebi;
|
|
|
|
placementsJson = pkgs.writeText "komorebi-placements.json" (
|
|
builtins.toJSON (filterNulls placements)
|
|
);
|
|
|
|
# a place that is neither a name nor a number
|
|
nowhereJson = pkgs.writeText "komorebi-nowhere.json" (
|
|
builtins.toJSON {
|
|
monitors = [
|
|
{
|
|
workspaces = [
|
|
{
|
|
name = "x";
|
|
initial_window_placement_rules = "Nowhere";
|
|
}
|
|
];
|
|
}
|
|
];
|
|
}
|
|
);
|
|
|
|
# the file has comment lines (komorebi reads them), which the schema checker does not
|
|
exampleJson = pkgs.runCommand "komorebi.example.json" { } ''
|
|
grep -v '^\s*//' ${../../docs/komorebi.example.json} > $out
|
|
'';
|
|
schema = ../../schema.json;
|
|
in
|
|
pkgs.runCommand "nix-options-validation"
|
|
{
|
|
nativeBuildInputs = [
|
|
pkgs.check-jsonschema
|
|
pkgs.jq
|
|
];
|
|
}
|
|
''
|
|
echo "Validating the example, written in Nix, against the schema..."
|
|
check-jsonschema --schemafile ${schema} ${evaluatedJson}
|
|
|
|
echo "Validating the example file of the docs against the schema..."
|
|
check-jsonschema --schemafile ${schema} ${exampleJson}
|
|
|
|
echo "Checking that the two examples say the same..."
|
|
jq -e --slurpfile example ${exampleJson} 'contains($example[0])' ${evaluatedJson} > /dev/null
|
|
|
|
echo "Validating the places a workspace can give a new window, in every form, against the schema..."
|
|
check-jsonschema --schemafile ${schema} ${placementsJson}
|
|
jq -e '[.monitors[0].workspaces[].initial_window_placement_rules | type] == ["string", "number", "string", "object"]' ${placementsJson} > /dev/null
|
|
|
|
echo "Checking that the schema refuses a place that is neither a name nor a number..."
|
|
if check-jsonschema --schemafile ${schema} ${nowhereJson} > /dev/null 2>&1; then
|
|
echo "the schema accepts a place that komorebi cannot read" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "All validations passed!"
|
|
touch $out
|
|
''
|