Skip to content

Commit

Permalink
[Windows] Fix pointer released event not being handled on ImageButton (
Browse files Browse the repository at this point in the history
…#21766)

* Fix pointer released event not being handled on ImageButton

* Revert bad file include

* Actually implement the scripts needed for right click

* Fix merge

* Remove dupe release event

* Update ref image

---------

Co-authored-by: Mike Corsaro <mikecorsaro@microsoft.com>
  • Loading branch information
Foda and Mike Corsaro committed May 7, 2024
1 parent 222ca3c commit 752eed7
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 3 deletions.
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue21706"
xmlns:ns="clr-namespace:Maui.Controls.Sample.Issues">
<VerticalStackLayout>
<ImageButton
Source="groceries.png"
WidthRequest="200"
HeightRequest="200"
AutomationId="WaitForElement"
x:Name="PointerImageButton">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup
x:Name="CommonStates">
<VisualState
x:Name="Normal">
<VisualState.Setters>
<Setter
Property="BackgroundColor" Value="Blue" />
</VisualState.Setters>
</VisualState>
<VisualState
x:Name="PointerOver">
<VisualState.Setters>
<Setter
Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ImageButton>

<Button
AutomationId="OtherButton"
WidthRequest="200"
HeightRequest="200"
Text="Other"/>
</VerticalStackLayout>
</ContentPage>
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Xaml;

namespace Maui.Controls.Sample.Issues
{
[XamlCompilation(XamlCompilationOptions.Compile)]
[Issue(IssueTracker.Github, 21706, "ImageButton stuck in PointerOver state", PlatformAffected.UWP)]
public partial class Issue21706 : ContentPage
{
public Issue21706()
{
InitializeComponent();
}
}
}
Expand Up @@ -39,6 +39,6 @@
FontSize="Large"
BackgroundColor="Pink"
HorizontalTextAlignment="Center" />
</FlexLayout>
</FlexLayout>
</views:BasePage.Content>
</views:BasePage>
25 changes: 25 additions & 0 deletions src/Controls/tests/UITests/Tests/Issues/Issue21706.cs
@@ -0,0 +1,25 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.AppiumTests.Issues
{
public class Issue21706 : _IssuesUITest
{
public override string Issue => "ImageButton stuck in PointerOver state";

public Issue21706(TestDevice device) : base(device) { }

[Test]
public async Task ImageButtonStuckAfterRightClick()
{
this.IgnoreIfPlatforms(new TestDevice[] { TestDevice.Android, TestDevice.Mac, TestDevice.iOS });
App.WaitForElement("WaitForElement");
App.RightClick("WaitForElement");
await Task.Delay(200);
App.Click("OtherButton");
await Task.Delay(200);
VerifyScreenshot();
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion src/Core/src/Handlers/ImageButton/ImageButtonHandler.Windows.cs
Expand Up @@ -11,6 +11,7 @@ public partial class ImageButtonHandler : ViewHandler<IImageButton, Button>
Image? _image;

PointerEventHandler? _pointerPressedHandler;
PointerEventHandler? _pointerReleasedHandler;

protected override Button CreatePlatformView()
{
Expand All @@ -34,6 +35,7 @@ protected override Button CreatePlatformView()
protected override void ConnectHandler(Button platformView)
{
_pointerPressedHandler = new PointerEventHandler(OnPointerPressed);
_pointerReleasedHandler = new PointerEventHandler(OnPointerReleased);

if (_image != null)
{
Expand All @@ -43,6 +45,7 @@ protected override void ConnectHandler(Button platformView)

platformView.Click += OnClick;
platformView.AddHandler(UIElement.PointerPressedEvent, _pointerPressedHandler, true);
platformView.AddHandler(UIElement.PointerReleasedEvent, _pointerReleasedHandler, true);

base.ConnectHandler(platformView);
}
Expand All @@ -57,8 +60,10 @@ protected override void DisconnectHandler(Button platformView)

platformView.Click -= OnClick;
platformView.RemoveHandler(UIElement.PointerPressedEvent, _pointerPressedHandler);
platformView.RemoveHandler(UIElement.PointerReleasedEvent, _pointerReleasedHandler);

_pointerPressedHandler = null;
_pointerReleasedHandler = null;

base.DisconnectHandler(platformView);

Expand Down Expand Up @@ -93,14 +98,18 @@ public static void MapPadding(IImageButtonHandler handler, IImageButton imageBut
void OnClick(object sender, RoutedEventArgs e)
{
VirtualView?.Clicked();
VirtualView?.Released();
}

void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
VirtualView?.Pressed();
}

void OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
VirtualView?.Released();
}

void OnImageOpened(object sender, RoutedEventArgs routedEventArgs)
{
VirtualView?.UpdateIsLoading(false);
Expand Down
35 changes: 34 additions & 1 deletion src/TestUtils/src/UITest.Appium/Actions/AppiumTouchActions.cs
Expand Up @@ -68,6 +68,16 @@ CommandResponse Tap(IDictionary<string, object> parameters)
{
return CommandResponse.FailedEmptyResponse;
}

if (parameters.TryGetValue("button", out var button) && button != null)
{
var buttonName = button.ToString();
if (!string.IsNullOrEmpty(buttonName) &&
buttonName.Equals("right", StringComparison.OrdinalIgnoreCase))
{
return RightClick(element.Id);
}
}
return TapElement(element);
}
else if (parameters.TryGetValue("x", out var x) &&
Expand Down Expand Up @@ -119,8 +129,31 @@ CommandResponse TapCoordinates(float x, float y)
return CommandResponse.SuccessEmptyResponse;
}

CommandResponse DoubleTap(IDictionary<string, object> parameters)

CommandResponse RightClick(string elementId)
{
// "ActionSequence" and "Actions" is not supported for right click on Windows
if (_appiumApp.GetTestDevice() == TestDevice.Windows)
{
_appiumApp.Driver.ExecuteScript("windows: click", new Dictionary<string, object>
{
{ "elementId", elementId },
{ "button", "right" },
});
}
else if (_appiumApp.GetTestDevice() == TestDevice.Mac)
{
_appiumApp.Driver.ExecuteScript("macos: rightClick", new Dictionary<string, object>
{
{ "elementId", elementId }
});
}

return CommandResponse.SuccessEmptyResponse;
}

CommandResponse DoubleTap(IDictionary<string, object> parameters)
{
var element = GetAppiumElement(parameters["element"]);

OpenQA.Selenium.Appium.Interactions.PointerInputDevice touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch);
Expand Down
10 changes: 10 additions & 0 deletions src/TestUtils/src/UITest.Appium/HelperExtensions.cs
Expand Up @@ -34,6 +34,16 @@ public static void Click(this IApp app, string element)
app.FindElement(element).Click();
}

public static void RightClick(this IApp app, string element)
{
var uiElement = app.FindElement(element);
uiElement.Command.Execute("click", new Dictionary<string, object>()
{
{ "element", uiElement },
{ "button", "right" }
});
}

public static string? GetText(this IUIElement element)
{
var response = element.Command.Execute("getText", new Dictionary<string, object>()
Expand Down

0 comments on commit 752eed7

Please sign in to comment.