Installing and configuring Hyprland on a Surface Pro 7 (1866)
Preface
This guide explains how I install and customize Hyprland on a Surface Pro 7 (1866). The steps themselves are not specific to Surface devices.
The title matches my Arch on Surface write up, and the system used here happens to be a Surface device.
For that reason, this guide assumes you are using Arch Linux.
All commands in this post target Arch Linux, for example pacman and yay.
Your distribution may already include some packages by default, such as PipeWire.
If you are using another distribution, you will need to adapt the commands or packages accordingly.
1. Install base components
Ly is a lightweight TUI display manager that can start your Wayland session without logging in on the console first.
brightnessctl is used to control screen brightness on laptops and notebooks.
sudo pacman -S ly hyprland brightnessctl
sudo systemctl enable ly
Hyprland also needs a few companion packages:
- Fonts for proper text rendering.
- PipeWire, pipewire-pulse, Pavucontrol, and WirePlumber for audio.
- dunst for notifications.
- xdg-desktop-portal-hyprland for system dialogs under Wayland.
- Qt Wayland backends for running Qt applications under Wayland.
- hyprpolkitagent for GUI privilege prompts.
- uwsm (User Wayland Session Manager) for proper session startup and shutdown.
- kitty (terminal), Firefox (browser), rofi (app launcher), and swww (wallpapers).
- rofi-bluetooth-git for a graphical Bluetooth interface.
sudo pacman -S dunst pipewire pipewire-pulse pavucontrol wireplumber \
xdg-desktop-portal-hyprland hyprpolkitagent qt5-wayland qt6-wayland \
noto-fonts noto-fonts-cjk noto-fonts-emoji ttf-jetbrains-mono-nerd \
uwsm kitty firefox rofi swww
jack2 or pipewire-jack, choose the latter.
Reboot the system:
sudo reboot now
At the Ly prompt, switch from “login” to “wayland”, then use the arrow keys to select “Hyprland (uwsm-managed)”.
2. Edit the autogenerated config
On first start you will see a warning about the autogenerated configuration. Fix this before you do anything else.
Open a terminal with “SUPER+Q” (kitty).
us!
Edit the config file:
nano /home/yourusername/.config/hypr/hyprland.conf
Delete everything up to this line:
# You can split this configuration into multiple files
Search for input and set your keyboard layout:
input {
kb_layout = de # or your layout
}
Save the file so you can use your keyboard layout. Hyprland applies configuration changes automatically.
firefox & disown to easily copy and paste commands from this guide.You can continue with the guide afterwards.
Open hyprland.conf again and set rofi as the app launcher:
$menu = pkill rofi || ~/.config/rofi/launchers/type-1/launcher.sh
No pressure to set it up right now, though, I’ve linked my my blog post further down so you can handle the installation later.
2.1 Display scaling
For the Surface display I use a scaling factor of 1.5 for readability, or 1.26667 if you want more screen space.
# was: monitor=,preferred,auto,auto
monitor=,preferred,auto,1.5
Keep the file open, you still need it for keybindings.
2.2 Keybinds
A minimal set of keybindings:
- SUPER+Q: close focused window
- SUPER+T: terminal
- SUPER+B: browser
- SUPER+E: file manager
- SUPER+SPACE: app launcher
- SUPER+V: toggle floating
- SUPER+J: toggles the tiling split mode
Search for “KEYBINDINGS” (CTRL+F) and edit:
bind = $mainMod, Q, killactive
bind = $mainMod, T, exec, $terminal
bind = $mainMod, B, exec, firefox
bind = $mainMod, E, exec, $fileManager
bind = $mainMod, V, togglefloating
bind = $mainMod, SPACE, exec, $menu
bind = $mainMod, J, togglesplit
SUPER+J toggles the tiling split mode.
Open two terminals and press SUPER+J to observe the layout change.
3. Get some wallpapers!
Download wallpapers from a site like Wallhaven.
Store them in:
~/Pictures/wallpapers/
You can use a different folder, but adjust the paths in later steps accordingly. You do not need wallpapers immediately, but having them prepared is convenient.
4. Waybar
Install Waybar:
sudo pacman -S waybar
In ~/.config/hypr/hyprland.conf, under AUTOSTART, enable Waybar and swww:
# exec-once = waybar & hyprpaper & firefox
exec-once = waybar
exec-once = swww-daemon
Start Waybar in the current session:
waybar & disown
4.1 Waybar config (minimal)
Create a minimal configuration:
mkdir -p ~/.config/waybar
nano ~/.config/waybar/config.jsonc
Paste:
{
"layer": "top",
"modules-left": ["clock", "hyprland/window"],
"modules-right": ["network", "bluetooth", "pulseaudio", "battery"],
"modules-center": ["hyprland/workspaces"],
"battery": {
"format": "{capacity}% {icon}",
"format-icons": ["","","","",""]
},
"clock": {
"format-alt": "{:%a, %d. %b %H:%M}"
}
}
4.2 Reload helper
Create a small helper script to restart Waybar:
mkdir -p ~/.config/waybar/scripts
nano ~/.config/waybar/scripts/launch.sh
Paste:
#!/bin/bash
killall -9 waybar 2>/dev/null
waybar &
Make it executable:
chmod +x ~/.config/waybar/scripts/launch.sh
Bind it in Hyprland:
bind = $mainMod, R, exec, ~/.config/waybar/scripts/launch.sh
Reload Waybar with SUPER+R.
4.3 Minimal styling
nano ~/.config/waybar/style.css
Paste:
@import "colors.css";
* {
border: none;
border-radius: 0;
font-family: Roboto, "JetBrainsMono Nerd Font", Helvetica, Arial, sans-serif;
font-size: 1rem;
min-height: 1rem;
}
#waybar>box {
margin: 10px 10px 0 10px;
}
#window {
margin: 0px 10px;
}
window#waybar {
background: transparent;
color: @on_surface;
}
tooltip {
background: @background;
border: 1px solid rgba(100, 114, 125, 0.5);
}
tooltip label {
color: @on_surface;
}
#workspaces button {
padding: 0 5px;
background: transparent;
color: white;
border-bottom: 3px solid transparent;
}
#workspaces button.focused {
background: #64727D;
border-bottom: 3px solid white;
}
#clock,
#battery,
#bluetooth,
#pulseaudio,
#network {
border-radius: 100px;
background-color: @primary;
color: #121212;
padding: 0px 20px;
margin: 0 10px;
}
#workspaces {
margin-top: 10px;
}
#clock {
padding: 0 7px;
font-weight: 500;
}
#pulseaudio {
padding: 0 15px;
}
#battery {
padding: 0 15px;
}
4.4 Workspaces, window titles, volume, bluetooth, wifi
Editing JSONC files is easier in VSCodium. VSCodium is not available in the official Arch repositories, so you will need an AUR helper.
Install yay:
sudo pacman -S --needed git base-devel
git clone https://aur.archlinux.org/yay.git && cd yay && makepkg -si
yay -S vscodium-bin
Packages to cleanBuild?” choose “A”.
Open “VSCodium - Wayland” by typing vscodium --ozone-platform-hint=wayland, and open:
~/.config/waybar/config.jsonc
In config.jsonc, make sure the clock block ends with a comma:
clock {
...
},
Add the workspaces configuration:
"hyprland/workspaces": {
"format": "{name}",
"persistent-workspaces": {
"*": 5,
"HDMI-A-1": 3
}
},
Add the focused window module:
"hyprland/window": {
"format": "{}",
"max-length": 20,
"separate-outputs": true
},
This displays the focused window title next to the workspace list.
Add a PulseAudio widget:
"pulseaudio": {
"format": "{volume}% {icon}",
"format-bluetooth": "{volume}% {icon}",
"format-muted": "x",
"format-icons": {
"headphone": "",
"default": ["", ""]
},
"scroll-step": 1,
"on-click": "pavucontrol",
"ignored-sinks": ["Easy Effects Sink"]
},
VSCodium may not render the icons correctly by default.
Go to Settings, search for “Font Family”, and replace "Droid Sans Mono" with "JetBrainsMono Nerd Font".
Add a Bluetooth widget:
"bluetooth": {
"on-click": "rofi-bluetooth",
"format-on": "",
"format-off": "",
"format-disabled": "", // an empty format will hide the module
"format-connected": " {num_connections}",
"tooltip-format-connected": "{device_enumerate}",
"tooltip-format-enumerate-connected": "{device_alias}\t{device_address}"
},
Add a WiFi widget:
"network": {
"interface": "wlp2s0",
"format": "{ifname}",
"format-wifi": "{essid} ",
"format-ethernet": "{ipaddr}/{cidr} ",
"format-disconnected": "",
"tooltip-format": "{ifname} via {gwaddr} ",
"tooltip-format-wifi": "{essid} ({signalStrength}%) ",
"tooltip-format-ethernet": "{ifname} ",
"tooltip-format-disconnected": "Disconnected",
"max-length": 50
}
"interface": "wlp2s0" to the name of your WiFi interface, for example wlan0.
Format the file (Ctrl+Shift+I), save and close, then press SUPER+R to reload Waybar.
5. Material colors from wallpapers (matugen)
matugen generates Material-style color palettes and CSS from wallpapers. It is available in the AUR:
yay -S matugen-bin
cd ~/.config && mkdir -p matugen && cd matugen && mkdir -p templates && nano config.toml
matugen-bin manually, but installing it through yay simplifies maintenance.
Paste into config.toml:
[config.wallpaper]
set = true
command = "swww"
arguments = ["img", "--transition-type", "center", "--transition-step", "255"]
[templates.hyprland]
input_path = '~/.config/matugen/templates/hyprland-colors.conf'
output_path = '~/.config/hypr/colors.conf'
post_hook = 'hyprctl reload'
[templates.kitty]
input_path = '~/.config/matugen/templates/kitty-colors.conf'
output_path = '~/.config/kitty/colors.conf'
post_hook = 'kill -SIGUSR1 $(pgrep kitty)'
[templates.rofi]
input_path = '~/.config/matugen/templates/rofi-colors.rasi'
output_path = '~/.config/rofi/colors/colors.rasi'
[templates.waybar]
input_path = '~/.config/matugen/templates/colors.css'
output_path = '~/.config/waybar/colors.css'
post_hook = 'pkill waybar; waybar & disown'
Now add hyprland-colors.conf to ~/.config/matugen/templates:
nano ~/.config/matugen/templates/hyprland-colors.conf
Paste:
<* for name, value in colors *>
$image = {{image}}
${{name}} = rgba({{value.default.hex_stripped}}ff)
<* endfor *>
Add kitty-colors.conf in the same directory:
nano ~/.config/matugen/templates/kitty-colors.conf
Paste:
cursor {{colors.on_surface.default.hex}}
cursor_text_color {{colors.on_surface_variant.default.hex}}
foreground {{colors.on_surface.default.hex}}
background {{colors.surface.default.hex}}
selection_foreground {{colors.on_secondary.default.hex}}
selection_background {{colors.secondary_fixed_dim.default.hex}}
url_color {{colors.primary.default.hex}}
# black
color8 #262626
color0 #4c4c4c
# red
color1 #ac8a8c
color9 #c49ea0
# green
color2 #8aac8b
color10 #9ec49f
# yellow
color3 #aca98a
color11 #c4c19e
# blue
/* color4 #8f8aac */
color4 {{colors.primary.default.hex}}
color12 #a39ec4
# magenta
color5 #ac8aac
color13 #c49ec4
# cyan
color6 #8aacab
color14 #9ec3c4
# white
color15 #e7e7e7
color7 #f0f0f0
Add a file called rofi-colors.rasi in the same directory:
nano ~/.config/matugen/templates/rofi-colors.rasi
Paste:
* {
background: {{colors.surface.default.hex}};
background-alt: {{colors.surface_dim.default.hex}};
foreground: {{colors.on_surface.default.hex}};
selected: {{colors.primary.default.hex}};
active: {{colors.secondary.default.hex}};
urgent: {{colors.error.default.hex}};
}
Add a file called colors.css in the same directory:
nano ~/.config/matugen/templates/colors.css
Paste:
/*
* Css Colors
* Generated with Matugen
*/
<* for name, value in colors *>
@define-color {{name}} {{value.default.hex}};
<* endfor *>
6. Set your wallpaper
Open a new terminal and run:
swww-daemon & disown
matugen image Pictures/wallpapers/yourwallpaper.png
yourwallpaper.png with a file from your wallpapers directory.
Whatever wallpaper you choose, Waybar will update its colors accordingly. At this point the dynamic color system becomes useful.
A few pieces are still missing. You will add them next.
7. Hyprland colors
Open ~/.config/hypr/hyprland.conf:
nano ~/.config/hypr/hyprland.conf
At the top of the file, add:
source = ~/.config/hypr/colors.conf
Search for col.active_border, remove everything after = for both col.active_border and col.inactive_border and replace with:
# was col.active_border = rgba() rgba() 45deg
# was col.inactive_border = rgba()
col.active_border = $primary
col.inactive_border = $outline_variant
This makes Hyprland use the colors generated by matugen.
8. Kitty colors
Set nano as your default editor in this shell:
export EDITOR="/usr/bin/nano"
Close the terminal and open a new one so $EDITOR takes effect.
In kitty, press Ctrl+Shift+F2 to open the configuration file.
At the top of the file, add:
include colors.conf
Next:
- Search for
window_padding, uncomment it, and set it to10. - Search for
cursor_shape, uncomment it, and add this on a new line:
shell_integration no-cursor
- Search for
background_opacity, uncomment it, and set it to0.8.
Save and close the kitty config file, then close the terminal.
9. Configure rofi
Open a terminal and run:
git clone --depth=1 https://github.com/adi1090x/rofi.git
cd rofi/files/launchers/type-1/
mkdir -p ~/.config/rofi
cp -r launcher.sh shared style-9.rasi ~/.config/rofi
cd ~/.config/rofi
chmod +x launcher.sh
mkdir -p launchers/type-1
mv launcher.sh shared/ style-9.rasi launchers/type-1/
cd launchers/type-1/
nano launcher.sh
In launcher.sh, change the theme variable to:
theme="style-9"
Save and exit.
Then:
nano shared/colors.rasi
Change the @import line to:
@import "~/.config/rofi/colors/colors.rasi"
Save and exit.
The only remaining adjustment is spacing between icons and text in rofi. Run:
nano ~/.config/rofi/launchers/type-1/style-9.rasi
Add a single space after the icon for “Files”, “SSH”, “Apps”, “Run”, and “Windows”. Edit further so that all text lines are neatly aligned after each icon.
SUPER+SPACE.
10. Automating wallpaper changes
Create a helper script to set a random wallpaper from your directory.
Run:
mkdir -p ~/.local/bin/
cd ~/.local/bin/
nano wallset
Paste:
#!/bin/bash
wallpapers_dir=~/Pictures/wallpapers
cd "$wallpapers_dir" || exit 1
img=$(find . -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.jpeg" \) | shuf -n 1)
matugen image "$img" &> /dev/null
Save and exit, then:
chmod +x wallset
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
You can now call:
wallset
from anywhere to set a random wallpaper and apply matching colors.
11. Get bluetooth working
Install rofi-bluetooth-git using yay:
yay -S rofi-bluetooth-git
Clicking the Bluetooth icon in Waybar should now open a small interface for selecting Bluetooth devices.
Postface
You have completed the setup! Yay! :D
I hope you found this guide useful. I will update the post as I make improvements.
Cheers.
This post is part of a series. Read the previous part: Installing Arch Linux with Secure Boot on a Surface Pro 7.
Other posts in this series: