MCPcopy Index your code
hub / github.com/calico32/waybar-niri-windows

github.com/calico32/waybar-niri-windows @v2.3.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v2.3.1 ↗ · + Follow
139 symbols 293 edges 15 files 37 documented · 27%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

niri-windows module for Waybar

This is a module for Waybar that displays a window minimap for the current niri workspace.

Image of the module Image of the module in text mode

[!IMPORTANT] niri ≥ v25.08 is required (for the window locations in IPC messages to be available).

Installation

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.

From source

If you'd like to build from source (or if you're on a different platform):

  1. Install GTK 3 + development headers (apt install libgtk-3-dev, pacman -S gtk3, etc.).
  2. Clone this repository.
  3. Run make to produce waybar-niri-windows.so. This might take a while (thanks to cgo).

Move the library anywhere permanent, e.g. ~/.config/waybar.

Configuration

Add a CFFI module to your Waybar config:

{
  "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
    }
  }
}

Styling

Use these selectors in your CSS to style the module.

Graphical mode

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 (see rules in 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-child to style the window when it is the only window in a column.
  • Add .urgent to style windows marked as urgent.

Containers:

  • .cffi-niri-windows .column: column of tiled windows
  • .cffi-niri-windows .floating: floating window view
  • Add :active to 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-child to 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-borders to the total height (in pixels) of the top and bottom border on .column
  • Set floating-borders to the total height (in pixels) of the top and bottom border on .floating

For example, for the following CSS:

```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;
}

Contributing

Contributions are welcome! If you find a bug or have a feature request, please open an issue or PR.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Extension points exported contracts — how you extend this code

Event (Interface)
(no doc) [16 implementers]
niri/niri_event.go
Numeric (Interface)
Numeric is a type constraint for numeric types.
niri/niri_types.go

Core symbols most depended-on inside this repo

Errorf
called by 27
log/log.go
Errorf
called by 23
log/log.go
Tracef
called by 16
log/log.go
Warnf
called by 10
log/log.go
Debugf
called by 9
log/log.go
GetInstance
called by 5
lib/state/state.go
printf
called by 5
log/log.go
safeDestroy
called by 3
module/module.go

Shape

Method 70
Struct 33
Function 27
TypeAlias 6
Interface 2
Class 1

Languages

Go99%
C++1%

Modules by API surface

niri/niri_event.go38 symbols
module/module.go22 symbols
log/log.go18 symbols
niri/niri_types.go11 symbols
module/config.go11 symbols
lib/state/state.go11 symbols
niri/niri_state.go8 symbols
lib/waybar_cffi_module.go8 symbols
niri/niri_ipc.go5 symbols
jsonc/jsonc.go3 symbols
main/main.go1 symbols
log/trace.go1 symbols

For agents

$ claude mcp add waybar-niri-windows \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page