From a900ababdcca98e7875d2b1a6e47f9d0f52dbb3f Mon Sep 17 00:00:00 2001 From: Don-Vito Date: Fri, 10 Sep 2021 20:16:41 +0300 Subject: [PATCH] Teach info bars to be dismissed permanently (#11139) ## Summary of the Pull Request * Introduces info bar shown upon session failure, that guides the user how to configure termination behavior * Allows this info bar to be dismissed permanently (choice stored in state) * Allows "keyboard service" info bar to be dismissed permanently ## PR Checklist * [x] Closes #10798, #8699 * [x] CLA signed. * [ ] Tests added/passed * [ ] Documentation updated. * [ ] Schema updated. * [ ] I've discussed this with core contributors already. ## Detailed Description of the Pull Request / Additional comments UI: * Introduce an additional info bar for "close on exit" configuration tip * Stack this bar after "keyboard service" bar * Add "Don't show again" button to both bars Dismiss Permanently: * Introduce a set of "dismissed messages" to the Application State * Add verification the message is not dismissed before showing an info bar * "Don't show again" persists the choice under "dismissed messages" Wiring the Info Bar: * Register `TerminalPage` on `TermControl`'s `ConnectionStateChanged` event * Once event is triggered check whether the state is failure * If so and the message was not dismissed permanently, show the info bar --- .../Resources/en-US/Resources.resw | 6 + src/cascadia/TerminalApp/TerminalPage.cpp | 106 +++++++++++++++++- src/cascadia/TerminalApp/TerminalPage.h | 8 +- src/cascadia/TerminalApp/TerminalPage.xaml | 34 ++++-- .../TerminalSettingsModel/ApplicationState.h | 3 +- .../ApplicationState.idl | 8 ++ .../TerminalSettingsSerializationHelpers.h | 8 ++ 7 files changed, 161 insertions(+), 12 deletions(-) diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 58d5437a8..3f2aaea18 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -709,4 +709,10 @@ Plain Text + + Termination behavior can be configured in advanced profile settings. + + + Don't show again + diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 8eda026cd..8e252098f 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1108,6 +1108,8 @@ namespace winrt::TerminalApp::implementation // Add an event handler for when the terminal or tab wants to set a // progress indicator on the taskbar term.SetTaskbarProgress({ get_weak(), &TerminalPage::_SetTaskbarProgressHandler }); + + term.ConnectionStateChanged({ get_weak(), &TerminalPage::_ConnectionStateChangedHandler }); } // Method Description: @@ -2876,11 +2878,14 @@ namespace winrt::TerminalApp::implementation // Method Description: // - Displays a dialog stating the "Touch Keyboard and Handwriting Panel // Service" is disabled. - void TerminalPage::ShowKeyboardServiceWarning() + void TerminalPage::ShowKeyboardServiceWarning() const { - if (auto keyboardWarningInfoBar = FindName(L"KeyboardWarningInfoBar").try_as()) + if (!_IsMessageDismissed(InfoBarMessage::KeyboardServiceWarning)) { - keyboardWarningInfoBar.IsOpen(true); + if (const auto keyboardServiceWarningInfoBar = FindName(L"KeyboardServiceWarningInfoBar").try_as()) + { + keyboardServiceWarningInfoBar.IsOpen(true); + } } } @@ -3242,4 +3247,99 @@ namespace winrt::TerminalApp::implementation } return profile; } + + // Method Description: + // - Handles the change of connection state. + // If the connection state is failure show information bar suggesting to configure termination behavior + // (unless user asked not to show this message again) + // Arguments: + // - sender: the ICoreState instance containing the connection state + // Return Value: + // - + winrt::fire_and_forget TerminalPage::_ConnectionStateChangedHandler(const IInspectable& sender, const IInspectable& /*args*/) const + { + if (const auto coreState{ sender.try_as() }) + { + const auto newConnectionState = coreState.ConnectionState(); + if (newConnectionState == ConnectionState::Failed && !_IsMessageDismissed(InfoBarMessage::CloseOnExitInfo)) + { + co_await winrt::resume_foreground(Dispatcher()); + if (const auto infoBar = FindName(L"CloseOnExitInfoBar").try_as()) + { + infoBar.IsOpen(true); + } + } + } + } + + // Method Description: + // - Persists the user's choice not to show information bar guiding to configure termination behavior. + // Then hides this information buffer. + // Arguments: + // - + // Return Value: + // - + void TerminalPage::_CloseOnExitInfoDismissHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/) const + { + _DismissMessage(InfoBarMessage::CloseOnExitInfo); + if (const auto infoBar = FindName(L"CloseOnExitInfoBar").try_as()) + { + infoBar.IsOpen(false); + } + } + + // Method Description: + // - Persists the user's choice not to show information bar warning about "Touch keyboard and Handwriting Panel Service" disabled + // Then hides this information buffer. + // Arguments: + // - + // Return Value: + // - + void TerminalPage::_KeyboardServiceWarningInfoDismissHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/) const + { + _DismissMessage(InfoBarMessage::KeyboardServiceWarning); + if (const auto infoBar = FindName(L"KeyboardServiceWarningInfoBar").try_as()) + { + infoBar.IsOpen(false); + } + } + + // Method Description: + // - Checks whether information bar message was dismissed earlier (in the application state) + // Arguments: + // - message: message to look for in the state + // Return Value: + // - true, if the message was dismissed + bool TerminalPage::_IsMessageDismissed(const InfoBarMessage& message) + { + if (const auto dismissedMessages{ ApplicationState::SharedInstance().DismissedMessages() }) + { + for (const auto& dismissedMessage : dismissedMessages) + { + if (dismissedMessage == message) + { + return true; + } + } + } + return false; + } + + // Method Description: + // - Persists the user's choice to dismiss information bar message (in application state) + // Arguments: + // - message: message to dismiss + // Return Value: + // - + void TerminalPage::_DismissMessage(const InfoBarMessage& message) + { + auto dismissedMessages = ApplicationState::SharedInstance().DismissedMessages(); + if (!dismissedMessages) + { + dismissedMessages = winrt::single_threaded_vector(); + } + + dismissedMessages.Append(message); + ApplicationState::SharedInstance().DismissedMessages(dismissedMessages); + } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 772d724ea..5ffee2fcb 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -92,7 +92,7 @@ namespace winrt::TerminalApp::implementation winrt::TerminalApp::TaskbarState TaskbarState() const; - void ShowKeyboardServiceWarning(); + void ShowKeyboardServiceWarning() const; winrt::hstring KeyboardServiceDisabledText(); winrt::fire_and_forget IdentifyWindow(); @@ -373,6 +373,12 @@ namespace winrt::TerminalApp::implementation winrt::Microsoft::Terminal::Settings::Model::Profile GetClosestProfileForDuplicationOfProfile(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile) const noexcept; + winrt::fire_and_forget _ConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const; + void _CloseOnExitInfoDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const; + void _KeyboardServiceWarningInfoDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const; + static bool _IsMessageDismissed(const winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage& message); + static void _DismissMessage(const winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage& message); + #pragma region ActionHandlers // These are all defined in AppActionHandlers.cpp #define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action); diff --git a/src/cascadia/TerminalApp/TerminalPage.xaml b/src/cascadia/TerminalApp/TerminalPage.xaml index ad592ec77..eea2039f6 100644 --- a/src/cascadia/TerminalApp/TerminalPage.xaml +++ b/src/cascadia/TerminalApp/TerminalPage.xaml @@ -114,13 +114,33 @@ PreviewKeyDown="_KeyDownHandler" Visibility="Collapsed" /> - + + + +