Skip to content

Floating window positioning requires viewport offset tracking #6

Description

@alexandergknoll

Problem

Floating windows cannot be accurately positioned on the minimap because Niri's IPC doesn't expose viewport scroll position information.

Background

Current Implementation Status

We've implemented partial support for floating window positioning with the following approach:

  1. Floating window detection: Windows with pos_in_scrolling_layout = None are identified as floating
  2. Viewport offset estimation: We estimate the viewport offset by assuming the focused column is left-aligned (matching center-focused-column "never" config)
  3. Position calculation: Floating window workspace position = viewport-relative position + estimated viewport offset

What Works

  • Floating windows are positioned correctly when a tiled window has focus
  • Position updates when switching focus between different columns
  • The calculation correctly accounts for column widths and positions

Known Limitations

  1. Focusing floating windows: When a floating window has focus, there's no tiled window to determine viewport offset from, so the offset defaults to 0 (incorrect)
  2. Viewport scrolling without focus changes: Operations like "center column" or vertical window stacking can scroll the viewport without changing focus, making our offset estimate incorrect
  3. Configuration dependency: The current implementation assumes center-focused-column "never" (left-align behavior). Different Niri configurations would require different offset calculations

Root Cause

Niri's IPC API provides window positions as viewport-relative coordinates but doesn't expose:

  • Current viewport scroll position
  • Workspace view offset
  • center-focused-column configuration setting

All tiled windows report tile_pos_in_workspace_view = (0, 0) because they're relative to the viewport, not absolute workspace coordinates. Floating windows are also viewport-relative.

Investigation Summary

We investigated several approaches:

  1. Using tiled window positions: All tiled windows report (0,0) regardless of which column is in view
  2. Finding leftmost visible column: All columns report windows at (0,0) simultaneously
  3. Querying viewport from Niri: No IPC request provides viewport/scroll information
  4. Estimating from focused column (current approach): Works partially but has the limitations above

Potential Solutions

Option 1: Enhance Niri IPC (Upstream)

Add viewport position information to Niri's IPC API. This would require:

  • Adding viewport offset to Workspace struct or creating a new ViewportPosition request
  • Potentially exposing center-focused-column configuration via IPC

Pros: Clean, accurate solution
Cons: Requires upstream changes to Niri

Option 2: Track Viewport State Locally

Maintain viewport offset state in nirimap by:

  • Tracking the last known offset when a tiled window has focus
  • Preserving that offset when floating windows are focused
  • Listening for all focus/layout events to update the estimate

Pros: No upstream changes needed
Cons: Still inaccurate for viewport scrolling without focus changes; complex state management

Option 3: Hide Floating Windows (Current Approach)

Don't render floating windows on the minimap until a proper solution is available.

Pros: No confusing/incorrect positioning
Cons: Incomplete minimap representation

Current Status

Floating windows are currently hidden from the minimap. The positioning code exists in src/ui/minimap.rs but is disabled, preserved for future use when a better solution becomes available.

Related Code Locations

  • Floating window detection: src/ipc/events.rs:156 (is_floating field)
  • Viewport offset calculation: src/ui/minimap.rs:440-464
  • Floating window rendering: src/ui/minimap.rs:466-495
  • Window state model: src/state/model.rs:23 (is_floating field)

Next Steps

  • Consider filing an upstream issue with Niri requesting viewport position in IPC
  • Monitor Niri IPC changes for potential solutions

Related Issues: #1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions