From 2e53d0bd1e5f786bf02d402873d0c78407524339 Mon Sep 17 00:00:00 2001 From: Stephen L Peters Date: Thu, 24 Mar 2022 11:48:29 -0700 Subject: [PATCH] Fix F6 unable to return from teaching tip in xaml island. (#6807) --- dev/TeachingTip/TeachingTip.cpp | 40 +++++++++++++++++++++++++++------ dev/TeachingTip/TeachingTip.h | 7 ++++-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/dev/TeachingTip/TeachingTip.cpp b/dev/TeachingTip/TeachingTip.cpp index 61ec366a1e..3d59f7a0e7 100644 --- a/dev/TeachingTip/TeachingTip.cpp +++ b/dev/TeachingTip/TeachingTip.cpp @@ -920,7 +920,7 @@ void TeachingTip::IsOpenChangedToOpen() return; } } - }; + } m_acceleratorKeyActivatedRevoker = Dispatcher().AcceleratorKeyActivated(winrt::auto_revoke, { this, &TeachingTip::OnF6AcceleratorKeyClicked }); return; @@ -953,6 +953,7 @@ void TeachingTip::IsOpenChangedToClose() m_acceleratorKeyActivatedRevoker.revoke(); m_previewKeyDownForF6Revoker.revoke(); + m_popupPreviewKeyDownForF6Revoker.revoke(); m_currentEffectiveTipPlacementMode = winrt::TeachingTipPlacementMode::Auto; TeachingTipTestHooks::NotifyEffectivePlacementChanged(*this); } @@ -1112,7 +1113,17 @@ void TeachingTip::OnF6PreviewKeyDownClicked(const winrt::IInspectable&, const wi } } -bool TeachingTip::HandleF6Clicked() +void TeachingTip::OnF6PopupPreviewKeyDownClicked(const winrt::IInspectable&, const winrt::KeyRoutedEventArgs& args) +{ + if (!args.Handled() && + IsOpen() && + args.Key() == winrt::VirtualKey::F6) + { + args.Handled(HandleF6Clicked(/*fromPopup*/true)); + } +} + +bool TeachingTip::HandleF6Clicked(bool fromPopup) { // Logging usage telemetry if (m_hasF6BeenInvoked) @@ -1127,9 +1138,16 @@ bool TeachingTip::HandleF6Clicked() auto const hasFocusInSubtree = [this]() { - auto current = winrt::FocusManager::GetFocusedElement().try_as(); if (auto const rootElement = m_rootElement.get()) { + auto current = [rootElement]() { + if (winrt::IUIElement10 uiElement10 = rootElement) + { + return winrt::FocusManager::GetFocusedElement(uiElement10.XamlRoot()).try_as(); + } + return winrt::FocusManager::GetFocusedElement().try_as(); + }(); + while (current) { if (current.try_as() == rootElement) @@ -1142,13 +1160,13 @@ bool TeachingTip::HandleF6Clicked() return false; }(); - if (hasFocusInSubtree) + if (hasFocusInSubtree && fromPopup) { bool setFocus = SetFocus(m_previouslyFocusedElement.get(), winrt::FocusState::Programmatic); m_previouslyFocusedElement = nullptr; return setFocus; } - else + else if (!hasFocusInSubtree && !fromPopup) { const winrt::Button f6Button = [this]() -> winrt::Button { @@ -1178,9 +1196,8 @@ bool TeachingTip::HandleF6Clicked() const bool setFocus = f6Button.Focus(winrt::FocusState::Keyboard); return setFocus; } - - return false; } + return false; } void TeachingTip::OnAutomationNameChanged(const winrt::IInspectable&, const winrt::IInspectable&) @@ -1214,6 +1231,15 @@ void TeachingTip::OnPopupOpened(const winrt::IInspectable&, const winrt::IInspec m_currentXamlRootSize = xamlRoot.Size(); m_xamlRoot.set(xamlRoot); m_xamlRootChangedRevoker = RegisterXamlRootChanged(xamlRoot, { this, &TeachingTip::XamlRootChanged }); + + if (auto&& popup = m_popup.get()) + { + if (auto const popupContent = popup.Child()) + { + // This handler is not required for Winui3 because the framework bug this works around has been fixed. + m_popupPreviewKeyDownForF6Revoker = popupContent.PreviewKeyDown(winrt::auto_revoke, { this, &TeachingTip::OnF6PopupPreviewKeyDownClicked }); + } + } } } else diff --git a/dev/TeachingTip/TeachingTip.h b/dev/TeachingTip/TeachingTip.h index c1e2144ad4..6b62eedc22 100644 --- a/dev/TeachingTip/TeachingTip.h +++ b/dev/TeachingTip/TeachingTip.h @@ -63,6 +63,8 @@ class TeachingTip : PropertyChanged_revoker m_automationIdChangedRevoker{}; winrt::CoreDispatcher::AcceleratorKeyActivated_revoker m_acceleratorKeyActivatedRevoker{}; winrt::UIElement::PreviewKeyDown_revoker m_previewKeyDownForF6Revoker{}; + // This handler is not required for Winui3 because the framework bug this works around has been fixed. + winrt::UIElement::PreviewKeyDown_revoker m_popupPreviewKeyDownForF6Revoker{}; winrt::Button::Click_revoker m_closeButtonClickedRevoker{}; winrt::Button::Click_revoker m_alternateCloseButtonClickedRevoker{}; winrt::Button::Click_revoker m_actionButtonClickedRevoker{}; @@ -115,9 +117,10 @@ class TeachingTip : void OnAutomationIdChanged(const winrt::IInspectable&, const winrt::IInspectable&); void OnContentSizeChanged(const winrt::IInspectable&, const winrt::SizeChangedEventArgs& args); - void OnF6AcceleratorKeyClicked(const winrt::CoreDispatcher&, const winrt::AcceleratorKeyEventArgs& args); void OnF6PreviewKeyDownClicked(const winrt::IInspectable&, const winrt::KeyRoutedEventArgs& args); - bool HandleF6Clicked(); + void OnF6PopupPreviewKeyDownClicked(const winrt::IInspectable&, const winrt::KeyRoutedEventArgs& args); + void OnF6AcceleratorKeyClicked(const winrt::CoreDispatcher&, const winrt::AcceleratorKeyEventArgs& args); + bool HandleF6Clicked(bool fromPopup = false); void OnCloseButtonClicked(const winrt::IInspectable&, const winrt::RoutedEventArgs&); void OnActionButtonClicked(const winrt::IInspectable&, const winrt::RoutedEventArgs&); void OnPopupOpened(const winrt::IInspectable&, const winrt::IInspectable&);