Add new module for configuring window-rules (#199)

This commit is contained in:
Robin Appelman 2024-06-22 20:48:19 +02:00 committed by GitHub
parent 6f182700ad
commit 675d5fc9cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 189 additions and 1 deletions

View File

@ -32,6 +32,7 @@ At the moment `plasma-manager` supports configuring the following:
- Panels (via the `panels` module)
- Screen locker (via the `kscreenlocker` module)
- Fonts (via the `fonts` module)
- Window Rules (via the `window-rules` module)
- KDE apps (via the `apps` module). In particular the following kde apps have
modules in `plasma-manager`:
- kate

View File

@ -104,6 +104,28 @@
}
];
window-rules = [
{
description = "Dolphin";
match = {
window-class = {
value = "dolphin";
type = "substring";
};
window-types = [ "normal" ];
};
apply = {
noborder = {
value = true;
apply = "force";
};
# `apply` defaults to "apply-initially"
maximizehoriz = true;
maximizevert = true;
};
}
];
#
# Some mid-level settings:

View File

@ -13,6 +13,7 @@
./spectacle.nix
./startup.nix
./windows.nix
./window-rules.nix
./workspace.nix
];

View File

@ -58,7 +58,7 @@ let
"plasmarc"
"plasmashellrc"
"systemsettingsrc"
] else [ ]);
] else lib.optional (builtins.length plasmaCfg.window-rules > 0) "kwinrulesrc");
in
{
options.programs.plasma = {

164
modules/window-rules.nix Normal file
View File

@ -0,0 +1,164 @@
{ lib
, pkgs
, config
, ...
}:
with lib.types; let
inherit (builtins) length listToAttrs foldl' toString attrNames getAttr hasAttr concatStringsSep add isAttrs;
inherit (lib) mkOption mkIf;
inherit (lib.trivial) mergeAttrs;
inherit (lib.lists) imap0;
inherit (lib.attrsets) optionalAttrs filterAttrs mapAttrsToList;
cfg = config.programs.plasma;
applyRules = {
"do-not-affect" = 1;
"force" = 2;
"initially" = 3;
"remember" = 4;
};
matchRules = {
"exact" = 1;
"substring" = 2;
"regex" = 3;
};
windowTypes = {
normal = 1;
desktop = 2;
dock = 4;
toolbar = 8;
torn-of-menu = 16;
dialog = 32;
menubar = 128;
utility = 256;
spash = 512;
osd = 65536;
};
matchNameMap = {
"window-class" = "wmclass";
"window-types" = "types";
};
matchOptionType = hasMatchWhole:
submodule {
options =
{
value = mkOption {
type = str;
description = "${name} to match";
};
type = mkOption {
type = enum (attrNames matchRules);
default = "exact";
description = "${name} match type";
};
}
// optionalAttrs hasMatchWhole {
match-whole = mkOption {
type = bool;
default = true;
description = "Match whole ${name}";
};
};
};
basicValueType = oneOf [ bool float int str ];
applyOptionType = submodule {
options = {
value = mkOption {
type = basicValueType;
description = "value to set";
};
apply = mkOption {
type = enum (attrNames applyRules);
default = "initially";
description = "how to apply the value";
};
};
};
mkMatchOption = name: hasMatchWhole:
mkOption {
type = nullOr (coercedTo str (value: { inherit value; }) (matchOptionType hasMatchWhole));
default = null;
description = "${name} matching";
};
fixMatchName = name: matchNameMap.${name} or name;
buildMatchRule = name: rule: ({
"${fixMatchName name}" = rule.value;
"${fixMatchName name}match" = getAttr rule.type matchRules;
}
// optionalAttrs (rule ? match-whole) {
"${fixMatchName name}complete" = rule.match-whole;
});
buildApplyRule = name: rule: {
"${name}" = rule.value;
"${name}rule" = getAttr rule.apply applyRules;
};
buildWindowRule = rule:
let
matchOptions = filterAttrs (_name: isAttrs) rule.match;
matchRules = mapAttrsToList buildMatchRule matchOptions;
applyRules = mapAttrsToList buildApplyRule rule.apply;
combinedRules = foldl' mergeAttrs { } (matchRules ++ applyRules);
in
{
Description = rule.description;
}
// optionalAttrs (rule.match.window-types != 0) {
types = rule.match.window-types;
}
// combinedRules;
windowRules = listToAttrs (imap0
(i: rule: {
name = toString (i + 1);
value = buildWindowRule rule;
})
cfg.window-rules);
in
{
options.programs.plasma = {
window-rules = mkOption {
type = listOf (submodule {
options = {
match = mkOption {
type = submodule {
options = {
window-class = mkMatchOption "Window class" true;
window-role = mkMatchOption "Window role" false;
title = mkMatchOption "Title" false;
machine = mkMatchOption "clientmachine" false;
window-types = mkOption {
type = listOf (enum (attrNames windowTypes));
default = [ ];
description = "Window types to match";
apply = values: foldl' add 0 (map (val: getAttr val windowTypes) values);
};
};
};
};
apply = mkOption {
type = attrsOf (coercedTo basicValueType (value: { inherit value; }) applyOptionType);
default = { };
description = "Values to apply";
};
description = mkOption {
type = str;
description = "value to set";
};
};
});
description = "Kwin window rules";
default = [ ];
};
};
config = mkIf (length cfg.window-rules > 0) {
programs.plasma.configFile = {
kwinrulesrc =
{
General = {
count = length cfg.window-rules;
rules = concatStringsSep "," (attrNames windowRules);
};
}
// windowRules;
};
};
}