Hyprland Migration Proposal
Status: proposal, not implemented.
Audience: OpenRiot maintainers and users evaluating a Wayland desktop.
Scope: replace the X11 stack (Xenodm or startx, i3, polybar, rofi, dunst, picom, feh, maim, i3lock) with Hyprland on OpenBSD, while keeping the current X11 session available as a fallback.
1. Executive Summary
Hyprland itself now builds and runs on OpenBSD. Upstream merged OpenBSD support in three batches during October and November 2026 (Hyprland PRs #16457, #16495, #16839, plus aquamarine #432, hyprwayland-scanner #21 and hyprland-protocols #24). A working OpenBSD port exists on the ports mailing list but is not in the ports tree as of the tree snapshot from 2026-11-06.
The migration is therefore not a compositor problem. It is a packaging and integration problem:
- Package the Hyprland dependency stack.
- Port the desktop integration from X11 tools to Wayland tools.
- Add Wayland backends to the Go code that talks to X11 today.
- Keep the X11 session selectable until the Wayland session is proven.
The single largest code risk is window layout restore (source/window),
because i3 has append_layout and Hyprland has no equivalent. The largest
packaging risk is the Hyprland dependency chain, not Hyprland itself.
2. Current Architecture
The current desktop is a set of X11 clients coordinated by i3.
| Layer | Current component | Coupling point |
|---|---|---|
| Session | Xenodm or startx, .xsession |
config/xsession/openriot-xsession, config/xinitrc/openriot-x11 |
| Window manager | i3 | config/i3/config, config/i3/keybindings.conf |
| Status bar | polybar, three bars (left, center, right) | source/polybar, config/polybar/config.ini.tmpl |
| Launcher | rofi and rofi-calc | source/rofi, source/settings |
| Notifications | dunst | source/notify |
| Compositor | picom | config/picom.conf, i3 autostart |
| Wallpaper | feh | source/backgrounds |
| Display control | xrandr | source/display, source/screen, source/resolution |
| Screenshots | maim and xclip | source/screenshot |
| Recording | ffmpeg x11grab | source/screenrec |
| Lock and idle | i3lock and xautolock | source/lock, .xinitrc autostart |
| Clipboard history | clipmenu | i3 keybinding |
| Night light | xrandr gamma and xset | source/nightlight |
| Terminal | alacritty | config/alacritty |
Workspace, title, icon and window switching all read i3 IPC or X11 properties:
source/workspace/workspace.gousesi3-msg -t get_workspaces.source/workspaceicons/workspaceicons.gousesi3-msg -t get_tree.source/windowtitle/windowtitle.goandsource/windowicon/windowicon.gousei3-msg -t get_tree.source/window/switch.gobuilds a rofi menu from the i3 tree.source/window/snapshot.gosaves and restores i3 layouts.source/commands/helpers.goreads_NET_CLIENT_LISTwithxprop.
3. Target Architecture
Target session:
greetd or TTY
start-hyprland (or Hyprland directly)
Hyprland
waybar
wofi or fuzzel
fnott or mako
swaybg (or hyprpaper)
hypridle
hyprlock (or swaylock)
XWayland for legacy apps
OpenRiot becomes desktop-aware instead of i3-aware. The Go packages should select a backend from the session type:
XDG_SESSION_TYPE=waylandandHYPRLAND_INSTANCE_SIGNATUREset: Hyprland backend.- Otherwise: existing i3 and X11 backend.
This keeps the migration reversible and lets the installer ship both sessions.
4. Dependency and Packaging Plan
4.1 Confirmed available in the local ports tree
Checked on 2026-11-06:
wayland,wayland-protocols,wlrootssway,labwc,niri,wayfirewaybar,wofi,fuzzelgrim,slurp,swaybg,swayidle,swaylockwl-clipboard,wlr-randrfnott(notification daemon)seatd,libudev-openbsd,libinput-openbsdxdg-desktop-portal,xdg-desktop-portal-gtklibdisplay-info,hwdata,udis86,glslang,muparser,re2libcanberra,epoll-shim,libei,libinotify
4.2 Missing from the local ports tree
These must be ported or supplied by the PoC tarball:
hyprlandaquamarinehyprutilshyprgraphicshyprcursorhyprwayland-scannerhyprland-protocolsglaze- Lua 5.5 (local
lang/luacurrently stops at 5.4) - Optional:
hyprlock,hypridle,hyprpaper,hyprsunset,hyprpicker,hyprshot,wlsunset,mako,cliphist
Until hyprlock, hypridle, hyprpaper, hyprsunset and mako are
packaged, use swaylock, swayidle, swaybg, fnott and a small
wsconsctl wrapper. These are in ports today and run on Hyprland because
they speak standard Wayland protocols.
4.3 Build order
lua 5.5
hyprland-protocols
hyprwayland-scanner
hyprutils
hyprgraphics
glaze
hyprcursor
aquamarine
hyprland
Then the optional tools.
4.4 OpenBSD packaging notes
- aquamarine requires
libseatandlibudev. On OpenBSD these map toseatdandlibudev-openbsd. Confirm the PoC patches do not assume the Linux systemd seat interface. - Hyprland requires Lua 5.5 at configure time. A Lua 5.5 port is a hard prerequisite unless the port carries a patch.
glazeis fetched with FetchContent on Linux. On OpenBSD the upstream CMake deliberately skips that branch, so the port must provide glaze.- Use
NO_SYSTEMD=1andNO_UWSM=1. There is no systemd on OpenBSD. - XWayland support is required for Thunar, LibreOffice, some Electron apps and older GTK applications.
- Keep the port under
wayland/hyprlandand add apkg/DESCRthat states amd64 only initially. i915 and amdgpu are the tested drivers.
5. Migration Phases
Phase 0: Bootstrap and prove the compositor
Tasks:
- Add the Hyprland stack ports or a local overlay from the ports@ tarball.
- Build and launch Hyprland from a TTY with
seatdrunning. - Confirm DRM/KMS, input, XWayland and a terminal.
- Record
hyprctl version,hyprctl monitors -j,hyprctl clients -j.
Exit criteria: Hyprland starts, alacritty runs, XWayland apps start, and the session can be exited cleanly.
Phase 1: Port the base configuration
Tasks:
- Create
config/hypr/hyprland.conf, split into:monitors.conf,keybindings.conf,windowrules.conf,workspaces.confandinput.conf. - Use the ArchRiot layout as the starting point (see section 15).
- Set
$mod = SUPER, matching i3Mod4. - Replace ArchRiot application variables with OpenRiot ones.
- Port the OpenRiot dialog rules from
config/i3/configlines 104 to 125.
Exit criteria: the whole i3 keybinding set has a Hyprland equivalent and OpenRiot dialogs float and center.
Phase 2: Session and autostart
Tasks:
- Add
config/hypr/openriot-hyprland-sessionthat setsXDG_RUNTIME_DIR,XCURSOR_*,GTK_THEME,PATH, creates~/Screenshots, thenexec start-hyprland. - Add a Wayland desktop file under
config/hypr/for greetd or any display manager that readswayland-sessions. - Start
waybar, notification daemon,hypridle,swaybgand clipboard history fromexec-once. - Keep the
.xsessionand.xinitrcfiles untouched so the X11 session remains selectable.
Exit criteria: a fresh login can choose either session; the Wayland session starts all services without manual commands.
Phase 3: Status bar
Tasks:
- Replace polybar with waybar.
- Add
config/waybar/configandconfig/waybar/style.css. - Reuse the ArchRiot module split: base modules, custom modules, groups and workspaces.
- Add OpenRiot JSON producers (section 8).
- Remove polybar restart throttling. Use
pkill -SIGUSR2 waybaron config reload.
Exit criteria: every polybar module has a waybar equivalent and clicks still open the same OpenRiot panels.
Phase 4: Launcher and menus
Tasks:
- Replace rofi with
wofiorfuzzel. - Add a Wayland theme to
config/wofi/orconfig/fuzzel/. - Replace
rofi -show calcwith an OpenRiot calculator command. - Replace
rofi -show filebrowserwith a Thunar invocation or a smallopenriot --file-browsermenu. - Keep
rofiinstalled while the X11 session remains supported.
Exit criteria: application launch, settings menu, power menu and window switcher work without rofi.
Phase 5: Notifications
Tasks:
- Replace dunst with
fnottormako. - Replace
dunstctlinsource/notifywith the new daemon’s control command. - Keep
notify-sendcalls unchanged. They are daemon agnostic. - Port the dunst scaling logic to the daemon’s font and width settings.
Exit criteria: every openriot --notify path and direct notify-send call
produces a visible notification with working actions.
Phase 6: Lock, idle and power
Tasks:
- Replace i3lock with
hyprlockif packaged, otherwiseswaylock. - Replace xautolock with
hypridleif packaged, otherwiseswayidle. - Lock on idle, dim before lock, suspend with
zzz, and lock before sleep. - Remove
xset,setxkbmap,loginctland other X11 or systemd calls. - Keep the existing
--smart-lockand--lockcommand interface. Only the backend changes.
Exit criteria: lock, unlock, idle dim, idle lock and suspend all work from a cold boot with no X11 processes.
Phase 7: Display, wallpaper, screenshots and recording
Tasks:
- Replace xrandr reads with
hyprctl monitors -jorwlr-randr. - Replace xrandr writes with
hyprctl keyword monitor. - Replace feh with
swaybg. - Replace maim with
grim, andmaim -swithgrimplusslurp. - Replace xclip with
wl-copyandwl-paste. - Replace the ffmpeg x11grab path. This needs a separate decision (section 14).
Exit criteria: mirror, extend, disable output, wallpaper rotation, full-screen and region screenshots all work on Wayland.
Phase 8: Go backends
Tasks:
- Introduce a small
desktopinterface and two implementations:i3andhyprland. - Migrate workspace, title, icon and window switching first.
- Migrate display and wallpaper next.
- Leave layout snapshot disabled on Hyprland until a replacement exists.
- Detect the backend once in
mainand pass it down, instead of having each package shell out toi3-msg.
Exit criteria: make test passes, both sessions pass the test matrix, and
no Hyprland code path invokes i3-msg, xrandr, xprop or xdotool.
Phase 9: Installer and default session
Tasks:
- Add a
desktop.hyprlandgroup toinstall/packages.yaml. - Install the Hyprland stack first, then the config files.
- Add a file conflict policy: polybar and waybar configs coexist in
~/.config. - Add an installer prompt or settings toggle for the default session.
- Keep i3 installed for at least one release cycle.
Exit criteria: a new install can choose Hyprland, an existing install can migrate, and a failed Hyprland install leaves the X11 session intact.
6. Tool Mapping
| Current | Wayland replacement | Notes |
|---|---|---|
| i3 | Hyprland | Different config language; layout concepts differ |
| polybar | waybar | Native Hyprland workspace and window modules |
| rofi | wofi or fuzzel | Theme must be rewritten |
| rofi-calc | OpenRiot calculator command | No direct rofi-calc equivalent |
| dunst | fnott or mako | notify-send unchanged |
| picom | Hyprland built-in compositor | Remove picom entirely |
| feh | swaybg | Hyprpaper optional |
| xrandr | hyprctl or wlr-randr |
Monitor hotplug needs testing |
| maim | grim | Region capture uses slurp |
| xclip | wl-clipboard | wl-copy, wl-paste |
| clipmenu | cliphist plus wofi | cliphist must be packaged |
| i3lock | hyprlock or swaylock | Keep OpenRiot --lock interface |
| xautolock | hypridle or swayidle | Keep OpenRiot --smart-lock interface |
| xset gamma | hyprsunset or wlsunset | Both need packaging |
| ffmpeg x11grab | unresolved | Hyprland screencopy path needs work |
| Xresources | GTK settings and env | No xrdb merge |
| setxkbmap, xinput | Hyprland input block |
Trackpoint setup uses wsconsctl |
| i3-msg | hyprctl |
JSON output is stable enough to parse |
7. Configuration Layout
Proposed tree:
config/hypr/
hyprland.conf # main, generated by the installer
monitors.conf # user-editable, survives reinstall
keybindings.conf # user-editable, survives reinstall
windowrules.conf # user-editable, survives reinstall
input.conf # keyboard and touchpad
openriot-hyprland-session
config/waybar/
config
style.css
Modules
ModulesCustom
ModulesWorkspaces
ModulesGroups
colors.css
config/wofi/
config
style.css
Main configuration skeleton:
$terminal = alacritty
$fileManager = thunar
$openriot_bin = $HOME/.local/share/openriot/install/openriot
$browser = $openriot_bin --browser
$mod = SUPER
source = ~/.config/hypr/monitors.conf
source = ~/.config/hypr/input.conf
source = ~/.config/hypr/windowrules.conf
env = XCURSOR_THEME,Bibata-Modern-Ice
env = XCURSOR_SIZE,24
env = GTK_THEME,Adwaita-dark
exec-once = waybar
exec-once = fnott
exec-once = swaybg -i ~/.local/share/openriot/backgrounds/default.jpg
exec-once = $openriot_bin --volume restore
exec-once = $openriot_bin --night-light-restore
exec-once = $openriot_bin --wireguard-autostart
general {
gaps_in = 0
gaps_out = 2
border_size = 1
col.active_border = rgba(37a29cff)
col.inactive_border = rgba(333333cc)
layout = dwindle
}
decoration {
rounding = 0
active_opacity = 1.0
inactive_opacity = 1.0
blur {
enabled = false
}
shadow {
enabled = false
}
}
animations {
enabled = false
}
input {
kb_layout = us
follow_mouse = 1
repeat_rate = 40
repeat_delay = 600
}
The zero gaps, zero rounding, no blur and no animations match the current i3 look. Enable them later if the hardware can afford it.
Monitor file:
monitor = , preferred, auto, 1
# Secondary display to the right
# monitor = HDMI-A-1, 1920x1080@60, 1920x0, 1
# Rotated display
# monitor = DVI-D-1, 1920x1080@60, 0x0, 1, transform, 1
8. Keybinding Migration
Mod4 in i3 maps to SUPER in Hyprland.
| i3 binding | Hyprland binding |
|---|---|
$mod+Return |
bind = SUPER, RETURN, exec, $terminal |
$mod+Shift+Return |
bind = SUPER SHIFT, RETURN, exec, $terminal --class floating_center |
$mod+D, $mod+space |
bind = SUPER, D, exec, wofi --show drun |
$mod+Shift+D |
bind = SUPER SHIFT, D, exec, thunar |
$mod+F |
bind = SUPER, F, exec, $fileManager |
$mod+B |
bind = SUPER, B, exec, $browser |
$mod+T |
bind = SUPER, T, exec, $terminal -e btop |
$mod+O |
bind = SUPER, O, exec, gnome-text-editor |
$mod+G |
bind = SUPER, G, exec, Telegram |
$mod+C |
bind = SUPER, C, exec, $openriot_bin --crush |
$mod+S |
bind = SUPER, S, exec, $openriot_bin --signal-launch |
$mod+Shift+K |
bind = SUPER SHIFT, K, exec, $terminal --class rmpc -e rmpc |
$mod+Q |
bind = SUPER, Q, killactive |
$mod+Z |
bind = SUPER, Z, togglefloating |
$mod+H |
bind = SUPER, H, togglesplit |
$mod+Shift+F |
bind = SUPER SHIFT, F, fullscreen, 0 |
$mod+P |
bind = SUPER, P, pseudo |
$mod+Shift+V |
bind = SUPER SHIFT, V, exec, cliphist list \| wofi --dmenu \| cliphist decode \| wl-copy |
$mod+Tab |
bind = SUPER, TAB, exec, $openriot_bin --window-switch |
$mod+Shift+Tab |
bind = SUPER SHIFT, TAB, exec, hyprctl dispatch cyclenext prev |
$mod+Left/Right/Up/Down |
bind = SUPER, left, movefocus, l (and r, u, d) |
$mod+1..4 |
bind = SUPER, 1, workspace, 1 (and so on) |
$mod+Shift+1..4 |
bind = SUPER SHIFT, 1, movetoworkspace, 1 |
$mod+Shift+Left..Down |
bind = SUPER SHIFT, left, swapwindow, l |
$mod+Ctrl+Left..Down |
bind = SUPER CTRL, left, movewindow, l |
$mod+equal |
bind = SUPER, equal, exec, $openriot_bin --calculator |
$mod+bracketright |
bind = SUPER, bracketright, resizeactive, 20 0 |
$mod+bracketleft |
bind = SUPER, bracketleft, resizeactive, -20 0 |
$mod+Shift+bracketright |
bind = SUPER SHIFT, bracketright, resizeactive, 0 20 |
$mod+Shift+bracketleft |
bind = SUPER SHIFT, bracketleft, resizeactive, 0 -20 |
$mod+minus |
bind = SUPER, minus, togglespecialworkspace, scratch |
$mod+Shift+minus |
bind = SUPER SHIFT, minus, movetoworkspacesilent, special:scratch |
$mod+button4/5 |
bind = SUPER, mouse_down, workspace, e+1 |
| Volume, brightness keys | Keep OpenRiot commands, use bindel |
Print |
bind = , PRINT, exec, $openriot_bin --screenshot |
$mod+E/M/X, Shift+X |
Keep existing browser app bindings |
$mod+L |
bind = SUPER, L, exec, $openriot_bin --lock |
$mod+Escape |
bind = SUPER, ESCAPE, exec, $openriot_bin --power-menu |
$mod+W, Shift+W |
Keep wallpaper next and previous |
$mod+Shift+space |
bind = SUPER SHIFT, SPACE, exec, pkill -SIGUSR2 waybar |
$mod+Shift+R |
bind = SUPER SHIFT, R, exec, hyprctl reload |
$mod+Shift+C |
bind = SUPER SHIFT, C, exec, hyprctl reload |
$mod+Shift+E |
bind = SUPER SHIFT, E, exec, hyprctl dispatch exit |
$mod+Shift+H |
bind = SUPER SHIFT, H, exec, $openriot_bin --help-launch |
Media keys must be bindel or bindl so they do not grab.
Window rules for OpenRiot dialogs:
windowrule {
name = floating-center
match:class = ^(floating_center|openriot_wifi|openriot_disk|openriot_migrate|openriot_resolution|zcash-mini)$
float = yes
center = yes
size = 50% 60%
}
windowrule {
name = openriot-upgrade
match:class = ^(openriot_upgrade)$
float = yes
center = yes
size = 50% 60%
}
windowrule {
name = transmission
match:class = ^(Transmission)$
float = yes
center = yes
size = 800 600
}
windowrule {
name = control-center
match:title = ^(OpenRiot Control Center)$
float = yes
center = yes
size = 480 340
}
9. Waybar Plan
Polybar currently runs as three bars. Waybar runs as one process with
modules-left, modules-center and modules-right. Keep the same visual
split: launcher and workspaces left, clock center, system status right.
Module mapping:
| Polybar module | Waybar module |
|---|---|
launcher |
custom/openriot-launcher |
| workspace list | hyprland/workspaces |
date |
clock |
volume |
custom/openriot-volume or pulseaudio |
network-wifi, network-eth |
network |
battery |
battery |
cpu, memory |
cpu, memory |
openriot-update |
custom/openriot-update |
hdmi |
custom/openriot-hdmi |
weather |
custom/openriot-weather |
proton-drive, transmission, nzbget |
custom/openriot-* |
crypto |
custom/openriot-crypto |
night-light |
custom/openriot-nightlight |
screenrec |
custom/openriot-rec |
wireguard, stealth |
custom/openriot-wireguard, custom/openriot-stealth |
power |
custom/openriot-power |
lock |
custom/openriot-lock |
Custom modules should use return-type: json, matching ArchRiot’s working
pattern (~/Code/ArchRiot/config/waybar/ModulesCustom lines 18 to 124):
"custom/openriot-volume": {
"format": "{}",
"return-type": "json",
"interval": 1,
"exec": "$HOME/.local/share/openriot/install/openriot --waybar-volume",
"on-click": "$HOME/.local/share/openriot/install/openriot --volume toggle",
"on-scroll-up": "$HOME/.local/share/openriot/install/openriot --volume inc",
"on-scroll-down": "$HOME/.local/share/openriot/install/openriot --volume dec",
"tooltip": true
}
New OpenRiot subcommands required:
--waybar-volume--waybar-cpu--waybar-memory--waybar-update--waybar-crypto--waybar-network--waybar-battery(native waybar battery may suffice)--waybar-rec--waybar-wireguard
Each must print one JSON object with text, tooltip, class and
optionally alt. This isolates formatting in Go and keeps the waybar config
thin.
Waybar workspace module:
"hyprland/workspaces": {
"active-only": false,
"all-outputs": true,
"format": "{icon}",
"on-click": "activate",
"on-scroll-up": "hyprctl dispatch workspace e+1",
"on-scroll-down": "hyprctl dispatch workspace e-1",
"persistent-workspaces": { "*": 4 },
"format-icons": {
"active": "●",
"default": "◉",
"empty": "○"
}
}
This replaces the i3 tree parsing in source/workspaceicons. The custom
workspace icon and name logic can be dropped unless it carries information
waybar cannot show.
10. Go Code Changes
10.1 Backend interface
Add a small interface, for example source/desktop:
type Backend interface {
Workspaces() ([]Workspace, error)
ActiveWindow() (Window, error)
Clients() ([]Window, error)
SwitchWorkspace(int) error
MoveToWorkspace(int) error
FocusWindow(id string) error
Monitors() ([]Monitor, error)
SetWallpaper(path string) error
}
Implementations: desktop/i3.go and desktop/hyprland.go. Existing
packages call the interface. This avoids scattering session checks through
every command.
10.2 Per-package migration
| File | Current | Proposed |
|---|---|---|
source/workspace/workspace.go |
i3-msg -t get_workspaces |
hyprctl -j workspaces |
source/workspaceicons/workspaceicons.go |
i3-msg -t get_tree |
hyprctl -j workspaces, hyprctl -j clients |
source/windowtitle/windowtitle.go |
i3-msg -t get_tree |
hyprctl -j activewindow |
source/windowicon/windowicon.go |
i3-msg -t get_tree |
hyprctl -j activewindow |
source/window/switch.go |
rofi plus i3 tree | wofi plus hyprctl -j clients |
source/window/snapshot.go |
i3 append_layout |
disable on Hyprland, or reimplement with window rules |
source/display/hdmi.go |
i3-msg get_outputs, xrandr |
hyprctl -j monitors, hyprctl keyword monitor |
source/screen/screen.go |
xrandr | hyprctl -j monitors |
source/resolution/backend.go |
xrandr | hyprctl monitors, wlr-randr |
source/backgrounds/backgrounds.go |
xrandr plus feh | hyprctl -j monitors plus swaybg |
source/screenshot/screenshot.go |
maim plus xclip | grim plus slurp plus wl-copy |
source/screenrec/screenrec.go |
ffmpeg x11grab | undecided, see section 14 |
source/lock/lock.go |
i3lock plus xset | hyprlock or swaylock plus hypridle or swayidle |
source/notify/notify.go |
dunst plus dunstctl | fnott or mako control command |
source/nightlight/nightlight.go |
xrandr gamma | hyprsunset or wlsunset |
source/polybar/polybar.go |
polybar config plus i3-msg | new source/waybar generator |
source/rofi/rofi.go |
rofi | wofi or fuzzel |
source/settings/settings.go |
rofi | wofi or fuzzel |
source/commands/helpers.go |
xprop, i3-msg exit | hyprctl -j clients, hyprctl dispatch exit |
install/packages.yaml |
i3, polybar, rofi, dunst | new desktop.hyprland group |
Notes per file:
source/window/snapshot.gois the hardest. i3 layout restore has no Hyprland equivalent. The proposal is to disable the feature on Hyprland and tell the user, rather than shipping a half-working restore.source/window/switch.gocurrently filters polybar and dunst. The Hyprland backend must filter waybar, fnott and other layer-shell clients.source/commands/helpers.go_NET_CLIENT_LISTlogic is X11 only. Usehyprctl -j clientsand map the address to a focus command.source/polybar/polybar.goshould not be deleted. It remains the X11 backend until the X11 session is removed.
11. Session Startup
Proposed openriot-hyprland-session:
#!/bin/sh
export XDG_RUNTIME_DIR=/tmp/$USER-runtime
mkdir -p "$XDG_RUNTIME_DIR"
chmod 0700 "$XDG_RUNTIME_DIR"
export PATH="$HOME/.local/bin:$HOME/.local/share/openriot/install:$PATH"
export XCURSOR_THEME=Bibata-Modern-Ice
export XCURSOR_SIZE=24
export GTK_THEME=Adwaita-dark
fc-cache -f 2>/dev/null
mkdir -p "$HOME/Screenshots"
exec start-hyprland
OpenBSD specifics:
XDG_RUNTIME_DIRmust be 0700. The existing.xsessionalready does this.seatdmust be enabled if Hyprland uses the libseat backend. Test both the seatd path and any no-op or direct DRM path the PoC provides.- There is no
loginctl. Lock before suspend withzzztriggered from the lock or idle daemon, not from a systemd unit. - Do not run
xsetorsetxkbmap. Keyboard layout belongs in the Hyprlandinputblock. - Keep XWayland enabled for Thunar, LibreOffice and older GTK apps.
12. OpenBSD Risks and Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Hyprland churn during Lua config transition | Config breaks between releases | Pin the tested commit in the port; ship a known config |
| Lua 5.5 not in ports | Build fails | Add a Lua 5.5 port or carry a patch |
| glaze not in ports | Build fails | Port glaze before Hyprland |
| aquamarine seat and udev assumptions | Session cannot start | Test seatd and libudev-openbsd early |
No hyprshot, hyprpaper, hyprsunset, hyprlock |
Missing features | Use grim, swaybg, wlsunset, swaylock first |
| Screencast and screen sharing | Broken feature | Research xdg-desktop-portal-hyprland and PipeWire on OpenBSD |
| Recording | No direct replacement | Decide between wf-recorder, Hyprland screencopy helper, or dropping the feature |
| Layout restore | Feature loss | Disable on Wayland and document it |
| X11 apps | Some break under XWayland | Keep the X11 session and test LibreOffice, Thunar, Telegram |
| AMD and Intel only | Unsupported GPUs | Mark amd64, i915 and amdgpu as supported; state the rest as untested |
| Installer regression | Users lose a working desktop | Keep the i3 group and do not remove X11 packages |
13. Test Matrix
Run on both sessions after each phase:
- Cold login from greetd or TTY.
- Every keybinding in section 8.
- Workspace switch, move and swap.
- Floating and centered OpenRiot dialogs.
- Bar modules: click, scroll and tooltip.
- Notifications with actions.
- Full-screen screenshot, region screenshot, clipboard paste.
- Lock, unlock, idle dim, idle lock, suspend and resume.
- HDMI hotplug, mirror, extend, disable laptop panel.
- Wallpaper next and previous, including multi-monitor.
- XWayland apps: Thunar, LibreOffice, Telegram, alacritty.
make testand the full OpenRiot command sweep.- Crypto and update bar modules.
- Session exit and restart.
14. Open Decisions
- Hard switch or dual session? Recommendation: dual session for at least one release cycle.
- Keep a custom bar or adopt waybar as the only bar? Recommendation: waybar, because it has native Hyprland modules and is already in ports.
hyprlockandhypridle, orswaylockandswayidlefirst? Recommendation: sway tools first, Hypr tools once packaged.mako,fnott, or keep dunst? Recommendation: fnott, already in ports.- What replaces layout restore? Options: drop it, recreate via window rules, or add a small per-workspace launcher list. Recommendation: drop it for the first Wayland release.
- What replaces screen recording? Options: wf-recorder if it works under Hyprland, a Hyprland screencopy helper, or defer the feature. Recommendation: defer until the compositor port is stable.
- What replaces
rofi-calc? Recommendation: addopenriot --calculatorand render it with wofi or a terminal UI. - Does the installer install the Hyprland stack by default? Recommendation: no, make it an explicit desktop choice until the port is in the tree.
15. Reference Material
Working Linux configuration and integration examples:
~/Code/ArchRiot/config/hypr/hyprland.conf- application variables: lines 33 to 47
- autostart: lines 49 to 66
- window rules: lines 70 to 786
- input: lines 788 to 813
- appearance: lines 815 to 899
- keybindings: lines 901 to 1049
- theme and performance overrides: lines 1054 to 1140
~/Code/ArchRiot/config/hypr/keybindings.conf~/Code/ArchRiot/config/hypr/monitors.conf~/Code/ArchRiot/config/hypr/windowrules.conf~/Code/ArchRiot/config/hypr/hypridle.conf~/Code/ArchRiot/config/hypr/hyprlock.conf~/Code/ArchRiot/config/waybar/config~/Code/ArchRiot/config/waybar/Modules~/Code/ArchRiot/config/waybar/ModulesCustom~/Code/ArchRiot/config/waybar/ModulesWorkspaces~/Code/ArchRiot/config/waybar/ModulesGroups~/Code/ArchRiot/config/waybar/style.css~/Code/ArchRiot/source/session/waybar.go~/Code/ArchRiot/source/waybar/
Existing OpenRiot material to port:
config/i3/configconfig/i3/keybindings.confconfig/polybar/config.ini.tmplconfig/rofi/config.rasiconfig/dunst/dunstrcconfig/picom.confconfig/xsession/openriot-xsessionconfig/xinitrc/openriot-x11
Upstream references:
- Hyprland OpenBSD PRs: #16457, #16495, #16839
- aquamarine OpenBSD PR: #432
- hyprwayland-scanner OpenBSD PR: #21
- hyprland-protocols OpenBSD PR: #24
- Hyprland wiki: configuration, monitors, keybinds, window rules, workspaces, idle, lock, xwayland