This is a module for Waybar that displays a window minimap for the current niri workspace.
Important
niri ≥ v25.08 is required (for the window locations in IPC messages to be available).
If you're using an amd64 system, you can get a pre-built binary from the
releases page.
Download and place waybar-niri-windows.so anywhere permanent;
~/.config/waybar is a good place.
If you'd like to build from source (or if you're on a different platform):
- Install GTK 3 + development headers (
apt install libgtk-3-dev,pacman -S gtk3, etc.). - Clone this repository.
- Run
maketo producewaybar-niri-windows.so. This might take a while (thanks to cgo).
Move the library anywhere permanent, e.g. ~/.config/waybar.
Add a CFFI module to your Waybar config:
Use these selectors in your CSS to style the module.
Windows:
.cffi-niri-windows .tile: any window, tiled or floating.cffi-niri-windows .column .tile: tiled window.cffi-niri-windows .floating .tile: floating window.cffi-niri-windows .<custom-class>: any window with a custom class (seerulesin the config)- Add
:hover(mouse hover) or:active(focused) to any of the above selectors to style those states. - Use
:first-child,:last-child, and:nth-child(n)to style the first, last, or nth window in a column. - Use
:only-childto style the window when it is the only window in a column. - Add
.urgentto style windows marked as urgent.
Containers:
.cffi-niri-windows .column: column of tiled windows.cffi-niri-windows .floating: floating window view- Add
:activeto any of the above selectors to style that container when they contain the focused window. - Use
:first-child,:last-child, and:nth-child(n)to style the first, last, or nth container. - Use
:only-childto style the container when it is the only container.
For example:
.cffi-niri-windows .tile {
background-color: rgba(255, 255, 255, 0.5);
}
.cffi-niri-windows .tile:hover {
background-color: rgba(255, 255, 255, 0.7);
}
.cffi-niri-windows .tile:active {
background-color: rgb(255, 255, 255);
}Note
Adding borders to containers may cause them to overflow the bar height. If this happens, set these config options to account for the borders:
- Set
column-bordersto the total height (in pixels) of the top and bottom border on.column - Set
floating-bordersto the total height (in pixels) of the top and bottom border on.floating
For example, for the following CSS:
.cffi-niri-windows .column {
border: 1px solid rgba(255, 255, 255, 0.85);
}
.cffi-niri-windows .floating {
border: 2px solid rgba(255, 255, 255, 0.85);
}Set column-borders to 2 and floating-borders to 4.
Text mode (be sure to specify a font that supports the symbols you're using):
.cffi-niri-windows label
.cffi-niri-windows label {
font-family: Uiua386;
font-size: 18px;
margin-top: -2px;
}Contributions are welcome! If you find a bug or have a feature request, please open an issue or PR.
This project is licensed under the MIT License. See the LICENSE file for details.


{ "modules-left": ["cffi/niri-windows"], "cffi/niri-windows": { // path where you placed the .so file "module_path": "/home/calico32/.config/waybar/waybar-niri-windows.so", // configure the module's behavior "options": { // set the module mode // "graphical" (default): draw a minimap of windows in the current workspace // "text": draws symbols and a focus indicator for each column (mirrors v1 behavior) "mode": "graphical", // ======= graphical mode options ======= // when to show floating windows // - "always": always show floating window view, even if there are no floating windows // - "auto" (default): show floating window view if there are floating windows on the current workspace // - "never": never show floating windows "show-floating": "auto", // pick where the floating windows be shown relative to tiled windows // - "left": show floating windows on the left // - "right" (default): show floating windows on the right "floating-position": "right", // set minimum size of windows, in pixels (default: 1, minimum: 1) // if this value is too large to fit all windows (e.g. in a column with many windows), // it will be reduced "minimum-size": 1, // set spacing between windows/columns, in pixels (default: 1, minimum: 0) // if this value is too large, it will be reduced "spacing": 1, // set minimum size of windows, in pixels, to draw icons for (default: 0, minimum: 0) // if unset or 0, icons will only be drawn for tiled windows that are the only one in their column // if 1+, icons will be drawn for all windows where w >= icon-minimum-size and h >= icon-minimum-size // icons must be set in the "rules" section below for this to have any effect "icon-minimum-size": 0, // account for borders when calculating window sizes; see note below (default: 0, minimum: 0) "column-borders": 0, // border on .column "floating-borders": 0, // border on .floating // trigger actions on tile click (see https://yalter.github.io/niri/niri_ipc/enum.Action.html for available actions) // only actions that take a single window ID are supported // set to an empty string to disable "on-tile-click": "FocusWindow", // (default: FocusWindow) "on-tile-middle-click": "CloseWindow", // (default: CloseWindow) "on-tile-right-click": "", // (default: none) // add CSS classes/icons to windows based on their App ID/Title (see `niri msg windows`) // Go regular expression syntax is supported for app-id and title (see https://pkg.go.dev/regexp/syntax) // rules are checked in the order they are defined - first match wins and checking stops // set "continue" to true to also check and apply subsequent rules even if this rule matches // if multiple rules with icons are applied, the first one will be used // *icons are not drawn for floating windows by default*; set "icon-minimum-size" to enable (see above) "rules": [ // .alacritty will be added to all windows with the App ID "Alacritty" // will be drawn in windows that match { "app-id": "Alacritty", "class": "alacritty", "icon": "" }, // .firefox will be added to all windows with the App ID "firefox" // subsequent rules are also checked and applied for firefox windows { "app-id": "firefox", "class": "firefox", "continue": true }, // .youtube-music will be added to all windows that have "YouTube Music" at the end of their title // will be drawn in windows that match { "title": "YouTube Music$", "class": "youtube-music", "icon": "" } ], // ======= text mode options ======= // customize the symbols used to draw the columns/windows "symbols": { "unfocused": "⋅", "focused": "⊙", "unfocused-floating": "∗", "focused-floating": "⊛", // text to display when there are no windows on the current workspace // if this is an empty string (default), the module will be hidden when there are no windows "empty": "" } }, "actions": { // use niri IPC action names to trigger them (see https://yalter.github.io/niri/niri_ipc/enum.Action.html for available actions) // any action that has no fields is supported "on-scroll-up": "FocusColumnLeft", "on-scroll-down": "FocusColumnRight" // in graphical mode, don't configure click actions here—they're handled by the module above } } }