Cara Install Hyprland Nixos

Panduan Install dan konfigurasi Hyprland di Nixos step by step

JagoTekno - Hyprland merupakan sebuah desktop compositor untuk wayland. Singkatnya dia sama seperti KDE, Gnome, Xfce, Awesome, dll, tapi dia hanya menyediakan tampilan saja, tidak include dengan aplikasi.

Hyprland menyajikan sebuah tampilan yang minimalis dan elegan lengkap dengan beberapa animasi keren pada setiap window.

Dengan menggunakan kelebihan dari teknologi Wayland + Sway, kita bisa merasakan pengalaman penggunakan desktop Linux yang berbeda dan menyenangkan.

Pengetahuan dasar seputar Hyprland, Wayland dan Xorg

install hyprland nixos

Hyprland berjalan di atas Wayland. Untuk bisa menjalankan Hyprland kita harus mengaktifkan modul wayland + Sway terlebih dahulu.

Kemudian setelah berjalan, kita coba jalankan aplikasi X11 dan berharap aplikasi tersebut bisa berfungsi dengan normal di atas Hyprland.

Jika membandingkan X11 dengan Hyprland akan sangat terasa bedanya, dimana beberapa aplikasi yang biasa kita gunakan mungkin tidak akan berfungsi.

Misalnya LxAppearance, Flameshot, tidak akan berjalan di X11, meskipun bisa terbuka tetapi tidak akan ngefek apa-apa jika kita mencoba mengubah pengaturannya.

Setelah saya menggunakan Hyprland beberapa waktu ini, saya merasakan bahwa X11 lebih mature karena dia sudah mendukung lebih banyak aplikasi, sedangkan Wayland masih belum sempurna.

Cara Install Hyprland di Nixos

Secara dasar, Hyprland bisa diinstall hanya dengan mengikuti tutorial pada wiki.hyprland.org.

Tapi di sini saya ingin menjelaskan lengkap dengan cara setting Hyprland step by step. Biar para pemula bisa memahami.

Juga sebagai catatan buat saya pribadi supaya tidak lupa.

Dan cara yang elegan untuk install aplikasi di Nixos adalah dengan menggunakan home-manager.

Install Hyprland melalui Home Manager

  1. Buka file configuration.nix lalu tambahkan baris ini
  nix = {
    settings.substituters = ["https://hyprland.cachix.org"];
    settings.trusted-public-keys = ["hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="];
  };
  1. Kemudian buka home-manager edit lalu tambahkan baris ini

let
flake-compat = builtins.fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz";

hyprland = (import flake-compat {
    src = builtins.fetchTarball "https://github.com/hyprwm/Hyprland/releases/download/v0.23.0beta/source-v0.23.0beta.tar.gz";
    }).defaultNix;
in 
{
  imports = [
    hyprland.homeManagerModules.default
  ];

  home.packages = with pkgs; [
    wofi swaybg wlsunset wl-clipboard 
#sway 
      slurp sway-contrib.grimshot jq socat
  ];


  wayland.windowManager.hyprland = {
    enable = true;
    extraConfig = ''
    # My HYPRLAND Configuration

    monitor=eDP-1,[email protected],0x0,1

    # For screen sharing 
    exec-once=dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
    exec-once=systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP

#    exec-once=xprop -root -f _XWAYLAND_GLOBAL_OUTPUT_SCALE 32c -set _XWAYLAND_GLOBAL_OUTPUT_SCALE 1

    exec-once=waybar

    # Set your Xrate setting in here 
    input {
      # Remap Capslock -> Esc for Vim users  
      #kb_options=caps:escape
      repeat_rate=50
      repeat_delay=300
    
      touchpad {
        disable_while_typing=1
        natural_scroll=0
        clickfinger_behavior=1
        middle_button_emulation=0
        tap-to-click=1
      }
    }
    
   # This will activate gesture so you can switch between workspace like Gnome 42 or MacOS  
    gestures { 
      workspace_swipe=true 
      workspace_swipe_min_speed_to_force=5
    }

    #Set gaps between window
      general {
        gaps_in = 5
        gaps_out = 5
        border_size = 1
        col.active_border = rgb(ffc0cb)
        col.inactive_border = rgba(595959aa)
        layout = dwindle # master|dwindle 
      }

    decoration {
      rounding=0
        blur = true
        blur_size = 3
        blur_passes = 3
        blur_new_optimizations = true
        drop_shadow=0
        shadow_range=60
        col.shadow=0x66000000
        multisample_edges = true
    }

    animations {
        enabled=1
        bezier=overshot,0.13,0.99,0.29,1.1
        animation=windows,1,4,overshot,slide
        animation=fade,1,10,default
        animation=workspaces,1,8.8,overshot,slide
        animation=border,1,14,default
    }
    
    dwindle {
        pseudotile=1 # enable pseudotiling on dwindle
        force_split=0
        no_gaps_when_only = true
    }
    
    # set only gaps if only more than 1 window opened
    master {
      new_on_top=true
      no_gaps_when_only = true
    }
    
    misc {
      # disable_hyprland_logo=true
      # disable_splash_rendering=true
      mouse_move_enables_dpms=true
      vfr = true
      hide_cursor_on_touch = true
    }

    bindm = SUPER, mouse:272, movewindow
    bindm = SUPER, mouse:273, resizewindow

    # Keybind for launch apps
    bind = SUPERSHIFT, Return, exec, kitty
    bind = SUPER, E, exec, nemo
    bind = SUPER, D, exec, wofi --show drun -I
    bind = SUPER, P, exec, wofi --show run
    bind = SUPER, W, exec, firefox
    bind = SUPER, Q, exec, ~/.scripts/powermenu.sh

    bind = ,Print,exec, grimshot save active
    bind = SHIFT,Print,exec, grimshot save area
    bind = CTRL,Print,exec, grimshot save window

    #exec-once=eww daemon
    #exec-once=eww open bar

    bind=SUPER,V,togglefloating,
    bind=SUPER,F,fullscreen,0

    bind= SUPER, g, togglegroup
    bind= SUPER, tab, changegroupactive

    bind = SUPER, h, movefocus, l
    bind = SUPER, l, movefocus, r
    bind = SUPER, j, movefocus, u
    bind = SUPER, k, movefocus, d

    bind = SUPER CTRL, left, resizeactive, -20 0
    bind = SUPER CTRL, right, resizeactive, 20 0
    bind = SUPER CTRL, up, resizeactive, 0 -20
    bind = SUPER CTRL, down, resizeactive, 0 20


    bind=SUPERSHIFT,C,killactive

    bind=SUPERSHIFT,h,movewindow,l
    bind=SUPERSHIFT,l,movewindow,r
    bind=SUPERSHIFT,k,movewindow,u
    bind=SUPERSHIFT,j,movewindow,d

    bind=SUPER,1,workspace,1
    bind=SUPER,2,workspace,2
    bind=SUPER,3,workspace,3
    bind=SUPER,4,workspace,4
    bind=SUPER,5,workspace,5
    bind=SUPER,6,workspace,6
    bind=SUPER,7,workspace,7
    bind=SUPER,8,workspace,8
    bind=SUPER,9,workspace,9

    bind=SUPERSHIFT,1,movetoworkspacesilent,1
    bind=SUPERSHIFT,2,movetoworkspacesilent,2
    bind=SUPERSHIFT,3,movetoworkspacesilent,3
    bind=SUPERSHIFT,4,movetoworkspacesilent,4
    bind=SUPERSHIFT,5,movetoworkspacesilent,5
    bind=SUPERSHIFT,6,movetoworkspacesilent,6
    bind=SUPERSHIFT,7,movetoworkspacesilent,7
    bind=SUPERSHIFT,8,movetoworkspacesilent,8
    bind=SUPERSHIFT,9,movetoworkspacesilent,9

    #bind=ALT,R,submap,resize
    #submap=resize
    #binde=,right,resizeactive,15 0
    #binde=,left,resizeactive,-15 0
    #binde=,up,resizeactive,0 -15
    #binde=,down,resizeactive,0 15
    #binde=,l,resizeactive,15 0
    #binde=,h,resizeactive,-15 0
    #binde=,k,resizeactive,0 -15
    #binde=,j,resizeactive,0 15
    #bind=,escape,submap,reset 
    #submap=reset

    bind=CTRL SHIFT, left, resizeactive,-15 0
    bind=CTRL SHIFT, right, resizeactive,15 0
    bind=CTRL SHIFT, up, resizeactive,0 -15
    bind=CTRL SHIFT, down, resizeactive,0 15
    bind=CTRL SHIFT, l, resizeactive, 15 0
    bind=CTRL SHIFT, h, resizeactive,-15 0
    bind=CTRL SHIFT, k, resizeactive, 0 -15
    bind=CTRL SHIFT, j, resizeactive, 0 15

    bind=,XF86MonBrightnessUp,exec, light -A 2
    bind=,XF86MonBrightnessDown,exec, light -U 2

    bind=,XF86AudioRaiseVolume,exec,pactl set-sink-volume 0 +5%
    bind=,XF86AudioLowerVolume,exec,pactl set-sink-volume 0 -5%
    bind=,XF86AudioMute,exec,pactl set-sink-mute toggle 

        '';

  };

# make stuff work on wayland
  home.sessionVariables = {
    _JAVA_AWT_WM_NONREPARENTING = "1";
    MOZ_ENABLE_WAYLAND = "1";
    QT_QPA_PLATFORM = "wayland";
    QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
    SDL_VIDEODRIVER = "wayland";
    XDG_SESSION_TYPE = "wayland";
  };


# ENABLE SWAY
  wayland.windowManager.sway = {
    enable = true;
    config = rec {
      #menu = "wofi";
      #terminal = default.terminal.name;
      modifier = "Mod4";
      bars = [];

      gaps = {
        smartBorders = "on";
        outer = 5;
        inner = 5;
      };

      startup = [{command = "dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY";}];

      input = {
        "type:pointer" = {
          accel_profile = "flat";
          pointer_accel = "0";
        };
        "type:touchpad" = {
          middle_emulation = "enabled";
          natural_scroll = "enabled";
          tap = "enabled";
        };
      };
#      output."*".bg = "~/.config/wallpaper.png fill";
    };

    extraConfig = ''
      exec ${pkgs.xorg.xprop}/bin/xprop -root -f _XWAYLAND_GLOBAL_OUTPUT_SCALE 32c -set _XWAYLAND_GLOBAL_OUTPUT_SCALE 2
      '';

    wrapperFeatures.gtk = true;
  };

}
  1. Jangan lupa melakukan rebuild home-manager switch

  2. Untuk menjalankan Hyprland, silahkan buka ke TTY lalu ketik Hyprland, dan semoga anda berhasil masuk ke desktop Hyprland.

