Tracking: light/dark mode #7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This is a tracking issue for light/dark mode switching, an advanced system that leverages functorOS's full system theming capabilities to provide automated and manual switching between light/dark variants of a system. This is a high priority for the functorOS team.
Current work to be done
The core theory and implementation of light/dark mode is completely done and has been running in my configuration in tandem with functorOS-next for quite a while.
However there are still a few minor issues to iron out. In particular the
switch-to-configuration
strategy described below requires administrator access so apolkit
rule needs to be created such that light/dark mode switching services can be done without inputting user credentials.Overview of light/dark mode implementation
The way we do this is very simple. In NixOS (by extension functorOS), all configuration is declarative and immutable. Therefore traditional tools like pywal are entirely the wrong approach for system theming, as they swap out configuration files on the fly. Rather, since NixOS already symlinks the entirety of the system/user configuration into place based on the currently selected generation, we simply hijack this system to create a light and dark variant of each generation.
We leverage a NixOS feature called specializations which allows you to define multiple variants of a single system with distinct options. This means that the only thing we need to do is define a light/dark mode specialization of the system with the colorscheme swapped, and we are basically done. NixOS will automatically generate light/dark variants of each generation with no further action. These will be visible and selectable in the boot menu, just like generations.
How do we swap on the fly though? Well, NixOS already allows you to hotswap system generations using
nixos-rebuild switch
(or equivalentnh os switch
). In fact,nixos-rebuild
is not a special program but rather just a bunch of scripts that find the correctswitch-to-configuration
binary to execute.switch-to-configuration
is a binary generated with each NixOS generation that provides theswitch
,boot
, and othernixos-rebuild commands
. Running theswitch-to-configuration
binary of a given generation will act on that generation. Accordingly,nixos-rebuild
simply figures out which generation we are trying to switch to and runs its correspondingswitch-to-configuration
binary.How does this information help us? Well, it means that if we can find the path to a system generation, we can directly hotswap to it just by finding its
switch-to-configuration
binary. When using specializations, the current system will contain a directory with symlinks to all of the specialized variants of the current booted generation. Hence, we can easily find the corresponding light/dark mode of our booted system and run itsswitch-to-configuration
binary to implement live light/dark switching.In functorOS, we use the convention dawn and dusk for light and dark mode respectively. Additionally, to reduce redundancy, we make the default system (without any specialization) the dark mode (aka "dusk") while the light mode is a specialization called "dawn." In theory we could also make "dusk" an additional specialization, but since the default system requires us to specify a color scheme anyways there's no reason to create the tertiary variant.
Then, the
switch-to-configuration
binaries will always be located at these paths:/nix/var/nix/profiles/system/specialisation/dawn/bin/switch-to-configuration
/nix/var/nix/profiles/system/bin/switch-to-configuration
Then it remains to write a few stupid simple bash scripts that handle the running of these binaries. We also create an auxiliary file called
/etc/polarity
that tells us whether our current booted system is dusk or dawn for convenience so that our bash script can implement a toggle feature.