wlr-chooser 1.2.0

Graphical window & screen picker for wlroots screencast portals (xdg-desktop-portal-wlr)
wlr-chooser-1.2.0 is not a library.

wlr-chooser

CI crates.io License: MIT OR Apache-2.0

Part of the wlr-utils workspace.

A graphical window & screen picker for wlroots screencast portals (xdg-desktop-portal-wlr) — a rofi-like overlay with live thumbnails.

When an application requests screen sharing (e.g. Firefox getDisplayMedia, a video call), the wlroots portal asks an external chooser which source to share. wlr-chooser replaces the text-only chooser with a grid of live previews — pick a window or a monitor with a click.

wlr-chooser overlay

Why

  • Real overlay, like rofi: a wlr-layer-shell surface that grabs the keyboard, dims the desktop behind a centred card, and cancels on click-outside or Escape.
  • Captures any window — including ones on other workspaces/outputs — via the compositor's native toplevel capture (ext-image-copy-capture-v1), not screen-region grabs. Off-screen windows are real previews, not icons.
  • Live thumbnails that actually move: previews refresh in real time, and on the GPU path (default) the dma-buf is imported straight as a texture — no read-back, near-zero CPU. Falls back to CPU shm where the GPU path isn't usable.
  • Doubles as a window switcher (--switch): pick a window to focus it.
  • Native Wayland (no XWayland), built in Rust with egui; opens near-instantly.
  • Themeable (8 ready palettes incl. Catppuccin), localised (13 languages, with CJK font fallback), and a configurable thumbnail grid.

Requirements

  • A wlroots-based compositor exposing ext-image-copy-capture-v1, ext-image-capture-source-v1, ext-foreign-toplevel-list-v1 and wlr-layer-shell (Sway ≥ 1.12 / wlroots ≥ 0.20).
  • xdg-desktop-portal-wlr ≥ 0.8 (for the screencast chooser use).
  • For the GPU path (default): a working EGL/GLES driver and libgbm (ships with Mesa). It falls back to CPU automatically if unavailable.
  • For the --switch window-switcher: zwlr-foreign-toplevel-management-v1.

Install

From a package

  • crates.io: cargo install wlr-chooser.
  • Debian/Ubuntu: download the .deb from the latest release and sudo apt install ./wlr-chooser_*.deb.
  • Arch (AUR): coming soon.

Prebuilt binary

Download the binary for your platform from the releases page, or run the installer script:

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/sjourdois/wlr-chooser/releases/latest/download/wlr-chooser-installer.sh | sh

From source

wlr-chooser lives in the wlr-utils Cargo workspace; build just this binary with -p:

cargo build --release -p wlr-chooser   # GPU path on by default; needs libgbm-dev
install -Dm755 target/release/wlr-chooser ~/.local/bin/wlr-chooser

The gpu feature (on by default) enables zero-copy dma-buf capture and needs libgbm-dev at build time (libgbm at runtime, from Mesa). For a pure-CPU build with no gbm dependency, use cargo build --release --no-default-features.

Set up the portal

Point the screencast chooser at the binary:

# ~/.config/xdg-desktop-portal-wlr/config
[screencast]
chooser_type=simple
chooser_cmd=wlr-chooser

Then restart the portal: systemctl --user restart xdg-desktop-portal-wlr.

Now any screen-share prompt opens wlr-chooser as a dimmed modal overlay on the focused output. You can pass options in chooser_cmd, e.g. chooser_cmd=wlr-chooser --windows --grid 4x3.

Options

-w, --windows          Show only windows
-o, --outputs          Show only screens          (alias: --screens)
    --both             Show both (default)
    --switch           Window switcher: focus the picked window (implies --windows)
    --layout <LAYOUT>  Switcher presentation: full (full-screen, default) | compact
    --include-system   Include windows with no app-id (system surfaces)
    --grid COLSxROWS   Fixed grid of that many thumbnails (e.g. 4x3)
-h, --help             Print help
-V, --version          Print version

In the overlay: type to filter, arrows to move, Enter/click to pick, Escape or click-outside to cancel, and the tab bar switches All / Windows / Screens.

Window switcher

wlr-chooser --switch turns the picker into a live alt-tab / exposé: a grid of live window thumbnails (updating in real time, even for windows on other workspaces); picking one focuses it instead of printing to stdout.

Two presentations via --layout:

  • full (default) — a full-screen, mission-control grid that dims the desktop.
  • compact — the centred rofi-like card.

Bind it in your compositor, e.g. Sway:

bindsym $mod+Tab  exec wlr-chooser --switch                  # full-screen
bindsym Alt+Tab   exec wlr-chooser --switch --layout compact # compact card

Only one switcher opens at a time (re-pressing the keybind is a no-op).

Looking for a floating live mirror? The companion tool wlr-pip keeps a picture-in-picture of a window always on top — see its README.

Output contract

wlr-chooser writes the selected source to stdout and exits 0:

Window: <foreign-toplevel-identifier>
Monitor: <output-name>

On cancel it writes nothing and exits non-zero.

Theming

Colours and fonts come from ~/.config/wlr-chooser/theme.toml ($XDG_CONFIG_HOME is honoured) with sensible dark defaults. Colour keys are #rrggbb / #rrggbbaa:

accent        = "#89b4fa"
screen-accent = "#74c7ec"   # outline for screens
window-accent = "#cba6f7"   # outline for windows
backdrop      = "#11111baa" # dimmed overlay

font      = "JetBrains Mono" # UI font family (via fontconfig)
# font-path = "/path/to/Font.ttf"
# cjk-font = "Noto Sans CJK JP"
font-size = 15.0

Screens are outlined in screen-accent, windows in window-accent, so the two can't be confused. Ready-made themes live in docs/themes/: Catppuccin (Mocha, Macchiato, Frappé, Latte), Nord, Gruvbox, Dracula, Tokyo Night. Symlink one so it tracks updates:

mkdir -p ~/.config/wlr-chooser
ln -sf "$PWD/docs/themes/catppuccin-mocha.toml" ~/.config/wlr-chooser/theme.toml

Localisation

The UI ships in 13 languages (English, French, German, Spanish, Italian, Brazilian Portuguese, Dutch, Polish, Russian, Ukrainian, Japanese, Korean, Simplified Chinese), translated with Fluent. It follows your desktop locale (LANG / LC_*) and falls back to English when no catalog matches. Override it any time with LANGUAGE:

LANGUAGE=ja wlr-chooser

Rendering CJK text needs a CJK font installed (e.g. Noto Sans CJK); one is auto-detected. New locales are welcome — copy crates/wlr-capture/i18n/en/wlr_capture.ftl.

Contributing

Bug reports, translations and patches welcome — see CONTRIBUTING.md. Please keep cargo fmt, cargo clippy and cargo test clean.

License

Licensed under either of Apache-2.0 or MIT at your option.