Skip to content

Feature proposal: Live window thumbnails with text filter and hint-based selection #477

Description

@sim590

Context

This proposal addresses #26 (Live thumbnails — 16 upvotes, help wanted) and #424 (Live window preview) by introducing live window thumbnails with a new selection workflow.

Hyprland already supports ext-image-capture-source-v1 with per-toplevel capture and ext-image-copy-capture-v1 with damage notifications — all the building blocks are there for live window previews.

Proposed feature

A grid of live window thumbnails with a two-phase selection workflow:

Phase 1: Text filter (default)

When activated, the view displays all windows as live thumbnails in a grid. The user types text to filter windows by title, class, or workspace name. As windows are filtered out:

  • They disappear from the grid
  • The grid reorganizes dynamically
  • Remaining thumbnails grow larger, making visual identification progressively easier

This addresses a fundamental problem with exposé-style views: with many windows, thumbnails are too small to be useful. Filtering reduces the count and increases thumbnail size proportionally.

Phase 2: Hint selection (via TAB)

Pressing TAB overlays alphanumeric hint labels (j, k, l, f, d, s, ...) on each remaining window. The user presses the corresponding key to select the window instantly. TAB toggles between the two phases, allowing users to go back and refine their filter if needed.

How it compares to existing modes

Switch Overview This proposal
Activation Hold modifier + Tab to cycle Toggle (quick press) Toggle (quick press)
Display Linear window list with icons Downscaled workspace layout + launcher Grid of live window thumbnails
Selection Sequential (Tab, Tab...) Mouse click or arrow keys Text filter → alphanumeric hints
Live thumbnails No No Yes (ext-image-capture-source)
Integrated launcher No Yes See "Structural options" below

Configuration

# Suggested configuration keys (names TBD)
charorder = "jkluiopyhnmfdsatgvcewqzx1234567890"
auto_select_threshold = 0  # 0 = disabled; when ≤ N windows remain, 
                           # auto-switch to hint phase
filter_fields = ["title", "class", "workspace"]
case_sensitive = false

Technical approach

Live thumbnails via ext-image-capture-source-v1

This would be the first screen capture integration in hyprshell. The protocol enables:

  • Per-window capture (not just per-output) via ext-foreign-toplevel-image-capture-source-v1
  • DMA-BUF transfer (GPU-to-GPU, no CPU copy overhead)
  • Continuous updates with damage notifications (only re-render changed windows)

Captured buffers would be displayed as GdkTexture (via gdk::Texture::for_dmabuf() or gdk::MemoryTexture) in GTK4 widgets.

What gets reused (unchanged)

  • exec-lib/collect.rs — Hyprland IPC data collection
  • core-libClientData, HyprlandData types
  • windows-lib/data.rs — MRU sorting
  • windows-lib/icon.rs — icon resolution
  • exec-libswitch_client(), switch_workspace()
  • GTK4 + gtk4-layer-shell + Relm4 framework
  • CSS theming system

Structural options

I see two ways this could be integrated, and I'd like your input on which you'd prefer:

Option A: New separate mode (mosaic)

A third mode alongside Switch and Overview, following the existing pattern:

crates/windows-lib/src/
├── switch/     # existing, unchanged
├── overview/   # existing, unchanged
├── mosaic/     # NEW
│   ├── root.rs
│   ├── capture.rs
│   ├── grid.rs
│   ├── filter.rs
│   └── hints.rs
└── shared/

Configuration would add a [windows.mosaic] section. No launcher integration — the text input is exclusively for filtering open windows.

Pros:

  • Clean separation, no risk of breaking existing modes
  • Input field has a single, unambiguous purpose (window filtering)
  • Easier to develop incrementally

Cons:

  • Potentially seen as redundant with Overview

Option B: Extend Overview

Add live thumbnails and the filter/hint workflow as options within the existing Overview mode.

Pros:

  • No new mode to maintain
  • Users get thumbnails in an interface they already know

Cons:

  • Input field conflict: Overview's input currently drives the launcher (search apps, calculate, web search). The mosaic workflow uses the input field to filter open windows. These serve fundamentally different purposes. Possible solutions (prefix character, mode toggle key) each add friction to one of the two workflows.
  • The display logic differs substantially: Overview organizes by workspace (windows nested inside workspace containers), while the mosaic flattens all windows into a single grid regardless of workspace.
  • Risk of increased complexity in an already working component.

My preference

I lean toward Option A (new separate mode). The input field conflict in Option B feels like a fundamental UX compromise that would add friction to one of the two workflows regardless of the solution chosen (prefix, toggle key, etc.). A separate mode keeps both experiences clean: Overview remains a workspace viewer with launcher, and the mosaic mode becomes a dedicated window finder.

That said, I'm open to Option B if you feel it fits better with the project's direction.

Questions

  1. Which structural approach do you prefer (new mode vs. extending Overview)?
  2. If extending Overview: how should the input field conflict be handled?
  3. Any preferences on where the capture protocol integration should live? (separate crate? inside exec-lib?)
  4. I have some experience with Rust (hypr-layout, contributions to Reedline/Nushell), but I'm relatively new to the hyprshell codebase — I'd welcome guidance on project-specific conventions and architecture decisions.

I'm happy to start with a proof-of-concept PR on whichever approach you prefer. Looking forward to your thoughts!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions