-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
[Windows] Subscribe pointer events only when needed #23515
[Windows] Subscribe pointer events only when needed #23515
Conversation
Hey there @MartyIX! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
This yields nice improvements in performance in a complex app. However, it does seem to break Visual States. Repro: Apply the following on an element and observe it not working.
|
Thank you for testing. I thought that this maui/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs Lines 463 to 466 in f323832
|
@MartyIX Here https://github.com/dotnet/maui/pull/23515/files#diff-779a3cbf8053213a2331cbf6a85a82af5c41cd858702c4fa4c4efdf16d7a6b13R772 use |
2cb2dca
to
2d28e4f
Compare
IList<IGestureRecognizer>? gestures = view?.GestureRecognizers; | ||
|
||
if (gestures is null) | ||
if (_container is null || Element is not View view || view.GestureRecognizers is not IList<IGestureRecognizer> gestures) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just modernize a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about a simpler if (ElementGestureRecognizers is not {} gestures) return;
?
I think that view.GestureRecognizer
is just wrong (not enough) in this situation.
Or do you think we would have strange side effects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a different method. I don't want to change behavior here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it can be done. I'm not sure. However, if I start with it - i.e. changing IList<IGestureRecognizer>
to ElementGestureRecognizers
- then nobody will want to review this PR and it will lead to delays.
So I sort of prefer as little change as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, CompositeGesureRecognizers
is basically a proxy of the GestureRecognizers
with the addition of the pointer over gesture recognizer which is (un)set by this method here who checks the VSM for pointer over states.
That said, and considering the only piece of code here caring about the pointer gesture recognizer is the one you changed, I feel this is a safe change.
Anyway I'll leave this to the MAUI team: my purpose is just to give more context information.
_container.PointerMoved += OnPgrPointerMoved; | ||
_container.PointerPressed += OnPgrPointerPressed; | ||
_container.PointerReleased += OnPgrPointerReleased; | ||
bool hasPointerGesture = ElementGestureRecognizers.HasAnyGesturesFor<PointerGestureRecognizer>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed according to: #23515 (comment)
I tested with https://github.com/MartyIX/maui/tree/feature/2024-07-09-Optional-pointer-event-subscription-TEST (MartyIX@62dc732) Test codeMainPage.xaml <ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.MainPage"
xmlns:local="clr-namespace:Maui.Controls.Sample">
<VerticalStackLayout>
<Label Text="First button has assigned a VisualStateManager with a pointer-over state."/>
<Button x:Name="button1" Text="Button 1">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light=Yellow, Dark=Orange}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
</Button>
<Label Text="Second button has assigned PointerEntered and PointerExited gesture recognizers."/>
<Button x:Name="button2" Text="Button 2">
<Button.GestureRecognizers>
<PointerGestureRecognizer PointerEntered="PointerGestureRecognizer_PointerEntered" PointerExited="PointerGestureRecognizer_PointerExited" />
</Button.GestureRecognizers>
</Button>
<Label Text="Third button has assigned a pointer-over event in code behind."/>
<Button x:Name="button3" Text="Button 3"/>
<Label Text="Fourth button has assigned no pointer events."/>
<Button x:Name="button4" Text="Button 4"/>
</VerticalStackLayout>
</ContentPage> MainPage.xaml.cs namespace Maui.Controls.Sample;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
PointerGestureRecognizer pointerGestureRecognizer = new();
pointerGestureRecognizer.PointerEnteredCommand = new Command(() =>
{
button3.Text = "Button 3 (pointer over)";
button3.BackgroundColor = Colors.Red;
});
pointerGestureRecognizer.PointerExitedCommand = new Command(() =>
{
button3.Text = "Button 3";
button3.BackgroundColor = null;
});
button3.GestureRecognizers.Add(pointerGestureRecognizer);
}
private void PointerGestureRecognizer_PointerEntered(object sender, PointerEventArgs e)
{
button2.Text = "Button 2 (pointer over)";
button2.BackgroundColor = Colors.Red;
}
private void PointerGestureRecognizer_PointerExited(object sender, PointerEventArgs e)
{
button2.Text = "Button 2";
button2.BackgroundColor = null;
}
} |
Azure Pipelines successfully started running 3 pipeline(s). |
src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs
Outdated
Show resolved
Hide resolved
src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs
Outdated
Show resolved
Hide resolved
2d28e4f
to
7a4b555
Compare
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
[Windows] Fix CollectionView DisconnectHandler SelectionMode Crash (dotnet#23726) * Reorder events to prevent disconnect issues * Add test --------- Co-authored-by: Mike Corsaro <mikecorsaro@microsoft.com> Use UIView.Window instead of the global window (dotnet#23693) [Windows] Subscribe pointer events only when needed (dotnet#23515) Fix iOS log exports (dotnet#23334) * Fix ios Device Logging * - fix up device test logging a bit more * Update ui-tests-steps.yml * Update ui-tests-steps.yml * Update ios.cake * Update ui-tests-steps.yml * Update maui-templates.yml * Update maui-templates.yml remove code from oldFragment add new shiny DialogFragment refactoring code to find and dismiss DialogFragment code cleanup delete ModalContainer to use only ModalFragment handle animation and add a map between page and dialogFragment We've back button enabled! After dismissing several demons summoned using obscure Android APIs, I was able to deal with the BackButtonPressed event add modal animations as anim.xml files using cleanup remowork PopModalPlatformAsync to work with dialogFragment remove tag final adjustments on DialogFragment change the ShowNow for Show to fix the issue Wait for animation to complete change local functions order fix build create window hooks for android (like iOS) clean up ModalFragment fields change Dictionary to ConditionalWeakTable clean up event animation refactor on Null notation remove comments - adjust back button - different back button code style remove unused prop. fix DontPushModalPagesWhenWindowIsDeactivated DeviceTest completes the task return back the way how modalManager handles android modals normilize animation duration Co-authored-by: Shane Neuville <shane94@hotmail.com> remove focusability code change how fragments are looked-up code style
Description of Change
The idea of the PR is that subscriptions
are only necessary if
PointerGestureRecognizer
, orThis arguments should suffice to claim that this PR is a refactoring after an element is initialization.
Now it is necessary to prove that the PR works even if
Performance impact
-> 98% improvement1.
Issues Fixed
Contributes to #21787
Footnotes
Note that this improvement is for view where there are no PointerGestureRecognizers assigned to elements as in my use case. ↩