diff --git a/flake.lock b/flake.lock index 219e8ba..872382a 100644 --- a/flake.lock +++ b/flake.lock @@ -512,6 +512,27 @@ "type": "github" } }, + "home-manager_3": { + "inputs": { + "nixpkgs": [ + "nix-hazkey", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778444552, + "narHash": "sha256-f18pIiR9q/p1vHY93gmAum7aHhQOG49oGvAB9+lptRo=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "dcebe66f958673729896eec2de4abfd86ef22d21", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, "lanzaboote": { "inputs": { "crane": "crane", @@ -634,6 +655,27 @@ "type": "github" } }, + "nix-hazkey": { + "inputs": { + "home-manager": "home-manager_3", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779529080, + "narHash": "sha256-CHa5L3I71NbPUNJp1gmmwbh91tKsZPyuRK50mLHjAVY=", + "owner": "aster-void", + "repo": "nix-hazkey", + "rev": "24cb2926666836988e78ceebeb67ad6c5a387ac3", + "type": "github" + }, + "original": { + "owner": "aster-void", + "repo": "nix-hazkey", + "type": "github" + } + }, "nix-index-database": { "inputs": { "nixpkgs": [ @@ -1040,6 +1082,7 @@ "llm-agents": "llm-agents", "niri-flake": "niri-flake", "nix-darwin": "nix-darwin", + "nix-hazkey": "nix-hazkey", "nix-index-database": "nix-index-database", "nixos-hardware": "nixos-hardware", "nixos-wsl": "nixos-wsl", diff --git a/flake.nix b/flake.nix index 6847993..3acd593 100644 --- a/flake.nix +++ b/flake.nix @@ -23,6 +23,11 @@ # Desktop niri-flake.url = "github:sodiboo/niri-flake"; + nix-hazkey = { + url = "github:aster-void/nix-hazkey"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + stylix = { url = "github:nix-community/stylix"; inputs.nixpkgs.follows = "nixpkgs"; diff --git a/modules/applications/discord/home.nix b/modules/applications/discord/home.nix index c0cb43e..fcc10c1 100644 --- a/modules/applications/discord/home.nix +++ b/modules/applications/discord/home.nix @@ -1,4 +1,19 @@ { lib, pkgs, ... }: +let + vesktop = pkgs.vesktop.overrideAttrs (oldAttrs: { + # Electron does not enable the PipeWire WebRTC capturer in Vesktop's + # wrapper, so Wayland compositors cannot hand screen sharing to their + # xdg-desktop-portal backend. + postFixup = + builtins.replaceStrings + [ "WaylandWindowDecorations" ] + [ "WaylandWindowDecorations,WebRTCPipeWireCapturer" ] + oldAttrs.postFixup; + }); +in lib.mkIf pkgs.stdenv.hostPlatform.isLinux { - programs.vesktop.enable = true; + programs.vesktop = { + enable = true; + package = vesktop; + }; } diff --git a/modules/applications/fcitx5/meta.nix b/modules/applications/fcitx5/meta.nix new file mode 100644 index 0000000..d6337b7 --- /dev/null +++ b/modules/applications/fcitx5/meta.nix @@ -0,0 +1,6 @@ +{ inputs, ... }: +{ + description = "Fcitx 5 input method framework with Hazkey Japanese input"; + + imports.nixos = [ inputs.nix-hazkey.nixosModules.hazkey ]; +} diff --git a/modules/applications/fcitx5/nixos.nix b/modules/applications/fcitx5/nixos.nix index 0e1905e..a004d6c 100644 --- a/modules/applications/fcitx5/nixos.nix +++ b/modules/applications/fcitx5/nixos.nix @@ -39,6 +39,8 @@ let }; in { + services.hazkey.enable = true; + i18n.inputMethod = { enable = true; type = "fcitx5"; @@ -67,6 +69,10 @@ in Name = "mozc"; Layout = ""; }; + "Groups/0/Items/2" = { + Name = "hazkey"; + Layout = ""; + }; }; }; }; diff --git a/modules/applications/gamemode/nixos.nix b/modules/applications/gamemode/nixos.nix new file mode 100644 index 0000000..cc488cd --- /dev/null +++ b/modules/applications/gamemode/nixos.nix @@ -0,0 +1,8 @@ +{ + programs.gamemode = { + enable = true; + enableRenice = true; + + settings.general.renice = 10; + }; +} diff --git a/modules/applications/gamescope/nixos.nix b/modules/applications/gamescope/nixos.nix new file mode 100644 index 0000000..0fed043 --- /dev/null +++ b/modules/applications/gamescope/nixos.nix @@ -0,0 +1,6 @@ +{ + programs.gamescope = { + enable = true; + capSysNice = true; + }; +} diff --git a/modules/applications/labwc/home.nix b/modules/applications/labwc/home.nix index 60e2de7..bb51960 100644 --- a/modules/applications/labwc/home.nix +++ b/modules/applications/labwc/home.nix @@ -151,6 +151,12 @@ in # Pull in graphical-session.target so Home Manager services such as # portals, Vicinae, and the idle manager follow the labwc session. systemd.extraCommands = [ + # The wlroots portal is conditionally started with WAYLAND_DISPLAY. It + # can otherwise be skipped before labwc imports its session environment, + # leaving the desktop portal without the ScreenCast interface. + "${lib.getExe' pkgs.systemd "systemctl"} --user restart xdg-desktop-portal-wlr.service" + "${lib.getExe' pkgs.systemd "systemctl"} --user restart xdg-desktop-portal.service" + # Clear the previous session's target first. Otherwise services such as # kanshi that lose their Wayland connection on logout remain in a # failed/start-limit-hit state and are not started for the next login. diff --git a/modules/applications/mangohud/home.nix b/modules/applications/mangohud/home.nix new file mode 100644 index 0000000..51f507d --- /dev/null +++ b/modules/applications/mangohud/home.nix @@ -0,0 +1,4 @@ +{ lib, pkgs, ... }: +lib.mkIf pkgs.stdenv.hostPlatform.isLinux { + programs.mangohud.enable = true; +} diff --git a/modules/applications/noctalia/home.nix b/modules/applications/noctalia/home.nix index 4a69928..8cf6154 100644 --- a/modules/applications/noctalia/home.nix +++ b/modules/applications/noctalia/home.nix @@ -89,6 +89,7 @@ let "codex" "vesktop" ]; + show_all_outputs = true; group_by_workspace = false; show_window_title = false; pinned_opacity = 0.60; diff --git a/modules/applications/pear-desktop/darwin.nix b/modules/applications/pear-desktop/darwin.nix new file mode 100644 index 0000000..4d8de9d --- /dev/null +++ b/modules/applications/pear-desktop/darwin.nix @@ -0,0 +1,7 @@ +{ + homebrew = { + enable = true; + taps = [ "pear-devs/pear" ]; + casks = [ "pear-desktop" ]; + }; +} diff --git a/modules/applications/pear-desktop/home.nix b/modules/applications/pear-desktop/home.nix new file mode 100644 index 0000000..e9d4629 --- /dev/null +++ b/modules/applications/pear-desktop/home.nix @@ -0,0 +1,76 @@ +{ + config, + inputs, + lib, + pkgs, + ... +}: +let + isLinux = pkgs.stdenv.hostPlatform.isLinux; + isDarwin = pkgs.stdenv.hostPlatform.isDarwin; + unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system}; + configDirectory = + if isDarwin then + "${config.home.homeDirectory}/Library/Application Support/YouTube Music" + else + "${config.xdg.configHome}/YouTube Music"; + configFile = "${configDirectory}/config.json"; + managedConfig = { + options.autoUpdates = false; + plugins = { + performance-improvement.enabled = true; + synced-lyrics = { + enabled = true; + preciseTiming = true; + showLyricsEvenIfInexact = true; + showTimeCodes = false; + defaultTextString = "♪"; + lineEffect = "fancy"; + romanization = true; + }; + do-not-track = { + enabled = true; + cache = true; + }; + album-color-theme = { + enabled = true; + ratio = 0.5; + enableSeekbar = true; + }; + custom-output-device.enabled = true; + }; + }; +in +{ + home.packages = lib.optionals isLinux [ unstable.pear-desktop ]; + + home.activation.configurePearDesktop = { + after = [ "writeBoundary" ]; + before = [ ]; + data = '' + config_directory=${lib.escapeShellArg configDirectory} + config_file=${lib.escapeShellArg configFile} + managed_config=${lib.escapeShellArg (builtins.toJSON managedConfig)} + + if [ -n "''${DRY_RUN_CMD:-}" ]; then + echo "Would merge managed Pear Desktop settings into $config_file" + else + umask 077 + mkdir -p "$config_directory" + + if [ ! -f "$config_file" ]; then + printf '{}\n' > "$config_file" + fi + + if ${pkgs.jq}/bin/jq -e . "$config_file" > /dev/null; then + temporary_file="$(${pkgs.coreutils}/bin/mktemp "$config_file.tmp.XXXXXX")" + ${pkgs.jq}/bin/jq --argjson managed "$managed_config" \ + '. * $managed' "$config_file" > "$temporary_file" + ${pkgs.coreutils}/bin/mv "$temporary_file" "$config_file" + else + echo "Pear Desktop config is invalid JSON; leaving it unchanged: $config_file" >&2 + fi + fi + ''; + }; +} diff --git a/modules/applications/steam/nixos.nix b/modules/applications/steam/nixos.nix new file mode 100644 index 0000000..27c06c7 --- /dev/null +++ b/modules/applications/steam/nixos.nix @@ -0,0 +1,18 @@ +{ pkgs, ... }: +{ + programs.steam = { + enable = true; + + # Keep Valve's Proton available through Steam and add Proton-GE as an + # explicitly selectable compatibility tool for games that need its extra + # patches and codecs. + extraCompatPackages = [ pkgs.proton-ge-bin ]; + + # Install the supported helper for changing an individual Proton prefix. + protontricks.enable = true; + + # Translate Steam's X11 input events to uinput under Wayland so Steam Input + # and controller remapping continue to work in the desktop sessions. + extest.enable = true; + }; +} diff --git a/modules/profiles/README.md b/modules/profiles/README.md index c8349e2..1733398 100644 --- a/modules/profiles/README.md +++ b/modules/profiles/README.md @@ -54,9 +54,20 @@ both sessions while sharing `interface.linux-desktop` and `interface.gui`. 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. +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. + +`workload.personal` provides Pear Desktop on both NixOS and macOS. Home Manager +enables performance improvements, synced lyrics, tracker blocking, the album +color theme, and custom output-device selection while preserving user-owned +settings such as the selected device. + +On NixOS, `workload.game` provides Steam with Valve Proton and Proton-GE, +Protontricks, Wayland-compatible Steam Input, GameMode, Gamescope, and MangoHud. +Enabling Steam also activates the 32-bit graphics and PipeWire support required +by older games. On macOS the same profile currently provides the portable game +applications that support that host class. `security.tpm-storage` deliberately does not own a disk identifier. A host that selects it must define `boot.initrd.luks.devices.cryptroot.device` in its diff --git a/modules/profiles/workload/game/meta.nix b/modules/profiles/workload/game/meta.nix index 210df22..56420c0 100644 --- a/modules/profiles/workload/game/meta.nix +++ b/modules/profiles/workload/game/meta.nix @@ -2,6 +2,10 @@ description = "Gaming applications"; includes = [ + "applications.gamemode" + "applications.gamescope" + "applications.mangohud" "applications.minecraft" + "applications.steam" ]; } diff --git a/modules/profiles/workload/personal/meta.nix b/modules/profiles/workload/personal/meta.nix index 5330c6f..d2d5320 100644 --- a/modules/profiles/workload/personal/meta.nix +++ b/modules/profiles/workload/personal/meta.nix @@ -8,6 +8,7 @@ "applications.gnome-text-editor" "applications.kde" "applications.moonlight" + "applications.pear-desktop" "applications.slack" "applications.zoom" ];