WLROOTS Infinite-Spatial Grid WM based on DWL. Inspired by DriftWM, VXWM, Hevel, Halley, Niri, and Hyprland.
  • C 95.8%
  • GLSL 1.6%
  • Roff 1.4%
  • Makefile 1.2%
Find a file
2026-05-31 21:54:59 -06:00
.gitea/issue_template history clear 2026-05-30 18:40:39 -06:00
protocols history clear 2026-05-30 18:40:39 -06:00
SHADER_EXAMPLE history clear 2026-05-30 18:40:39 -06:00
.gitignore k 2026-05-30 19:47:34 -06:00
.mailmap history clear 2026-05-30 18:40:39 -06:00
CHANGELOG.md history clear 2026-05-30 18:40:39 -06:00
client.h history clear 2026-05-30 18:40:39 -06:00
config.def.h history clear 2026-05-30 18:40:39 -06:00
config.mk history clear 2026-05-30 18:40:39 -06:00
CursorFX.md history clear 2026-05-30 18:40:39 -06:00
drm_lease.patch history clear 2026-05-30 18:40:39 -06:00
dwl.1 history clear 2026-05-30 18:40:39 -06:00
dwl.c removed /tmp/uwwm_coords, no longer serves a purpose 2026-05-31 21:54:59 -06:00
dwl.desktop history clear 2026-05-30 18:40:39 -06:00
dwl.so removed /tmp/uwwm_coords, no longer serves a purpose 2026-05-31 21:54:59 -06:00
LICENSE history clear 2026-05-30 18:40:39 -06:00
LICENSE.dwm history clear 2026-05-30 18:40:39 -06:00
LICENSE.sway history clear 2026-05-30 18:40:39 -06:00
LICENSE.tinywl history clear 2026-05-30 18:40:39 -06:00
Makefile history clear 2026-05-30 18:40:39 -06:00
README.md pre chording video added 2026-05-31 04:23:59 -06:00
SHADERS.md history clear 2026-05-30 18:40:39 -06:00
util.c history clear 2026-05-30 18:40:39 -06:00
util.h history clear 2026-05-30 18:40:39 -06:00

UWWM - Unlimited Wayland Window Manager

UWWM is a infinite-spatial grid WM for [Wayland] based on [wlroots]. It is intended to fill the same space in the Wayland world that [vxwm] does in X11, primarily in terms of functionality, and secondarily in terms of philosophy. Like [dwl], UWWM is:

  • Easy to understand, hack on, and extend.
  • One C source file along with a configurable config.h
  • Tied to as few external dependencies as possible

Building UWWM

UWWM has the following dependencies:

  • libinput
  • wayland
  • wlroots (compiled with the libinput backend)
  • xkbcommon
  • grim
  • satty (recommended for default config, see config)
  • wmenu (recommendede for default config, see config)
  • wayland-protocols (compile-time only)
  • pkg-config (compile-time only)

UWWM has the following additional dependencies if XWayland support is enabled:

  • libxcb
  • libxcb-wm
  • wlroots (compiled with X11 support)
  • Xwayland (runtime only)

Install these (and their -devel versions if your distro has separate development packages) and run make. If you wish to build against a released version of wlroots (you probably do), use a [release] or a [0.x branch]. If you want to use the unstable development main branch, you need to use the git version of [wlroots].

XWayland is on by default. It's recommended you use it over something like XWaylnd-Satellite due to how the window management is done. Although, your mileage may vary.

Configuration

All configuration is done by editing config.h and recompiling, in the same manner as [dwl]. Any changes done in the config can be reapplied upon recompilation and a hit of the keybind to restart the WM. Sometimes you may need to restart the window you had open previously to apply more decorative changes.

Performance

I went absolutely wild with the performance. I wanted this to be able to run on as many machines as possible while being as cool as possible. So you may come to notice when you do things like play games, there's quite literally ZERO delay due to how i'm handling the input. Events are done before they're drawn and there's nothing like forced vsync. Meaning applications are able to run as fast and respond as fast as your hardware allows.

Shaders still come with a cost, so use them wisely. I tried to optimize the shader pipeline as reasonably as I could while still letting people do anything they wanted. That being said, enjoy your time with this amazing WM, and I hope you like using it as much as I did making it!

Features + Quick-Start Tutorial

UWWM introduces an infinite-space canvas combined with dynamic physics, interactive window clustering, custom GLSL shader pipelines, and tight D-Bus integrations.

1. Infinite-Space Canvas + Spring Physics

Windows are spawned in a concentric, non-overlapping grid on an infinite canvas rather than being confined to a static monitor boundary.

  • Pan the Camera: Hold Left Click on any empty area of the desktop background and drag your mouse. The camera drifts with natural kinetic momentum.
  • Camera Zoom: Press Mod + Minus (-) to zoom out, or Mod + Plus (+) to zoom in. You can also zoom by holding Alt (or your configured modifier) and scrolling the Mouse Wheel [1].
  • Physics Animation: Windows and the camera utilize underdamped spring physics. Grabbing, tiling, zooming, or panning results in organic overshoots and elastic bounciness [1].

2. Multi-Pipeline Shader System (ManagerFX, CursorFX, WindowFX)

UWWM integrates three independent GLSL fragment shader pipelines. Shaders are loaded dynamically from directories defined in config.h [1].

  • Cycle Shaders:
    • Background (ManagerFX): Press Mod + S [1]
    • Cursor Trails (CursorFX): Press Mod + C [1]
    • Window Afterimages (WindowFX): Press Mod + W [1]
  • Toggle Shaders on/off:
    • Background: Press Mod + Shift + S [1]
    • Cursor: Press Mod + Ctrl + C [1]
    • Window: Press Mod + Ctrl + W [1]
  • Setup: Drop any .glsl fragment shader into your folders (default ~/.config/uwwm/shaders/[manager|cursor|window]/) and use the keybinds to hot-swap them instantly.

3. Interactive Window Clustering (Mod + I)

You can visually group and bind windows together to move them as single units across the infinite layout.

  • Enter Overview Mode: Press Mod + I. Floating indicator bubbles will appear above your windows [1].
  • Connect Windows: Inside the Mod + I overlay, click the "O" button next to any window and drag a connection line to another window [1].
  • Sever Connections: Hover over the midpoint "X" button on any connecting link and Left Click to break the cluster link [1].
  • Rename Clusters: Left Click on the cluster name label. An asynchronous Zenity dialog will pop up, allowing you to name the group without stalling compositor frames [1].

4. Smart Embedded Notifications

UWWM intercepts standard system notifications via low-level D-Bus bindings and handles them inside the window manager [1].

  • Stealth and Content Modes: Configure notification_stealth_mode in config.h.
    • In Stealth Mode (1), notifications show a generic "Notification received!" alert [1].
    • In Content Mode (0), they display the actual text of the alert [1]. Prepend the triggering window's title by enabling notification_show_sender_window [1].
  • Reviewing Alerts: When a window receives a notification, its indicator bubble displays a badge count (e.g., 🔔 [3]) in Mod + I overview mode [1]. Left Click on the badge to render a vertically stacked list of all pending alerts with their respective app icons and summaries.

5. Ambient MPRIS Music Player

A built-in glassmorphic player tracks your media and renders directly onto your workspace [1].

  • Layout Modes: Toggle mpris_layout_mode in your config:
    • 0: Standard wide card (Cover Art left, track metadata right, timeline progress) [1].
    • 1: Compact vertical card (Centered Cover Art, title and artist below, progress bar, formatted time) [1].
  • Real-Time Seeking: The timeline progress bar interpolates playback every 100ms. If you scrub, rewind, or fast-forward inside Audacious or any other player, UWWM catches the D-Bus Seeked signal to snap the progress bar instantly [1].
  • Monitor Routing: Target the player to a single display by setting mpris_target_monitor to your screen's index, or use -1 to render it across all connected outputs [1].
  • Layer Depth Routing: Configure mpris_player_layer in config.h to choose where the card lives:
    • 0: Background layer (sits at the absolute bottom of the rendering stack).
    • 1: Overlay layer (always on top of active application windows).
    • 2: Between layer (rests on LyrBottom — sits above background shaders but cleanly behind active tiled or floating windows).

6. Native Position Coordinate Tracker Overlay

UWWM features a built-in coordinate tracking overlay drawn directly on the bottom right of each output canvas.

  • Intelligent Visibility Layers: By default, coordinate tracking is drawn on the background layer (LyrBottom) so it sits elegantly behind your workspace windows without distracting from active tasks.
  • Top-Surface Elevation (Mod + I): Pressing Mod + I instantly elevates the coordinate overlay to the topmost layer (LyrOverlay), presenting it on top of all active window borders and popups for immediate reading.
  • Customizable Polling Rate: Update intervals are rate-limited via coord_tracker_interval_ms in config.h (default 100ms), eliminating continuous filesystem write bottlenecks and ensuring stutter-free compositor performance.

7. Native Unix IPC Socket Manager (/tmp/uwwm_ipc)

UWWM implements a high-performance, non-blocking UNIX domain socket at /tmp/uwwm_ipc powered natively by the Wayland event loop. This enables low-latency workspace automation, hotkey dispatching, and external status bar piping without requiring an embedded interpreter or external scripting daemon.

8. Drag-to-Spawn Mouse Chording (Mod + Ctrl + Left Click)

UWWM introduces a native region-definition gesture that allows you to drag out a specific workspace boundary before launching a program.

  • Define a Region: Hold Mod + Ctrl + Left Click on any area of the screen (regardless of whether you are clicking on a window or the empty background) and drag to draw a boundary box.

  • Launcher Execution: Upon releasing the mouse click, the selection overlay (customized by chord_color in config.h) is destroyed, and your designated chording menu tool (chord_cmd, default wmenu-run) is spawned. If you have nothing selected, the next window spawned will take the sizing of your choice. Without the menu command showing up. This is called pre-chording.

  • Canvas-Relative Mapping: The next managed application window that maps to the compositor will bypass standard concentric grid slot placement. It will initialize as a floating client, sized and positioned exactly within the canvas coordinates of the selection region you dragged out.

  • Cancellation: Press Escape at any point during an active drag gesture to cancel the action and return to the normal cursor mode. Although, the next opened window will take the coordinates and size you last chose with your chord. Even if you cancel.

  • Pre-Chording vs. Post-Chording: Unlike other compositors that rely on external tools (like slurp) which cannot communicate with the window manager's layout engine, UWWM handles chording natively.

    • Pre-Chording: Drag out a boundary box first, cancel or accept, and the next spawned application automatically conforms to those exact dimensions on launch.
    • Post-Chording: Hold Mod + Ctrl while clicking on an already active window to instantly adjust, drag, or re-chord its placement boundaries dynamically.

9. Edge Panning & Resizing with Monitor Protection

When moving or resizing windows near screen edges, the viewport automatically pans at a controlled rate to keep the action within view.

  • Smooth Resizing: Resizing a window near the edge scales smoothly up to your configured panning velocity, avoiding feedback-loop scaling bugs or extreme window expansion crashes.
  • Optional Monitor Intersection Panning: Using edge_pan_between_monitors in config.h, you can control how display boundaries behave:
    • 0: Prevents edge panning when dragging windows across borders shared with adjacent monitors, enabling a smooth crossover between displays.
    • 1 (Default): Edge panning occurs on all boundaries, shifting the active viewport camera even when moving windows across adjacent outputs.
  • Acceleration Configuration: Adjust panning threshold, starting speed, limits, and acceleration curves using edge_pan_threshold, edge_pan_min_speed, edge_pan_max_speed, and edge_pan_accel inside config.h.

Control & State Commands

Commands are evaluated via space-separated parameters. You can send commands to the socket using standard utilities like nc or socat [1]:

  • Viewport & Camera Navigation
    • recenter — Smoothly pans the active viewport back to coordinate (0,0).
    • pancamera <direction> — Triggers camera momentum panning. Directions: 0 (Left), 1 (Right), 2 (Up), 3 (Down).
    • zoomcamera <factor> — Adjusts viewport zoom. Accepts float modifiers (e.g., 1.1 to scale in, 0.9 to scale out).
  • Window Management
    • focusdirection <direction> — Shifts active focus to an adjacent client window. Directions: 0 (Left), 1 (Right), 2 (Up), 3 (Down).
    • focusstack <direction> — Focuses next (1) or previous (-1) window in focus history.
    • togglefloating — Toggles active window floating/tiling state.
    • togglefullscreen — Toggles the active window in and out of fullscreen.
    • killclient — Gracefully closes the focused window.
  • Workspaces & Tags
    • view <workspace_num> — Switches viewport tag focus (accepts integers 1 through 9).
    • tag <workspace_num> — Pins the active window to targeted tag (accepts integers 1 through 9).
  • Visual Pipelines & Shaders
    • togglehelpers — Toggles interactive clustering overlays and indicators (matching Mod + I) [1].
    • toggle_shader_manager / toggle_shader_cursor / toggle_shader_window — Enable or disable targeted GLSL FX pipelines dynamically [1].
    • cycle_manager_shader / cycle_cursor_shader / cycle_window_shader — Cycle to the next fragment shader in targeted directory [1].
  • System & Execution
    • spawn <shell_command> — Asynchronously runs arbitrary shell scripts or commands on the compositor thread.
    • quit — Gracefully terminates the window manager.

Querying Compositor State

The socket writes structured layout, window metadata, or telemetry details directly to the client connection [1]:

  • get_coords — Outputs the current viewport coordinates and active zoom factor: X, Y, Zoom.
  • get_active_window — Returns focused application details or NONE if workspace is empty:
    appid: <id>
    title: <window_title>
    x: <geom_x>
    y: <geom_y>
    w: <geom_w>
    h: <geom_h>
    
  • get_monitors — Returns a newline-separated list of active monitor viewports, scaling metrics, and screen boundary states.

Quick Scripting Integrations

You can bind commands directly to your custom status bar scripts or hotkey aliases:

# Query focused window title for custom panels (e.g., Waybar, somebar)
focused_title=$(echo "get_active_window" | nc -U /tmp/uwwm_ipc | grep "title:" | cut -d' ' -f2-)

# Switch to workspace 3
echo "view 3" | nc -U /tmp/uwwm_ipc

Problems and Fixes

"Roblox/Sober having strange input problems"

Solution: Run flatpak override --user --nosocket=wayland org.vinegarhq.Sober in a terminal and open Sober.

"Embedded notifications don't work!"

Ensure you source /tmp/uwwm_dbus_env in your shell of choice. Then run: notify-send "test"

The window should shake and you should get a notification received message!

"Why did the MRPIS Music Module stop working all of a sudden?"

If you pres the keybind to restart the WM after a config change, mpris can get stuck, just stop and play the music/audio. If it doesn't work, you may have to hit "STOP", not pause, and play it again.

"My window manager just crashed when I applied settings! What happened?"

Either you changed the quality level of the shaders while you were running it (the only thing I've noticed that crashes when restarting the WM), or you set a setting far too high or too low and it's causing issues.

The Philosophy: Stop Settling for Duct Tape and Dreams

I didnt build UWWM to be just another configuration folder you throw into your dotfiles. I built it because I am tired of watching the Wayland scene slide into mediocrity, and I am tired of watching people settle for it.

We used to live in a golden era of desktop ricing where developers made genuine, hard-nosed architectural improvements. Somewhere along the way, we lost that drive. Now, we are expected to praise bloated, laggy compositors held together by duct tape and dreams—software where standard features break the moment a flashy new animation is added. Or, we are told to accept "minimalism" as a convenient excuse for developers being too lazy to implement standard capabilities like hardware DRM leasing or robust input chording.

I am not going to sugarcoat it, and I am not going to let us settle for software that feels like it is constantly struggling to stay alive under load. Here is the reality of the scene today:

  • The Flashy But Fragile Bloat: The most popular modern compositors are sluggish, resource-heavy, and built on fragile foundations. They look great in a screen recording, but the moment you push them with intensive, real-world workflows, the cracks show. Features regress, inputs lag, and basic stability is sacrificed for superficial hype.
  • The Stalled Sparks: [Niri] was a brilliant concept, a genuine spark of innovation that got people excited. But the momentum stopped. The drive to aggressively develop and expand on its standout spatial features plateaued, leaving a great paradigm frozen in time.
  • The Antiques: The only mature, highly functional spatial-grid window manager right now is [vxwm]. But it is chained to X11. Running an infinite-space canvas on an outdated display server that struggles with multi-monitor layouts and feels laggy under load is a compromise you shouldnt have to make.
  • The "Shell" Bloat Epidemic: My god have we have reached a new level of insanity when a modern setup requires an entire separate desktop shell, panel, or widget bar just to display workspace indicators and system coordinates. Spawning a complete JavaScript/TypeScript runtime (like AGS) or running a massive, template-heavy C++ engine (like Waybar) just to draw a flat panel on the screen is a ridiculous waste of resources. It is hundreds of megabytes of memory and constant CPU context-switching wasted on an external event loop that has no business being separate. I designed UWWM to bypass this entirely—coordinates, watermarks, and layout tracking overlays are composited natively onto the canvas, giving you immediate system feedback with zero process overhead. Yes, this WM does still support those kinds of shells since this WM is designed to support everything and people will run whatever they want. But actually think to yourself, what problem does running a shell like that actually solve? Every functionality of it can be replicated by another program or can be done in a more efficient manner that doesn't soak up a bunch of CPU on your 2009 laptop.

I built UWWM from a place of love for this community and for the art of UX design. I wanted to prove that you can have an organic, physics-driven, infinite-space workspace on Wayland that actually works without lag, without broken features, and without lazy compromises.

Stop settling for software that struggles to keep up with your hardware. We can do better, and we should demand better. Wayland itself is an amazing protocol. The fact that I built this up to this point in just FIVE DAYS is a testament to how incredible the protocol is. We just need to push the boundaries of it further. Both literally and figuratively.

Some videos of the beta version (Pre-Forgejo release):

Click to play: Watch the video

Click to play: Watch the video

But.. what about VR?

Heh, I got you ~

VR working on the beta version of UWWM

What is pre-chording?

This:

Click to play: Watch the video