Skip to content

[Bug]: ScrollViewer extent changes close unrelated ContextMenus #236

Description

@satanikia1300

Environment

Windows11, .NET 11, MewUI 0.20.2, Direct2D

Reproduction steps

  1. Run the minimal sample below.
  2. Right-click the Right-click me and wait button to open its context menu.
  3. Do not click, move the mouse, or press any key.
  4. Wait for the timer to change the height of the content inside the unrelated ScrollViewer.
  5. Observe that the context menu closes when the ScrollViewer extent changes.

Expected behavior

The context menu should remain open.

Changing the extent of an unrelated ScrollViewer should not be treated as a scroll operation when its scroll offset has not changed.

Actual behavior

The context menu closes when the content height of the unrelated ScrollViewer changes, even though no scrolling or other user input occurs.

Minimal repro / code / screenshots / logs

using Aprillz.MewUI;
using Aprillz.MewUI.Controls;

var builder = new ApplicationBuilder(new AppOptions())
    .UseWin32()
    .UseDirect2D();

var content = new Border()
    .Width(200)
    .Height(40);

var button = new Button()
    .Content("Right-click me and wait")
    .ContextMenu(new ContextMenu().Item("Test"));

var expanded = false;
var timer = new DispatcherTimer(TimeSpan.FromSeconds(3));

timer.Tick += () =>
{
    expanded = !expanded;
    content.Height = expanded ? 400 : 40;
};

timer.Start();

var window = new Window()
    .Title("ContextMenu repro")
    .Resizable(600, 300)
    .Content(
        new StackPanel()
            .Horizontal()
            .Spacing(24)
            .Children(
                button,
                new ScrollViewer
                {
                    Width = 220,
                    Height = 120,
                    VerticalScroll = ScrollMode.Auto,
                    Content = content,
                }));

builder.Run(window);

The issue appears to be related to ScrollViewer.NotifyScrollChanged().

NotifyScrollChanged() is invoked when the extent, viewport, or offset changes, and it subsequently requests:

window.RequestClosePopups(PopupCloseRequest.Scroll(source: this));

This means that an extent change caused by content resizing can dismiss context menus even when the scroll offset itself did not change.

NotifyScrollChanged() already distinguishes an actual offset change for OnScrolled():

if (!double.IsNaN(_lastNotifiedOffset.X) &&
    _lastNotifiedOffset != offset)
{
    OnScrolled();
}

It may be more appropriate for popup dismissal caused by scrolling to use the same actual-offset-change condition.

Before submitting

  • I searched for existing issues and did not find a duplicate.
  • I included enough information to reproduce or investigate the problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions