diff --git a/home/panotaka/Bellerophon.nix b/home/panotaka/Bellerophon.nix index 7fa9380..aec7f71 100644 --- a/home/panotaka/Bellerophon.nix +++ b/home/panotaka/Bellerophon.nix @@ -10,8 +10,8 @@ # # FIXME(starter): add or remove any optional config directories or files ehre common/optional/browsers - common/optional/desktops/hyprland - common/optional/desktops/hyprland/zenbook-screen.nix + common/optional/desktops/gnome + common/optional/desktops/gnome/zenbook-screen.nix common/optional/comms common/optional/media common/optional/coding diff --git a/home/panotaka/common/optional/desktops/gnome/default.nix b/home/panotaka/common/optional/desktops/gnome/default.nix new file mode 100644 index 0000000..21d39c2 --- /dev/null +++ b/home/panotaka/common/optional/desktops/gnome/default.nix @@ -0,0 +1,71 @@ +{ + pkgs, + lib, + ... +}: { + # GNOME desktop packages + home.packages = with pkgs; [ + gnome-tweaks + dconf-editor + gnome-control-center # GNOME Settings app for display configuration + # Note: gnome-monitor-config might not be available as a standalone package + # It's usually part of mutter/gnome-shell, we'll use gdbus calls instead + inotify-tools # for watching USB changes + iio-sensor-proxy # for rotation detection (includes monitor-sensor) + + # GNOME Extensions + gnomeExtensions.dash-to-dock + gnomeExtensions.blur-my-shell + gnomeExtensions.user-themes + gnomeExtensions.vitals + gnomeExtensions.appindicator + gnomeExtensions.tray-icons-reloaded + gnomeExtensions.caffeine + gnomeExtensions.clipboard-indicator + gnomeExtensions.launch-new-instance + ]; + + # GNOME desktop settings via dconf + dconf.settings = { + "org/gnome/desktop/interface" = { + enable-hot-corners = false; + color-scheme = lib.mkForce "prefer-dark"; + }; + + "org/gnome/desktop/wm/preferences" = { + button-layout = "appmenu:minimize,maximize,close"; + }; + + # Enable GNOME Extensions + "org/gnome/shell" = { + enabled-extensions = [ + "dash-to-dock@micxgx.gmail.com" + "blur-my-shell@aunetx" + "user-theme@gnome-shell-extensions.gcampax.github.com" + "Vitals@CoreCoding.com" + "appindicatorsupport@rgcjonas.gmail.com" + "trayIconsReloaded@selfmade.pl" + "caffeine@patapon.info" + "clipboard-indicator@tudmotu.com" + "launch-new-instance@gnome-shell-extensions.gcampax.github.com" + ]; + }; + + # Enable natural scrolling on touchpad + "org/gnome/desktop/peripherals/touchpad" = { + natural-scroll = true; + two-finger-scrolling-enabled = true; + tap-to-click = true; + }; + + # Disable middle-click paste + "org/gnome/desktop/interface" = { + gtk-enable-primary-paste = false; + }; + + # Enable fractional scaling for HiDPI displays and VRR support + "org/gnome/mutter" = { + experimental-features = ["scale-monitor-framebuffer" "variable-refresh-rate"]; + }; + }; +} diff --git a/home/panotaka/common/optional/desktops/gnome/zenbook-screen.nix b/home/panotaka/common/optional/desktops/gnome/zenbook-screen.nix new file mode 100644 index 0000000..2934509 --- /dev/null +++ b/home/panotaka/common/optional/desktops/gnome/zenbook-screen.nix @@ -0,0 +1,363 @@ +{pkgs, ...}: let + # Main duo script for display management + duoScript = pkgs.writeShellScript "duo" '' + #!/usr/bin/env bash + + # Configuration for 3K model (adjust as needed) + prefered_resolution="2880x1800@120.000" + ui_scale=1.5 + # y offset = height of resolution / ui_scale (1800/1.5 = 1200) + y_offset=1200 + backlight=card1-eDP-2-backlight + + # Uncomment for 1080p model + #prefered_resolution="1920x1200@60.003" + #ui_scale=1 + #y_offset=1200 + + function suenv { + sudo /usr/bin/env "$@" + } + + function external-display-connected { + [ "$(${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list|grep display-name|grep -v 'Built-in display'|wc -l)" != "0" ] + } + + function active-external-displays { + ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list|grep -vE 'eDP-[12]'|sed -nE 's/Monitor \[ (.+) \] ON/\1/p' + } + + case "$1" in + watch-displays) + while ${pkgs.inotify-tools}/bin/inotifywait -e attrib /dev/bus/usb/*/ ; do + if ! external-display-connected; then + "$0" normal + fi + done + ;; + set-displays) + sleep 1 + if ! external-display-connected; then + "$0" normal + fi + ;; + normal|bottom-up) + if ${pkgs.usbutils}/bin/lsusb|grep 0b05:1b2c ; then + "$0" top + else + "$0" both + fi + ;; + top) + ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM eDP-1 -m $prefered_resolution -s $ui_scale -x 0 -y 0 + ;; + both) + ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM eDP-1 -m $prefered_resolution -s $ui_scale -x 0 -y 0 \ + -LM eDP-2 -m $prefered_resolution -s $ui_scale -x 0 -y $y_offset + ;; + bottom) + ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM eDP-2 -m $prefered_resolution -s $ui_scale -x 0 -y 0 + ;; + left-up) + ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM eDP-2 -m $prefered_resolution -s $ui_scale -t left -x 0 -y 0 \ + -LM eDP-1 -m $prefered_resolution -s $ui_scale -t left -x $y_offset -y 0 + ;; + right-up) + ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LM eDP-1 -m $prefered_resolution -s $ui_scale -t right -x 0 -y 0 \ + -LpM eDP-2 -m $prefered_resolution -s $ui_scale -t right -x $y_offset -y 0 + ;; + status-internal) + internal_monitors="$(${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list|grep -E "Monitor \\[ eDP-. \\] ON")" + case "$(echo "$internal_monitors"|grep -v -E "^$"|wc -l)" in + 0) echo "none" ;; + 1) case "$(echo "$internal_monitors"|grep ON)" in + "Monitor [ eDP-1 ] ON") echo top ;; + "Monitor [ eDP-2 ] ON") echo bottom ;; + esac ;; + 2) echo "both" ;; + esac + ;; + status) + ( + active-external-displays + )|grep -vE "^$"|sed -z "s/\n/+/g" + "$0" status-internal + ;; + toggle) + if ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list | grep OFF | grep eDP > /dev/null; then + "$0" both + else + "$0" top + fi + ;; + set-tablet-mapping) + for type in tablets touchscreens; do + ${pkgs.dconf}/bin/dconf write "/org/gnome/desktop/peripherals/''${type}/04f3:425b/output" \ + "['SDC', '0x419d', '0x00000000', 'eDP-1']" + ${pkgs.dconf}/bin/dconf write "/org/gnome/desktop/peripherals/''${type}/04f3:425a/output" \ + "['SDC', '0x419d', '0x00000000', 'eDP-2']" + done + ;; + toggle-bottom-touch) + path="/org/gnome/desktop/peripherals/touchscreens/04f3:425a/output" + if [ -z "$(${pkgs.dconf}/bin/dconf read "$path")" ]; then + ${pkgs.dconf}/bin/dconf write "$path" "['SDC', '0x419d', '0x00000000', 'eDP-2']" + else + ${pkgs.dconf}/bin/dconf reset "$path" + fi + ;; + bat-limit) + echo "''${2:-80}" | suenv tee /sys/class/power_supply/BAT0/charge_control_end_threshold + ;; + sync-backlight) + cat "/sys/class/backlight/intel_backlight/brightness" | + suenv tee /sys/class/backlight/$backlight/brightness + ;; + set-kb-backlight) + suenv ${zenbook-kb-backlight}/bin/zenbook-kb-backlight "$2" + ;; + watch-backlight) + "$0" sync-backlight + while ${pkgs.inotify-tools}/bin/inotifywait -e modify /sys/class/backlight/intel_backlight/brightness ; do + "$0" sync-backlight + done + ;; + watch-rotation) + ${pkgs.iio-sensor-proxy}/bin/monitor-sensor --accel | + ${pkgs.coreutils}/bin/stdbuf -oL grep orientation | + ${pkgs.coreutils}/bin/stdbuf -oL cut -d: -f2 | + ${pkgs.coreutils}/bin/stdbuf -oL sed 's/[ )]//g' | + ${pkgs.findutils}/bin/xargs -I '{}' ${pkgs.coreutils}/bin/stdbuf -oL "$0" '{}' + ;; + *) echo "Usage: duo " + esac + ''; + + # Keyboard backlight control script + zenbook-kb-backlight = pkgs.python3Packages.buildPythonApplication { + pname = "zenbook-kb-backlight"; + version = "1.0.0"; + format = "other"; + + src = pkgs.writeText "zenbook-kb-backlight.py" '' + #!/usr/bin/env python3 + + import usb.core + import usb.util + import sys + import time + + # USB vendor and product IDs for ZenBook Duo 2024 + VENDOR_ID = 0x0b05 # ASUS + PRODUCT_ID = 0x19b6 # ZenBook Duo specific + + def find_keyboard_device(): + """Find the ZenBook Duo keyboard device""" + devices = usb.core.find(find_all=True, idVendor=VENDOR_ID) + for device in devices: + if device.idProduct == PRODUCT_ID: + return device + return None + + def set_backlight(brightness): + """Set keyboard backlight brightness (0-3)""" + device = find_keyboard_device() + if not device: + print("ZenBook Duo keyboard device not found") + return False + + try: + # Detach kernel driver if it's attached + if device.is_kernel_driver_active(0): + device.detach_kernel_driver(0) + + # Set configuration + device.set_configuration() + + # Send backlight control command + # This is a generic HID command structure for keyboard backlight + # Values might need adjustment based on actual hardware + device.ctrl_transfer( + bmRequestType=0x21, # USB_TYPE_CLASS | USB_RECIP_INTERFACE + bRequest=0x09, # HID SET_REPORT + wValue=0x0301, # Report type and ID + wIndex=0, # Interface + data_or_wLength=[0x5d, 0xba, brightness, 0x00, 0x00, 0x00, 0x00, 0x00] + ) + return True + + except usb.core.USBError as e: + print(f"USB Error: {e}") + return False + except Exception as e: + print(f"Error: {e}") + return False + + def main(): + if len(sys.argv) != 2: + print("Usage: zenbook-kb-backlight ") + print("Brightness levels: 0 (off), 1 (low), 2 (medium), 3 (high)") + sys.exit(1) + + try: + brightness = int(sys.argv[1]) + if brightness < 0 or brightness > 3: + raise ValueError("Brightness must be between 0 and 3") + + if set_backlight(brightness): + print(f"Keyboard backlight set to level {brightness}") + else: + print("Failed to set keyboard backlight") + sys.exit(1) + + except ValueError as e: + print(f"Invalid brightness value: {e}") + sys.exit(1) + + if __name__ == "__main__": + main() + ''; + + propagatedBuildInputs = with pkgs.python3Packages; [pyusb]; + + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp $src $out/bin/zenbook-kb-backlight + chmod +x $out/bin/zenbook-kb-backlight + runHook postInstall + ''; + + meta = { + description = "ZenBook keyboard backlight control utility"; + license = pkgs.lib.licenses.mit; + }; + }; + + # Combined package with both scripts + zenbook-duo-tools = pkgs.stdenv.mkDerivation { + pname = "zenbook-duo-tools"; + version = "1.0.0"; + + dontUnpack = true; + + installPhase = '' + mkdir -p $out/bin + cp ${duoScript} $out/bin/duo + cp ${zenbook-kb-backlight}/bin/zenbook-kb-backlight $out/bin/zenbook-kb-backlight + chmod +x $out/bin/* + ''; + }; +in { + # Install the ZenBook Duo tools + home.packages = with pkgs; [ + zenbook-duo-tools + gnome-settings-daemon + gnome-monitor-config + inotify-tools + usbutils + dconf + iio-sensor-proxy + ]; + + # Systemd user services for automatic display management + systemd.user.services = { + zenbook-display-startup = { + Unit = { + Description = "ZenBook Duo Display Setup on Startup"; + After = ["graphical-session.target"]; + PartOf = ["graphical-session.target"]; + }; + Service = { + Type = "oneshot"; + ExecStart = "${zenbook-duo-tools}/bin/duo normal"; + RemainAfterExit = true; + }; + Install.WantedBy = ["graphical-session.target"]; + }; + + zenbook-display-watcher = { + Unit = { + Description = "ZenBook Duo Display Watcher"; + After = ["graphical-session.target" "zenbook-display-startup.service"]; + PartOf = ["graphical-session.target"]; + }; + Service = { + Type = "simple"; + ExecStart = "${zenbook-duo-tools}/bin/duo watch-displays"; + Restart = "always"; + RestartSec = "5"; + }; + Install.WantedBy = ["graphical-session.target"]; + }; + + zenbook-backlight-sync = { + Unit = { + Description = "ZenBook Duo Backlight Sync"; + After = ["graphical-session.target"]; + PartOf = ["graphical-session.target"]; + }; + Service = { + Type = "simple"; + ExecStart = "${zenbook-duo-tools}/bin/duo watch-backlight"; + Restart = "always"; + RestartSec = "5"; + }; + Install.WantedBy = ["graphical-session.target"]; + }; + + zenbook-rotation-watcher = { + Unit = { + Description = "ZenBook Duo Rotation Watcher"; + After = ["graphical-session.target"]; + PartOf = ["graphical-session.target"]; + }; + Service = { + Type = "simple"; + ExecStart = "${zenbook-duo-tools}/bin/duo watch-rotation"; + Restart = "always"; + RestartSec = "5"; + }; + Install.WantedBy = ["graphical-session.target"]; + }; + }; + + # Shell aliases for convenience (generic across all shells) + home.shellAliases = { + duo = "${zenbook-duo-tools}/bin/duo"; + duo-toggle = "${zenbook-duo-tools}/bin/duo toggle"; + duo-both = "${zenbook-duo-tools}/bin/duo both"; + duo-top = "${zenbook-duo-tools}/bin/duo top"; + duo-status = "${zenbook-duo-tools}/bin/duo status"; + zenbook-kb = "${zenbook-duo-tools}/bin/zenbook-kb-backlight"; + }; + + # GNOME specific configuration + dconf.settings = { + # Enable tablet/touchscreen support for specific device IDs + "org/gnome/desktop/peripherals/tablets/04f3:425b" = { + output = ["SDC" "0x419d" "0x00000000" "eDP-1"]; + }; + + "org/gnome/desktop/peripherals/tablets/04f3:425a" = { + output = ["SDC" "0x419d" "0x00000000" "eDP-2"]; + }; + + "org/gnome/desktop/peripherals/touchscreens/04f3:425b" = { + output = ["SDC" "0x419d" "0x00000000" "eDP-1"]; + }; + + "org/gnome/desktop/peripherals/touchscreens/04f3:425a" = { + output = ["SDC" "0x419d" "0x00000000" "eDP-2"]; + }; + }; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/default.nix b/home/panotaka/common/optional/desktops/hyprland/default.nix index 80c3d8f..52139d5 100644 --- a/home/panotaka/common/optional/desktops/hyprland/default.nix +++ b/home/panotaka/common/optional/desktops/hyprland/default.nix @@ -7,9 +7,18 @@ imports = [ ./hyprlock.nix ./hypridle.nix + ./wofi.nix + ./waybar.nix + ./keyring.nix ]; - # Misc settingsmanager configuration + # Add network utility packages + home.packages = with pkgs; [ + networkmanager # Network utility + uwsm # Universal Wayland Session Manager + ]; + + # Configure UWSM for Hyprland session management wayland.windowManager.hyprland = { enable = true; plugins = with pkgs.hyprlandPlugins; [ @@ -24,24 +33,67 @@ # Disable middle click on touchpad "input:touchpad:clickfinger_behavior" = false; "input:touchpad:middle_button_emulation" = false; + # Disable middle-click paste + "misc:middle_click_paste" = false; # Enable 3-finger swipe to change workspaces "gestures:workspace_swipe" = true; "gestures:workspace_swipe_fingers" = 3; "plugin:overview:reverseSwipe" = true; + + # UWSM integration - finalize session with important variables + exec-once = [ + "uwsm finalize HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP WAYLAND_DISPLAY" + ]; + # Keybinds bind = [ - # Launch terminal (kitty) - "$mod,RETURN,exec,kitty" - # Launch browser (zen) - "$mod,B,exec,zen" + # Launch terminal (kitty) via UWSM + "$mod,RETURN,exec,uwsm app -- kitty" + # Launch browser (zen) via UWSM + "$mod,B,exec,uwsm app -- zen" # Close window "$mod,Q,killactive" - # Logout - "$mod SHIFT,E,exit" + # Logout - use UWSM stop + "$mod SHIFT,E,exec,uwsm stop" - # Overview - "$mod,TAB,overview:toggle" + # Network utility (NetworkManager TUI) via UWSM + "$mod,N,exec,uwsm app -- kitty -e nmtui" + # Secrets manager (Seahorse - GNOME keyring GUI) via UWSM + "$mod,K,exec,uwsm app -- seahorse" + + # Overview - apply to all displays + "$mod,TAB,exec,hyprctl dispatch overview:toggle all" + + # Move active window to workspace + "$mod SHIFT,1,movetoworkspace,1" + "$mod SHIFT,2,movetoworkspace,2" + "$mod SHIFT,3,movetoworkspace,3" + "$mod SHIFT,4,movetoworkspace,4" + "$mod SHIFT,5,movetoworkspace,5" + "$mod SHIFT,6,movetoworkspace,6" + "$mod SHIFT,7,movetoworkspace,7" + "$mod SHIFT,8,movetoworkspace,8" + "$mod SHIFT,9,movetoworkspace,9" + "$mod SHIFT,0,movetoworkspace,10" + + # Cycle through workspaces + "$mod,Right,workspace,e+1" + "$mod,Left,workspace,e-1" + ]; + + # Mouse binds for workspace switching + bindm = [ + # Mod + scroll to change workspaces + "$mod,mouse:272,movewindow" + "$mod,mouse:273,resizewindow" + ]; + + # Scroll binds for workspace switching + binde = [ + # Mod + scroll wheel to switch workspaces + "$mod,mouse_down,workspace,e+1" + "$mod,mouse_up,workspace,e-1" ]; }; }; diff --git a/home/panotaka/common/optional/desktops/hyprland/hypridle.nix b/home/panotaka/common/optional/desktops/hyprland/hypridle.nix index fde468e..2c336a2 100644 --- a/home/panotaka/common/optional/desktops/hyprland/hypridle.nix +++ b/home/panotaka/common/optional/desktops/hyprland/hypridle.nix @@ -3,7 +3,7 @@ enable = true; settings = { general = { - lock_cmd = "pidof hyprlock || hyprlock"; + lock_cmd = "pidof hyprlock || uwsm app -- hyprlock"; before_sleep_cmd = "loginctl lock-session"; after_sleep_cmd = "hyprctl dispatch dpms on"; }; diff --git a/home/panotaka/common/optional/desktops/hyprland/hyprlock.nix b/home/panotaka/common/optional/desktops/hyprland/hyprlock.nix index 730da86..e6758e5 100644 --- a/home/panotaka/common/optional/desktops/hyprland/hyprlock.nix +++ b/home/panotaka/common/optional/desktops/hyprland/hyprlock.nix @@ -3,8 +3,9 @@ enable = true; }; + # Use UWSM to launch hyprlock wayland.windowManager.hyprland.settings.bind = [ - "$mod,L,exec,hyprlock" + "$mod,L,exec,uwsm app -- hyprlock" ]; home.packages = with pkgs; [ diff --git a/home/panotaka/common/optional/desktops/hyprland/keyring.nix b/home/panotaka/common/optional/desktops/hyprland/keyring.nix new file mode 100644 index 0000000..21af794 --- /dev/null +++ b/home/panotaka/common/optional/desktops/hyprland/keyring.nix @@ -0,0 +1,31 @@ +{pkgs, ...}: { + # Additional keyring packages for user interaction + home.packages = with pkgs; [ + seahorse # GUI for managing keyrings and passwords + libsecret # Secret service API library + ]; + + # Session variables for proper keyring integration + home.sessionVariables = { + # SSH agent socket for SSH key management + SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/keyring/ssh"; + # Control socket for GNOME Keyring daemon + GNOME_KEYRING_CONTROL = "$XDG_RUNTIME_DIR/keyring"; + # Enable secret service D-Bus API + SECRET_SERVICE_API = "1"; + # Ensure proper D-Bus session bus integration + DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus"; + # Enable password store integration + PASSWORD_STORE_ENABLE_EXTENSIONS = "true"; + # Set keyring backend for applications that support it + KEYRING_BACKEND = "gnome-keyring"; + }; + + # Additional session setup for keyring integration + wayland.windowManager.hyprland.settings.env = [ + # Ensure XDG runtime directory is available + "XDG_RUNTIME_DIR,/run/user/1000" + # Enable keyring unlock via PAM + "GNOME_KEYRING_UNLOCK_PASSWORD,1" + ]; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/waybar.nix b/home/panotaka/common/optional/desktops/hyprland/waybar.nix new file mode 100644 index 0000000..adc3e1b --- /dev/null +++ b/home/panotaka/common/optional/desktops/hyprland/waybar.nix @@ -0,0 +1,137 @@ +{pkgs, ...}: { + programs.waybar = { + enable = true; + settings = { + mainBar = { + layer = "top"; + position = "top"; + height = 30; + + modules-left = ["hyprland/workspaces" "hyprland/mode" "hyprland/window"]; + modules-center = ["clock"]; + modules-right = ["network" "bluetooth" "pulseaudio" "battery" "tray" "custom/notification"]; + + "hyprland/workspaces" = { + disable-scroll = true; + all-outputs = true; + format = "{icon}"; + format-icons = { + "1" = "1"; + "2" = "2"; + "3" = "3"; + "4" = "4"; + "5" = "5"; + "6" = "6"; + "7" = "7"; + "8" = "8"; + "9" = "9"; + "10" = "10"; + }; + }; + + "hyprland/mode" = { + format = "{}"; + }; + + "hyprland/window" = { + format = "{}"; + max-length = 50; + separate-outputs = true; + }; + + "clock" = { + tooltip-format = "{:%Y %B}\n{calendar}"; + format-alt = "{:%Y-%m-%d}"; + format = "{:%H:%M}"; + }; + + "network" = { + format-wifi = " {essid} ({signalStrength}%)"; + format-ethernet = " {ipaddr}/{cidr}"; + tooltip-format = " {ifname} via {gwaddr}"; + format-linked = " {ifname} (No IP)"; + format-disconnected = "⚠ Disconnected"; + format-alt = "{ifname}: {ipaddr}/{cidr}"; + }; + + "bluetooth" = { + format = " {status}"; + format-disabled = ""; + format-connected = " {device_alias}"; + format-connected-battery = " {device_alias} {device_battery_percentage}%"; + tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected"; + tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}"; + tooltip-format-enumerate-connected = "{device_alias}\t{device_address}"; + tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%"; + }; + + "pulseaudio" = { + scroll-step = 5; + format = "{icon} {volume}%"; + format-bluetooth = "{icon} {volume}% "; + format-bluetooth-muted = " {icon}"; + format-muted = " {format_source}"; + format-source = "{volume}% "; + format-source-muted = ""; + format-icons = { + headphone = ""; + hands-free = ""; + headset = ""; + phone = ""; + portable = ""; + car = ""; + default = ["" "" ""]; + }; + on-click = "pavucontrol"; + }; + + "battery" = { + states = { + good = 95; + warning = 30; + critical = 15; + }; + format = "{icon} {capacity}%"; + format-charging = " {capacity}%"; + format-plugged = " {capacity}%"; + format-alt = "{icon} {time}"; + format-icons = ["" "" "" "" ""]; + }; + + "tray" = { + icon-size = 21; + spacing = 10; + show-passive-items = true; + }; + + "custom/notification" = { + tooltip = false; + format = "{icon}"; + format-icons = { + notification = ""; + none = ""; + dnd-notification = ""; + dnd-none = ""; + }; + return-type = "json"; + exec-if = "which swaync-client"; + exec = "swaync-client -swb"; + on-click = "swaync-client -t -sw"; + on-click-right = "swaync-client -d -sw"; + escape = true; + }; + }; + }; + }; + + # Auto-start waybar with Hyprland via UWSM + wayland.windowManager.hyprland.settings.exec-once = [ + "uwsm app -- waybar" + ]; + + home.packages = with pkgs; [ + waybar + libappindicator-gtk3 + swaynotificationcenter + ]; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/wofi.nix b/home/panotaka/common/optional/desktops/hyprland/wofi.nix new file mode 100644 index 0000000..cee417c --- /dev/null +++ b/home/panotaka/common/optional/desktops/hyprland/wofi.nix @@ -0,0 +1,43 @@ +{pkgs, ...}: { + programs.wofi = { + enable = true; + settings = { + width = 600; + height = 400; + location = "center"; + show = "drun"; + prompt = "Search..."; + filter_rate = 100; + allow_markup = true; + no_actions = true; + halign = "fill"; + orientation = "vertical"; + content_halign = "fill"; + insensitive = true; + allow_images = true; + image_size = 40; + gtk_dark = true; + dynamic_lines = false; + matching = "contains"; + hide_scroll = true; + print_command = true; + layer = "overlay"; + sort_order = "default"; + term = "kitty"; #, SU + exec_search = false; + }; + }; + + # Add wofi keybind to Hyprland: just $mod for drun (toggle behavior) with UWSM integration + wayland.windowManager.hyprland.settings.bindr = [ + "$mod, SUPER_L, exec, pkill wofi || wofi --show drun --launch-prefix='uwsm app -- '" + ]; + # Add wofi keybind to Hyprland: $mod+R for run (toggle behavior) with UWSM integration + wayland.windowManager.hyprland.settings.bind = [ + "$mod,R,exec, pkill wofi || wofi --show run --launch-prefix='uwsm app -- '" + ]; + + home.packages = with pkgs; [ + wofi + ]; +} diff --git a/home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix b/home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix index 9e338c8..9508cec 100644 --- a/home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix +++ b/home/panotaka/common/optional/desktops/hyprland/zenbook-screen.nix @@ -1,4 +1,8 @@ -{pkgs, ...}: let +{ + pkgs, + lib, + ... +}: let # Configuration variables from your script preferred_resolution = "2880x1800"; refresh_rate = "120"; @@ -91,13 +95,62 @@ ${zenbook-normal}/bin/zenbook-normal ''; + # Enhanced lid monitoring with multiple detection methods + zenbook-lid-monitor = pkgs.writeShellScriptBin "zenbook-lid-monitor" '' + echo "Starting comprehensive lid monitoring..." + + # Method 1: Monitor ACPI events + (${pkgs.acpi}/bin/acpi_listen | while read event; do + if echo "$event" | grep -q "button/lid"; then + echo "ACPI lid event detected: $event" + sleep 0.5 && ${zenbook-set-displays}/bin/zenbook-set-displays + fi + done) & + + # Method 2: Poll lid state file directly + (while true; do + if [ -f /proc/acpi/button/lid/LID0/state ] || [ -f /proc/acpi/button/lid/LID/state ]; then + current_state=$(cat /proc/acpi/button/lid/*/state 2>/dev/null | head -1) + if [ "$current_state" != "$previous_state" ]; then + echo "Lid state changed: $current_state" + previous_state="$current_state" + sleep 0.5 && ${zenbook-set-displays}/bin/zenbook-set-displays + fi + fi + sleep 2 + done) & + + # Method 3: Monitor systemd logind events + (${pkgs.systemd}/bin/journalctl -f --user -u "*" | while read line; do + if echo "$line" | grep -i "lid\|suspend\|resume"; then + echo "Systemd event: $line" + sleep 1 && ${zenbook-set-displays}/bin/zenbook-set-displays + fi + done) & + + wait + ''; + # Auto-run display setup on startup zenbook-autostart = pkgs.writeShellScriptBin "zenbook-autostart" '' # Initial display setup - ${zenbook-normal}/bin/zenbook-normal + echo "Running initial display setup" + ${zenbook-set-displays}/bin/zenbook-set-displays + + # Wait a moment for system to stabilize + sleep 2 + + # Run display setup again to ensure proper configuration + echo "Running secondary display setup" + ${zenbook-set-displays}/bin/zenbook-set-displays # Start USB monitoring in background + echo "Starting USB monitoring for display changes" ${zenbook-watch-displays}/bin/zenbook-watch-displays & + + # Start enhanced lid monitoring + echo "Starting enhanced lid monitoring" + ${zenbook-lid-monitor}/bin/zenbook-lid-monitor & ''; in { # Zenbook dual-screen display configuration @@ -118,12 +171,21 @@ in { vfr = true; }; - # Auto-start the event-driven display management + # Auto-start the event-driven display management via UWSM exec-once = [ - "${zenbook-autostart}/bin/zenbook-autostart" + "uwsm app -- ${zenbook-autostart}/bin/zenbook-autostart" + # Additional trigger after a delay to handle race conditions + "sleep 5 && uwsm app -- ${zenbook-set-displays}/bin/zenbook-set-displays" + # Monitor for display hotplug events (DRM/KMS events) + "uwsm app -- sh -c 'while ${pkgs.inotify-tools}/bin/inotifywait -e modify /sys/class/drm/*/status 2>/dev/null; do sleep 1 && ${zenbook-set-displays}/bin/zenbook-set-displays; done' &" + # Monitor for graphics card state changes + "uwsm app -- sh -c '${pkgs.udev}/bin/udevadm monitor --udev --subsystem-match=drm | while read line; do if echo \"$line\" | grep -q \"change\"; then sleep 2 && ${zenbook-set-displays}/bin/zenbook-set-displays; fi; done' &" ]; }; + # Hook into hypridle for unlock/resume events + services.hypridle.settings.general.after_sleep_cmd = lib.mkForce "hyprctl dispatch dpms on && ${zenbook-set-displays}/bin/zenbook-set-displays"; + # Add the scripts to home packages home.packages = [ zenbook-top @@ -136,5 +198,6 @@ in { zenbook-watch-displays zenbook-set-displays zenbook-autostart + zenbook-lid-monitor ]; } diff --git a/hosts/common/optional/gnome.nix b/hosts/common/optional/gnome.nix index b9cc323..e658c8d 100644 --- a/hosts/common/optional/gnome.nix +++ b/hosts/common/optional/gnome.nix @@ -23,7 +23,6 @@ ]; environment.systemPackages = with pkgs; [ - gnomeExtensions.appindicator gsettings-desktop-schemas ]; } diff --git a/hosts/common/optional/greetd.nix b/hosts/common/optional/greetd.nix index f4e8d23..98ced11 100644 --- a/hosts/common/optional/greetd.nix +++ b/hosts/common/optional/greetd.nix @@ -9,6 +9,22 @@ }; }; + # Enable the GNOME Keyring daemon system-wide + services.gnome.gnome-keyring.enable = true; + + # Enable GNOME Keyring support in PAM + security.pam.services.greetd.enableGnomeKeyring = true; + security.pam.services.login.enableGnomeKeyring = true; + + # Ensure gnome-keyring daemon runs for user sessions + systemd.user.services.gnome-keyring = { + wantedBy = ["default.target"]; + serviceConfig = { + ExecStart = "${pkgs.gnome-keyring}/bin/gnome-keyring-daemon --start --foreground --components=pkcs11,secrets,ssh"; + Restart = "on-abort"; + }; + }; + # Disable conflicting getty services on tty1 systemd.services."getty@tty1".enable = false; systemd.services."autovt@tty1".enable = false; diff --git a/hosts/common/optional/hyprland.nix b/hosts/common/optional/hyprland.nix index 3693264..7f86bd1 100644 --- a/hosts/common/optional/hyprland.nix +++ b/hosts/common/optional/hyprland.nix @@ -14,5 +14,17 @@ portalPackage = pkgs.xdg-desktop-portal-hyprland; }; + # Enable UWSM for better Wayland session management + programs.uwsm = { + enable = true; + waylandCompositors = { + hyprland = { + prettyName = "Hyprland"; + comment = "Hyprland Wayland compositor"; + binPath = "/run/current-system/sw/bin/Hyprland"; + }; + }; + }; + environment.sessionVariables.NIXOS_OZONE_WL = "1"; } diff --git a/hosts/common/optional/sddm.nix b/hosts/common/optional/sddm.nix index dcac5a3..4c44ccb 100644 --- a/hosts/common/optional/sddm.nix +++ b/hosts/common/optional/sddm.nix @@ -1,10 +1,10 @@ # NOTE(starter): This is just a basic enabling of the XFCE windows manager for simplicity { -services.displayManager = { + services.displayManager = { sddm.enable = true; sddm.wayland = { enable = true; compositor = "kwin"; }; -}; + }; } diff --git a/hosts/nixos/Bellerophon/default.nix b/hosts/nixos/Bellerophon/default.nix index d557279..dd3d6d7 100644 --- a/hosts/nixos/Bellerophon/default.nix +++ b/hosts/nixos/Bellerophon/default.nix @@ -74,8 +74,8 @@ "hosts/common/optional/services/docker.nix" "hosts/common/optional/services/tailscale.nix" "hosts/common/optional/audio.nix" # pipewire and cli controls - "hosts/common/optional/hyprland.nix" - "hosts/common/optional/greetd.nix" + "hosts/common/optional/gnome.nix" + "hosts/common/optional/gdm.nix" "hosts/common/optional/flatpak.nix" "hosts/common/optional/thermal-management.nix"