Foyer is a Hyprland-specific QuickShell-based desktop shell with:
- menu bar
- notifications
- on-screen display
- application launcher
Foyer can currently only be installed via Home Manager.
- Add Foyer as an input to your configuration flake:
inputs.foyer.url = "github:jerbaroo/foyer";
- Include the Home Manager module:
homeConfigurations."your-user" = inputs.home-manager.lib.homeManagerConfiguration { inherit pkgs; modules = [ inputs.foyer.homeManagerModules.default ./home.nix ]; };
- Enable Foyer and configure its options. Required options are
highlighted.
programs.foyer = { accent = "#b4befe"; font = { name = "Cascadia Mono"; package = pkgs.cascadia-code; size = 18; }; actions = { audioSettings = lib.getExe pkgs.pwvucontrol; # required bluetoothSettings = lib.getExe' pkgs.blueman "blueman-manager"; # required lockScreen = lib.getExe pkgs.hyprlock; # required systemMonitor = "${lib.getExe pkgs.kitty} ${lib.getExe pkgs.btop}"; # required }; animation = { enter = { curve = [ 0.215 0.61 0.355 1 ]; durationMs = 150; }; exit = { curve = [ 0.215 0.61 0.355 1 ]; durationMs = 100; }; resize = { curve = [ 0.34 1.08 0.22 1 ]; durationMs = 280; }; slide = { curve = [ 0.215 0.61 0.355 1 ]; durationMs = 160; }; }; backgroundOpacity = 0.35; enable = true; # required iconTheme = { name = "Papirus-Dark"; package = pkgs.papirus-icon-theme; }; layout = { borderWidthPx = 2; cornerRadiusPx = 8; gapPx = 16; }; palette = { background = "#11111b"; controlActive = "#313244"; controlBorder = "#6c7086"; controlHover = "#45475a"; danger = "#f38ba8"; fieldBackground = "#1e1e2e"; notificationBody = "#f9e2af"; panelBackground = "#181825"; text = "#cdd6f4"; textMuted = "#a6adc8"; }; search.port = 1235; };
Foyer exports read-only layer namespaces which you can target with blur rules.
Make sure programs.foyer.backgroundOpacity is set to a suitable value. Also
pay attention to the ignore_alpha value, it should be greater than zero and
less than programs.foyer.backgroundOpacity.
wayland.windowManager.hyprland = {
configType = "lua";
extraConfig = let
namespaces = "^(${lib.concatStringsSep "|" (builtins.attrValues config.programs.foyer.layers)})$";
in ''
hl.layer_rule({
match = {
namespace = ${builtins.toJSON namespaces},
},
blur = true,
ignore_alpha = 0.001,
})
'';
};wayland.windowManager.hyprland.settings.layer_rule = [
{
blur = true;
ignore_alpha = 0.001;
match.namespace =
"^(${lib.concatStringsSep "|" (builtins.attrValues config.programs.foyer.layers)})$";
}
];Each surface supports show, hide, and toggle. These commands control
running instances; they don't start services. Hiding the bar keeps
notifications, the OSD, and sleep/lock inhibitors running.
foyer bar hide
foyer launcher show
foyer notifications togglefoyer lock starts a minimal lock screen using the host's login PAM service.
To set a keybinding to toggle notifications use "${lib.getExe config.programs.foyer.package} bar toggle" in Home Manager keybindings.
“No sleep” holds a systemd sleep inhibitor. “No lock” holds a systemd idle
inhibitor, pausing automatic locking and screen-off. Manual locking is still
available. Your idle daemon must honour logind idle inhibitors; hypridle does
so by default with
ignore_systemd_inhibit = false.
Foyer installs its configuration under $XDG_CONFIG_HOME/foyer (normally
~/.config/foyer). Its user services are foyer-bar, foyer-launcher, and
foyer-server. Layer namespaces use the foyer- prefix and are exported
through programs.foyer.layers.
nix developGenerates development settings automatically and configures the import path.
Run inside nix develop; it adds quickshell/dev-generated to
QML_IMPORT_PATH so QML can find FoyerConfig and Cmds.
systemctl --user stop foyer-bar foyer-launcher
quickshell -p quickshell/bar.qml
# In another terminal, enter nix develop first:
quickshell -p quickshell/app_launcher.qml
# From a third dev shell, open the launcher:
foyer launcher showEdit QML in the checkout; no rebuild is needed. After changing
dev-settings.nix or templates, run nix run .#configure-dev or re-enter the
dev shell. It writes Config.qml and Cmds under the ignored
quickshell/dev-generated/ directory. Production files are unaffected. The
launcher also needs the search server below.
python cli.py --help
cargo test --manifest-path foyer-server/Cargo.toml
cargo clippy --manifest-path foyer-server/Cargo.tomlqmlformat -i quickshell/bar/HoverPanel.qml
nixfmt configure-dev.nix defaults.nix dev-settings.nix flake.nix generate-settings.nix home-manager.nix options.nixsystemctl --user stop foyer-server
cargo run --manifest-path foyer-server/Cargo.toml -- --port 1235
# After exiting the development server:
systemctl --user start foyer-serverServer defaults to port 1235.
quickshell -p quickshell/nmtui.qmljournalctl --user -u foyer-server -f
journalctl --user -u foyer-bar -f
systemctl --user restart foyer-bar foyer-launcher