Gliver brings the keyboard-driven, manual-tiling workflow of StumpWM to Wayland, using River as the compositor backend and GNU Guile Scheme as the extension language. It attempts to be highly customizable while relying entirely on the keyboard for input.
Gliver is considered almost complete feature-wise, it’s possible to use it as a window manager if you are willing to tolerate some crashes and bugs. Please submit all the issues you face so we can make Gliver more stable.
I have Gliver installed which allows me to select it as the window manager from my display manager, but once I am in, I open a terminal on my Gliver source code and use the below command.
while true; do (killall -q gliver || true) && make run || sleep 3; doneThe above will keep running make run on the source so if Gliver crashes, it will simply be executed again. This way you don’t lose your wayland session (Gliver state like how windows are arranged is lost). You can also simply kill the Gliver process if you make changes to the code and want them to take effect immediately.
You can find Gliver’s logs in ${XDG_STATE_HOME}/gliver/gliver.log (~/.local/state/gliver/gliver.log by default).
You may also connect the REPL via socket if you use a tool like Emacs Geiser via geiser-connect-local. The socket path is ${XDG_STATE_HOME}/gliver/repl.sock (~/.local/state/gliver/repl.sock by default)
Gliver is heavily inspired by Emacs and StumpWM, tailored specifically for the modern Wayland stack. This project aims to be “The Emacs of Wayland WMs.”
- Hackable and can be customized and enhanced in
Guile Schemeutilizing aREPLin real-time - Configured using the exact same language it is written in (configuration is code, rather than a static configuration file). You can start by simply configuring it and later implement new features.
- Free of a single enforced layout; you can use manual, alternating, scrolling, or any other layout you write yourself.
- A standalone Wayland compositor; it runs alongside River as a client and delegates all rendering and hardware duties.
- A drop-in replacement for any other window manager, even though you may find built-in configurations that can replicate most of the features found in other window managers.
Gliver runs alongside River as the window manager client.
Because River relies on a non-monolithic architecture, it separates the compositor from the layout manager. River handles all compositor duties (rendering, input devices, GPU, Wayland protocol). Gliver communicates with River via Wayland protocols (such as river-window-management-v1) to determine window placement, focus, borders, keybindings, and all window management policy.
- River (v0.4+)
- libwayland
- libxkbcommon
- librsvg
- GNU Guile (3.0+)
- Guile-Cairo
- Pango
- GNU Make
Building Gliver from source is straightforward:
make
sudo make installGliver’s configuration is by default located in ~/.config/gliver/init.scm. To get started, you may want to copy the sample configuration in doc/examples/init.scm into your configuration file. From gliver’s source code, you may execute the below:
mkdir -p ~/.config/gliver && cp -n doc/examples/init.scm ~
C95A
/.config/gliver/init.scmBecause gliver depends on river, the cleanest way to run them is by passing the -c flag which ensures river initializes first and immediately runs gliver as its init executable.
river -c gliverNote: make install installs a Wayland session file (gliver.desktop) into $(SESSIONDIR) (by default $(PREFIX)/share/wayland-sessions), you can use your favorite display manager to run gliver and you should see it listed along with other window managers/candidates available on your system.
You can run Gliver directly from source without installing it on your system, which is ideal for rapid development and testing. Ensure that River is running first, then execute:
make && make runNote: If you are running River in a nested session (which is useful for debugging), you must set the correct WAYLAND_DISPLAY environment variable before starting Gliver:
export WAYLAND_DISPLAY=wayland-1
make && make runGliver provides a super key driven keybindings via (gliver contrib keybindings gliver) which is the keybindings used in the default configuration file provided. Gliver’s keybindings use Emacs style to describe keybindings.
s-Super/WindowskeyS-ShiftkeyC-ControlkeyM-Meta/Altkey
| Key Combination | Command | Description |
|---|---|---|
s-Return | terminal-spawn | Spawn terminal emulator |
s-q | window-kill | Close/kill focused window |
s-o | launcher-run | Open application via launcher launcher |
s-f | window-fullscreen-toggle | Toggle fullscreen for focused window |
s-S-r | config-reload! | Reload configuration |
s-S-q | gliver-quit | Quit Gliver session |
| Key Combination | Command | Description |
|---|---|---|
s-h, s-Left | container-focus-left | Focus container to the left |
s-j, s-Down | container-focus-down | Focus container below |
s-k, s-Up | container-focus-up | Focus container above |
s-l, s-Right | container-focus-right | Focus container to the right |
s-n, s-Tab | window-focus-next | Focus next window in container stack |
s-p, s-S-Tab | window-focus-prev | Focus previous window in container stack |
s-C-n, s-C-Tab | window-swap-next | Swap current window with next window in container |
s-C-p, s-C-S-Tab | window-swap-prev | Swap current window with previous window in container |
| Key Combination | Command | Description |
|---|---|---|
s-M-h, s-M-Left | window-container-move-left | Move focused window to container on left |
s-M-j, s-M-Down | window-container-move-down | Move focused window to container below |
s-M-k, s-M-Up | window-container-move-up | Move focused window to container above |
s-M-l, s-M-Right | window-container-move-right | Move focused window to container on right |
| Key Combination | Command | Description |
|---|---|---|
s-C-h, s-C-Left | workspace-focus-left | Focus workspace to the left |
s-C-j, s-C-Down | workspace-focus-down | Focus workspace below |
s-C-k, s-C-Up | workspace-focus-up | Focus workspace above |
s-C-l, s-C-Right | workspace-focus-right | Focus workspace to the right |
| Key Combination | Command | Description |
|---|---|---|
s-C-M-h, s-C-M-Left | window-workspace-move-left | Move window to workspace on the left |
s-C-M-j, s-C-M-Down | window-workspace-move-down | Move window to workspace below |
s-C-M-k, s-C-M-Up | window-workspace-move-up | Move window to workspace above |
s-C-M-l, s-C-M-Right | window-workspace-move-right | Move window to workspace on the right |
| Key Combination | Command | Description |
|---|---|---|
s-s | container-split-horizontal | Split container horizontally |
s-v | container-split-vertical | Split container vertically |
s-d | container-destroy | Destroy active container slot |
s-D | container-destroy-others | Destroy all other containers in workspace |
| Key Combination | Command | Description |
|---|---|---|
XF86AudioMute | media-audio-mute | Toggle audio mute |
XF86AudioLowerVolume | media-audio-volume-decrease | Lower audio volume |
XF86AudioRaiseVolume | media-audio-volume-increase | Raise audio volume |
XF86AudioMicMute | media-mic-mute | Toggle microphone mute |
XF86MonBrightnessDown | media-brightness-decrease | Decrease screen brightness |
XF86MonBrightnessUp | media-brightness-increase | Increase screen brightness |
Print | media-screenshot | Take screenshot |
Pull requests are always welcome! Here are some guidelines to ensure your contribution gets merged:
- Document your work: Preserve comments and docstrings explaining what the code does, and update them if your patch changes.
- Target the right directory: Most new features, modules, and packages should go into the
contribdirectory. - Avoid change in
core: Contributions to thecoredirectory will go through a lengthy review process, I prefer not to break existing APIs. - Avoid AI-generated code: To ensure strict compliance with Codeberg’s Terms of Use, please refrain from submitting code written by Large Language Models (LLMs).
Here’s a wishlist of features for the Gliver project:
- Implementing animations driven by Guile timers over the
set_dimensionsWayland request. - Implementing automated testing (most likely needs simulating river).
- Add guard checks whenever needed, some clients will violate the defined protocol and send null-pointers or invalid parameters which always needs to be checked to avoid crashes.
This was observed so far in vlc where it will resize itself based on video resolution. While it’s possible to disable this behavior from vlc itself, I am looking for a solution that will work on all clients.
NOTE: this issue doesn’t seem to be easy to resolve, clients in this case violate the wayland protocol and it doesn’t seem to me that there is a way to stop them from doing so.
This was observered so far in Emacs and librewolf where they will include a titlebar, I believe all gtk applications will do so. While it’s possible to have a workaround from gtk css, I again want to have a solution that will work on other clients as well.
NOTE: this issue doesn’t seem to be easy to resolve, clients in this case violate the wayland protocol and it doesn’t seem to me that there is a way to stop them from doing so.
| Name | Gliver Component | Good Alternatives |
|---|---|---|
| output configuration | core/output.scm | kanashi |
| input configuration | core/keybinding.scm | channel, kwim |
| topbar / statusbar | gleui/statusbar.scm | waybar, swaybar |
| screen locker | TODO | swaylock, waylock |
| idle management | TODO | swayidle |
| screen capture | not planned | flameshot, grim |
| application launcher | gleui/launcher.scm | fuzzel, rofi |
| notification daemon | gleui/notifications.scm | mako, dunst |
| wallpaper manager | river/wallpaper-manager.scm | swaybg, awww |
As in Emacs and StumpWM, you can always get documentation natively through Gliver:
| Key | Help |
|---|---|
s-SPC h v | Variables |
s-SPC h f | Functions |
s-SPC h k | Key sequences |
You can also drop into the Live REPL at any time to inspect state.