diff --git a/configuration.nix b/configuration.nix index 50cd19b..dc7b0a5 100644 --- a/configuration.nix +++ b/configuration.nix @@ -20,6 +20,7 @@ }; }; }; + services.blueman.enable = true; networking.networkmanager.enable = true; networking.networkmanager.settings = { @@ -155,32 +156,34 @@ virtualisation.docker.enable = true; - services.displayManager.gdm.enable = true; - services.desktopManager.gnome.enable = true; - services.gnome.sushi.enable = true; + programs.sway = { + enable = true; + wrapperFeatures.gtk = true; + }; - # Remove default GNOME apps (keeping loupe and file-roller) - environment.gnome.excludePackages = with pkgs; [ - epiphany # GNOME Web - gnome-calculator - gnome-calendar - gnome-characters - gnome-clocks - gnome-connections - gnome-console - gnome-contacts - gnome-maps - gnome-music - gnome-weather - gnome-text-editor - simple-scan - totem # Videos (have VLC) - yelp # Help docs - evince # PDF viewer (using Zen Browser) - geary # Email - gnome-tour - gnome-font-viewer # Have font-manager - ]; + services.greetd = { + enable = true; + settings.default_session = { + command = "${pkgs.tuigreet}/bin/tuigreet --time --remember --remember-session --sessions /run/current-system/sw/share/wayland-sessions --cmd /run/current-system/sw/bin/sway"; + user = "greeter"; + }; + }; + + xdg.portal = { + enable = true; + wlr.enable = true; + config.common.default = [ + "wlr" + "gtk" + ]; + extraPortals = with pkgs; [ xdg-desktop-portal-gtk ]; + }; + + programs.dconf.enable = true; + services.gvfs.enable = true; + services.udisks2.enable = true; + security.polkit.enable = true; + security.pam.services.swaylock = { }; services.printing.enable = true; diff --git a/home-modules/default.nix b/home-modules/default.nix index 1d3394b..bd8bf83 100644 --- a/home-modules/default.nix +++ b/home-modules/default.nix @@ -10,6 +10,7 @@ ./terminal.nix ./browser.nix ./desktop.nix + ./sway.nix ./opencode.nix ]; } diff --git a/home-modules/desktop.nix b/home-modules/desktop.nix index e4ed242..361af21 100644 --- a/home-modules/desktop.nix +++ b/home-modules/desktop.nix @@ -1,69 +1,6 @@ -{ - pkgs, - homeLib, - hostname, - ... -}: - -let - autostartEntries = - if hostname == "framework-work" then - [ - "${homeLib.zenStartup}/share/applications/zen-startup.desktop" - "${homeLib.ghosttyZellijStartup}/share/applications/ghostty-zellij-startup.desktop" - "${pkgs.slack}/share/applications/slack.desktop" - "${homeLib.betterbird}/share/applications/betterbird.desktop" - ] - else - [ - "${homeLib.zenStartup}/share/applications/zen-startup.desktop" - "${homeLib.ghosttyZellijStartup}/share/applications/ghostty-zellij-startup.desktop" - "${homeLib.signalStartup}/share/applications/signal-startup.desktop" - "${pkgs.slack}/share/applications/slack.desktop" - "${homeLib.betterbird}/share/applications/betterbird.desktop" - "${homeLib.vesktopStartup}/share/applications/vesktop-startup.desktop" - "${homeLib.zulipStartup}/share/applications/zulip-startup.desktop" - ]; -in +{ ... }: { - dconf.settings = { - "org/gnome/desktop/interface" = { - clock-format = "12h"; - clock-show-weekday = true; - color-scheme = "prefer-dark"; - enable-animations = false; - enable-hot-corners = false; - }; - "org/gnome/system/location" = { - enabled = true; - }; - "org/gnome/settings-daemon/plugins/power" = { - sleep-inactive-ac-type = "nothing"; - }; - "org/gtk/gtk4/settings/file-chooser" = { - show-hidden = true; - }; - "org/gtk/settings/file-chooser" = { - clock-format = "12h"; - show-hidden = true; - }; - "org/gnome/desktop/peripherals/touchpad" = { - disable-while-typing = false; - }; - "org/gnome/shell" = { - disable-user-extensions = false; - enabled-extensions = [ - "hidetopbar@mathieu.bidon.ca" - "wifiqrcode@glerro.pm.me" - "system-monitor@paradoxxx.zero.gmail.com" - "clipboard-indicator@tudmotu.com" - "emoji-copy@felipeftn" - "tailscale-gnome-qs@tailscale-qs.github.io" - ]; - }; - }; - xdg.desktopEntries.extract-here = { name = "Extract Here"; exec = "file-roller --extract-here %U"; @@ -85,39 +22,6 @@ in noDisplay = true; }; - xdg.autostart = { - enable = true; - entries = autostartEntries; - }; - - home.file.".local/share/gnome-shell/extensions/tailscale-gnome-qs@tailscale-qs.github.io" = { - source = "${homeLib.tailscaleQsExtension}/share/gnome-shell/extensions/tailscale-gnome-qs@tailscale-qs.github.io"; - recursive = true; - }; - - systemd.user.services.nasa-apod-wallpaper = { - Unit = { - Description = "Fetch NASA APOD wallpaper"; - After = [ "graphical-session.target" ]; - PartOf = [ "graphical-session.target" ]; - }; - Service = { - Type = "oneshot"; - ExecStart = "${homeLib.nasaApodWallpaper}/bin/nasa-apod-wallpaper"; - }; - }; - - systemd.user.timers.nasa-apod-wallpaper = { - Unit.Description = "Refresh NASA APOD wallpaper regularly"; - Timer = { - OnStartupSec = "2m"; - OnCalendar = "hourly"; - Persistent = true; - Unit = "nasa-apod-wallpaper.service"; - }; - Install.WantedBy = [ "timers.target" ]; - }; - xdg.mimeApps = { enable = true; defaultApplications = { diff --git a/home-modules/lib.nix b/home-modules/lib.nix index 747f6ed..b04c6cc 100644 --- a/home-modules/lib.nix +++ b/home-modules/lib.nix @@ -13,20 +13,6 @@ let "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu jet@extremist.software" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPyic30I+SaDw0Lz/EFpMNeHCwxpwPfkgfR6uz3g7io7 jet@corp.primitive.dev" ]; - tailscaleQsExtension = pkgs.stdenvNoCC.mkDerivation { - pname = "tailscale-gnome-qs"; - version = "5"; - src = pkgs.fetchzip { - url = "https://github.com/tailscale-qs/tailscale-gnome-qs/archive/refs/tags/v5.tar.gz"; - sha256 = "0b9jy8pyxvpkxf3adlwq42kii14jn5g7xyxggjzg87pb5jg4zfg2"; - }; - dontBuild = true; - installPhase = '' - mkdir -p "$out/share/gnome-shell/extensions" - cp -r "$src/tailscale-gnome-qs@tailscale-qs.github.io" \ - "$out/share/gnome-shell/extensions/tailscale-gnome-qs@tailscale-qs.github.io" - ''; - }; wrappedOpencode = pkgs.symlinkJoin { name = "opencode-wrapped"; paths = [ pkgs.opencode ]; @@ -147,8 +133,8 @@ let runtimeInputs = [ pkgs.coreutils pkgs.curl - pkgs.glib pkgs.jq + pkgs.sway ]; text = '' set -euo pipefail @@ -171,11 +157,15 @@ let set_wallpaper() { local target="$1" - gsettings set org.gnome.desktop.background picture-uri "file://$target" - gsettings set org.gnome.desktop.background picture-uri-dark "file://$target" - gsettings set org.gnome.desktop.background picture-options 'zoom' + if [ -n "''${SWAYSOCK:-}" ] && [ -n "''${WAYLAND_DISPLAY:-}" ]; then + swaymsg output "*" bg "$target" fill >/dev/null + fi } + if [ -e "$current_link" ]; then + set_wallpaper "$current_link" + fi + json="$(curl "''${curl_args[@]}" 'https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY' || true)" if [ -z "$json" ]; then exit 0 @@ -209,10 +199,13 @@ let if curl "''${curl_args[@]}" "$image_url" -o "$tmp" && [ -s "$tmp" ]; then mv "$tmp" "$target" ln -sfn "$target" "$current_link" - set_wallpaper "$target" else rm -f "$tmp" fi + + if [ -e "$current_link" ]; then + set_wallpaper "$current_link" + fi ''; }; zellijNewTabZoxide = pkgs.writeShellApplication { @@ -420,7 +413,6 @@ in signalStartup sshPublicKeys sshSigningKey - tailscaleQsExtension wrappedOpencode zenStartup zellijNewTabZoxide diff --git a/home-modules/packages.nix b/home-modules/packages.nix index 9f5be49..16058e5 100644 --- a/home-modules/packages.nix +++ b/home-modules/packages.nix @@ -55,13 +55,24 @@ linphone lmstudio homeLib.betterbird + blueman + brightnessctl + cliphist + fuzzel + grim + mako + nautilus + networkmanagerapplet + nwg-displays + playerctl + polkit_gnome + slurp + swaybg + swayidle + swaylock + waybar + wl-clipboard nerd-fonts.commit-mono - - gnomeExtensions.clipboard-indicator - gnomeExtensions.emoji-copy - gnomeExtensions.hide-top-bar - gnomeExtensions.system-monitor-next - gnomeExtensions.wifi-qrcode ]; } diff --git a/home-modules/sway.nix b/home-modules/sway.nix new file mode 100644 index 0000000..40b4c42 --- /dev/null +++ b/home-modules/sway.nix @@ -0,0 +1,296 @@ +{ + config, + pkgs, + homeLib, + hostname, + ... +}: + +let + apodCurrent = "${config.home.homeDirectory}/.local/state/nasa-apod/current"; + lockCommand = pkgs.writeShellScript "sway-lock-apod" '' + set -euo pipefail + + if [ -e "${apodCurrent}" ]; then + exec ${pkgs.swaylock}/bin/swaylock -f -i "${apodCurrent}" -s fill --color 000000 + fi + + exec ${pkgs.swaylock}/bin/swaylock -f --color 000000 + ''; + screenshotCommand = pkgs.writeShellScript "sway-screenshot" '' + set -euo pipefail + + dir="$HOME/Pictures/Screenshots" + ${pkgs.coreutils}/bin/mkdir -p "$dir" + file="$dir/screenshot-$(${pkgs.coreutils}/bin/date +%Y%m%d-%H%M%S).png" + + if geometry="$(${pkgs.slurp}/bin/slurp)"; then + ${pkgs.grim}/bin/grim -g "$geometry" "$file" + ${pkgs.wl-clipboard}/bin/wl-copy < "$file" + fi + ''; + cliphistCommand = pkgs.writeShellScript "cliphist-fuzzel" '' + set -euo pipefail + + ${pkgs.cliphist}/bin/cliphist list | ${pkgs.fuzzel}/bin/fuzzel --dmenu | ${pkgs.cliphist}/bin/cliphist decode | ${pkgs.wl-clipboard}/bin/wl-copy + ''; + commonStartup = [ + "${homeLib.nasaApodWallpaper}/bin/nasa-apod-wallpaper" + "${pkgs.waybar}/bin/waybar" + "${pkgs.networkmanagerapplet}/bin/nm-applet --indicator" + "${pkgs.blueman}/bin/blueman-applet" + "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1" + "${pkgs.wl-clipboard}/bin/wl-paste --type text --watch ${pkgs.cliphist}/bin/cliphist store" + "${pkgs.wl-clipboard}/bin/wl-paste --type image --watch ${pkgs.cliphist}/bin/cliphist store" + "${pkgs.swayidle}/bin/swayidle -w timeout 300 '${lockCommand}' before-sleep '${lockCommand}'" + ]; + workStartup = [ + "${config.programs.zen-browser.package}/bin/zen-beta" + "${pkgs.ghostty}/bin/ghostty --fullscreen=true -e ${homeLib.zellijPersistentSession}/bin/zellij-persistent-session" + "${pkgs.slack}/bin/slack" + "${homeLib.betterbird}/bin/betterbird" + ]; + personalStartup = [ + "${config.programs.zen-browser.package}/bin/zen-beta" + "${pkgs.ghostty}/bin/ghostty --fullscreen=true -e ${homeLib.zellijPersistentSession}/bin/zellij-persistent-session" + "${pkgs.vesktop}/bin/vesktop --start-fullscreen" + "${homeLib.betterbird}/bin/betterbird" + "${pkgs.signal-desktop}/bin/signal-desktop --start-fullscreen" + "${pkgs.zulip}/bin/zulip --start-fullscreen" + ]; + appStartup = if hostname == "framework-work" then workStartup else personalStartup; +in + +{ + wayland.windowManager.sway = { + enable = true; + systemd.enable = true; + wrapperFeatures.gtk = true; + config = null; + extraConfig = '' + set $mod Mod4 + + exec ${pkgs.dbus}/bin/dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway SWAYSOCK + exec ${pkgs.systemd}/bin/systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP SWAYSOCK + + default_border none + default_floating_border none + hide_edge_borders both + gaps inner 0 + gaps outer 0 + smart_gaps off + focus_follows_mouse no + + input type:touchpad { + tap enabled + dwt disabled + } + + output * bg #000000 solid_color + + bindsym $mod+d exec ${pkgs.fuzzel}/bin/fuzzel + bindsym $mod+b exec ${pkgs.procps}/bin/pkill -SIGUSR1 waybar + bindsym $mod+l exec ${lockCommand} + bindsym $mod+Shift+e exec ${pkgs.sway}/bin/swaymsg exit + bindsym $mod+Shift+r reload + bindsym $mod+Shift+q kill + bindsym $mod+f fullscreen toggle + bindsym $mod+c exec ${cliphistCommand} + bindsym Print exec ${screenshotCommand} + bindsym Sys_Req exec ${screenshotCommand} + bindsym $mod+Print exec ${screenshotCommand} + + bindsym $mod+h focus left + bindsym $mod+j focus down + bindsym $mod+k focus up + bindsym $mod+Left focus left + bindsym $mod+Down focus down + bindsym $mod+Up focus up + bindsym $mod+Right focus right + + bindsym XF86AudioMute exec ${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle + bindsym XF86AudioLowerVolume exec ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- + bindsym XF86AudioRaiseVolume exec ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ + bindsym XF86AudioPlay exec ${pkgs.playerctl}/bin/playerctl play-pause + bindsym XF86MonBrightnessDown exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%- + bindsym XF86MonBrightnessUp exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%+ + + bindsym $mod+1 workspace number 1 + bindsym $mod+2 workspace number 2 + bindsym $mod+3 workspace number 3 + bindsym $mod+4 workspace number 4 + bindsym $mod+5 workspace number 5 + bindsym $mod+6 workspace number 6 + bindsym $mod+7 workspace number 7 + bindsym $mod+8 workspace number 8 + bindsym $mod+9 workspace number 9 + bindsym $mod+0 workspace number 10 + + bindsym $mod+Shift+1 move container to workspace number 1 + bindsym $mod+Shift+2 move container to workspace number 2 + bindsym $mod+Shift+3 move container to workspace number 3 + bindsym $mod+Shift+4 move container to workspace number 4 + bindsym $mod+Shift+5 move container to workspace number 5 + bindsym $mod+Shift+6 move container to workspace number 6 + bindsym $mod+Shift+7 move container to workspace number 7 + bindsym $mod+Shift+8 move container to workspace number 8 + bindsym $mod+Shift+9 move container to workspace number 9 + bindsym $mod+Shift+0 move container to workspace number 10 + + for_window [all] fullscreen enable + for_window [app_id="zen"] move to workspace number 1, fullscreen enable + for_window [app_id="zen-beta"] move to workspace number 1, fullscreen enable + for_window [class="zen-beta"] move to workspace number 1, fullscreen enable + for_window [app_id="com.mitchellh.ghostty"] move to workspace number 2, fullscreen enable + for_window [class="Slack"] move to workspace number 3, fullscreen enable + for_window [app_id="slack"] move to workspace number 3, fullscreen enable + for_window [app_id="Slack"] move to workspace number 3, fullscreen enable + for_window [app_id="dev.vencord.Vesktop"] move to workspace number 3, fullscreen enable + for_window [app_id="vesktop"] move to workspace number 3, fullscreen enable + for_window [class="Betterbird"] move to workspace number 4, fullscreen enable + for_window [class="eu.betterbird.Betterbird"] move to workspace number 4, fullscreen enable + for_window [app_id="betterbird"] move to workspace number 4, fullscreen enable + for_window [app_id="Betterbird"] move to workspace number 4, fullscreen enable + for_window [class="Signal"] move to workspace number 5, fullscreen enable + for_window [app_id="signal"] move to workspace number 5, fullscreen enable + for_window [app_id="signal-desktop"] move to workspace number 5, fullscreen enable + for_window [class="Zulip"] move to workspace number 6, fullscreen enable + for_window [app_id="org.zulip.Zulip"] move to workspace number 6, fullscreen enable + + ${pkgs.lib.concatMapStringsSep "\n" (command: "exec ${command}") commonStartup} + ${pkgs.lib.concatMapStringsSep "\n" (command: "exec ${command}") appStartup} + ''; + }; + + programs.waybar = { + enable = true; + settings.mainBar = { + layer = "top"; + position = "top"; + mode = "hide"; + start_hidden = true; + modules-left = [ ]; + modules-center = [ "clock" ]; + modules-right = [ + "tray" + "network" + "bluetooth" + "wireplumber" + "battery" + ]; + clock = { + format = "{:%a %b %d %I:%M %p}"; + tooltip-format = "{:%Y-%m-%d}"; + }; + network = { + format-wifi = "wifi {essid}"; + format-disconnected = "wifi disconnected"; + tooltip-format-wifi = "{ifname}: {ipaddr}"; + }; + bluetooth = { + format = "bt on"; + format-disabled = "bt off"; + format-off = "bt off"; + format-connected = "bt {device_alias}"; + }; + wireplumber = { + format = "vol {volume}%"; + format-muted = "muted"; + }; + battery = { + format = "bat {capacity}%"; + format-charging = "chg {capacity}%"; + format-plugged = "ac {capacity}%"; + states.warning = 25; + states.critical = 10; + }; + tray.spacing = 8; + }; + style = '' + * { + border: none; + border-radius: 0; + font-family: "CommitMono Nerd Font", monospace; + font-size: 12px; + min-height: 0; + } + + window#waybar { + background: #0d1117; + color: #f0f6fc; + } + + #clock, + #tray, + #network, + #bluetooth, + #wireplumber, + #battery { + padding: 2px 8px; + } + + #battery.warning { + color: #d29922; + } + + #battery.critical, + #network.disconnected, + #wireplumber.muted { + color: #f85149; + } + ''; + }; + + services.mako = { + enable = true; + settings = { + background-color = "#0d1117"; + text-color = "#f0f6fc"; + border-color = "#30363d"; + border-radius = 0; + default-timeout = 5000; + }; + }; + + programs.fuzzel = { + enable = true; + settings = { + main = { + font = "CommitMono Nerd Font:size=12"; + terminal = "ghostty"; + }; + colors = { + background = "0d1117ff"; + text = "f0f6fcff"; + match = "3fb950ff"; + selection = "238636ff"; + selection-text = "ffffffff"; + border = "30363dff"; + }; + border.radius = 0; + }; + }; + + systemd.user.services.nasa-apod-wallpaper = { + Unit = { + Description = "Fetch NASA APOD wallpaper"; + After = [ "graphical-session.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + Type = "oneshot"; + ExecStart = "${homeLib.nasaApodWallpaper}/bin/nasa-apod-wallpaper"; + }; + }; + + systemd.user.timers.nasa-apod-wallpaper = { + Unit.Description = "Refresh NASA APOD wallpaper regularly"; + Timer = { + OnStartupSec = "2m"; + OnCalendar = "hourly"; + Persistent = true; + Unit = "nasa-apod-wallpaper.service"; + }; + Install.WantedBy = [ "timers.target" ]; + }; +}