# Your niri config.kdl, translated for macOS

Source: https://ribbonformac.com/niri-config-macos  
Updated: 2026-10-22

No Mac app reads `config.kdl`, but most of niri's `layout` and `input` options have a direct twin in Ribbon's settings window. Below, each option sits next to the Ribbon setting that does the same job, with an honest note wherever macOS has nothing to offer.

## How Ribbon's settings are organised

[niri](https://github.com/niri-wm/niri) keeps everything in one KDL file that reloads when you save it. Ribbon keeps everything in a settings window, and changes apply as soon as you flip a switch. The pages you'll use are:

- **Configuration:** gaps, animation, centring, width presets, mouse and trackpad, focus border, window rules.
- **Shortcuts:** every action, rebindable, with several chords allowed per action. Covered in [niri keybindings on Mac](https://ribbonformac.com/niri-keybindings-mac).
- **Mac Setup:** checks the macOS settings that would get in the way.

If you haven't installed Ribbon yet, the [setup guide](https://ribbonformac.com/setup) covers the permission and trackpad settings first.

## layout {}

### gaps

```kdl
layout {
    gaps 16
}
```

Ribbon: **Gap between windows**, in pixels. The default is 8. The same gap is used between windows and at the screen edges, so `gaps 16` becomes 16 in Ribbon.

### center-focused-column and always-center-single-column

```kdl
layout {
    center-focused-column "on-overflow"
    always-center-single-column
}
```

Ribbon: **Centre the focused column**, with three choices that match niri's word for word: *Never*, *On overflow* and *Always*. niri defaults to `"never"`; Ribbon defaults to *On overflow*, so set it to *Never* if you want niri's stock behaviour.

There's no separate switch for `always-center-single-column`. You can centre any column on demand with <kbd>⌃⌥C</kbd>, which is niri's `Mod+C`.

### preset-column-widths

```kdl
layout {
    preset-column-widths {
        proportion 0.33333
        proportion 0.5
        proportion 0.66667
    }
}
```

Ribbon: **Column width presets**, edited as percentages. The defaults are 25, 33, 50, 66, 75 and 100%. Delete the ones you don't use to get niri's three-step cycle. <kbd>⌃⌥R</kbd> cycles forward like `Mod+R`. A **Width presets wrap around** toggle decides whether the cycle loops back to the first preset. Fixed pixel widths (`fixed 1200`) have no equivalent; presets are proportions only.

`preset-window-heights` has no twin. In a stack you change heights step by step with <kbd>⌃⌥⇧=</kbd> and <kbd>⌃⌥⇧-</kbd>, and <kbd>⌃⌥0</kbd> makes them equal again.

### default-column-width and default-column-display

```kdl
layout {
    default-column-width { proportion 0.5; }
    default-column-display "tabbed"
}
```

Ribbon has no setting for the width a new column opens at, and columns don't open tabbed by default. Press <kbd>⌃⌥R</kbd> after a window opens to pick a width, and <kbd>⌃⌥⇧T</kbd> to turn a column into tabs.

### focus-ring and border

```kdl
layout {
    focus-ring {
        width 4
        active-color "#7fc8ff"
        inactive-color "#505050"
    }
}
```

Ribbon: **Focus border**. Turn it on or off, set the width, and pick a colour, with a separate colour for Dark Mode. There are no gradients and no inactive colour. The nearest thing to an inactive colour is **Dim inactive windows**, which darkens every unfocused window by 0 to 100%.

niri's `border` (drawn around every window, shrinking it to make room) has no equivalent. Ribbon only marks the focused window.

### struts and shadow

```kdl
layout {
    struts {
        left 64
        right 64
    }
}
```

Neither `struts` nor `shadow` has a direct twin. Ribbon's gap applies evenly at every edge, and there's no setting to keep a slice of the neighbouring window peeking in. macOS draws its own window shadows, and window managers can't change them through the Accessibility API.

## input {}

```kdl
input {
    focus-follows-mouse max-scroll-amount="0%"
    warp-mouse-to-focus
    touchpad {
        tap
        natural-scroll
    }
}
```

- `focus-follows-mouse` → **Focus follows mouse** (off by default). There's no `max-scroll-amount` limit.
- `warp-mouse-to-focus` → **Mouse follows focus** (off by default).
- `touchpad { tap; natural-scroll; ... }` → macOS System Settings → Trackpad. Ribbon doesn't override it.
- `keyboard { xkb { ... } }` → macOS System Settings → Keyboard. Ribbon's shortcut recorder works with any layout.

niri scrolls the view with a three-finger swipe out of the box. Ribbon does too, and its options sit under **Swipe fingers** (Off, 3 or 4, default 3), with **Natural direction**, **Continuous swipe** (let the strip scroll past the last window) and **Sensitivity**. For the swipe to reach Ribbon, macOS's "Swipe between full-screen applications" must not be on three fingers. The [setup guide](https://ribbonformac.com/setup) shows where to change it.

niri's `Mod+WheelScrollRight/Left` becomes Ribbon's **Scroll-wheel modifier**: hold <kbd>⌥</kbd> (or ⌘, ⌃ or fn) and scroll sideways to slide the strip.

## window-rule {}

```kdl
window-rule {
    match app-id=r#"firefox$"# title="^Picture-in-Picture$"
    open-floating true
}
```

Ribbon: **Window rules**. Pick a running app and it always floats. Calculator and System Settings float by default, and dialogs and fixed-size windows float on their own. Rules match whole apps, not titles, and there's no regex. The other rule properties, such as `open-on-output`, `open-on-workspace`, `open-maximized`, a per-app `default-column-width`, `block-out-from` and `geometry-corner-radius`, have no equivalent.

## output, animations and workspaces

```kdl
output "eDP-1" {
    scale 2
    position x=1280 y=0
}
animations {
    slowdown 2.0
}
```

- **output:** resolution, scale, rotation and position belong to macOS. Use System Settings → Displays. Ribbon gives every display its own strip automatically.
- **animations:** Ribbon has one **Animation speed** slider for its spring (default 14; 0 turns it off, like `animations { off }`). Lower values feel slower, so it plays the role of `slowdown`. There are no per-animation springs or easing curves. **Animate size changes too** is off by default, so windows slide but snap to a new size.
- **Workspaces:** Ribbon has none of its own. Each macOS Space on each display gets its own strip. Use Mission Control to add Spaces, and turn on "Displays have separate Spaces" and off "Automatically rearrange Spaces"; Mac Setup checks both.

## The full table

| niri option | Ribbon equivalent |
| --- | --- |
| `gaps` | Gap between windows |
| `center-focused-column` | Centre the focused column: Never / On overflow / Always |
| `always-center-single-column` | No equivalent (<kbd>⌃⌥C</kbd> on demand) |
| `preset-column-widths` | Column width presets (proportions only) |
| `preset-window-heights` | No equivalent (step resize in a stack) |
| `default-column-width` | No equivalent |
| `default-column-display` | No equivalent (<kbd>⌃⌥⇧T</kbd> per column) |
| `focus-ring` | Focus border (width, colour, Dark Mode colour) |
| `focus-ring` inactive colour | Dim inactive windows (closest) |
| `border` | No equivalent |
| `struts` | No equivalent |
| `shadow` | No equivalent (macOS draws shadows) |
| `focus-follows-mouse` | Focus follows mouse |
| `warp-mouse-to-focus` | Mouse follows focus |
| `touchpad`, `keyboard` | macOS System Settings |
| Touchpad swipe gesture | Swipe fingers, Natural direction, Sensitivity |
| `window-rule` + `open-floating` | Window rules (per app) |
| Other window-rule properties | No equivalent |
| `output` | macOS Displays settings |
| `animations` | Animation speed (one spring for everything) |
| Workspaces | macOS Spaces, one strip each |
| `binds` | Shortcuts page |
| Live reload | Settings apply instantly |

Two things Ribbon has that niri's config doesn't: **Restore the layout after a restart**, and an **Advanced** field where power users can append raw engine TOML in [Paneru](https://github.com/karinushka/paneru)'s syntax. Most people never need the second one.

## Before you buy

If the gaps, presets and centring above cover what your `config.kdl` did, you'll feel at home. If you rely on struts, per-app widths or niri's workspaces, look at the free options in [niri for Mac](https://ribbonformac.com/niri-for-mac) and [Ribbon vs OmniWM](https://ribbonformac.com/ribbon-vs-omniwm) too. Try the strip in the [live demo](https://ribbonformac.com/#demo), then [buy Ribbon](https://ribbonformac.com/buy) if it fits.

## FAQ

### Can Ribbon import my niri config.kdl?

No. Ribbon has no KDL importer. Most layout options take a minute to copy across by hand using the table above.

### Does Ribbon have center-focused-column?

Yes. "Centre the focused column" offers Never, On overflow and Always, the same three choices as niri. Ribbon's default is On overflow.

### Can I set fixed pixel column widths like niri's fixed option?

No. Ribbon's width presets are proportions of the screen. You can add, remove and edit them, but not in pixels.

### Is there an equivalent of niri's struts?

No. Ribbon uses one gap value between windows and at the screen edges, with no extra outer margins.

### Does Ribbon have a config file I can keep in my dotfiles?

Not in the niri sense. Settings live in the app's settings window. Power users can append raw engine TOML in the Advanced field, but there's no full text config.

## Keep reading
- [Niri for Mac](https://ribbonformac.com/niri-for-mac) — Niri itself is Linux-only. Five ways to get its scrolling strip on macOS.
- [Niri keybindings on Mac](https://ribbonformac.com/niri-keybindings-mac) — Each default niri bind next to its Ribbon shortcut, and the ones with no Mac twin.
- [Setup guide](https://ribbonformac.com/setup) — Install, Accessibility, licence key, and the macOS settings the swipe needs.
- [Ribbon vs OmniWM](https://ribbonformac.com/ribbon-vs-omniwm) — Free and Tahoe-only vs paid and macOS 13+. Spaces, gestures and setup compared.
