An application switcher for niri, with support for workspaces and automatic light and dark mode.

Screencast.from.2025-05-15.00-14-58.mp4
To install the development version use:
pipx install --system-site-packages git+https://github.com/isaksamsten/niriswitcher.gitappend @tag, where tag is a tagged version number, e.g., 0.1.2, to the url
to install a release version.
Note
You must use --system-site-packages to avoid having to build pygobjects from source.
You also need to install the following system packages:
python3-gobjectgtk4-layer-shelllibadwaita
These are the names of the packages on Fedora, but I'm sure they are distributed for other distributions.
For users of Fedora, I maintain a COPR built for every release.
dnf copr enable isaksamsten/niriswitcher
dnf install niriswitcherniriswitcher is now available in the AUR. You can use any of your AUR helpers to install.
yay -S niriswitcherA Nix package for niriswitcher is available. Add the following to your configuration:
environment.systemPackages = with pkgs; [
niriswitcher
];niriswitcher is also available on NUR. Nix users can setup NUR by following this guide, but a short summary is provided below.
Note
NUR packages are built against Nixpkgs unstable.
For a simple flake based setup:
- Add NUR to your flake inputs
nur = { url = "github:nix-community/NUR"; inputs.nixpkgs.follows = "nixpkgs"; };
- Add the NUR overlay to your NixOS configuration (optional)
{ nixpkgs.overlays = [ nur.overlays.default ]; }
- To your packages list, add:
pkgs.nur.repos.Vortriz.niriswitcherif you added the overlaynur.legacyPackages."${pkgs.system}".repos.Vortriz.niriswitcherif you did not use the overlay
- Add NUR to your flake inputs
nur = { url = "github:nix-community/NUR"; inputs.nixpkgs.follows = "nixpkgs"; };
- Add
nur.legacyPackages."${pkgs.system}".repos.Vortriz.homeManagerModules.niriswitcherto yourimportsinhome.nix - Set
programs.niriswitcher.enable = true. Optionally, you can configure niriswitcher withprograms.niriswitcher.config(forconfig.toml) andprograms.niriswitcher.style(forstyle.css). The exact configuration values for these options are detailed in the section ahead.
For more information on using the module itself, check out the source file.
First we need to execute the niriswitcher application. The program is
deamonized and waits for USR1 signal to be shown. In the niri
config.kdl-file we first start niriswitcher at startup:
spawn-at-startup "niriswitcher"Note
Replace niriswitcher with ~/.local/bin/niriswitcher if you installed using pipx and the binary is not on $PATH
Next, we add keybindings to send the USR1 signal to niriswitcher on Alt+Tab and Alt+Shift+Tab.
bind {
Alt+Tab repeat=false { spawn "pkill" "-USR1" "niriswitcher"; }
Alt+Shift+Tab repeat=false { spawn "pkill" "-USR1" "niriswitcher"; }
}Note
Remember to synchronize the keybinding set in Niri, with the one set for niriswitcher. For example, if you use Mod+Tab to trigger niriswitcher ensure that modifier=Mod in config.toml (see below).
By default, niriswitcher uses the following keybindings:
-
Alt+Tabselect next application -
Alt+Shift+Tabselect previous application -
Alt+Esccloseniriswitcherand do not focus -
Alt+qto close the selected application -
Alt+`to show the next workspace -
Alt+Shift+`to show the previous workspace -
Release
Altto focus to currently selected application and closeniriswitcher
The default mappings and modifier key can be configured in the config.toml file.
niriswitcher has a few options that we can change
- The icon size
- The maximum width of the switcher window (before scrolling)
- The scroll animation speed (set to 0 to disable)
- If single click change application without hiding the switcher (double clicking an application changes focus and hides the switcher)
- If
separate_workspacesis set to true, the application switcher will show windows from the current workspace and enable workspace navigation. Iffalse, the switcher will show applications from all workspaces and disable workspace navigation.
The configuration file is a simple .toml-file in
$XDG_CONFIG_HOME/niriswitcher/config.toml. This is the default config:
separate_workspaces = true
double_click_to_hide = false
center_on_focus = false
[appearance]
icon_size = 128
max_width = 800
min_width = 600
system_theme = "dark" # auto or light
[appearance.animation.hide]
duration = 200
easing = "ease-out-cubic"
[appearance.animation.resize]
duration = 200
easing = "ease-in-out-cubic"
[appearance.animation.workspace]
duration = 200
transition = "slide"
[appearance.animation.switch]
duration = 200
easing = "ease-out-cubic"
[keys]
modifier = "Alt_L"
[keys.switch]
next = "Tab"
prev = "Shift+Tab"
[keys.window]
close = "q"
abort = "Escape"
[keys.workspace]
next = "grave"
prev = "Shift+asciitilde"The modifier key keeps niriswitcher active (once released, niriswitcher
is closed and the selected application activated). It's implicitly part of the
other key mappings, so in the default configuration Alt+Tab moves to the next
application, Alt+Shift+Tab to the previous, and so forth. To change the
modifier key, select another key among: Alt, Super, Shift, or Control.
The other bindings are expressed as bindings, e.g.,
Shift+Tab or Control+j. Note that modifier is implicit in all
bindings.
Warning
When using Mod or Super as the modifier, niri seems to inhibit
Super+Escape reaching niriswitcher. Please select another binding for
abort.
We can also change/improve the style of the switcher using a style.css file
in the same configuration directory.
The following CSS can be styled:
#niriswitcher: the main window#application-title: the title (above the icons)#workspace-name: the workspace name (above the icons)#workspaces: the workspace area.workspace: a workspace in the workspace area (contains the icons)#workspace-indicators: the workspace indicator area.workspace-indicator: the workspace indicator.workspace-indicator.selected: the currently selected workspace indicator.application-icon: the icon.application-name: the application name (below the icon).application-strip: the area behind the icons (inside the scroll).application: the application area (name + icon).application.selected: the currently selected application (by keyboard or mouse)
Example (see ./src/niriswitcher/resources/style.css for the default config):
To make the application title and selected application name red.
.application-title {
color: red;
}
.application.selected .application-name {
color: red;
}To make the application name visible for non-selected applications (but dimmed):
.application-name {
opacity: 1;
color: rgba(255, 255, 255, 0.6);
}
.application.selected .application-name {
color: rgba(255, 255, 255, 1);
}niriswitcher also uses style-dark.css to style the application in dark mode.
If you only want to change the colors, you only need to override the colors
(these are the default colors in light mode, see style-dark.css in the
resources folder for default colors in dark mode):
:root {
--bg-color: rgba(229, 229, 234, 1);
--label-color: rgb(58, 58, 60);
--alternate-label-color: rgb(44, 44, 46);
--dim-label-color: rgb(142, 142, 147);
--border-color: rgba(199, 199, 204, 0.95);
--highlight-color: rgba(209, 209, 214, 0.95);
--urgency-color: rgb(255, 69, 58);
--indicator-focus-color: rgba(10, 132, 255, 0.95);
--indicator-color: rgba(209, 209, 214, 0.95);
}Input on the default design is welcome
If Alt (the modifier key) is released before niriswitcher has been fully initialized, the window will not close unless the modifier key is pressed and released (to change to the next application) or Esc is pressed to close the window.

