Skip to content

Hovering over dictionary entries with different heights makes the popup overlap over subs #4

Description

@Tricked-dev

Issue body

When moving between dictionary entries of different heights, the popup can either grow over the hovered subtitle or leave a much larger gap than configured.

Environment

  • JitenMPV 0.1.1 / master at 015b58c
  • Linux
  • KDE Plasma Wayland/XWayland
  • popup_position=above-subtitle
  • popup_offset_px=60

Steps to reproduce

  1. Hover a token whose dictionary popup has only a few meanings.
  2. Move directly to a token whose popup is substantially taller.
  3. Move back to a token with a short popup.

Expected behavior

For above-subtitle, the popup's bottom edge remains popup_offset_px above the pointer. A taller entry should extend farther upward without covering the hovered subtitle.

Actual behavior

  • Short to tall: the top remains near its previous position, so the window
    grows downward over the pointer or subtitle.
  • Tall to short: the top remains too high, leaving an excessive gap.

Workaround

A local X11 helper watches the popup's actual post-layout height and recalculates its Y position whenever that height changes. In an isolated Xvfb test with a pointer at Y=900 and a 60 px offset:

337 px popup: outer bottom Y=840
225 px popup: outer bottom Y=840

This confirms that positioning from the final height resolves both directions of the transition.

Investigation notes

In AvaloniaPopupPresenter.ShowAsync, the view model is updated and PositionWindow immediately reads _window.Bounds.Size. Avalonia has not necessarily completed SizeToContent layout for the new entry, so this can still be the previous entry's size.

The additional render-priority positioning call does not always run after the final text wrapping and window sizing. No later size-change handler corrects the position.

Possible direction

Subscribe once to the popup window's Avalonia size-change event and reposition with the retained cursor point after every final size change:

_window.SizeChanged += (_, args) =>
{
    if (!_window.IsVisible || args.NewSize == args.PreviousSize)
        return;

    PositionWindow(_lastCursorPos);
};

Moving the window does not change its size, so this should not create a feedback loop. The existing render-priority call can remain as the initial fast path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions