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

[VDG] Unfocus SearchBar on Escape key #10722

Merged

Conversation

SuperJMN
Copy link
Collaborator

@SuperJMN SuperJMN commented May 17, 2023

Focusing away is the only method to hide the popup. We focus MainWindow so the SearchBar automatically closes its popup.

WalletWasabi.Fluent.Desktop_Cz4FY1zyN2.mp4

I've tried other solutions, but the UX is was bad. Just closing the flyout makes the keyboard caret stay inside without any feedback.

This is a good solution IMHO because, by definition, the searchbar will show the flyout whenever it's focused.

Fixes #10691

{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } mainWindow } && Application.Current.FocusManager is { } focusManager)
{
focusManager.Focus(mainWindow);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mainWindow.Focus()


if (AssociatedObject is InputElement interactive)
{
this.WhenAnyValue(x => x.EventRoutingStrategy, x => x.Key)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputRoot.AddDisposableHandler(InputElement.KeyDownEvent, RootDefaultKeyDown, EventRoutingStrategy)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why listen for changes just not use AddDisposableHandler as in linked behavior

Copy link
Collaborator Author

@SuperJMN SuperJMN May 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AddDisposableHandler creates a subscription, but my the pipeline requires IObservable<T>. That's why I use OnEvent instead.

		if (AssociatedObject is InputElement element)
		{
			this.WhenAnyValue(x => x.EventRoutingStrategy, x => x.Key, (strategy, key) => new { Key = key, RoutingStrategy = strategy })
				.Select(args => element.OnEvent(InputElement.KeyDownEvent, args.RoutingStrategy).Where(x => x.EventArgs.Key == args.Key))
				.Switch()
				.Do(_ => Interaction.ExecuteActions(AssociatedObject, Actions, null))
				.Subscribe()
				.DisposeWith(_disposables);
		}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can discuss which way is better if you show me how you'd implement it using AddDisposableHandler. I discarded it because the handler it takes doesn't fit well with the reactive paradigm.

Copy link
Collaborator

@soosr soosr May 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what @wieslawsoltes meant is it is very unlikely that either EventRoutingStrategy or Key will ever change during runtime, so observing for changes is unnecessary and just increases the complexity.

With his suggestion, you could do:

_subscription = element.AddDisposableHandler(InputElement.KeyDownEvent, OnKeyDown, EventRoutingStrategy);
private void OnKeyDown(object? sender, KeyEventArgs e)
{
	if (e.Key == Key)
	{
		Interaction.ExecuteActions(AssociatedObject, Actions, null);
	}
}

And also I think it would make sense to have a similar class like DisposingBehavior called DisposingTrigger. So the disposing could happen as usual and would also simplify a bit as you could do .DisposeWith(disposable);

@SuperJMN SuperJMN requested a review from ichthus1604 May 22, 2023 09:28
YohDeadfall
YohDeadfall previously approved these changes May 22, 2023
yahiheb
yahiheb previously approved these changes May 23, 2023
Copy link
Collaborator

@yahiheb yahiheb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK

@SuperJMN SuperJMN dismissed stale reviews from yahiheb and YohDeadfall via db1a198 May 23, 2023 09:03
Copy link
Collaborator

@soosr soosr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK

Comment on lines +20 to +26
public void Unfocus()
{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } mainWindow })
{
mainWindow.Focus();
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we should have a flag like SearchBar.IsActive and we should just modify that one value. And when it is false, the flyout should close and SearchBar should lose focus.

And everything should control that one flag. It is getting complex to handle every edge case.
Anyway, this is out of the scope of this PR.

@soosr soosr merged commit d501391 into zkSNACKs:master May 23, 2023
9 checks passed
@SuperJMN SuperJMN deleted the fixes/10691-escape-should-hide-searchbar branch May 23, 2023 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[VDG] Escape should close search bar pop-up
5 participants