Di atas adalah copy paste pengaturan saya saat ini.

Fitur Hyprland yang didapatkan saat ini

  • Animasi antar window
  • Gaps
  • Cursor Rate biar lebih cepat
  • Screenshot menggunakan grimshot, karena Flameshot tidak bisa
  • Floating window
  • Resize window
  • Tiling window

Install Waybar sebagai status bar

Untuk install waybar silahkan copy paste bagian ini pada config home manager di atas.

{
nixpkgs.overlays = [
    (final: prev: {
      waybar =
        let
          hyprctl = "${pkgs.hyprland}/bin/hyprctl";
          waybarPatchFile = import ./workspace-patch.nix { inherit pkgs hyprctl; };
        in
        prev.waybar.overrideAttrs (oldAttrs: {
          mesonFlags = oldAttrs.mesonFlags ++ [ "-Dexperimental=true" ];
          patches = (oldAttrs.patches or [ ]) ++ [ waybarPatchFile ];
        });
    })
  ];

 # home.packages = with pkgs; [
 #   waybar
 # ];

programs.waybar = {
    enable = true;
    systemd.enable = false;
    style = ''
            * {
                 font-family: "SF Pro Display";
                 font-size: 10pt;
                 font-weight: 600;
                 border-radius: 0px;
                 transition-property: background-color;
                 transition-duration: 0.5s;
               }
               @keyframes blink_red {
                 to {
                   background-color: rgb(242, 143, 173);
                   color: rgb(26, 24, 38);
                 }
               }
               .warning, .critical, .urgent {
                 animation-name: blink_red;
                 animation-duration: 1s;
                 animation-timing-function: linear;
                 animation-iteration-count: infinite;
                 animation-direction: alternate;
               }
               window#waybar {
                 background-color: transparent;
               }
               window > box {
                 margin-left: 5px;
                 margin-right: 5px;
                 margin-top: 5px;
                 background-color: rgb(30, 30, 46);
               }
         #workspaces {
                 padding-left: 0px;
                 padding-right: 4px;
               }
         #workspaces button {
                 padding-top: 5px;
                 padding-bottom: 5px;
                 padding-left: 6px;
                 padding-right: 6px;
               }
         #workspaces button.active {
                 background-color: rgb(181, 232, 224);
                 color: rgb(26, 24, 38);
               }
         #workspaces button.urgent {
                 color: rgb(26, 24, 38);
               }
         #workspaces button:hover {
                 background-color: rgb(248, 189, 150);
                 color: rgb(26, 24, 38);
               }
               tooltip {
                 background: rgb(48, 45, 65);
               }
               tooltip label {
                 color: rgb(217, 224, 238);
               }
         #custom-launcher {
                 font-size: 20px;
                 padding-left: 8px;
                 padding-right: 6px;
                 color: #7ebae4;
               }
         #mode, #clock, #memory, #temperature,#cpu,#mpd, #custom-wall, #temperature, #backlight, #pulseaudio, #network, #battery, #custom-powermenu, #custom-cava-internal {
                 padding-left: 10px;
                 padding-right: 10px;
               }
               /* #mode { */
               /* 	margin-left: 10px; */
               /* 	background-color: rgb(248, 189, 150); */
               /*     color: rgb(26, 24, 38); */
               /* } */
         #memory {
                 color: rgb(181, 232, 224);
               }
         #cpu {
                 color: rgb(245, 194, 231);
               }
         #clock {
                 color: rgb(217, 224, 238);
               }
        /* #idle_inhibitor {
                 color: rgb(221, 182, 242);
               }*/
         #custom-wall {
                 color: rgb(221, 182, 242);
            }
         #temperature {
                 color: rgb(150, 205, 251);
               }
         #backlight {
                 color: rgb(248, 189, 150);
               }
         #pulseaudio {
                 color: rgb(245, 224, 220);
               }
         #network {
                 color: #ABE9B3;
               }
         #network.disconnected {
                 color: rgb(255, 255, 255);
               }
         #battery.charging, #battery.full, #battery.discharging {
                 color: rgb(250, 227, 176);
               }
         #battery.critical:not(.charging) {
                 color: rgb(242, 143, 173);
               }
         #custom-powermenu {
                 color: rgb(242, 143, 173);
               }
         #tray {
                 padding-right: 8px;
                 padding-left: 10px;
               }
         #mpd.paused {
                 color: #414868;
                 font-style: italic;
               }
         #mpd.stopped {
                 background: transparent;
               }
         #mpd {
                 color: #c0caf5;
               }
         #custom-cava-internal{
                 font-family: "Hack Nerd Font" ;
               }
    '';

    settings = [{
        "layer" = "top";
        "position" = "top";
        "height" = 20;
        modules-left = [
          #"custom/launcher"
          "wlr/workspaces"
          "temperature"
          #"idle_inhibitor"
          #"custom/wall"
          #"mpd"
          #"custom/cava-internal"
        ];
        modules-center = [
          "clock"
        ];
        modules-right = [
          "pulseaudio"
          "backlight"
          "memory"
          "cpu"
          #"network"
          "battery"
          "custom/powermenu"
          "tray"
        ];
        "custom/launcher" = {
          "format" = " ";
          "on-click" = "pkill rofi || ~/.config/rofi/launcher.sh";
          "tooltip" = false;
        };
        "custom/wall" = {
          "on-click" = "wallpaper_random";
          "on-click-middle" = "default_wall";
          "on-click-right" = "killall dynamic_wallpaper || dynamic_wallpaper &";
          "format" = " ﴔ ";
          "tooltip" = false;
        };
        "custom/cava-internal" = {
          "exec" = "sleep 1s && cava-internal";
          "tooltip" = false;
        };
        "wlr/workspaces" = {
          "format" = "{icon}";
          "on-click" = "activate";
          # "on-scroll-up" = "hyprctl dispatch workspace e+1";
          # "on-scroll-down" = "hyprctl dispatch workspace e-1";
        };
        "idle_inhibitor" = {
          "format" = "{icon}";
          "format-icons" = {
            "activated" = "";
            "deactivated" = "";
          };
          "tooltip" = false;
        };
        "backlight" = {
          "device" = "intel_backlight";
          "scroll-step" = 2;
          "on-scroll-up" = "light -A 5";
          "on-scroll-down" = "light -U 5";
          "format" = "{icon} {percent}%";
          "format-icons" = [ "" "" "" "" ];
        };
        "pulseaudio" = {
          "scroll-step" = 1;
          "format" = "{icon} {volume}%";
          "format-muted" = "婢 Muted";
          "format-icons" = {
            "default" = [ "" "" "" ];
          };
          "states" = {
            "warning" = 85;
          };
          "on-click" = "pamixer -t";
          "tooltip" = false;
        };
        "battery" = {
          "interval" = 10;
          "states" = {
            "warning" = 20;
            "critical" = 10;
          };
          "format" = "{icon} {capacity}%";
          "format-icons" = [ "" "" "" "" "" "" "" "" "" ];
          "format-full" = "{icon} {capacity}%";
           # "format-charging" = " {capacity}%";
          "format-charging" = " {capacity}%";
          "tooltip" = false;
        };
        "clock" = {
          "interval" = 1;
          "format" = "{:%I:%M %p  %A, %d %b }";
          "tooltip" = true;
          /* "tooltip-format"= "{=%A; %d %B %Y}\n<tt>{calendar}</tt>" */
          "tooltip-format" = "上午:高数\n下午:Ps\n晚上:Golang\n<tt>{calendar}</tt>";
        };
        "memory" = {
          "interval" = 1;
          # "format" = "﬙ {percentage}%";
          "format" = " {percentage}%";
          "states" = {
            "warning" = 85;
          };
        };
        "cpu" = {
          "interval" = 1;
          "format" = " {usage}%";
        };
        "mpd" = {
          "max-length" = 25;
          "format" = "<span foreground='#bb9af7'></span> {title}";
          "format-paused" = " {title}";
          "format-stopped" = "<span foreground='#bb9af7'></span>";
          "format-disconnected" = "";
          "on-click" = "mpc --quiet toggle";
          "on-click-right" = "mpc update; mpc ls | mpc add";
          "on-click-middle" = "kitty --class='ncmpcpp' ncmpcpp ";
          "on-scroll-up" = "mpc --quiet prev";
          "on-scroll-down" = "mpc --quiet next";
          "smooth-scrolling-threshold" = 5;
          "tooltip-format" = "{title} - {artist} ({elapsedTime:%M:%S}/{totalTime:%H:%M:%S})";
        };
        "network" = {
          "interval" = 1;
          "format-wifi" = "說 {essid}";
          "format-ethernet" = "  {ifname} ({ipaddr})";
          "format-linked" = "說 {essid} (No IP)";
          "format-disconnected" = "說 Disconnected";
          "tooltip" = false;
        };
        "temperature" = {
          # "hwmon-path"= "${env:HWMON_PATH}";
          #"critical-threshold"= 80;
          "tooltip" = false;
          "format" = " {temperatureC}°C";
        };
        "custom/powermenu" = {
          "format" = "";
          "on-click" = "pkill rofi || ~/.scripts/powermenu.sh";
          "tooltip" = false;
        };
        "tray" = {
          "icon-size" = 15;
          "spacing" = 5;
        };
      }];
  };
}

