From 6e132be7db7cfc766c4a704ebad0af28bb9a7516 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Thu, 4 Aug 2022 22:28:40 -0700 Subject: [PATCH] sway: allow overriding or disabling our configs per user --- Makefile | 1 - README.md | 6 ++-- fedora-sway-configs.spec.rpkg | 1 - scripts/sway/layered-include | 50 +++++++++++++++++++++++++++++++ sway/50-fedora.conf.in | 14 --------- sway/config.d/90-bar-swaybar.conf | 17 ----------- sway/{config => config.in} | 24 +++++++++++++-- sway/config.test | 4 +-- 8 files changed, 76 insertions(+), 41 deletions(-) create mode 100755 scripts/sway/layered-include delete mode 100644 sway/50-fedora.conf.in delete mode 100644 sway/config.d/90-bar-swaybar.conf rename sway/{config => config.in} (84%) diff --git a/Makefile b/Makefile index 7607b72..7b96c5f 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,6 @@ install-sddm: install-sway: build install -D -m 0644 -pv -t $(DESTDIR)$(SYSCONFDIR)/sway sway/config - install -D -m 0644 -pv -t $(DESTDIR)$(SYSCONFDIR)/sway/config.d sway/50-fedora.conf install -D -m 0644 -pv -t $(DESTDIR)$(DATADIR)/wayland-sessions sway/sway.desktop install -D -m 0644 -pv -t $(DESTDIR)$(DATADIR)/sway/config.d sway/config.d/*.conf install -D -m 0755 -pv -t $(DESTDIR)$(LIBEXECDIR)/sway scripts/sway/* diff --git a/README.md b/README.md index 4f2eed9..6e7d2bc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ ## Sway config -Sway config is split to 3 parts: +Sway config is split to 2 parts: * `sway/config` — is the main config to be installed to `/etc/sway/config`. Some light changes are applied, such as removing things we want to override later (bar, launcher, etc.). - * `sway/config.d/*.conf` — is a set of small self-contained configuration snippets with each containing the description and the list of required packages. Will be installed as `/usr/share/sway/config.d/*.conf`. - * `sway/50-fedora.conf` is a list of config snippets included by default. + * `sway/config.d/*.conf` — is a set of small self-contained configuration snippets with each containing the description and the list of required packages. + Will be installed as `/usr/share/sway/config.d/*.conf` and loaded by default. ## Upstream config changes sync diff --git a/fedora-sway-configs.spec.rpkg b/fedora-sway-configs.spec.rpkg index 2376121..b1f224f 100644 --- a/fedora-sway-configs.spec.rpkg +++ b/fedora-sway-configs.spec.rpkg @@ -103,7 +103,6 @@ to use Sway for the greeter display server. %files -n sway-config-fedora %license LICENSE %config(noreplace) %{_sysconfdir}/sway/config -%config(noreplace) %{_sysconfdir}/sway/config.d/50-fedora.conf # should it be in the swaylock package? %dir %{_sysconfdir}/swaylock %config(noreplace) %{_sysconfdir}/swaylock/config diff --git a/scripts/sway/layered-include b/scripts/sway/layered-include new file mode 100755 index 0000000..d61f338 --- /dev/null +++ b/scripts/sway/layered-include @@ -0,0 +1,50 @@ +#!/usr/bin/python3 +""" +A helper for doing the config layering with sway style `include` expressions +(which are pretty much just shell/wordexp(3) patterns). + +The script is meant to be invoked from sway (i3?) config as following +``` +include '$(/path/to/the/script "/path1/*.conf" "/path2/*.conf" ...)' +``` +(note the quoting, it is important), expand each expression to a list of files +and layer them in a way that the files with the same name matched by a later +patterns loaded over the earlier matches. +""" + +import os +import sys +from hashlib import sha256 +from glob import iglob +from os.path import basename, expandvars +from tempfile import gettempdir + + +def wordexp(value: str): + """A very bad wordexp(3) approximation""" + value = expandvars(value) + return iglob(value) + + +configs: dict[str, str] = {} + +for arg in sys.argv[1:]: + # Expand the expression and collect the paths while overwriting previously + # collected entries with the same filename. + # Our internal wordexp is quite incomplete, but the calling wordexp should + # do all the heavy lifting and expand the variables. + for inc in wordexp(arg): + configs[basename(inc)] = inc + +# Write collected paths as an include directives to a temporary file. +# This step is required because the filenames may contain $IFS characters +# (whitespaces — I don't expect this to happen, but can't exclude the +# possibility), and wordexp(3) will handle that quite bad. +fnhash = sha256("\n".join(sys.argv).encode("UTF-8")) +fname = f"{gettempdir()}/sway-{os.getuid()}-{str(fnhash.hexdigest())}.conf" +fd = os.open(fname, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, mode=0o600) +with open(fd, mode="w", encoding="UTF-8") as file: + for key in sorted(configs): + file.write(f"include '{configs[key]}'\n") +# Send the temporary file name back to a calling wordexp +print(fname) diff --git a/sway/50-fedora.conf.in b/sway/50-fedora.conf.in deleted file mode 100644 index bf2d8cd..0000000 --- a/sway/50-fedora.conf.in +++ /dev/null @@ -1,14 +0,0 @@ -# Enable some configuration snippets by default - -include $DATADIR/sway/config.d/20-swayidle.conf - -include $DATADIR/sway/config.d/30-bindings-brightness-light.conf -include $DATADIR/sway/config.d/30-bindings-media-playerctl.conf -include $DATADIR/sway/config.d/30-bindings-volume-pactl.conf - -include $DATADIR/sway/config.d/60-rules-browser.conf -include $DATADIR/sway/config.d/60-rules-lxqt-policykit-agent.conf - -include $DATADIR/sway/config.d/90-bar-waybar.conf - -include $DATADIR/sway/config.d/95-autostart-lxqt-policykit-agent.conf diff --git a/sway/config.d/90-bar-swaybar.conf b/sway/config.d/90-bar-swaybar.conf deleted file mode 100644 index 90c4b64..0000000 --- a/sway/config.d/90-bar-swaybar.conf +++ /dev/null @@ -1,17 +0,0 @@ -# Status Bar: swaybar (the upstream default) -# -# Read `man 5 sway-bar` for more information about this section. - -bar { - position top - - # When the status_command prints a new line to stdout, swaybar updates. - # The default just shows the current date and time. - status_command while date +'%Y-%m-%d %I:%M:%S %p'; do sleep 1; done - - colors { - statusline #ffffff - background #323232 - inactive_workspace #32323200 #32323200 #5c5c5c - } -} diff --git a/sway/config b/sway/config.in similarity index 84% rename from sway/config rename to sway/config.in index 1e62d5d..6ded86b 100644 --- a/sway/config +++ b/sway/config.in @@ -199,5 +199,25 @@ mode "resize" { } bindsym $mod+r mode "resize" -# Restricted to .conf files to avoid including .rpmnew/.rpmsave -include /etc/sway/config.d/*.conf +# Include configs from 3 locations: +# - $DATADIR/sway/config.d +# - $SYSCONFDIR/sway/config.d +# - $XDG_CONFIG_HOME/sway/config.d ($HOME/.config/sway/config.d) +# +# If multiple directories contain the files with the same name, the later +# directory takes precedence; `$XDG_CONFIG_HOME/sway/config.d/20-swayidle.conf` +# will always be loaded instead of `$DATADIR/sway/config.d/20-swayidle.conf` +# or `$SYSCONFDIR/sway/config.d/20-swayidle.conf` +# +# This mechanism permits overriding our default configuration per-system +# ($SYSCONFDIR) or per-user ($XDG_CONFIG_HOME) basis. Just create the file you +# want to modify/override in the higher-level directory. +# +# For example, to disable the default bar from Fedora configs, you'll need to +# $ echo -n > "$HOME/.config/sway/config.d/90-bar.conf" +# +# Note the quoting, the $() and the arguments quoting. All the parts are equally +# important to make the magic work. And if you want to learn the secret behind +# the trick, it's all in the `wordexp(3)`. +# +include '$($LIBEXECDIR/sway/layered-include "$DATADIR/sway/config.d/*.conf" "$SYSCONFDIR/sway/config.d/*.conf" "${XDG_CONFIG_HOME:-$HOME/.config}/sway/config.d/*.conf")' diff --git a/sway/config.test b/sway/config.test index 88953b7..a6d0b4b 100644 --- a/sway/config.test +++ b/sway/config.test @@ -6,7 +6,5 @@ set $SYSCONFDIR $SRCDIR set $LIBEXECDIR $SRCDIR/scripts # Intentionally broken set $HOME $SRCDIR -# Include base config first to set the variables -include config # Include unprocessed config to allow variable substitution -include 50-fedora.conf.in +include config.in