diff --git a/home/duynguyen/niri.kdl b/home/duynguyen/config/niri/config.kdl similarity index 83% rename from home/duynguyen/niri.kdl rename to home/duynguyen/config/niri/config.kdl index 473fc9f..81e70f7 100644 --- a/home/duynguyen/niri.kdl +++ b/home/duynguyen/config/niri/config.kdl @@ -16,7 +16,8 @@ input { touchpad { tap natural-scroll - scroll-factor 0.3 + accel-profile "flat" + scroll-factor 1.0 } mouse { @@ -33,13 +34,13 @@ input { /-output "eDP-1" { mode "1920x1080@120.030" - scale 2 + scale 1.5 transform "normal" position x=1280 y=0 } layout { - gaps 16 + gaps 8 center-focused-column "never" preset-column-widths { @@ -51,7 +52,7 @@ layout { default-column-width { proportion 0.5; } focus-ring { - width 4 + width 1 active-color "#7fc8ff" inactive-color "#505050" } @@ -84,14 +85,21 @@ spawn-at-startup "xwayland-satellite" spawn-at-startup "mako" hotkey-overlay { - // skip-at-startup + skip-at-startup } -screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" +screenshot-path null + +gestures { + hot-corners { + off + } +} + +prefer-no-csd animations { - // off - // slowdown 3.0 + slowdown 0.5 } window-rule { @@ -99,8 +107,22 @@ window-rule { default-column-width {} } +// Slight rounded corners window-rule { - match app-id=r#"firefox$"# title="^Picture-in-Picture$" + geometry-corner-radius 2 + clip-to-geometry true +} + +// Floating windows +window-rule { + match app-id=r#"^Tk$"# + match app-id=r#"^gimp$"# title=r#"Preferences"# + match app-id=r#"^mpv$"# + match app-id=r#"^soffice$"# title=r#"^Text Import"# + match app-id=r#"^thunar$"# title=r#"^Rename "# + match app-id=r#"^xarchiver$"# + match app-id=r#"firefox$"# title=r#"^(Picture-in-Picture|Library|About Mozilla Firefox|Firefox - Choose a profile)$"# + open-floating true } @@ -126,7 +148,7 @@ binds { XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "10%-"; } Mod+O repeat=false { toggle-overview; } - Mod+Q repeat=false { close-window; } + Mod+Shift+Q repeat=false { close-window; } Mod+Left { focus-column-left; } Mod+Down { focus-window-down; } @@ -137,28 +159,28 @@ binds { Mod+K { focus-window-up; } Mod+L { focus-column-right; } - Mod+Ctrl+Left { move-column-left; } - Mod+Ctrl+Down { move-window-down; } - Mod+Ctrl+Up { move-window-up; } - Mod+Ctrl+Right { move-column-right; } - Mod+Ctrl+H { move-column-left; } - Mod+Ctrl+J { move-window-down; } - Mod+Ctrl+K { move-window-up; } - Mod+Ctrl+L { move-column-right; } + Mod+Shift+Left { move-column-left; } + Mod+Shift+Down { move-window-down; } + Mod+Shift+Up { move-window-up; } + Mod+Shift+Right { move-column-right; } + Mod+Shift+H { move-column-left; } + Mod+Shift+J { move-window-down; } + Mod+Shift+K { move-window-up; } + Mod+Shift+L { move-column-right; } Mod+Home { focus-column-first; } Mod+End { focus-column-last; } Mod+Ctrl+Home { move-column-to-first; } Mod+Ctrl+End { move-column-to-last; } - Mod+Shift+Left { focus-monitor-left; } - Mod+Shift+Down { focus-monitor-down; } - Mod+Shift+Up { focus-monitor-up; } - Mod+Shift+Right { focus-monitor-right; } - Mod+Shift+H { focus-monitor-left; } - Mod+Shift+J { focus-monitor-down; } - Mod+Shift+K { focus-monitor-up; } - Mod+Shift+L { focus-monitor-right; } + Mod+Ctrl+Left { focus-monitor-left; } + Mod+Ctrl+Down { focus-monitor-down; } + Mod+Ctrl+Up { focus-monitor-up; } + Mod+Ctrl+Right { focus-monitor-right; } + Mod+Ctrl+H { focus-monitor-left; } + Mod+Ctrl+J { focus-monitor-down; } + Mod+Ctrl+K { focus-monitor-up; } + Mod+Ctrl+L { focus-monitor-right; } Mod+Shift+Ctrl+Left { move-column-to-monitor-left; } Mod+Shift+Ctrl+Down { move-column-to-monitor-down; } @@ -246,7 +268,7 @@ binds { Print { screenshot; } Ctrl+Print { screenshot-screen; } - Alt+Print { screenshot-window; } + Mod+Print { screenshot-window; } Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } Mod+Shift+E { quit; } diff --git a/home/duynguyen/config/waybar/config.json b/home/duynguyen/config/waybar/config.json new file mode 100644 index 0000000..2fe7657 --- /dev/null +++ b/home/duynguyen/config/waybar/config.json @@ -0,0 +1,154 @@ +{ + "reload_style_on_change": true, + "layer": "top", + "position": "top", + "spacing": 0, + "height": 24, + "modules-left": [ + "custom/menu", + "niri/workspaces" + ], + "modules-center": [ + "clock" + ], + "modules-right": [ + "group/tray-expander", + "pulseaudio", + "bluetooth", + "network", + "cpu", + "battery" + ], + + "custom/menu": { + "format": "󰣇", + "on-click": "walker", + "tooltip-format": "Open launcher" + }, + + "niri/workspaces": { + "on-click": "activate", + "on-click-right": "niri msg action toggle-overview", + "format": "{icon}", + "format-icons": { + "default": "", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7", + "8": "8", + "9": "9", + "active": "󱓻" + } + }, + + "clock": { + "format": "{:%I:%M %p %Z :: %a %b %d %Y}", + "format-alt": "{:%H:%M %Z :: %a %b %d %Y}", + "tooltip": true, + "tooltip-format": "{calendar}", + "timezones": ["", "UTC"], + "on-click-right": "xdg-open https://calendar.google.com", + "actions": { + "on-scroll-up": "tz_up", + "on-scroll-down": "tz_down" + }, + "calendar": { + "mode": "year", + "mode-mon-col": 3, + "weeks-pos": "right", + "on-scroll": 1, + "format": { + "months": "{}", + "days": "{}", + "weeks": "W{:%V}", + "weekdays": "{}", + "today": "{}" + } + } + }, + + "group/tray-expander": { + "orientation": "horizontal", + "drawer": { + "transition-duration": 300, + "children-class": "tray-group-item" + }, + "modules": [ + "custom/expand-icon", + "tray" + ] + }, + + "custom/expand-icon": { + "format": "", + "tooltip": false + }, + + "tray": { + "icon-size": 12, + "spacing": 12 + }, + + "pulseaudio": { + "format": "{icon}", + "on-click": "wiremix", + "on-click-right": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", + "tooltip-format": "Playback volume: {volume}%", + "scroll-step": 5, + "format-muted": "󰝟", + "format-icons": { + "default": ["", "", ""] + } + }, + + "bluetooth": { + "format": "", + "format-disabled": "󰂲", + "format-connected": "", + "tooltip-format": "Devices connected: {num_connections}", + "on-click": "blueman-manager" + }, + + "network": { + "format-icons": ["󰤯", "󰤟", "󰤢", "󰤥", "󰤨"], + "format": "{icon}", + "format-wifi": "{icon}", + "format-ethernet": "󰀂", + "format-disconnected": "󰖪", + "tooltip-format-wifi": "{essid} ({frequency} GHz)\n⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}\n\n{ipaddr}", + "tooltip-format-ethernet": "⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}\n\n{ipaddr}", + "tooltip-format-disconnected": "Disconnected", + "interval": 10, + "on-click-right": "xdg-open https://speedtest.net" + }, + + "cpu": { + "interval": 5, + "format": "󰍛", + "on-click": "kitty -e btop", + "tooltip-format": "CPU usage: {usage}%" + }, + + "battery": { + "format": "{capacity}% {icon}", + "format-discharging": "{icon}", + "format-charging": "{icon}", + "format-plugged": "", + "format-icons": { + "charging": ["󰢜", "󰂆", "󰂇", "󰂈", "󰢝", "󰂉", "󰢞", "󰂊", "󰂋", "󰂅"], + "default": ["󰁺", "󰁻", "󰁼", "󰁽", "󰁾", "󰁿", "󰂀", "󰂁", "󰂂", "󰁹"] + }, + "format-full": "󰂅", + "tooltip-format-discharging": "{power:>1.0f}W↓ {capacity}%", + "tooltip-format-charging": "{power:>1.0f}W↑ {capacity}%", + "interval": 5, + "states": { + "warning": 20, + "critical": 10 + } + } +} diff --git a/home/duynguyen/config/waybar/style.css b/home/duynguyen/config/waybar/style.css new file mode 100644 index 0000000..4d6093a --- /dev/null +++ b/home/duynguyen/config/waybar/style.css @@ -0,0 +1,95 @@ +* { + font-family: "JetBrainsMono Nerd Font", "Font Awesome 6 Free", "FreeSans", sans-serif; + font-size: 13px; + border: none; + border-radius: 0; + min-height: 0; + margin: 0; + padding: 0; +} + +window#waybar { + background-color: #1e1e2e; + color: #cdd6f4; +} + +.modules-left, +.modules-center, +.modules-right { + margin: 4px 8px; +} + +#workspaces button { + padding: 0 8px; + color: #6c7086; + background: transparent; +} + +#workspaces button.active { + color: #cdd6f4; + font-weight: bold; +} + +#workspaces button:hover { + color: #89b4fa; + box-shadow: none; + text-shadow: none; + background: transparent; +} + +#window { + color: #a6adc8; + padding: 0 8px; +} + +#clock, +#battery, +#network, +#pulseaudio, +#bluetooth, +#cpu, +#tray, +#custom-menu, +#custom-expand-icon { + padding: 0 10px; + color: #cdd6f4; +} + +#clock { + font-weight: bold; +} + +#custom-menu { + color: #89b4fa; + font-size: 16px; + padding: 0 12px; +} + +#custom-expand-icon { + padding: 0 6px; + color: #6c7086; +} + +.tray-group-item { + padding: 0 4px; +} + +#battery.warning { + color: #f9e2af; +} + +#battery.critical { + color: #f38ba8; +} + +#network.disconnected { + color: #f38ba8; +} + +#bluetooth.disabled { + color: #6c7086; +} + +#pulseaudio.muted { + color: #6c7086; +} diff --git a/home/duynguyen/default.nix b/home/duynguyen/default.nix index d592c66..3de039e 100644 --- a/home/duynguyen/default.nix +++ b/home/duynguyen/default.nix @@ -1,4 +1,4 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: { home.username = "duynguyen"; @@ -19,13 +19,18 @@ foot # lightweight, good default for Niri # Niri supporting tools - fuzzel # app launcher - waybar # status bar + walker # app launcher + elephant # modular data provider for walker (clipboard, files, niri actions, etc.) + fuzzel # app launcher (alternative) + waybar mako # notifications wl-clipboard # copy/paste in Wayland terminal swaylock # screen locker swayidle # idle management + swaybg # wallpaper xwayland-satellite # X11 app support in Niri + xdg-utils # xdg-open, file associations + inotify-tools # filesystem event tools # Editor vscodium @@ -33,17 +38,49 @@ # Daily apps mpv imv + gimp + obs-studio + zathura # PDF viewer + thunar # file manager + xfce.thunar-archive-plugin # right-click archive operations + xfce.tumbler # thumbnail service + ffmpegthumbnailer # video thumbnails + xarchiver # archive manager GUI grim # Wayland screenshot slurp # region selector for grim + swappy # screenshot annotation libreoffice telegram-desktop + pavucontrol # audio GUI + blueman # Bluetooth GUI + + # Clipboard + cliphist # clipboard history (pairs with wl-clipboard) # CLI tools + vim + neovim + tmux + fastfetch btop ripgrep + fd # fast find alternative fzf eza # modern ls bat # modern cat + dust # intuitive disk usage + jq # JSON processing + yq # YAML processing + shellcheck # shell script linter + ffmpeg + imagemagick + unzip + p7zip + wiremix # TUI PipeWire audio mixer + + # System control + brightnessctl # brightness keys + playerctl # media keys # Dev tools gh @@ -59,6 +96,17 @@ syntaxHighlighting.enable = true; }; + programs.waybar = { + enable = true; + style = builtins.readFile ./config/waybar/style.css; + settings = builtins.fromJSON (builtins.readFile ./config/waybar/config.json); + }; + + programs.kitty = { + enable = true; + settings.wheel_scroll_multiplier = 10; + }; + programs.zoxide = { enable = true; enableZshIntegration = true; @@ -89,12 +137,21 @@ ]; }; + # Zen Browser scroll speed — written to all profiles via activation script + # so it works even if the profile ID changes on a fresh install + home.activation.zenBrowserUserJs = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + for profile in "$HOME/.config/zen/"*.*/; do + [[ -d "$profile" ]] || continue + echo 'user_pref("mousewheel.default.delta_multiplier_y", 50);' > "$profile/user.js" + done + ''; + xdg.configFile."niri/config.kdl".source = pkgs.runCommand "niri-config-checked" { nativeBuildInputs = [ pkgs.niri ]; } '' - niri validate -c ${./niri.kdl} - cp ${./niri.kdl} $out + niri validate -c ${./config/niri/config.kdl} + cp ${./config/niri/config.kdl} $out ''; programs.home-manager.enable = true; diff --git a/hosts/nixos/configuration.nix b/hosts/nixos/configuration.nix index a59230f..4c99a19 100644 --- a/hosts/nixos/configuration.nix +++ b/hosts/nixos/configuration.nix @@ -77,6 +77,21 @@ security.polkit.enable = true; + fonts.packages = with pkgs; [ + freefont_ttf + noto-fonts-color-emoji + font-awesome + nerd-fonts.jetbrains-mono + ]; + + hardware.bluetooth.enable = true; + services.blueman.enable = true; + + xdg.portal = { + enable = true; + extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; + }; + nixpkgs.config.allowUnfree = true; environment.systemPackages = with pkgs; [