Kemudian, karena pengaturan saya saat ini ternyata waybar tidak bisa mengaktifkan Workspace, jadi saya harus mencari cara supaya fitur ini aktif. Untungnya bisa diaktifkan melalui Patch.

Silahkan buat sebuah file bernama workspace-patch.nix yang disimpan di dalam folder ~/.config/home-manager/ kemudian isi dengan kode overlay berikut :


{ pkgs ? null, hyprctl ? null, ... }:
pkgs.writeTextFile {
  name = "waybar-hyprctl.diff";
  text = ''
    diff --git a/src/modules/wlr/workspace_manager.cpp b/src/modules/wlr/workspace_manager.cpp
    index da83cb7..4c33ac3 100644
    --- a/src/modules/wlr/workspace_manager.cpp
    +++ b/src/modules/wlr/workspace_manager.cpp
    @@ -450,7 +450,8 @@ auto Workspace::handle_clicked(GdkEventButton *bt) -> bool {
       if (action.empty())
         return true;
       else if (action == "activate") {
    -    zext_workspace_handle_v1_activate(workspace_handle_);
    +    const std::string command = "${hyprctl} dispatch workspace " + name_;
    +       system(command.c_str());
       } else if (action == "close") {
         zext_workspace_handle_v1_remove(workspace_handle_);
       } else {
  '';
}

Setelah itu rebuild lagi home-manager, dan semoga sekarang sudah bisa mengaktifkan waybar dengan sempurna.

Fitur waybar yang diinginkan

  • Workspace indicator
  • Temperature
  • Tanggal dan jam
  • Volume
  • Brightness
  • Indicator Ram
  • Indicator CPU
  • Indicator Baterai
  • Clickable custom power menu
  • Tray Icon

Membuat Hyprland autostart

Untuk menggunakan hyprland sebagai default desktop dan autostart saat berada di tty, kita gunakan GDM wayland.

Silahkan copy baris ini pada file configuration.nix


services.greetd = {
  enable = true;
  settings = rec {
    initial_session = {
      command = "Hyprland";
      user = "usernamekamu";
    };
    default_session = initial_session;
  };
};

Lalu rebuild nixos-rebuild switch

Sekarang semoga anda sudah bisa menjalankan Hyprland melalui Nixos anda.

Semoga bermanfaat.

Ditulis oleh Rafi pada Sunday, 19 March 2023

Baca juga

comments powered by Disqus