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

Update popups and flyouts to properly support OverlayDismissEventPassThrough #15517

Merged

Conversation

billhenn
Copy link
Contributor

We have found that clicking outside of popups/flyouts takes an extra click, since the first click dismisses the popup, and a second click is required to focus/activate whatever target control was clicked. This is a productivity annoyance to desktop users who are used to single clicking on a control outside of a popup to focus/activate it.

There is a Popup.OverlayDismissEventPassThrough property that can be set to true, which is meant to help with this. However, flyouts don't support it at all, and the pass-through event should be raised prior to the dismiss overlay closing the popup. This is in case the pass-through event closed the popup already, which should occur in Button, ComboBox, and several other native controls.

Related Issues/PRs

A related issue was opened recently by another user, requesting that OverlayDismissEventPassThrough be added to PopupFlyoutBase.

Another past PR worked to prevent Button with a flyout open from closing and instantly reopening the flyout when it was clicked. It accomplished this by forcing the flyout popup's OverlayDismissEventPassThrough property to false. While it achieved that goal, it prevented flyouts from ever supporting event pass-through, which is not ideal.

Goals

The intended goal of the code changes in this new PR are:

  • OverlayDismissEventPassThrough is supported on both Popup and PopupFlyoutBase.
  • When OverlayDismissEventPassThrough is true, any clicks to another control outside of the popup will work as expected, thereby preventing a second click from being necessary to dismiss the popup.
  • Clicking a popup anchor control while its popup is open will close the popup, even when OverlayDismissEventPassThrough is true.
  • When OverlayDismissEventPassThrough is false, the same run-time behavior should be achieved as before this PR.
  • Several native Avalonia controls need minor updates to catch pass-through pointer press events for the OverlayDismissEventPassThrough scenario, so they can close their own popup.

Implementation Details

  • Popup
    • Updated PointerPressedDismissOverlay logic so the pass-through event fires first, then the popup is closed if the pass-through event didn't already close it.
  • PopupFlyoutBase
    • Add a OverlayDismissEventPassThrough property and assign it to the Popup used by the flyout.
    • Updated the CreatePopup method to remove the Popup.OverlayDismissEventPassThrough from always being false.
  • Button
    • Updated OnPointerPressed to watch for OverlayDismissEventPassThrough scenarios when a flyout is open and close the flyout without marking the button as pressed.
  • SplitButton
    • Added a secondary button PreviewPointerPressed handler to watch for OverlayDismissEventPassThrough scenarios when a flyout is open and close the flyout.
  • CalendarDatePicker
    • Updated DropDownButton_PointerPressed to watch for OverlayDismissEventPassThrough scenarios when a flyout is open and close the flyout.
  • ComboBox
    • Updated OnPointerPressed to watch for OverlayDismissEventPassThrough scenarios when a drop-down is open and close the drop-down. If no popup is open, the ComboBox is flagged as pressed.
    • Updated OnPointerReleased to only open the drop-down if the ComboBox is flagged as pressed.
    • Updated PopupClosed logic to remove code that blindly focuses itself when the drop-down closes. This was bad because when OverlayDismissEventPassThrough was true on the ComboBox's popup, clicking on an external control while the drop-down was open would not let the other control get focus. With the focus code removed, the ComboBox is still properly focused when the popup is closed by clicking on the ComboBox, pressing Esc, etc. Therefore, the focus code was removed since it was unnecessary and caused problems.

Contact me if you have any questions on the code changes.

…o possibly closing the popup when a pointer is pressed. Added the PopupFlyoutBase.OverlayDismissEventPassThrough property and updated logic in Button.
…l. This was problematic when the popup was open with OverlayDismissEventPassThrough and clicking onto another control. Focus would not move to the clicked control.
@cla-avalonia
Copy link
Collaborator

cla-avalonia commented Apr 25, 2024

  • All contributors have signed the CLA.

@billhenn
Copy link
Contributor Author

@cla-avalonia agree

@maxkatz6
Copy link
Member

maxkatz6 commented May 8, 2024

@billhenn thanks! Would it be possible to add some tests for Flyout control at least? https://github.com/AvaloniaUI/Avalonia/blob/master/tests/Avalonia.Controls.UnitTests/FlyoutTests.cs

Also, Clicking_On_Control_PseudoClass test is failing now with this PR, for some reason pseudoclasses are not applied.

@maxkatz6 maxkatz6 added the backport-candidate-11.1.x Consider this PR for backporting to 11.1 branch label May 8, 2024
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.2.999-cibuild0048207-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.2.999-cibuild0048222-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@maxkatz6 maxkatz6 merged commit 0d1d72e into AvaloniaUI:master May 9, 2024
10 checks passed
grokys pushed a commit that referenced this pull request Aug 2, 2024
…Through (#15517)

* Updated Popup to raise the pass-through overlay dismiss event prior to possibly closing the popup when a pointer is pressed.  Added the PopupFlyoutBase.OverlayDismissEventPassThrough property and updated logic in Button.

* Updated SplitButton logic to handle OverlayDismissEventPassThrough scenarios.

* Updated CalendarDatePicker logic to handle OverlayDismissEventPassThrough scenarios.

* Updated ComboBox logic to handle OverlayDismissEventPassThrough scenarios.

* Removed unncessary ComboBox.PopupClosed logic that focused the control.  This was problematic when the popup was open with OverlayDismissEventPassThrough and clicking onto another control.  Focus would not move to the clicked control.

* Fixed the Clicking_On_Control_PseudoClass unit test to properly recognize pseudo-class behavior change.

* Added a couple unit tests to FlyoutTests.
@grokys grokys added backported-11.1.x and removed backport-candidate-11.1.x Consider this PR for backporting to 11.1 branch labels Aug 2, 2024
grokys pushed a commit that referenced this pull request Aug 2, 2024
…Through (#15517)

* Updated Popup to raise the pass-through overlay dismiss event prior to possibly closing the popup when a pointer is pressed.  Added the PopupFlyoutBase.OverlayDismissEventPassThrough property and updated logic in Button.

* Updated SplitButton logic to handle OverlayDismissEventPassThrough scenarios.

* Updated CalendarDatePicker logic to handle OverlayDismissEventPassThrough scenarios.

* Updated ComboBox logic to handle OverlayDismissEventPassThrough scenarios.

* Removed unncessary ComboBox.PopupClosed logic that focused the control.  This was problematic when the popup was open with OverlayDismissEventPassThrough and clicking onto another control.  Focus would not move to the clicked control.

* Fixed the Clicking_On_Control_PseudoClass unit test to properly recognize pseudo-class behavior change.

* Added a couple unit tests to FlyoutTests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants