Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behavior of cursor after PointerPressed and ShowDialog (Linux) #15281

Open
Tulesha opened this issue Apr 9, 2024 · 6 comments
Open

Comments

@Tulesha
Copy link

Tulesha commented Apr 9, 2024

Describe the bug

When I catch PointerPressed event of InputElement (testing on TextBlock and ContentPresenter) and showing dialog window, I got strange behavior of pointer like it is still pointing to the InputElement.

To Reproduce

I define interface ILinkInfo which has method Navigate. In implementations of method I can navigate through application and opening windows:

public interface ILinkInfo
{
    void Navigate(PointerPressedEventArgs e);
}

public class LinkInfoDialog : ILinkInfo
{
    private readonly Window _ownerWindow;

    public LinkInfoDialog(Window ownerWindow)
    {
        _ownerWindow = ownerWindow;
    }

    public async void Navigate(PointerPressedEventArgs e)
    {
        if (e.KeyModifiers == KeyModifiers.Control)
        {
            // Show ContextMenu
            var contextMenu = new ContextMenu
            {
                Items = { new MenuItem { Header = "Menu1" }, new MenuItem { Header = "Menu2" } }
            };
            contextMenu.Open(e.Source as Control);
            return;
        }

        // Some kind of dialog
        var window = new Window
        {
            Width = 300,
            Height = 300,
            WindowStartupLocation = WindowStartupLocation.CenterOwner
        };
        await window.ShowDialog(_ownerWindow);
    }
}

public class LinkInfoSmth : ILinkInfo
{
    public LinkInfoSmth()
    {
    }

    public void Navigate(PointerPressedEventArgs e)
    {
        // Do smth
    }
}

I got Window.xaml with two TextBlock's which imitating Link behaviour:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:AvaloniaApplication1.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="AvaloniaApplication1.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"
        Icon="/Assets/avalonia-logo.ico"
        Title="AvaloniaApplication1">

    <Window.Styles>
        <Style Selector="TextBlock.hyperLink">
            <Setter Property="Foreground" Value="Aqua" />
            <Setter Property="Cursor" Value="Hand" />
            <Style Selector="^:pointerover">
                <Setter Property="TextDecorations" Value="Underline" />
            </Style>
        </Style>
    </Window.Styles>

    <StackPanel Orientation="Vertical" Spacing="5">
        <TextBlock Name="Link1"
                   Text="Link1"
                   FontSize="30"
                   Classes="hyperLink"
                   PointerPressed="Link_OnPointerPressed" />

        <TextBlock Name="Link2"
                   Text="Link2"
                   FontSize="30"
                   Classes="hyperLink"
                   PointerPressed="Link_OnPointerPressed" />
    </StackPanel>

</Window>

In code behind of MainWindow I catch PointerPressed event of TextBlock's and calling Navigate method of ILinkInfo:

public partial class MainWindow : Window
{
    private readonly ILinkInfo _linkInfo1;
    private readonly ILinkInfo _linkInfo2;

    public MainWindow()
    {
        InitializeComponent();

        _linkInfo1 = new LinkInfoDialog(this);
        _linkInfo2 = new LinkInfoSmth();
    }

    private void Link_OnPointerPressed(object? sender, PointerPressedEventArgs e)
    {
        if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
            return;

        if (Equals(sender, Link1))
            _linkInfo1.Navigate(e);
        else
            _linkInfo2.Navigate(e);

        e.Handled = true;
    }
}

And when I'm click to the TextBlock, which open window, I getting behaviour of cursor like this:
pointerover

It seems like application think that I'm steel pointed to the TextBlock.

I publish this code to GitHub repo

Expected behavior

InputElement should be not pointed after closing Window

Avalonia version

release: 11.0.10
night: 11.2.999-cibuild0047060-alpha

OS

Linux (Ubuntu 23.10)

Additional context

This is can be reproduce only on Linux. On Windows it handles like it should be.

I testing this behaviour on cathing Tapped event and I got right behaviour. But it this strange thing that I can't repoduce this in PointerPressed event handler. And also in my application I should use PointerPressed event to mark it handled if I navigate through application.

@Tulesha Tulesha added the bug label Apr 9, 2024
@Tulesha
Copy link
Author

Tulesha commented May 17, 2024

No more reproduce in Ubuntu 23.10 with installed packages:

  • xserver-xorg-core_2:21.1.7-3ubuntu2.9
  • xserver-common_2:21.1.7-3ubuntu2.9
  • xwayland_2:23.2.0-1ubuntu0.6

UPD: was wrong, steel same behaviour

@Tulesha Tulesha closed this as completed May 17, 2024
@Tulesha Tulesha reopened this May 17, 2024
@pawn86
Copy link

pawn86 commented Jul 5, 2024

Hi, I'm having the same issue.Have you solved it?

@jonko0493
Copy link

Can confirm that this is happening for me on both Linux (Debian) and macOS as well.

@Tulesha
Copy link
Author

Tulesha commented Jul 29, 2024

@pawn86, @jonko0493 as a workaround for this issue, you can Capture pointer to null after showing a window

Example:

private void Link_OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
    if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
        return;

    if (Equals(sender, Link1))
        _linkInfo1.Navigate(e);
    else
        _linkInfo2.Navigate(e);

    // workaround
    if ( RuntimeInformation.IsOSPlatform( OSPlatform.Linux ) ||  RuntimeInformation.IsOSPlatform( OSPlatform.OSX) )
        e.Pointer.Capture( null );

    e.Handled = true;
}

@aianlinb
Copy link

Same here (macOS)

@wild-coffee
Copy link

Debian arm64,bug!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants