diff --git a/modules/applications/fcitx5/home.nix b/modules/applications/fcitx5/home.nix index 5b561cd..21771ae 100644 --- a/modules/applications/fcitx5/home.nix +++ b/modules/applications/fcitx5/home.nix @@ -1,6 +1,44 @@ +{ + config, + lib, + osConfig, + ... +}: +let + mkSessionService = target: { + Unit = { + Description = "Fcitx 5 input method"; + Documentation = [ "https://fcitx-im.org/" ]; + PartOf = [ target ]; + After = [ target ]; + }; + + Service = { + ExecStart = "${osConfig.i18n.inputMethod.package}/bin/fcitx5 --replace"; + Restart = "on-failure"; + }; + + Install.WantedBy = [ target ]; + }; +in { home.file.".config/fcitx5/config" = { recursive = true; source = ./config; }; + + # niri starts XDG autostart entries through systemd. The explicit service + # below is shared with labwc, so suppress the package-provided entry. + xdg.configFile."autostart/org.fcitx.Fcitx5.desktop".text = '' + [Desktop Entry] + Hidden=true + ''; + + systemd.user.services = + lib.optionalAttrs config.my.applications.niri.enable { + fcitx5-niri = mkSessionService "niri.service"; + } + // lib.optionalAttrs config.my.applications.labwc.enable { + fcitx5-labwc = mkSessionService "labwc-session.target"; + }; } diff --git a/modules/applications/labwc/home.nix b/modules/applications/labwc/home.nix index 09c5ccf..0ab647c 100644 --- a/modules/applications/labwc/home.nix +++ b/modules/applications/labwc/home.nix @@ -1,24 +1,157 @@ { lib, pkgs, ... }: +let + action = key: name: { + "@key" = key; + action = { + "@name" = name; + }; + }; + + execute = key: command: { + "@key" = key; + action = { + "@name" = "Execute"; + "@command" = command; + }; + }; + + desktopKeybinds = lib.concatMap ( + desktop: + let + number = toString desktop; + in + [ + { + "@key" = "W-${number}"; + action = { + "@name" = "GoToDesktop"; + "@to" = number; + }; + } + { + "@key" = "W-C-${number}"; + action = { + "@name" = "SendToDesktop"; + "@to" = number; + }; + } + ] + ) (lib.range 1 9); +in { - xdg.configFile = { - "labwc/rc.xml".source = ./rc.xml; + wayland.windowManager.labwc = { + enable = true; + # NixOS owns the package so Home Manager only generates the user config. + package = null; - "labwc/environment".text = '' - XKB_DEFAULT_LAYOUT=jp - XKB_DEFAULT_OPTIONS=ctrl:nocaps - ''; + rc = { + core = { + decoration = "client"; + gap = 10; + autoEnableOutputs = "yes"; + reuseOutputMode = "yes"; + }; - "labwc/autostart".text = '' - # Pull in graphical-session.target so Home Manager services such as - # portals, Vicinae, and the idle manager follow the labwc session. - ${lib.getExe' pkgs.systemd "systemctl"} --user --no-block start labwc-session.target + theme = { + name = "Dracula"; + cornerRadius = 8; + dropShadows = "yes"; + dropShadowsOnTiled = "yes"; + }; - # labwc does not run XDG autostart entries itself. Start the input method - # explicitly so both native Wayland and XWayland applications can use it. - fcitx5 -d --replace >/dev/null 2>&1 & + windowSwitcher = { + "@preview" = "yes"; + "@outlines" = "yes"; + osd = { + "@style" = "thumbnail"; + }; + }; - NOCTALIA_CONFIG_HOME="$HOME/.config/noctalia-labwc" noctalia >/dev/null 2>&1 & - ${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1 >/dev/null 2>&1 & - ''; + focus = { + followMouse = "yes"; + followMouseRequiresMovement = "yes"; + raiseOnFocus = "no"; + }; + + desktops = { + "@number" = 9; + "@popupTime" = 500; + "@prefix" = "Workspace"; + }; + + keyboard = { + default = true; + numlock = "on"; + keybind = [ + (action "W-q" "Close") + (action "W-f" "ToggleMaximize") + (action "W-Tab" "NextWindow") + (action "W-S-Tab" "PreviousWindow") + (action "W-j" "NextWindow") + (action "W-k" "PreviousWindow") + { + "@key" = "W-a"; + action = { + "@name" = "ShowMenu"; + "@menu" = "client-list-combined-menu"; + }; + position = { + x = "center"; + y = "center"; + }; + } + (execute "W-t" "ghostty") + (execute "W-d" "vicinae toggle") + (execute "W-e" "nautilus --new-window") + (execute "W-l" "loginctl lock-session") + (execute "W-v" "vicinae vicinae://launch/clipboard/history?toggle=true") + (execute "W-space" "ghostty +toggle-quick-terminal") + (execute "W-p" "wdisplays") + (execute "W-s" "noctalia msg panel-toggle control-center") + (execute "W-comma" "noctalia msg settings-toggle") + (action "W-S-e" "Exit") + ] + ++ desktopKeybinds + ++ [ + (execute "XF86AudioRaiseVolume" "noctalia msg volume-up") + (execute "XF86AudioLowerVolume" "noctalia msg volume-down") + (execute "XF86AudioMute" "noctalia msg volume-mute") + (execute "XF86AudioMicMute" "noctalia msg mic-mute") + (execute "XF86MonBrightnessUp" "noctalia msg brightness-up") + (execute "XF86MonBrightnessDown" "noctalia msg brightness-down") + ]; + }; + + mouse.default = true; + + libinput.device = [ + { + "@category" = "touchpad"; + naturalScroll = "yes"; + tap = "yes"; + tapAndDrag = "yes"; + dragLock = "yes"; + clickMethod = "clickfinger"; + scrollMethod = "twoFinger"; + scrollFactor = "4.0"; + } + { + "@category" = "non-touch"; + pointerSpeed = "-0.1"; + accelProfile = "flat"; + } + ]; + }; + + environment = [ + "XKB_DEFAULT_LAYOUT=jp" + "XKB_DEFAULT_OPTIONS=ctrl:nocaps" + ]; + + # Pull in graphical-session.target so Home Manager services such as + # portals, Vicinae, and the idle manager follow the labwc session. + systemd.extraCommands = [ + "${lib.getExe' pkgs.systemd "systemctl"} --user --no-block start labwc-session.target" + ]; }; } diff --git a/modules/applications/labwc/rc.xml b/modules/applications/labwc/rc.xml deleted file mode 100644 index 4237980..0000000 --- a/modules/applications/labwc/rc.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - - server - 10 - yes - yes - - - - Dracula - 8 - yes - yes - - - - - - - - yes - yes - no - - - - - - - - - - - - - - - - - - - - - - - - - - - - - center - center - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - yes - yes - yes - yes - clickfinger - twoFinger - 4.0 - - - -0.1 - flat - - - diff --git a/modules/applications/niri/home.nix b/modules/applications/niri/home.nix index d595206..92b07b6 100644 --- a/modules/applications/niri/home.nix +++ b/modules/applications/niri/home.nix @@ -31,15 +31,6 @@ in }; }; - spawn-at-startup = [ - { command = [ "noctalia" ]; } - { - command = [ - "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1" - ]; - } - ]; - cursor.size = 16; layout = { diff --git a/modules/applications/noctalia/home.nix b/modules/applications/noctalia/home.nix index c67836b..428687b 100644 --- a/modules/applications/noctalia/home.nix +++ b/modules/applications/noctalia/home.nix @@ -39,6 +39,25 @@ let ${lib.getExe config.programs.noctalia.package} config validate ${labwcRawConfig} cp ${labwcRawConfig} $out ''; + + mkSessionService = target: environment: { + Unit = { + Description = "Noctalia Wayland desktop shell"; + Documentation = [ "https://docs.noctalia.dev/" ]; + PartOf = [ target ]; + After = [ target ]; + }; + + Service = { + ExecStart = lib.getExe config.programs.noctalia.package; + Restart = "on-failure"; + } + // lib.optionalAttrs (environment != [ ]) { + Environment = environment; + }; + + Install.WantedBy = [ target ]; + }; in { home.packages = [ pkgs.networkmanagerapplet ]; @@ -54,8 +73,7 @@ in programs.noctalia = { enable = true; - # Both compositors start Noctalia themselves so labwc can select its own - # config home without racing the generic graphical-session service. + # Session-specific services below let labwc select its own config home. systemd.enable = false; settings = { @@ -74,6 +92,11 @@ in fingerprint = false; }; + osd.kinds = { + keyboard_layout = false; + media = false; + }; + bar.main = { margin_ends = 15; position = "top"; @@ -214,5 +237,15 @@ in }; }; + systemd.user.services = + lib.optionalAttrs config.my.applications.niri.enable { + noctalia-niri = mkSessionService "niri.service" [ ]; + } + // lib.optionalAttrs config.my.applications.labwc.enable { + noctalia-labwc = mkSessionService "labwc-session.target" [ + "NOCTALIA_CONFIG_HOME=%h/.config/noctalia-labwc" + ]; + }; + xdg.configFile."noctalia-labwc/noctalia/config.toml".source = labwcConfig; } diff --git a/modules/profiles/README.md b/modules/profiles/README.md index 528ad34..4e02d51 100644 --- a/modules/profiles/README.md +++ b/modules/profiles/README.md @@ -50,8 +50,10 @@ when removing it from any supported host would make that host invalid. Select independent concerns independently in `hosts/default.nix`. For example, a NixOS desktop can combine `interface.labwc` and `interface.niri` to provide both sessions while sharing `interface.linux-desktop` and `interface.gui`. -The shared Linux desktop profile provides the common desktop applications; both -session profiles select ly. A daily-use macOS development machine can combine `interface.macos`, +The shared Linux desktop profile provides the common desktop applications and +session-independent services; both session profiles select ly. The laptop +platform selects niri as Ly's default session, while the desktop platform +selects labwc. A daily-use macOS development machine can combine `interface.macos`, `workload.development`, and `workload.personal`. Hardware support does not implicitly select an interface or workload. diff --git a/modules/profiles/interface/linux-desktop/meta.nix b/modules/profiles/interface/linux-desktop/meta.nix index 43bcc5a..4b142f6 100644 --- a/modules/profiles/interface/linux-desktop/meta.nix +++ b/modules/profiles/interface/linux-desktop/meta.nix @@ -8,6 +8,7 @@ "applications.gtk" "applications.nautilus" "hardwares.graphics" + "services.polkit-gnome" "systems.audio" "systems.fonts" ]; diff --git a/modules/services/polkit-gnome/home.nix b/modules/services/polkit-gnome/home.nix new file mode 100644 index 0000000..1a60bbf --- /dev/null +++ b/modules/services/polkit-gnome/home.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + pkgs, + ... +}: +let + mkSessionService = target: { + Unit = { + Description = "GNOME PolicyKit authentication agent"; + Documentation = [ "man:polkit(8)" ]; + PartOf = [ target ]; + After = [ target ]; + }; + + Service = { + ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; + Restart = "on-failure"; + }; + + Install.WantedBy = [ target ]; + }; +in +{ + systemd.user.services = + lib.optionalAttrs config.my.applications.niri.enable { + polkit-gnome-niri = mkSessionService "niri.service"; + } + // lib.optionalAttrs config.my.applications.labwc.enable { + polkit-gnome-labwc = mkSessionService "labwc-session.target"; + }; +} diff --git a/modules/services/polkit-gnome/nixos.nix b/modules/services/polkit-gnome/nixos.nix new file mode 100644 index 0000000..8029f61 --- /dev/null +++ b/modules/services/polkit-gnome/nixos.nix @@ -0,0 +1,3 @@ +{ + security.polkit.enable = true; +}