diff --git a/home/packages/gui/default.nix b/home/packages/gui/default.nix index 63b0638..e0d4165 100644 --- a/home/packages/gui/default.nix +++ b/home/packages/gui/default.nix @@ -1,3 +1,5 @@ _: { - imports = [ ]; + imports = [ + ./wayland.nix + ]; } diff --git a/home/packages/gui/wayland.nix b/home/packages/gui/wayland.nix new file mode 100644 index 0000000..f90c92d --- /dev/null +++ b/home/packages/gui/wayland.nix @@ -0,0 +1,15 @@ +{ + lib, + pkgs, + osConfig, + ... +}: let + inherit (lib) mkIf; + +in { + config = mkIf osConfig.myOptions.home-manager.wms.isWayland { + home.packages = with pkgs; [ + wlogout + ]; + }; +} diff --git a/home/programs/graphical/wms/hyprland/config/default.nix b/home/programs/graphical/wms/hyprland/config/default.nix new file mode 100644 index 0000000..a6dd8b3 --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/default.nix @@ -0,0 +1,12 @@ +_: { + imports = [ + ./exec.nix + ./gestures.nix + ./input.nix + ./keybinds.nix + ./layout.nix + ./misc.nix + ./style.nix + ./window_rules.nix + ]; +} diff --git a/home/programs/graphical/wms/hyprland/config/exec.nix b/home/programs/graphical/wms/hyprland/config/exec.nix new file mode 100644 index 0000000..546b93c --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/exec.nix @@ -0,0 +1,8 @@ +{ + wayland.windowManager.hyprland.settings = { + exec-once = [ + # TODO: Add this (probably only vesktop) + ]; + }; +} + diff --git a/home/programs/graphical/wms/hyprland/config/gestures.nix b/home/programs/graphical/wms/hyprland/config/gestures.nix new file mode 100644 index 0000000..7c3923d --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/gestures.nix @@ -0,0 +1,13 @@ +{ + wayland.windowManager.hyprland.settings = { + gestures = { + workspace_swipe = true; + workspace_swipe_fingers = 3; + workspace_swipe_distance = 300; + workspace_swipe_invert = false; + workspace_swipe_min_speed_to_force = 20; + workspace_swipe_cancel_ratio = 0.650000; + }; + }; +} + diff --git a/home/programs/graphical/wms/hyprland/config/input.nix b/home/programs/graphical/wms/hyprland/config/input.nix new file mode 100644 index 0000000..bac0c6b --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/input.nix @@ -0,0 +1,25 @@ +{ + wayland.windowManager.hyprland.settings = { + input = { + # Keyboard layout settings + # Default to US keyboard, but allow switching to SK with alt-shift + kb_layout = "us, sk"; + kb_variant = ",qwerty"; + kb_options = "grp:alt_shift_toggle"; + + # Enable numlock by default (once Hyprland is loaded) + numlock_by_default = true; + + # cursor movement will always change focus to the window under the cursor + follow_mouse = 1; + + touchpad = { + # Sending LMB + RMB = MMB + middle_button_emulation = true; + # I'm not natural + natural_scroll = false; + }; + }; + }; +} + diff --git a/home/programs/graphical/wms/hyprland/config/keybinds.nix b/home/programs/graphical/wms/hyprland/config/keybinds.nix new file mode 100644 index 0000000..880a730 --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/keybinds.nix @@ -0,0 +1,166 @@ +{ + wayland.windowManager.hyprland.settings = { + "$MOUSE_LMB" = "mouse:272"; + "$MOUSE_RMB" = "mouse:273"; + "$MOUSE_MMB" = "mouse:274"; + "$MOUSE_EX1" = "mouse:275"; + "$MOUSE_EX2" = "mouse:276"; + + "$XF86Favorites" = "164"; + + bind = [ + # + # Active window + # + "SUPER, W, killactive," + "SUPER, F, togglefloating," + "SUPER, Space, fullscreen, 0" + "SUPER, Space, fullscreen, 1" # maximize + "SUPER_SHIFT, S, layoutmsg, togglesplit" + + # + # Programs + # + "SUPER, Return, exec, kitty" + # TODO: requires programs + + # + # DE/WM Control programs + # + # TODO: Requires programs + "SUPER_SHIFT, L, exec, wlogout -p layer-shell" + + # + # Screenshots + # + # TODO: requires script + + # + # Brightness control + # + # TODO: requires script + + + # + # Audio/Volume control + # + "SUPER, Down, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05-" + "SUPER, Up, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05+" + ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05-" + ", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05+" + ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" + + # + # Notifications + # + # TODO: Requires notification daemon (dunst?) + + + # + # Window groups + # + "SUPER, G, togglegroup," + "ALT, tab, changegroupactive, f" + "ALT, grave, changegroupactive, b" + + # + # Special workspace (scratchpad) + # + "ALT, grave, movetoworkspace, special" + "SUPER, grave, togglespecialworkspace," + + # + # Move window focus + # + "SUPER, h, movefocus, l" + "SUPER, l, movefocus, r" + "SUPER, k, movefocus, u" + "SUPER, j, movefocus, d" + + # + # Move active window in direction + # + "SUPER_ALT, h, movewindow, l" + "SUPER_ALT, l, movewindow, r" + "SUPER_ALT, k, movewindow, u" + "SUPER_ALT, j, movewindow, d" + + # + # Move floating windows + # + # TODO: requires script (move-window.sh) + + # + # Override split direction for next window (manual tiling) + # + "SUPER_ALT, left, layoutmsg, preselect l" + "SUPER_ALT, right, layoutmsg, preselect r" + "SUPER_ALT, up, layoutmsg, preselect u" + "SUPER_ALT, down, layoutmsg, preselect d" + + # + # Switch workspace (swapping to current monitor) + # + # TODO: requires script (swap-workspace) + + # + # Move window to workspace + # + "SUPER_SHIFT, 1, movetoworkspacesilent, 1" + "SUPER_SHIFT, 2, movetoworkspacesilent, 2" + "SUPER_SHIFT, 3, movetoworkspacesilent, 3" + "SUPER_SHIFT, 4, movetoworkspacesilent, 4" + "SUPER_SHIFT, 5, movetoworkspacesilent, 5" + "SUPER_SHIFT, 6, movetoworkspacesilent, 6" + "SUPER_SHIFT, 7, movetoworkspacesilent, 7" + "SUPER_SHIFT, 8, movetoworkspacesilent, 8" + "SUPER_SHIFT, 9, movetoworkspacesilent, 9" + + # + # Move window to workspace + focus it + # + "ALT, 1, movetoworkspace, 1" + "ALT, 2, movetoworkspace, 2" + "ALT, 3, movetoworkspace, 3" + "ALT, 4, movetoworkspace, 4" + "ALT, 5, movetoworkspace, 5" + "ALT, 6, movetoworkspace, 6" + "ALT, 7, movetoworkspace, 7" + "ALT, 8, movetoworkspace, 8" + "ALT, 9, movetoworkspace, 9" + + # + # Cycle workspaces (relative movement) + # + "SUPER, mouse_down, workspace, +1" + "SUPER, mouse_up, workspace, -1" + "SUPER, bracketright, workspace, +1" + "SUPER, bracketleft, workspace, -1" + + # + # Cycle monitors (relative movement) + # + "SUPER_SHIFT, mouse_down, focusmonitor, +1" + "SUPER_SHIFT, mouse_up, focusmonitor, -1" + "SUPER_SHIFT, bracketright, focusmonitor, +1" + "SUPER_SHIFT, bracketleft, focusmonitor, -1" + + # + # Window resizing + # + # TODO: Submaps + binde + + # + # Isolation group + # + # TODO: Submaps + ]; + + bindm = [ + # Mouse window resizing + "SUPER, $MOUSE_LMB, movewindow" + "SUPER, $MOUSE_RMB, resizewindow" + ]; + }; +} diff --git a/home/programs/graphical/wms/hyprland/config/layout.nix b/home/programs/graphical/wms/hyprland/config/layout.nix new file mode 100644 index 0000000..a35c564 --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/layout.nix @@ -0,0 +1,25 @@ +{ + wayland.windowManager.hyprland.settings = { + general.layout = "dwindle"; + + dwindle = { + # Don't change the split (side/top) regardless of what happens to the container + preserve_split = true; + + # Show gaps even when there's only 1 window opened + no_gaps_when_only = false; + + # Scale down special workspaces (bigger borders) + special_scale_factor = 0.9; + }; + + group = { + # Add new windows in the group after the current window + # rather than after the group tail window + insert_after_current = true; + + # Focus the window that was just moved out of the group + focus_removed_window = true; + }; + }; +} diff --git a/home/programs/graphical/wms/hyprland/config/misc.nix b/home/programs/graphical/wms/hyprland/config/misc.nix new file mode 100644 index 0000000..b101754 --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/misc.nix @@ -0,0 +1,19 @@ +{ + wayland.windowManager.hyprland.settings = { + misc = { + # Disable redundant renders (covered by wallpaper) + disable_hyprland_logo = true; + disable_splash_rendering = true; + + # Follow requests from windows to be focused + focus_on_activate = true; + + # Auto-reload is unnecessary on NixOS, config is readonly + disable_autoreload = true; + + # Enable DPMS on these actions + mouse_move_enables_dpms = true; + key_press_enables_dpms = true; + }; + }; +} diff --git a/home/programs/graphical/wms/hyprland/config/style.nix b/home/programs/graphical/wms/hyprland/config/style.nix new file mode 100644 index 0000000..2607cca --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/style.nix @@ -0,0 +1,127 @@ +{ + config, + ... +}: +{ + wayland.windowManager.hyprland.settings = { + + # + # Window gaps + # + + general = { + gaps_in = 5; + gaps_out = 8; + }; + + # + # Borders + # + + decoration.rounding = 8; + + general = { + border_size = 2; + + # Regular windows + "col.active_border" = "rgba(FFA500FF)"; # orange + "col.inactive_border" = "rgba(666666AA)"; # transparent gray + + # Windows with nogroup property + "col.nogroup_border_active" = "rgba(FF00FFFF)"; # purple + "col.nogroup_border" = "rgba(FF00FFAA)"; # transparent purple + }; + + group = { + # Groupped windows + "col.border_active" = "rgba(00A500FF)"; # green + "col.border_inactive" = "rgba(5AA500FF)"; # transparent green + + # Locked groupped windows + "col.border_locked_active" = "rgba(A0A500FF)"; # yellow + "col.border_locked_inactive" = "rgba(A0A500AA)"; # transparent yellow + }; + + # + # Group bar + # + + group = { + groupbar = { + # Title box above window + render_titles = false; # disable, looks kinda bad + font_family = "Monaspace Krypton"; + font_size = 11; + text_color = "rgba(FFFFFFFF)"; # white + + # Gradients should be enabled only if title rendering is also enabled + # on their own, they look really bad + gradients = false; + + "col.active" = "rgba(FFA500FF)"; # light orange + "col.inactive" = "rgba(00A500AA)"; # transparent green + + "col.locked_active" = "rgba(FF8000FF)"; # dark orange + "col.locked_inactive" = "rgba(A0A500AA)"; # transparent yello + + # Scrolling in the groupbar shouldn't change the active window + scrolling = false; + }; + }; + + # + # Drop shadow + # + + decoration = { + drop_shadow = true; + shadow_range = 20; + shadow_render_power = 2; + "col.shadow" = "rgba(0F0F0FE6)"; + "col.shadow_inactive" = "rgba(0F0F0F99)"; + }; + + + # + # Window Blur + # + + decoration.blur = { + enabled = true; + size = 8; + passes = 1; + }; + + + # + # Dim inactive windows + # + + decoration = { + dim_inactive = false; # disabled for now + dim_strength = 0.05; + dim_special = 0.2; + inactive_opacity = 0.9; + }; + + # + # Animation + # + + animations = { + enabled = true; + first_launch_animation = true; # fade in on first launch + + animation = [ + "windows, 1, 3, default, popin 50%" + "border, 1, 4, default" + "fade, 1, 4, default" + "workspaces, 1, 3, default" + "specialWorkspace, 1, 2, default, slidefadevert" + ]; + }; + + misc.animate_manual_resizes = true; + }; +} + diff --git a/home/programs/graphical/wms/hyprland/config/window_rules.nix b/home/programs/graphical/wms/hyprland/config/window_rules.nix new file mode 100644 index 0000000..52564eb --- /dev/null +++ b/home/programs/graphical/wms/hyprland/config/window_rules.nix @@ -0,0 +1,8 @@ +{ + wayland.windowManager.hyprland.settings = { + windowrulev2 = [ + # TODO: Add these + ]; + }; +} + diff --git a/home/programs/graphical/wms/hyprland/default.nix b/home/programs/graphical/wms/hyprland/default.nix index 0d4eb74..43c1e4d 100644 --- a/home/programs/graphical/wms/hyprland/default.nix +++ b/home/programs/graphical/wms/hyprland/default.nix @@ -1,10 +1,31 @@ { - wayland.windowManager.hyprland = { - enable = true; - xwayland.enable = true; - systemd = { + osConfig, + pkgs, + lib, + ... +}: let + inherit (lib) mkIf; + + inherit (import ./packages {inherit pkgs;}) dbus-hyprland-env; + + cfg = osConfig.myOptions.home-manager.wms.hyprland; +in { + imports = [ + ./config + ]; + + config = mkIf cfg.enable { + home.packages = with pkgs; [ + dbus-hyprland-env + ]; + + wayland.windowManager.hyprland = { enable = true; - variables = ["--all"]; + xwayland.enable = true; + systemd = { + enable = true; + variables = ["--all"]; + }; }; }; } diff --git a/home/programs/graphical/wms/hyprland/packages/dbus-hyprland-env.nix b/home/programs/graphical/wms/hyprland/packages/dbus-hyprland-env.nix new file mode 100644 index 0000000..8fef3e5 --- /dev/null +++ b/home/programs/graphical/wms/hyprland/packages/dbus-hyprland-env.nix @@ -0,0 +1,11 @@ +{pkgs, ...}: +pkgs.writeTextFile { + name = "dbus-hyprland-env"; + destination = "/bin/dbus-hyprland-environment"; + executable = true; + text = '' + dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=hyprland + systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr + systemctl --user start pipewire wireplumber pipewire-media-session xdg-desktop-portal xdg-desktop-portal-hyprland + ''; +} diff --git a/home/programs/graphical/wms/hyprland/packages/default.nix b/home/programs/graphical/wms/hyprland/packages/default.nix new file mode 100644 index 0000000..36e2305 --- /dev/null +++ b/home/programs/graphical/wms/hyprland/packages/default.nix @@ -0,0 +1,9 @@ +{ + pkgs, + ... +}: let + packages = { + dbus-hyprland-env = pkgs.callPackage ./dbus-hyprland-env.nix {}; + }; +in + packages diff --git a/hosts/herugrim/default.nix b/hosts/herugrim/default.nix index 5cc148c..0364a98 100644 --- a/hosts/herugrim/default.nix +++ b/hosts/herugrim/default.nix @@ -85,6 +85,7 @@ key = "FA2745890B7048C0"; }; }; + wms.hyprland.enable = true; }; }; } diff --git a/options/home/default.nix b/options/home/default.nix index f959229..506671b 100644 --- a/options/home/default.nix +++ b/options/home/default.nix @@ -4,6 +4,7 @@ in { imports = [ ./git.nix + ./wms.nix ]; options.myOptions.home-manager = { diff --git a/options/home/wms.nix b/options/home/wms.nix new file mode 100644 index 0000000..1708710 --- /dev/null +++ b/options/home/wms.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + ... +}: let + inherit (lib) mkEnableOption mkOption types; +in { + options.myOptions.home-manager.wms = { + hyprland.enable = mkEnableOption '' + Hyprland wayland compositor. + ''; + + isWayland = mkOption { + type = types.bool; + default = with config.myOptions.home-manager.wms; (hyprland.enable); + description = '' + Whether to enable Wayland exclusive modules, this contains a variety + of packages, modules, overlays, XDG portals and so on. + ''; + }; + }; +}