feat: floating panes in the minimap, selectable when hidden (#110) - #112
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds configurable floating-pane support to the minimap, including hidden-float chips, visible overlays, click-to-reveal focus, visible-float traversal, projection helpers, rendering integration, tests, examples, and documentation. ChangesFloating minimap
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…llij float-manifest behavior (#110)
…#110) paint::bar / minimap::render gained a floating-layer parameter (#110); pass the no-float value (`&BTreeMap::new()` / `FloatLayer::None`) from every example so `cargo build --examples` stays green. Also repair render_close_button's `Close` variants, which #94 turned into color-carrying tuples — an incidental pre-existing break surfaced by rebuilding the examples.
A dependency-free render sample mirroring the other examples/render_*: three tabs showing the floating-pane states side by side — a plain tab, the active tab with a visible-float overlay, and a tab with hidden-float corner chips. Drives the real paint::bar → assemble → render path, so the preview can't drift from what ships.
There was a problem hiding this comment.
Pull request overview
Adds first-class floating-pane support to the tab minimap so users can see floats and interact with them (including selecting hidden-layer floats via chips), while keeping the renderer dependency-free and maintaining the “pure projection of zellij state” approach.
Changes:
- Introduces a new floating-pane layer model (
floating.rs) and config key (floating = hybrid|off) with tests. - Extends minimap rendering + hit-testing to support hidden-float chips and visible-float overlays (float-priority click routing).
- Wires the new layer through render assembly (
paint/tab_block/lib) and updates examples + docs accordingly.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/tab_block.rs | Threads per-tab float layer into grid-rung minimap assembly; adds chip rendering test. |
| src/router.rs | Adds float chip/overlay hit-testing and prioritizes floats over tiled panes on click. |
| src/projection.rs | Adds floating-pane filtering + projection (is_floating_terminal, project_floating). |
| src/paint.rs | Passes per-tab floating specs into tab block rendering. |
| src/minimap.rs | Implements hidden-float chips and visible-float overlay rendering + hit-testing. |
| src/lib.rs | Builds per-frame floating specs, records float geometry for routing, and dispatches reveal+focus. |
| src/floating.rs | New dependency-free module for floating mode/config + chip layout/hit-test primitives. |
| src/config.rs | Adds floating config key parsing with default hybrid and tests. |
| README.md | Documents the new floating configuration option and behavior. |
| examples/render_top_label.rs | Updates example call signature for new paint API. |
| examples/render_perspective.rs | Updates example call signature for new paint API. |
| examples/render_palette.rs | Updates example call signature for new paint API. |
| examples/render_new_tab_button.rs | Updates example call signature for new paint API. |
| examples/render_gradient.rs | Updates example call signature for new minimap render API. |
| examples/render_floating.rs | New example showcasing floating overlay + hidden chips side-by-side. |
| examples/render_demo.rs | Updates example call signature for new paint API. |
| examples/render_close_button.rs | Updates close-button example to match updated close color tuple variants + new paint API. |
| examples/render_active_cue.rs | Updates example call signature for new paint API. |
| docs/superpowers/specs/2026-07-12-floating-panes-in-minimap-design.md | Adds detailed design spec for floating panes rendering/interaction. |
| docs/superpowers/plans/2026-07-12-floating-panes-in-minimap.md | Adds full implementation plan and testing approach for #110. |
| .claude/rules/zellij-plugin-development.md | Documents verified zellij behavior re: hidden floats remaining in the manifest. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let px0 = map(p.x, minx, bw, pw).min(pw); | ||
| let px1 = match map(p.x + p.w, minx, bw, pw).min(pw) { | ||
| hi if hi <= px0 => (px0 + 1).min(pw), | ||
| hi => hi, | ||
| }; |
There was a problem hiding this comment.
Fixed in c9aa323 — project_floats_into now clamps the left edge to pw - 1, so a float flush against the tiled bbox's right edge maps to a non-empty one-column strip instead of an empty pw..pw box that paints nothing. Added project_floats_into_keeps_a_right_edge_float_visible.
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/minimap.rs (1)
1072-1196: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winReserve hidden-chip cells before label placement.
chip_layoutis created after tiled labels. A bottom-row wide label can overlap a chip’s glyph/continuation cells, desynchronizing cursor width and corrupting the row. Build the chip layout before creatingoverlayentries and exclude its occupied columns from bottom-row labels.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/minimap.rs` around lines 1072 - 1196, Build the hidden-float chip layout via chip_cells before constructing overlay entries, then reserve every occupied chip column, including wide-glyph continuation cells, when placing bottom-row labels. Update the label-placement logic to skip those reserved columns so labels cannot overlap chips while preserving correct cursor-width accounting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/specs/2026-07-12-floating-panes-in-minimap-design.md`:
- Around line 84-93: Reconcile the §6.1 focused-float focus-ring requirement
with Task 10: either update §6.1 to explicitly defer the focus ring in v1 while
retaining the plain border, or add a tracked follow-up item for implementing the
active-tab focused-float ring per `#59`. Ensure the chosen plan does not leave the
requirement implicitly unresolved.
- Around line 70-72: Update the sentence ending with “したがって:” in the
floating-pane visibility explanation to use natural Japanese punctuation and
introduce the following table, such as “したがって、以下のようになる:”.
In `@src/lib.rs`:
- Around line 526-559: Update the focused-pane anchor logic used by scroll_panes
so focused_pane_id accepts visible floating terminals in addition to tiled
terminals. Use the owning tab’s are_floating_panes_visible state when
determining eligibility, while continuing to exclude hidden floats and unrelated
panes. Add or update a test covering scrolling when focus starts on a visible
floating pane.
In `@src/minimap.rs`:
- Around line 848-872: Update the float border computation near float_ring to
derive edges from final ownership in float_grid rather than iterating every
float_bounds entry. For each occupied cell, use its owning float’s bounds to
mark only that owner’s border, preserving last-wins behavior and preventing
earlier float rings from appearing inside later floats.
- Around line 1230-1247: Update the tiled-label placement branch to skip cells
occupied by visible floats, including wide-glyph continuation cells, so labels
remain beneath floats before float_px is evaluated. Use the existing float-grid
visibility data for reservation, and add an overlay test covering LabelMode::All
to verify tiled labels do not appear over a visible float.
In `@src/router.rs`:
- Around line 72-79: Update the hidden-float selection flow around
chip_index_at_cell so PlusK cells expose each omitted hidden float individually
instead of falling through. Add a picker, paging, or equivalent intent that maps
the overflow cell to every hidden-float ID, while preserving direct selection
for regular float cells and ensuring all overflow IDs remain reachable.
---
Outside diff comments:
In `@src/minimap.rs`:
- Around line 1072-1196: Build the hidden-float chip layout via chip_cells
before constructing overlay entries, then reserve every occupied chip column,
including wide-glyph continuation cells, when placing bottom-row labels. Update
the label-placement logic to skip those reserved columns so labels cannot
overlap chips while preserving correct cursor-width accounting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 68f984c1-f4ab-4bd4-a25a-fa273377fd1f
⛔ Files ignored due to path filters (1)
assets/floating-demo.pngis excluded by!**/*.png
📒 Files selected for processing (21)
.claude/rules/zellij-plugin-development.mdREADME.mddocs/superpowers/plans/2026-07-12-floating-panes-in-minimap.mddocs/superpowers/specs/2026-07-12-floating-panes-in-minimap-design.mdexamples/render_active_cue.rsexamples/render_close_button.rsexamples/render_demo.rsexamples/render_floating.rsexamples/render_gradient.rsexamples/render_new_tab_button.rsexamples/render_palette.rsexamples/render_perspective.rsexamples/render_top_label.rssrc/config.rssrc/floating.rssrc/lib.rssrc/minimap.rssrc/paint.rssrc/projection.rssrc/router.rssrc/tab_block.rs
| let index = crate::floating::chip_index_at_cell( | ||
| geom.width, | ||
| geom.rows, | ||
| geom.hidden_floats.len(), | ||
| col, | ||
| row, | ||
| )?; | ||
| geom.hidden_floats.get(index).copied() |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Make overflow hidden floats individually reachable.
chip_index_at_cell ignores PlusK, while overflow layout exposes only the first cols - 1 float ids. Clicking +k falls through, so every omitted hidden float has no focus/reveal path. Add a picker, paging, or equivalent intent that exposes all overflow ids.
Also applies to: 191-198
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/router.rs` around lines 72 - 79, Update the hidden-float selection flow
around chip_index_at_cell so PlusK cells expose each omitted hidden float
individually instead of falling through. Add a picker, paging, or equivalent
intent that maps the overflow cell to every hidden-float ID, while preserving
direct selection for regular float cells and ensuring all overflow IDs remain
reachable.
There was a problem hiding this comment.
Good catch — the floats folded into +k are visible as a count but not yet reachable from the bar. Making them reachable (picker/paging) is a distinct feature, so I split it into #113 rather than widen this PR. This PR does fix the related wart that clicking ⋯ mis-focused the pane beneath it — it's now a no-op (45f2c64).
There was a problem hiding this comment.
@GeneralD Thanks for the context — splitting the "make overflow floats individually reachable" work into #113 makes sense, since a picker/paging mechanism is a meaningfully separate feature from this PR's core hidden/visible float rendering and hit-testing.
The fix for the +k marker no-op (verified in chip_marker_at / route_click in src/router.rs, commit 45f2c64) does close the related correctness gap — clicking the overflow marker no longer mis-focuses the tiled pane underneath it. Good call keeping that fix in this PR while deferring the broader reachability feature to #113.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb458200a0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| order.extend( | ||
| projection::project_floating(p) | ||
| .into_iter() | ||
| .map(|f| f.id as u32), |
There was a problem hiding this comment.
Include focused floats in the pane-scroll anchor
When scroll = pane and focus is on a visible floating pane, these newly appended floating ids can never be used as the current anchor: scroll_panes still calls focused_pane_id(), which filters the active tab through projection::is_tiled_terminal and returns None for a focused float. After a user clicks or otherwise focuses a visible float, wheel navigation therefore hits the guard and does nothing instead of advancing to the next pane; the current-pane lookup needs to include the same visible floats that are added to this traversal.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 4e5eaf4 — focused_pane_id now accepts a focused floating terminal while its layer is visible (mirroring pane_focus_order, which appends visible floats), so the wheel has an anchor to step from. Added focused_pane_id_resolves_a_focused_visible_float plus the hidden-layer negative case.
| let top = float_px(2 * tr) | ||
| .or_else(|| pixel_color(&grid, &ring, panes, palette, &sweeps, pw, c, 2 * tr)); | ||
| let bottom = float_px(2 * tr + 1) | ||
| .or_else(|| pixel_color(&grid, &ring, panes, palette, &sweeps, pw, c, 2 * tr + 1)); |
There was a problem hiding this comment.
Paint visible floats above tiled labels
When a visible floating pane overlaps a tiled pane title, the label branch above this block emits the tiled label and continues before the float overlay is considered. That leaves the underlying tiled title painted over the float while float_pane_at_cell routes clicks in the same cell to the floating pane, so the visual target and click target diverge; the float layer needs to suppress or overpaint tiled labels inside its footprint.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed earlier in this PR (occlusion + drop-shadow, e6a842a onward) — the visible float now occludes the tiled labels it covers, so a label no longer reads as sitting on top of the float; a cut label gets a … cue.
| if tr == chip_row { | ||
| if let Some((_, chip)) = chip_layout.iter().find(|(cc, _)| *cc == c) { |
There was a problem hiding this comment.
Reserve chip cells before laying out labels
When a bottom-row pane label contains a wide glyph whose leading or continuation cell overlaps a hidden-float chip, this chip branch emits a one-column glyph before the later OverlayCell::Continuation handling runs. A CJK title in a bottom pane can therefore either skip a continuation after only a one-cell chip or emit the chip after a wide glyph already advanced over its cell, pushing the row width and click alignment out of sync; chip cells need to be reserved or cleared during label layout rather than overwritten during emission.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in c9aa323 — a bottom-row label's right_bound is now capped at the leftmost hidden-float chip column, mirroring the top-row close-glyph cap, so a wide glyph can't straddle and overrun the corner chips.
| if let Some(id) = float_chip_at(tab_layout, tab_panes, row, column) | ||
| .or_else(|| float_overlay_at(tab_layout, tab_panes, row, column)) |
There was a problem hiding this comment.
Consume overflow chip clicks before pane hits
When a hidden layer has more floats than fit in the tab width, the drawn ⋯ overflow marker is deliberately not selectable, but float_chip_at returns None for that cell and this routing then falls through to pane_at. Clicking the marker therefore focuses the tiled pane underneath instead of acting as the documented no-op overflow affordance; the chip/marker layer needs to consume marker cells before tiled-pane hit testing.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 45f2c64 — clicking the decorative +k marker is now consumed as ClickIntent::NoOp (via chip_marker_at) instead of falling through to focus the tiled pane beneath it. Added route_click_treats_the_overflow_marker_as_a_no_op.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/minimap.rs (1)
944-954: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDerive float borders from final grid ownership.
float_gridis last-wins for overlapping floats, but this loop marks ring pixels from everyfloat_boundsbox. Where an earlier float's edge falls inside a later float,float_px(Line 1366-1372) reads the later float as the cell owner yetfloat_ringis still set, so it paints the later float'sring_forshade at an interior pixel — a stray border line inside the float. Compute ring status from the finalfloat_gridowner and that owner's bounds.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/minimap.rs` around lines 944 - 954, Update the float_ring construction to derive each pixel’s border status from its final owner in float_grid, rather than marking edges from every float_bounds entry. For each owned pixel, use the owning float’s bounds to determine whether it is on that float’s border, keeping float_px consistent with the last-wins ownership model and avoiding interior stray borders.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/specs/2026-07-12-float-label-occlusion-design.md`:
- Around line 47-52: Update the wide-glyph edge-case section to state that any
covered column causes the entire wide glyph, including its Continuation, to
become Fill; never convert it to Ellipsis, which is limited to width-1 glyphs.
Revise the example API around the label-resolution description to match
resolve_label_plan’s batch signature and LabelDraw variants: Char, Ellipsis,
Skip, and Fill, replacing the outdated per-cell label_over_float/Occluded model.
---
Duplicate comments:
In `@src/minimap.rs`:
- Around line 944-954: Update the float_ring construction to derive each pixel’s
border status from its final owner in float_grid, rather than marking edges from
every float_bounds entry. For each owned pixel, use the owning float’s bounds to
determine whether it is on that float’s border, keeping float_px consistent with
the last-wins ownership model and avoiding interior stray borders.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b55a78ee-21e5-4fe7-9e54-e416fa223b7f
⛔ Files ignored due to path filters (1)
assets/floating-demo.pngis excluded by!**/*.png
📒 Files selected for processing (3)
docs/superpowers/plans/2026-07-12-float-label-occlusion.mddocs/superpowers/specs/2026-07-12-float-label-occlusion-design.mdsrc/minimap.rs
…#110) The occlusion shadow was tied to the truncated … cell; make it the float's own drop-shadow instead — non-covered tiled cells to the float's right/below are darkened (light from top-left), independent of labels, so plain fill rows beside the float shade too. The … cue is drawn independently and inherits the shade only where it falls in the band. Harden resolve_label_plan (review): a wide glyph with no room before the right edge drops to Fill (no width overflow), and the … boundary check respects the pane index so an adjacent different-pane label never trips a false cue. Add pure shadow_cells helper + tests; rename LABEL_SHADOW_BLEND to FLOAT_SHADOW_BLEND. 302 lib tests pass; no-float path stays byte-identical.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/specs/2026-07-12-float-label-occlusion-design.md`:
- Around line 95-103: Update the stale specification around the wide-glyph
behavior and API sketch to match resolve_label_plan. State that any wide glyph
touching covered columns, as well as one exceeding the row width, becomes Fill
across every occupied column; only uncovered width == 1 glyphs may produce
Ellipsis, with pane-aware boundary checks. Replace the outdated
label_over_float/Occluded sketch with the shipped resolve_label_plan(overlay,
cover, pw, text_rows) result model using LabelDraw variants Char, Ellipsis,
Skip, and Fill.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 84b84c3a-fe02-499b-b5ec-3d83f8954886
⛔ Files ignored due to path filters (1)
assets/floating-demo.pngis excluded by!**/*.png
📒 Files selected for processing (2)
docs/superpowers/specs/2026-07-12-float-label-occlusion-design.mdsrc/minimap.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- src/minimap.rs
…cell (#110) The shadow was applied at cell granularity, so a half-block below the float darkened the whole cell. Move it to half-block pixel resolution: a tiled pixel is shaded only when a float pixel sits to its left/up/up-left, so the shadow is one pixel wide on the float's right and below. Label cells still darken whole (a cell has one background — it can't shade a single half), which is the only place a full-cell shade remains. Rename shadow_cells → generic drop_shadow(cover, w, h), called on the pixel grid. Also fix the render_floating demo: it marked both a tiled pane AND the float as focused, drawing two focus frames at once — zellij focuses one pane at a time, so with the float focused no tiled pane carries a ring.
…rom labels (#110) Address PR #112 review (Copilot, CodeRabbit): - project_floats_into: clamp a float's left edge to the last column, not pw, so a float flush against the tiled bbox's right edge maps to a non-empty one-column strip instead of an empty pw..pw box that paints nothing. - render float border: derive the ring from final float_grid ownership, so an occluded float's outline never pokes through the float drawn on top of it. - render label placement: cap a bottom-row label's right_bound at the leftmost hidden-float chip column, mirroring the top-row close-glyph cap, so a wide glyph can't straddle and overrun the corner chips.
focused_pane_id filtered to tiled terminals only, so with a visible float focused it returned None and the wheel found no anchor to step from — even though pane_focus_order appends visible floats to the traversal. Accept a focused floating terminal too while its layer is visible, and keep excluding hidden floats (reached only via their chip). Addresses PR #112 review (CodeRabbit, Codex).
Clicking the decorative +k marker (the stand-in for hidden floats that overflow the chip run) fell through to focus the tiled pane beneath it. Add floating::chip_marker_k / router::chip_marker_at and consume a click on the marker as ClickIntent::NoOp before the tiled pane_at fallback. Making those overflow floats reachable is tracked in #113. Addresses PR #112 review (Codex).
…#110) Address PR #112 review (CodeRabbit): - occlusion spec: a covered wide glyph drops every column to Fill (never …), and the API sketch now matches resolve_label_plan's batch signature and its Char/Ellipsis/Skip/Fill variants. - floating-panes spec: note v1 ships a plain border for floats and defers the focused-float focus ring (#59) to a follow-up, matching Task 10. - grammar: fix the dangling "したがって:" before the visibility table.
Implements #110 — render floating panes in the tabmap, and make a floating pane selectable even while its layer is hidden.
Left → right: ⌘1 no floats; ⌘2 (active) a visible float overlaid on the tiled minimap — it sits on top of the labels it covers (cutting
cargo→car…andtest→…st,gituntouched) and casts a one-pixel drop-shadow onto the tiled cells to its right and below (only the float carries a focus frame, not the tiles beneath it); ⌘3 a hidden layer shown as two corner chips (◲) — click one to reveal + focus that float.What it does
Floating panes render as a hybrid (default on; opt out with
floating "off"), following each tab's own floating layer:…(cargo→car…), so a truncated title never reads as a real, shorter pane name; the cue inherits the drop-shadow only where it falls inside the band.◲) docked in the block's bottom-right corner (a⋯marker stands in for any that overflow the width). Left-clicking a chip reveals + focuses that float (focus_terminal_pane(id, should_float_if_hidden = true, …)) — satisfying ask plugin: parse config and stabilize the 3-row bar #2: a hidden floating pane is reachable straight from the bar.The mouse-wheel
panewalk (#80) steps through a tab's visible floats after its tiled panes, but never a hidden one — a hidden float is reached only via its chip, so wheeling never pops a hidden layer open.The bar stays a pure projection of zellij state — it never hides/shows floats itself; it re-derives the depiction each frame from
TabInfo.are_floating_panes_visibleand the live pane set. All new rendering lives in a dependency-freefloating.rs+minimap.rs, unit-tested off-wasm. No new permission — rides the already-grantedChangeApplicationState, so existing installs gain this on update with no re-grant and no auto-update freeze (zellij#4982).Config
floatinghybrid|offhybridhybridoverlays visible floats and chips hidden ones;offdraws no floating panes (the pre-#110 look).Implementation
Design spec and the full TDD plan are committed under
docs/superpowers/. The work is split so the renderer stays free of any zellij type (testable off-wasm):floating.rs(new, dependency-free):FloatingModeconfig enum,FloatLayer/FloatSpec, chip layout + hit-test (chip_cells/chip_index_at_cell).projection.rs:is_floating_terminal+project_floating— floating-only extraction (excludes suppressed).minimap.rs:bbox_ofextraction,project_floats_into(maps floats through the tiled bbox without expanding it), the visible-overlay composite inrender, andfloat_pane_at_cellhit-test.router.rs:float_chip_at/float_overlay_at, float-priority inroute_click, and theFocusFloatingPaneintent.lib.rs: builds each tab'sFloatSpecper frame, records chips / overlays for hit-testing, dispatches reveal+focus on a chip/overlay click, and walks visible floats with the wheel.examples/render_floating.rs: the visual sample above — drives the realpaint::bar→assemble→renderpath, so the preview can't drift from what ships. (The otherrender_*samples were updated for the new signature;render_close_buttonalso got an incidental fix for theClosecolor-tuple variants introduced in Close-button hot-fix: enable by default, fix Nerd Font glyph position & per-mode color #94.)Testing
CARGO_BUILD_TARGET=<host-triple> cargo test --lib— 306 passing.cargo build --target wasm32-wasip1— builds clean.cargo build --examples— every render sample builds.cargo clippy --target wasm32-wasip1 --lib— clean (production lib).Closes #110.
Summary by CodeRabbit
floatingminimap/tab-bar option (hybriddefault,offto disable).