23 KiB
Hyprland
Hyprland
Hyprland is a dynamic wayland compositor which provides autotiling and beautiful animations out of the box.
Environment variables
This part will be very short, but I first need to set some environment variables.
env = XCURSOR_SIZE,24
env = SDL_VIDEODRIVER,wayland
Hardware configuration
The first configuration I want to set is my keyboard and touchpad configuration. My keyboard uses the AFNOR standard for the bépo layout, and I do not use the caps lock key which is replaced by the control key.
input {
kb_layout = fr
kb_variant = bepo_afnor
kb_model =
kb_options = caps:ctrl_modifier
kb_rules =
follow_mouse = 1
touchpad {
natural_scroll = false
}
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
}
We can then set the monitors used. If HDMI-A-1
is not found when
Hyprland launches, it will simply ignore it. And at worst, I can use
wdisplays to manually set the position of my screens.
Monitor name | Resolution | Refresh rate (Hz) | Position |
---|---|---|---|
HDMI-A-1 | 2560x1080 | 0x0 | |
eDP-1 | 1920x1080 | 120 | 2560x0 |
This translates into the following configuration:
monitor = HDMI-A-1, 2560x1080, 0x0, 1
monitor = eDP-1, 1920x1080@120, 2560x0, 1
Visual configuration
Now, onto the visual configuration. I like my gaps, and I feel keeping my windows relatively tight together but with a greater gap around them looks nice. I also like the Nord palette which I use here for my window border colours. Active windows get a gradient from nord9 to nord14, while inactive windows get a nord3 border. Lastly, I use the dwindle layout as I find it nicer to use than the master layout.
general {
gaps_in = 5
gaps_out = 20
border_size = 2
col.active_border = rgb(81a1c1) rgb(a3be8c) 45deg
col.inactive_border = rgb(4c566a)
layout = dwindle
}
I may one day use the layout_center
layout from pyprland, but I
haven’t got around to do that yet.
Decorations are just a nice thing to make things look pretty. I like some slight rounding on my windows with a nice though light shadow. Again, the colour comes from the Nord palette with nord0.
decoration {
rounding = 5
blur {
enabled = true
size = 9
passes = 1
}
drop_shadow = true
shadow_range = 4
shadow_render_power = 3
col.shadow = rgba(2e3440aa)
}
Animations are fun! I mostly kept the default animations from the example config of Hyprland.
animations {
enabled = true
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
animation = windows, 1, 7, myBezier
animation = windowsOut, 1, 7, default, popin 80%
animation = border, 1, 10, default
animation = borderangle, 1, 8, default
animation = fade, 1, 7, default
animation = workspaces, 1, 6, default
}
Now, we can take care of the configuration of the layouts. The only notable thing here is that I prefer to have no gaps when there is only one window in the dwindle layout.
dwindle {
pseudotile = true
preserve_split = true
no_gaps_when_only = 1
}
Autolaunch of programs
The exec-once
directive of Hyprland allows the user to launch the
associated command only when Hyprland starts in order to avoid
launching multiple instances of some programs.
First, I’ll import some environment variables into Hyprland. These may be necessary for some programs.
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=Hyprland
Next, I’ll launch some programs that will give Hyprland a nice appearance: waybar and wpaperd.
exec-once = wpaperd
exec-once = waybar
Let’s also take care of some sound stuff. If any new input or output is detected, switch to it. And stop the music, just in case.
exec-once = pactl load-module module-switch-on-connect
exec-once = mpc stop
Having a working policy kit is generally a good idea.
exec-once = xfce-polkit
Now, let’s launch the notification daemon swaync.
exec-once = swaync
Let’s also launch wlsunset. I’ll very vagely aim at Paris with the longitude and latitude.
exec-once = wlsunset -l 48.5 -L 2.2 -d 1500
Let’s launch some apps and their applet. Here, we’re launching the applets for NetworkManager, KDE Connect, and blueman (the bluetooth manager).
exec-once = nm-applet
exec-once = /usr/lib/kdeconnectd
exec-once = kdeconnect-indicator
exec-once = blueman-applet
Finally, let’s launch swayidle which lets us lock our session. It’ll automatically pause any media playing.
exec-once = swayidle -w timeout 600 'plock' before-sleep 'playerctl pause; plock' lock 'plock'
Keybindings
First, let me make a couple of variables for reusability. Mind you,
hjkl
becomes ctsr
in the bépo keyboard layout.
$left = c
$right = r
$up = s
$down = t
$menu = rofi -combi-modi drun -show combi
Now, I’d like to introduce a concept which I really enjoy: submaps.
They allow the Hyprland user to make keychords similar to Emacs, which
allows us to unlock the full potential of keybindings in a window
manager. In Hyprland, something to be wary of is that there is no
automatic submap switching. If there is no explicit indication to exit
the current submap or to switch to another submap, Hyprland will just
stay on the current submap. So, using something like bind = CTRL, g,
submap, reset
is necessary to exit the current submap on C-g
(or
Control + g
, I like the Emacs notation).
In the submap tables below, the submap column may indicate reset
, a
submap’s name, or nothing. If nothing is indicated, the key will not
act on the current submap or switch to another one. A submap’s name
will make the key switch to said submap, while the value reset
will
make us go back to the root submap. Note that all submaps will also
have the escape and C-g
keys mapped to exiting the current submap.
Note also that I sometimes use bind flags. I’ll only set the flag in the appropriate column when necessary.
These are the keybindings that are present on the top-level keybinding map.
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
SUPER | Return | exec | kitty | |
SUPER | Space | leader | ||
screenshot |
<<gen-submap(table=top-submap, submap="", reset-submap="no")>>
<<gen-submap(table=leader-submap, submap="leader", reset-submap="yes")>>
<<gen-submap(table=apps-submap, submap="apps", reset-submap="yes")>>
<<gen-submap(table=buffers-submap, submap="buffers", reset-submap="yes")>>
<<gen-submap(table=resize-submap, submap="resize", reset-submap="yes")>>
<<gen-submap(table=rofi-submap, submap="rofi", reset-submap="yes")>>
<<gen-submap(table=screenshot-submap, submap="screenshot", reset-submap="yes")>>
<<gen-submap(table=windows-submap, submap="windows", reset-submap="yes")>>
submap = reset
<<gen-submap(table=top-media, submap="", reset-submap="no")>>
<<gen-submap(table=top-windows-movements, submap="", reset-submap="no")>>
<<gen-mouse(table=top-windows-actions)>>
<<gen-submap(table=top-workspace-movements, submap="", reset-submap="no")>>
Top keybindings
Media keys
Modifiers | Key | Action | Argument | Submap | Bind flag |
---|---|---|---|---|---|
XF86AudioPlay | exec | playerctl play-pause | l |
||
XF86AudioPause | exec | playerctl pause | l |
||
XF86AudioStop | exec | playerctl stop | l |
||
XF86AudioPrev | exec | playerctl previous | l |
||
XF86AudioNext | exec | playerctl next | l |
||
XF86AudioForward | exec | playerctl position +1 | l |
||
XF86AudioRewind | exec | playerctl position -1 | l |
||
XF86AudioRaiseVolume | exec | pamixer -i 2 | l |
||
XF86AudioLowerVolume | exec | pamixer -d 2 | l |
||
XF86MonBrightnessUp | exec | xbacklight -perceived -inc 2 | l |
||
XF86MonBrightnessDown | exec | xbacklight -perceived -dec 2 | l |
||
XF86KbdBrightnessUp | exec | xbacklight -perceived -inc 2 | l |
||
XF86KbdBrightnessDown | exec | xbacklight -perceived -dec 2 | l |
Quick window movements and actions
These are basically a rehash of what you can find in the windows submap but with a few missing keybindings and other extras.
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
SUPER | $left |
movefocus | l | |
SUPER | $right |
movefocus | r | |
SUPER | $up |
movefocus | u | |
SUPER | $down |
movefocus | d | |
SUPER_SHIFT | $left |
movewindow | l | reset |
SUPER_SHIFT | $right |
movewindow | r | reset |
SUPER_SHIFT | $up |
movewindow | u | reset |
SUPER_SHIFT | $down |
movewindow | d | reset |
SUPER_CTRL_SHIFT | $left |
moveworkspacetomonitor | e+0 +1 | reset |
SUPER_CTRL_SHIFT | $right |
moveworkspacetomonitor | e+0 -1 | reset |
SUPER | Tab | cyclenext | ||
SUPER_SHIFT | Tab | cyclenext | prev |
Something I really appreciate with window managers in Linux is the able to really easily move and resize windows. The keybinds below allow the user to press down the super key and perform an action on the window:
- with a left click, move the window around
- with a right click, resize the window
Modifiers | Key | Action |
---|---|---|
SUPER | mouse:272 | movewindow |
SUPER | mouse:273 | resizewindow |
Workspace movements
Due to the bépo layout, the number row does not give immediate access to numbers, but to punctuation symbols. You can find below a table of equivalence of the characters’ name and the actual character, as well as the number that sits on the same key when pressing shift.
/ | <l> | |
---|---|---|
Character name | Character | Number |
quotedbl | " |
1 |
guillemotleft | « |
2 |
guillemotright | » |
3 |
parenleft | ( |
4 |
parenright | ) |
5 |
at | @ |
6 |
plus | + |
7 |
minus | - |
8 |
slash | / |
9 |
asterisk | * |
0 |
Modifiers | Key | Action | Argument |
---|---|---|---|
SUPER | quotedbl | workspace | 1 |
SUPER | guillemotleft | workspace | 2 |
SUPER | guillemotright | workspace | 3 |
SUPER | parenleft | workspace | 4 |
SUPER | parenright | workspace | 5 |
SUPER | at | workspace | 6 |
SUPER | plus | workspace | 7 |
SUPER | minus | workspace | 8 |
SUPER | slash | workspace | 9 |
SUPER | asterisk | workspace | 10 |
SUPER | mouse_down | workspace | e+1 |
SUPER | mouse_up | workspace | e-1 |
SUPER_SHIFT | quotedbl | movetoworkspace | 1 |
SUPER_SHIFT | guillemotleft | movetoworkspace | 2 |
SUPER_SHIFT | guillemotright | movetoworkspace | 3 |
SUPER_SHIFT | parenleft | movetoworkspace | 4 |
SUPER_SHIFT | parenright | movetoworkspace | 5 |
SUPER_SHIFT | at | movetoworkspace | 6 |
SUPER_SHIFT | plus | movetoworkspace | 7 |
SUPER_SHIFT | minus | movetoworkspace | 8 |
SUPER_SHIFT | slash | movetoworkspace | 9 |
SUPER_SHIFT | asterisk | movetoworkspace | 10 |
Leader
The leader submap is accessible by pressing s-SPC
(Super and space).
It is sort of the general menu for my keybindings.
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
l | exec | plock |
reset | |
a | apps | |||
b | buffers | |||
w | windows |
Apps
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
b | exec | firefox |
reset | |
SHIFT | b | exec | qutebrowser |
reset |
d | exec | vesktop |
reset | |
e | exec | emacsclient -c -n |
reset | |
g | exec | gimp |
reset | |
n | exec | nemo |
reset | |
r | rofi | |||
u | exec | $menu |
reset |
Buffers
I call this the buffer window, but it’s mostly due to my habit of handling Emacs buffers. Some of my muscle memory may never fade away. Consider this as an addition to the windows submap.
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
d | killactive | reset |
Resize
This is an example of a submap where I may not want to immediately
exit it. We enter it with the keychord s-SPC w .
and exit it with
either the usual C-g
, escape key, but also with the q
key.
Modifiers | Key | Action | Argument | Submap | Bind flag |
---|---|---|---|---|---|
$left |
resizeactive | -10 0 | e |
||
$right |
resizeactive | 10 0 | e |
||
$up |
resizeactive | 0 -10 | e |
||
$down |
resizeactive | 0 10 | e |
||
q | reset |
Rofi
This submap hosts quite a few menus handled with rofi (I use this wayland fork). You may want to take a look at custom scripts to know what most of these do.
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
a | exec | awiki |
reset | |
b | exec | bluetooth-connect |
reset | |
e | exec | rofi-emoji |
reset | |
r | exec | $menu |
reset | |
s | exec | rofi -show ssh |
reset | |
y | exec | ytplay |
reset | |
SHIFT | y | exec | rofi-ytdl |
reset |
Screenshots
Here are the keybinding for the screenshot submap
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
exec | screenshot |
reset | ||
d | exec | screenshot -d 3 |
reset | |
Shift | d | exec | screenshot -sced 3 |
reset |
e | exec | screenshot -sec |
reset | |
s | exec | screenshot -s |
reset | |
Shift | s | exec | screenshot -sc |
reset |
Windows
Modifiers | Key | Action | Argument | Submap |
---|---|---|---|---|
period | resize | |||
$left |
movefocus | l | reset | |
$right |
movefocus | r | reset | |
$up |
movefocus | u | reset | |
$down |
movefocus | d | reset | |
SHIFT | $left |
movewindow | l | reset |
SHIFT | $right |
movewindow | r | reset |
SHIFT | $up |
movewindow | u | reset |
SHIFT | $down |
movewindow | d | reset |
CTRL_SHIFT | $left |
moveworkspacetomonitor | e+0 +1 | reset |
CTRL_SHIFT | $right |
moveworkspacetomonitor | e+0 -1 | reset |
d | killactive | reset | ||
f | fullscreen | reset | ||
SHIFT | f | togglefloating | reset |
Window rules
For now, I don’t have a lot of window rules. One, actually. It makes the XFCE polkit a floating window.
windowrulev2 = float,class:^(xfce-polkit)$