diff --git a/src/Files.App.Controls/Omnibar/Omnibar.Events.cs b/src/Files.App.Controls/Omnibar/Omnibar.Events.cs index 9b224f0f442f..f33680ad704f 100644 --- a/src/Files.App.Controls/Omnibar/Omnibar.Events.cs +++ b/src/Files.App.Controls/Omnibar/Omnibar.Events.cs @@ -1,10 +1,8 @@ // Copyright (c) Files Community // Licensed under the MIT License. -using Microsoft.UI.Input; using Microsoft.UI.Xaml.Input; using Windows.System; -using Windows.UI.Core; namespace Files.App.Controls { @@ -28,7 +26,7 @@ private void AutoSuggestBox_GettingFocus(UIElement sender, GettingFocusEventArgs private void AutoSuggestBox_LosingFocus(UIElement sender, LosingFocusEventArgs args) { - if (IsModeButtonPressed) + if (args.NewFocusedElement is Button && IsModeButtonPressed) { IsModeButtonPressed = false; args.TryCancel(); @@ -47,12 +45,16 @@ private void AutoSuggestBox_GotFocus(object sender, RoutedEventArgs e) private void AutoSuggestBox_LostFocus(object sender, RoutedEventArgs e) { // TextBox still has focus if the context menu for selected text is open - if (_textBox.ContextFlyout.IsOpen) + var element = Microsoft.UI.Xaml.Input.FocusManager.GetFocusedElement(this.XamlRoot); + if (element is FlyoutBase or Popup) return; GlobalHelper.WriteDebugStringForOmnibar("The TextBox lost the focus."); IsFocused = false; + + // Reset to the default mode when Omnibar loses focus + CurrentSelectedMode = Modes?.FirstOrDefault(); } private async void AutoSuggestBox_KeyDown(object sender, KeyRoutedEventArgs e) @@ -112,16 +114,6 @@ private async void AutoSuggestBox_KeyDown(object sender, KeyRoutedEventArgs e) previouslyFocusedElement?.Focus(FocusState.Programmatic); } } - else if (e.Key == VirtualKey.Tab && !InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down)) - { - GlobalHelper.WriteDebugStringForOmnibar("The TextBox accepted the Tab key."); - - // Focus on inactive content when pressing Tab instead of moving to the next control in the tab order - e.Handled = true; - IsFocused = false; - await Task.Delay(15); - CurrentSelectedMode?.ContentOnInactive?.Focus(FocusState.Keyboard); - } else { _textChangeReason = OmnibarTextChangeReason.UserInput; @@ -141,6 +133,8 @@ private void AutoSuggestBox_TextChanged(object sender, TextChangedEventArgs e) _textChangeReason = OmnibarTextChangeReason.UserInput; _userInput = _textBox.Text; } + else if (_textChangeReason is OmnibarTextChangeReason.ProgrammaticChange) + _textBox.SelectAll(); TextChanged?.Invoke(this, new(CurrentSelectedMode, _textChangeReason)); diff --git a/src/Files.App.Controls/Omnibar/Omnibar.cs b/src/Files.App.Controls/Omnibar/Omnibar.cs index ff02da54c508..fbe301a3b9df 100644 --- a/src/Files.App.Controls/Omnibar/Omnibar.cs +++ b/src/Files.App.Controls/Omnibar/Omnibar.cs @@ -128,7 +128,7 @@ protected void ChangeMode(OmnibarMode? oldMode, OmnibarMode newMode) // Add the reposition transition to the all modes mode.Transitions = [new RepositionThemeTransition()]; mode.UpdateLayout(); - mode.IsTabStop = true; + mode.IsTabStop = false; } var index = _modesHostGrid.Children.IndexOf(newMode); diff --git a/src/Files.App.Controls/Omnibar/Omnibar.xaml b/src/Files.App.Controls/Omnibar/Omnibar.xaml index c5afe0825931..546902e4663a 100644 --- a/src/Files.App.Controls/Omnibar/Omnibar.xaml +++ b/src/Files.App.Controls/Omnibar/Omnibar.xaml @@ -117,9 +117,6 @@ - - - @@ -127,23 +124,21 @@ x:Name="PART_RootGrid" Height="{TemplateBinding Height}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" - Background="{TemplateBinding Background}" - TabFocusNavigation="Local"> + Background="{TemplateBinding Background}"> - - - - + ToolTipService.ToolTip="{Binding ModeName, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"> + + + + - + - - - - - + - diff --git a/src/Files.App.Controls/Omnibar/OmnibarMode.Events.cs b/src/Files.App.Controls/Omnibar/OmnibarMode.Events.cs index 39fed9ea25b1..a40dd8abbdcb 100644 --- a/src/Files.App.Controls/Omnibar/OmnibarMode.Events.cs +++ b/src/Files.App.Controls/Omnibar/OmnibarMode.Events.cs @@ -35,11 +35,6 @@ private void ModeButton_PointerReleased(object sender, PointerRoutedEventArgs e) GlobalHelper.WriteDebugStringForOmnibar($"The mouse pointer has been unpressed from the UI area of this Mode ({this})"); VisualStateManager.GoToState(this, "PointerOver", true); - - owner.IsModeButtonPressed = true; - - // Change the current mode - owner.CurrentSelectedMode = this; } private void ModeButton_PointerExited(object sender, PointerRoutedEventArgs e) @@ -48,5 +43,14 @@ private void ModeButton_PointerExited(object sender, PointerRoutedEventArgs e) VisualStateManager.GoToState(this, "PointerNormal", true); } + + private void ModeButton_Click(object sender, RoutedEventArgs e) + { + if (_ownerRef is null || _ownerRef.TryGetTarget(out var owner) is false || owner.CurrentSelectedMode == this) + return; + + owner.IsModeButtonPressed = true; + owner.CurrentSelectedMode = this; + } } -} +} \ No newline at end of file diff --git a/src/Files.App.Controls/Omnibar/OmnibarMode.cs b/src/Files.App.Controls/Omnibar/OmnibarMode.cs index f75bffcb9412..e91e05abe24b 100644 --- a/src/Files.App.Controls/Omnibar/OmnibarMode.cs +++ b/src/Files.App.Controls/Omnibar/OmnibarMode.cs @@ -16,7 +16,7 @@ public partial class OmnibarMode : ItemsControl private WeakReference? _ownerRef; - private Border _modeButton = null!; + private Button _modeButton = null!; // Constructor @@ -33,7 +33,7 @@ protected override void OnApplyTemplate() { base.OnApplyTemplate(); - _modeButton = GetTemplateChild(TemplatePartName_ModeButton) as Border + _modeButton = GetTemplateChild(TemplatePartName_ModeButton) as Button ?? throw new MissingFieldException($"Could not find {TemplatePartName_ModeButton} in the given {nameof(OmnibarMode)}'s style."); Loaded += OmnibarMode_Loaded; @@ -41,6 +41,7 @@ protected override void OnApplyTemplate() _modeButton.PointerPressed += ModeButton_PointerPressed; _modeButton.PointerReleased += ModeButton_PointerReleased; _modeButton.PointerExited += ModeButton_PointerExited; + _modeButton.Click += ModeButton_Click; GlobalHelper.WriteDebugStringForOmnibar($"The template and the events of the Omnibar Mode ({this}) have been initialized."); } diff --git a/src/Files.App/UserControls/NavigationToolbar.xaml b/src/Files.App/UserControls/NavigationToolbar.xaml index acf1697fc5f4..5d4a2db52e38 100644 --- a/src/Files.App/UserControls/NavigationToolbar.xaml +++ b/src/Files.App/UserControls/NavigationToolbar.xaml @@ -351,7 +351,7 @@ x:Load="{x:Bind ViewModel.EnableOmnibar, Mode=OneWay}" CurrentSelectedModeName="{x:Bind ViewModel.OmnibarCurrentSelectedModeName, Mode=TwoWay}" IsFocused="{x:Bind ViewModel.IsOmnibarFocused, Mode=TwoWay}" - LostFocus="Omnibar_LostFocus" + ModeChanged="Omnibar_ModeChanged" PreviewKeyDown="Omnibar_PreviewKeyDown" QuerySubmitted="Omnibar_QuerySubmitted" TextChanged="Omnibar_TextChanged"> diff --git a/src/Files.App/UserControls/NavigationToolbar.xaml.cs b/src/Files.App/UserControls/NavigationToolbar.xaml.cs index 900d19f769d6..719b32093f3c 100644 --- a/src/Files.App/UserControls/NavigationToolbar.xaml.cs +++ b/src/Files.App/UserControls/NavigationToolbar.xaml.cs @@ -12,6 +12,7 @@ using Microsoft.UI.Xaml.Navigation; using Windows.AI.Actions.Hosting; using Windows.System; +using Windows.UI.Core; namespace Files.App.UserControls { @@ -427,22 +428,31 @@ private void BreadcrumbBar_ItemDropDownFlyoutClosed(object sender, BreadcrumbBar e.Flyout.Items.Clear(); } - private void Omnibar_LostFocus(object sender, RoutedEventArgs e) + private void Omnibar_ModeChanged(object sender, OmnibarModeChangedEventArgs e) { + // Reset the command palette text when switching modes if (Omnibar.CurrentSelectedMode == OmnibarCommandPaletteMode) - { - Omnibar.CurrentSelectedMode = OmnibarPathMode; ViewModel.OmnibarCommandPaletteModeText = string.Empty; - } } - private void Omnibar_PreviewKeyDown(object sender, KeyRoutedEventArgs e) + private async void Omnibar_PreviewKeyDown(object sender, KeyRoutedEventArgs e) { if (e.Key is VirtualKey.Escape) { Omnibar.IsFocused = false; (MainPageViewModel.SelectedTabItem?.TabItemContent as Control)?.Focus(FocusState.Programmatic); } + else if (e.Key is VirtualKey.Tab && Omnibar.IsFocused && !InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down)) + { + var currentSelectedMode = Omnibar.CurrentSelectedMode; + Omnibar.IsFocused = false; + await Task.Delay(15); + + if (currentSelectedMode == OmnibarPathMode) + BreadcrumbBar.Focus(FocusState.Keyboard); + else if (currentSelectedMode == OmnibarCommandPaletteMode) + OmnibarCommandPaletteMode.Focus(FocusState.Keyboard); + } } private void NavigationButtonOverflowFlyoutButton_LosingFocus(UIElement sender, LosingFocusEventArgs args)