Files
vim-mirror/runtime
Yasuhiro Matsumoto e3d9929109 patch 9.2.0469: popup: textprop-anchored popups bleed past host window edges
Problem:  A popup anchored to a text property in a split window is
          positioned relative to the screen and may extend into
          adjacent splits or off-screen regions.  There is no way to
          confine the popup to the window that contains the textprop.
Solution: Add the "clipwindow" popup option to allow clipping the text
          property popup to the host window (Yasuhiro Matsumoto).

Adds a "clipwindow" boolean option to popup_create()/popup_setoptions().
When set on a textprop-anchored popup, the popup's drawn extent is
confined to its host (textprop) window's content rectangle so the popup
no longer bleeds across a horizontal split's statusline (top/bottom) or
a vsplit's separator (right) into another window.

The popup keeps its full logical size and position; only the rows or
columns that fall outside the host window's content area are skipped
during drawing, so a popup that scrolls toward the host's edge looks
visually "cut off" without its borders being relocated.  popup_getoptions
and popup_getpos continue to report the unclipped geometry.

Implementation:

  - w_popup_topoff / w_popup_bottomoff record how many rows of the
    popup fall outside the host on each side.  popup_adjust_position()
    computes them from the host rectangle after the logical layout is
    finalised, and update_popups() and the popup-mask builder subtract
    them when emitting cells/borders/scrollbar and when marking
    popup-owned cells.  win_update() is bracketed by transient
    w_height/w_topline/w_winrow adjustments so the buffer's drawn
    content matches the visible row range.

  - w_popup_rightclip is the horizontal counterpart for the host's
    right edge: the right border, padding and content columns past
    the host are not drawn.  win_update() is bracketed by a transient
    w_width reduction so the buffer text is not written past the
    host's right edge either.

  - When the textprop scrolls just above the host window's top, the
    popup is kept visible by extending the prop search above topline
    (new helper find_prop_in_lines) and synthesising a negative
    screen_row so the top-clip path can roll the popup off the top.
    When the textprop has scrolled far enough that even the bottom
    border would overlap the host edge -- or when the popup would
    overflow the host's left edge at all -- the popup is hidden, and
    unhidden again once it comes back within range.

  - The "reduce-height" / "clamp winrow to 0" fallbacks in
    popup_adjust_position are bypassed for host-clipped popups so the
    popup keeps its natural anchored position instead of being
    snapped to the screen edge.

    Left-edge partial clipping is intentionally not supported: it
    would require shrinking the buffer width during win_update, which
    reflows wrapped lines and corrupts the displayed content; the
    popup is hidden instead.

closes: #20166

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
2026-05-10 19:02:38 +00:00
..
2026-05-04 19:10:37 +00:00
2026-05-04 19:10:37 +00:00