Hyprland crash course
EDIT I made my config files available here: gchamon/.config.
For the past week I have been configuring hyprland and using it as my daily driver. Coming from major Desktop Environments like KDE or Gnome, this was definitely quite challanging, specially when implementing features that we take it for granted on these DEs, like screen sharing or screenshot annotating.
In this post I will be going through all the tools and scripts I have been creating to configure this amazing Window Manager to my liking.
Introduction
First things first, the system I daily drive is Archlinux, and it comes with its own set of pros and cons. However specially for hyprland, everything is available from the package manager. Apparently nix configurations are also very well supported. Other system architectures might not have such a thorough support from the distro.
All of this to say, I am going to assume you are using arch.
Hyprland itself has a nice Master tutorial which I recommend you to follow. I believe this gets you 90% of the way there. This post aims to polish the rough edges after installing it successfully.
Your mileage may vary, but it took me maybe two days to get a functional installation and maybe four more days of polishing until I felt I could just ditch GNOME.
Things I'll cover here
So what I really aim to do after you have a working hyprland setup is the following:
- My scripts;
- How to screenshot;
- Some tips and tricks I came across;
The master tutorial
So basically after installing hyprland with:
sudo pacman -S hyprland kitty
You get to a nice window manager environment. For a quick introduction about the difference between Desktop environments and Window managers, try this blog post by the nice folks from linuxfordevices.com.
Launching hyprland from GDM worked flawlessly for me, so you can try that. Now you can boot into it and start configuring it.
After the master tutorial you should take a look at:
You would probably also need nm-applet and blueman-applet.
My scripts
These scripts aim to extend functionality and work around problems of hyprland and its applications.
Rofi
Rofi is nice in that it presents you with a couple of options. You can install it from the AUR.
You can configure hyprland to use it by setting $menu = rofi -show drun
and running it with SUPER+R
.
What was missing for me is the ability to launch programs in a shell, in or outside a terminal emulator, using rofi.
This can be easily achieved with a command like kitty bash -c $(rofi -dmenu -p terminal)
. However Rofi won't remember the commands.
I found frece from this issue and used the example scripts as a reference
to add history to rofi commands:
#!/bin/bash
set -euo pipefail
# this adds frequency sorted history to rofi -dmenu
if [[ -z "$1" ]]; then
echo Usage ./launch-rofi-frece.sh {ROFI_TYPE}
echo Rofi type can be anything describing the rofi usage, for instance shell or terminal
fi
ROFI_TYPE="$1"
DB_FILE="$HOME/.cache/rofi.$ROFI_TYPE.db"
if ! [[ -f "$DB_FILE" ]]; then
frece init "$DB_FILE" /dev/null
fi
item=$(frece print "$DB_FILE" | rofi "$@" -dmenu -p $ROFI_TYPE)
[[ -z $item ]] && exit 1
if ! frece increment "$DB_FILE" "$item" >/dev/null 2>&1; then
frece add "$DB_FILE" "$item"
fi
echo "$item"
This will initialize an empty frece database with the context type I am using rofi (either shell or terminal). Then I can use this script from hyprland:
$shellMenu = bash -c "$(~/.config/hypr/scripts/launch-rofi-frece.sh shell)"
$terminalMenu = kitty bash -c "$(~/.config/hypr/scripts/launch-rofi-frece.sh terminal)"
bind = $mainMod SHIFT, R, exec, $shellMenu
bind = $mainMod CTRL SHIFT, R, exec, $terminalMenu
This way you can have a separate history with frequency tracking for rofi:
Waybar
You can just start using waybar, but if you want to customize it, it won't reload by itself. I use this script to reload waybar whenever I want to change the theme:
#!/bin/bash
CONFIG_FILES="$HOME/.config/waybar/config $HOME/.config/waybar/style.css"
trap "killall waybar" EXIT
while true; do
waybar &
inotifywait -e create,modify $CONFIG_FILES
killall waybar
done
Which you can launch by changing how you launch waybar with hyprland to exec-once = ~/.config/hypr/scripts/launch-waybar.sh
.
Dunst notification sounds
You can configure dunst to play notification sounds by following this comment on github. However powersaving policies, most likely from the bluetooth protocol, prevents my headphones to play music straight away. It would only play the end of the audio from A link to the past. To work around this I use this 500ms silent mp3 file to warm up my device. Needless to say it introduces a half-second latency to every notification sound, but it does the job. The script will then look like this:
#!/bin/bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
source "$HOME/.zshenv"
if [[ "$DUNST_QUIET" != "true" ]]; then
# warm up audio device in case of powersave policies (like bluetooth)
pw-play $SCRIPT_DIR/../assets/500-milliseconds-of-silence.mp3
pw-play $SCRIPT_DIR/../assets/link.mp3
fi
As you can see I also implemented a quiet mode by setting DUNST_QUIET=true
in .zshenv
. Yes, bash and zsh shouldn't mix but let this slide, please :D
Wayland lock screen
I use sawlock-effects for locking my screen. The script looks like this (just so that it doesn't clutter the hyprland config file):
#!/usr/bin/env bash
swaylock \
--image /usr/share/backgrounds/archlinux/split.png \
--clock \
--indicator \
--indicator-radius 100 \
--indicator-thickness 7 \
--effect-blur 7x5 \
--effect-vignette 0.5:0.5 \
--ring-color bb00cc \
--key-hl-color 880033 \
--line-color 00000000 \
--inside-color 00000088 \
--separator-color 00000000 \
--fade-in 1
And I invoke it with bind = $mainMod, L, exec, ~/.config/hypr/scripts/wayland-lock.sh
.
Screenshot with editor
I use grimblast from aur
together with ksnip, which is available from the extra
packages.
There is a captureArea.sh
script:
#!/bin/bash
export GRIMBLAST_EDITOR=ksnip
grimblast --cursor edit area
And a captureAll.sh
script:
#!/bin/bash
set -euo pipefail
SCREENSHOT_FILENAME=$(date +'%Y-%m-%dT%H:%M:%S%z_grim.png')
SCREENSHOT_FILENAME_ABSOLUTE=$HOME/Pictures/Screenshots/$SCREENSHOT_FILENAME
notify-send --app-name=grim --urgency=normal --category=screenshot "Capturing entire screen to $SCREENSHOT_FILENAME_ABSOLUTE"
grim $SCREENSHOT_FILENAME_ABSOLUTE
Which I launch with
bind = SHIFT, 107, exec, ~/.config/hypr/scripts/screenshot/captureAll.sh
bind = , 107, exec, ~/.config/hypr/scripts/screenshot/captureArea.sh
The number 107
being the PrintScreen key. It can also be referenced by Print
, but for some reason I left it with the code.
BTW you can use wev
and get codes from keys you press and just use them in hyprland config.
Kill hyprland if stuck on exit
Hyprland, at least for me, will randomly freeze on a blackscreen upon exit. This issue covers the problem and also offers a workaround by using this script:
echo "Hyprland exit" | systemd-cat -t coffebar -p info
hyprctl dispatch exit &
sleep 10
echo "Hyprland failed to exit" | systemd-cat -t coffebar -p err
killall -9 Hyprland
You can then just call it with SUPER+M
instead of dispatching exit directly. It won't solve the problem, but at least you don't need to reboot everytime it happens.
Quick tips
These are some quick references to tips and tricks I came across during this last few days.
Multiple keyboard layouts
Since I have two keyboards with two different layouts (a us mx-keys and a br-abnt2 built-in keyboard on my notebook) it wasn't clear for me how I should configure hyprland. At first I was looking for a way to display the current keyboard and maybe toggle it with waybar, but I quickly realised that hyprland toggle will work only for the keyboard which pressed the toggle key.
However you can set different layouts for different devices in hyprland.conf
. My configuration looks like this:
input {
kb_layout = br
kb_variant = abnt2
# ...
}
device {
name = logitech-mx-keys
kb_layout = us
kb_variant = intl
}
This is nice because I get consistent layout configuration with whatever keyboard I use. You can find which input devices you have with hyprctl devices
.
Waybar on-click actions
After applying cjbassi's theme I wanted more functionality for my bar. BTW you can find more themes here.
First, you should install pamixer
so that clicking on the volume to mute works.
Oh, and install otf-font-awesome
, otherwise the nice icons won't render.
Then I mapped:
- pulseaudio
- Right click:
pavucontrol
- Right click:
- memory
- Left click:
gnome-system-monitor --show-processes-tab
- Left click:
- cpu
- Right click:
kitty top
- Left click:
gnome-system-motnitor --show-resources-tab
- Right click:
- battery
- Left click:
tlpui
- Left click:
- disk
- Left click:
kitty ncdu ~
- Right click:
gnome-system-monitor --show-file-systems-tab
- Left click:
I thought about leaving right-click on disk to open ncdu
on root, but it takes an ungodly amount of time to go through the files in my NAS, but you could do that
if this isn't a problem for you.
gnome-keyring
Just a headsup: if you enter a wrong password for your ssh keys, it won't complain, there won't be a warning, ssh-add
will just gobble 100% cpu and ssh
or git clone
will just hang there. You will have to kill it with pkill ssh-add
. To fix this, open seahorse
, go to Login
and remove the offending ssh key password there.
Just don't remove it from OpenSSH Keys
tab as it will delete the keys themselves.
Also, either use this or keychain, never both.