Skip to content

feat: floating panes in the minimap, selectable when hidden (#110) - #112

Merged
GeneralD merged 34 commits into
mainfrom
feat/110-floating-panes
Jul 15, 2026
Merged

feat: floating panes in the minimap, selectable when hidden (#110)#112
GeneralD merged 34 commits into
mainfrom
feat/110-floating-panes

Conversation

@GeneralD

@GeneralD GeneralD commented Jul 12, 2026

Copy link
Copy Markdown
Owner

agent type issue tests permission

Implements #110 — render floating panes in the tabmap, and make a floating pane selectable even while its layer is hidden.

Floating panes on the tab bar: a plain tab, the active tab with a visible float occluding the labels it covers and casting a drop-shadow, and a tab whose hidden layer shows corner chips

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 cargocar… and test…st, git untouched) 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:

  • Visible layer → each float is overlaid graphically on the tiled minimap, mapped through the same bounding box as the tiles so it never shifts them; a thin border in the float's shade sets it apart from the tiles beneath. The overlay occludes the tiled labels it covers and casts a one-pixel drop-shadow onto the tiled cells to its right and below (light from top-left), so a float reads as floating on top of the panes below. A label the float cuts is marked with a (cargocar…), 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.
  • Hidden layer → each float becomes a small selectable chip () 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 pane walk (#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_visible and the live pane set. All new rendering lives in a dependency-free floating.rs + minimap.rs, unit-tested off-wasm. No new permission — rides the already-granted ChangeApplicationState, so existing installs gain this on update with no re-grant and no auto-update freeze (zellij#4982).

Config

Key Values Default Meaning
floating hybrid | off hybrid hybrid overlays visible floats and chips hidden ones; off draws 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): FloatingMode config 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_of extraction, project_floats_into (maps floats through the tiled bbox without expanding it), the visible-overlay composite in render, and float_pane_at_cell hit-test.
  • router.rs: float_chip_at / float_overlay_at, float-priority in route_click, and the FocusFloatingPane intent.
  • lib.rs: builds each tab's FloatSpec per 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 real paint::barassemblerender path, so the preview can't drift from what ships. (The other render_* samples were updated for the new signature; render_close_button also got an incidental fix for the Close color-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 --lib306 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

  • New Features
    • Added a new floating minimap/tab-bar option (hybrid default, off to disable).
    • Floating panes now appear as overlays when visible and as selectable chips when hidden; chips reveal and focus the pane.
    • Click and scroll/focus traversal now include visible floating panes (with hidden-chip behavior supported).
  • Bug Fixes
    • Floating panes no longer distort/expand underlying minimap bounds.
  • Documentation
    • Documented floating-pane behavior, configuration, and label occlusion/ellipsis rendering specs.
  • Tests
    • Added/updated coverage for floating parsing, projection, hit-testing, routing priorities, and rendering.

@GeneralD GeneralD self-assigned this Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 871f6e95-6685-4eb8-a943-43658f240404

📥 Commits

Reviewing files that changed from the base of the PR and between 6aec4c2 and ae3ed12.

📒 Files selected for processing (1)
  • README.md

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Floating minimap

Layer / File(s) Summary
Behavior contract and rollout plan
.claude/rules/..., README.md, docs/superpowers/...
Documents floating-pane state, hybrid/off behavior, rendering, interaction, label occlusion, and implementation phases.
Floating data model and configuration
src/floating.rs, src/config.rs, src/projection.rs
Adds floating-layer types, strict mode parsing, chip layout and hit-testing, configuration defaults, and floating-terminal projection.
Minimap rendering and compositor wiring
src/minimap.rs, src/tab_block.rs, src/paint.rs
Projects floats against tiled bounds, renders overlays or chips, handles label occlusion, and threads floating layers through rendering.
Floating click and traversal integration
src/router.rs, src/lib.rs
Prioritizes floating hit targets, dispatches reveal-and-focus behavior, records float geometry, and includes only visible floats in traversal.
Renderer examples and call sites
examples/*
Updates renderer examples for new arguments and adds a floating-pane rendering example.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding selectable floating panes to the minimap.
Linked Issues check ✅ Passed The changes implement #110 by rendering floating panes, making hidden floats selectable, and excluding suppressed panes.
Out of Scope Changes check ✅ Passed The docs, examples, and README updates all support the floating-pane minimap feature and do not appear unrelated.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/110-floating-panes

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.28735% with 18 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/minimap.rs 97.50% 13 Missing ⚠️
src/lib.rs 98.21% 3 Missing ⚠️
src/floating.rs 98.18% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

GeneralD added 14 commits July 12, 2026 21:05
…#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.
@GeneralD
GeneralD marked this pull request as ready for review July 12, 2026 12:55
Copilot AI review requested due to automatic review settings July 12, 2026 12:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/minimap.rs Outdated
Comment on lines +707 to +711
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,
};

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent action

Fixed in c9aa323project_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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Reserve hidden-chip cells before label placement.

chip_layout is 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 creating overlay entries 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3b0fab8 and bb45820.

⛔ Files ignored due to path filters (1)
  • assets/floating-demo.png is excluded by !**/*.png
📒 Files selected for processing (21)
  • .claude/rules/zellij-plugin-development.md
  • README.md
  • docs/superpowers/plans/2026-07-12-floating-panes-in-minimap.md
  • docs/superpowers/specs/2026-07-12-floating-panes-in-minimap-design.md
  • examples/render_active_cue.rs
  • examples/render_close_button.rs
  • examples/render_demo.rs
  • examples/render_floating.rs
  • examples/render_gradient.rs
  • examples/render_new_tab_button.rs
  • examples/render_palette.rs
  • examples/render_perspective.rs
  • examples/render_top_label.rs
  • src/config.rs
  • src/floating.rs
  • src/lib.rs
  • src/minimap.rs
  • src/paint.rs
  • src/projection.rs
  • src/router.rs
  • src/tab_block.rs

Comment thread src/lib.rs
Comment thread src/minimap.rs
Comment thread src/minimap.rs Outdated
Comment thread src/router.rs
Comment on lines +72 to +79
let index = crate::floating::chip_index_at_cell(
geom.width,
geom.rows,
geom.hidden_floats.len(),
col,
row,
)?;
geom.hidden_floats.get(index).copied()

@coderabbitai coderabbitai Bot Jul 12, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent action

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).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/lib.rs
Comment on lines +551 to +554
order.extend(
projection::project_floating(p)
.into_iter()
.map(|f| f.id as u32),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent action

Fixed in 4e5eaf4focused_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.

Comment thread src/minimap.rs Outdated
Comment on lines +1244 to +1247
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));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent action

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.

Comment thread src/minimap.rs
Comment on lines +1166 to +1167
if tr == chip_row {
if let Some((_, chip)) = chip_layout.iter().find(|(cc, _)| *cc == c) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent action

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.

Comment thread src/router.rs
Comment on lines +194 to +195
if let Some(id) = float_chip_at(tab_layout, tab_panes, row, column)
.or_else(|| float_overlay_at(tab_layout, tab_panes, row, column))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent action

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/minimap.rs (1)

944-954: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Derive float borders from final grid ownership.

float_grid is last-wins for overlapping floats, but this loop marks ring pixels from every float_bounds box. Where an earlier float's edge falls inside a later float, float_px (Line 1366-1372) reads the later float as the cell owner yet float_ring is still set, so it paints the later float's ring_for shade at an interior pixel — a stray border line inside the float. Compute ring status from the final float_grid owner 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

📥 Commits

Reviewing files that changed from the base of the PR and between bb45820 and b01945a.

⛔ Files ignored due to path filters (1)
  • assets/floating-demo.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • docs/superpowers/plans/2026-07-12-float-label-occlusion.md
  • docs/superpowers/specs/2026-07-12-float-label-occlusion-design.md
  • src/minimap.rs

Comment thread docs/superpowers/specs/2026-07-12-float-label-occlusion-design.md Outdated
GeneralD added 2 commits July 13, 2026 02:27
…#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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between b01945a and 9bb00f1.

⛔ Files ignored due to path filters (1)
  • assets/floating-demo.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • docs/superpowers/specs/2026-07-12-float-label-occlusion-design.md
  • src/minimap.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/minimap.rs

Comment thread docs/superpowers/specs/2026-07-12-float-label-occlusion-design.md
GeneralD added 2 commits July 13, 2026 02:41
…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.
GeneralD added 6 commits July 14, 2026 02:07
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: show floating panes in the minimap, selectable when hidden

2 participants