Skip to content

feat(minimap): add workspace window minimap module#817

Open
kiryl wants to merge 3 commits into
MalpenZibo:mainfrom
kiryl:feat/minimap
Open

feat(minimap): add workspace window minimap module#817
kiryl wants to merge 3 commits into
MalpenZibo:mainfrom
kiryl:feat/minimap

Conversation

@kiryl

@kiryl kiryl commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a Minimap module: a compact, scaled visualisation of the active
workspace's tiled window layout in the bar. Tiled windows are drawn by their
column/row index with proportional sizes; the focused window is highlighted and
urgent windows use the danger color. Opt-in — add "Minimap" to a module list
in your config.

2026-06-13T17:51:22

Behaviour

  • Niri: renders the tiled (scrolling-layout) windows as a column/row map.
  • Hyprland: the widget stays hidden — the compositor doesn't expose enough
    per-window layout info.
  • Floating windows have no grid position and aren't drawn (see Follow-up).

What's inside

Three commits:

  1. refactor(compositor): box state inside CompositorService — boxes the
    service state so ServiceEvent stays small.
  2. refactor(compositor): track per-window state in compositor abstraction
    adds a per-window record (CompositorWindow: workspace, focus/floating/urgent
    flags, tile grid index + size) to the generic compositor state, produced by
    the Niri backend (Hyprland leaves the window list empty for now).
  3. feat(minimap): add workspace window minimap module — the module itself: a
    single iced canvas renderer, wired into config/app, with a website docs
    entry.

Net: +333/-10 across 10 files; the module is ~250 lines.

Follow-up (not in this PR)

A spatial variant — drawing the on-screen viewport rectangle and placing
floating windows within it — needs the workspace scrolling view position,
which I've proposed for niri in niri-wm/niri#4147. A working implementation
built on that lives on my branch
kiryl/ashell@feat/minimap-scrolling-view-pos.
It's intentionally left out here so this PR builds against released niri-ipc
and works on any current niri; I'll follow up once the niri side lands.

kiryl added 2 commits June 13, 2026 15:46
CompositorService used to embed CompositorState by value, so every
ServiceEvent<CompositorService> variant carried ~280 bytes. Modules
that included ServiceEvent in their own Message enum (e.g.
window_title) had to box it themselves to keep clippy's
large_enum_variant lint happy — boilerplate scattered across consumers
for a problem that lives at the source.

Move the indirection into CompositorService itself: state is now
Box<CompositorState>. The handle stays ~16 bytes, ServiceEvent
becomes small, and consumers don't need to box anything. window_title
sheds its Box<ServiceEvent<...>> as a result.

App::Message is a top-level dispatcher whose variant size disparity
is intrinsic to its role (network/bluetooth service messages are
naturally big; unit variants are tiny). Box-ing every "big" sub-
message there would just push verbosity onto call sites without
runtime benefit, so it gets a documented allow(clippy::large_enum_variant).
Introduces a per-window record (CompositorWindow) carrying workspace
membership, focus/floating/urgent flags, and tile geometry (grid index
and size), plus a window list in the generic compositor state. The Niri
backend populates it from its event stream; the Hyprland backend leaves
the list empty for now (placeholder), so window-level features are
Niri-only until it's filled in.

No consumer yet — the new state intentionally warns as unread until the
minimap module is added.
A compact visualisation of the active workspace's tiled window layout in
the status bar. Tiled windows are laid out by their column/row index with
proportional sizes and scaled to fit; the focused window is highlighted
and urgent windows use the danger color.

Floating windows have no grid position, so they aren't rendered;
showing them is something to explore later, once niri exposes enough
information to place them.

Hyprland doesn't expose per-window layout, so the widget stays hidden
there.

Adds a `Minimap` module name to config; opt-in via the user's module
order list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant