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
This commit is contained in:
parent
54ed295588
commit
a900ababdc
|
@ -709,4 +709,10 @@
|
||||||
<data name="PlainText" xml:space="preserve">
|
<data name="PlainText" xml:space="preserve">
|
||||||
<value>Plain Text</value>
|
<value>Plain Text</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
|
||||||
|
<value>Termination behavior can be configured in advanced profile settings.</value>
|
||||||
|
</data>
|
||||||
|
<data name="InfoBarDismissButton.Content" xml:space="preserve">
|
||||||
|
<value>Don't show again</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -1108,6 +1108,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
// Add an event handler for when the terminal or tab wants to set a
|
// Add an event handler for when the terminal or tab wants to set a
|
||||||
// progress indicator on the taskbar
|
// progress indicator on the taskbar
|
||||||
term.SetTaskbarProgress({ get_weak(), &TerminalPage::_SetTaskbarProgressHandler });
|
term.SetTaskbarProgress({ get_weak(), &TerminalPage::_SetTaskbarProgressHandler });
|
||||||
|
|
||||||
|
term.ConnectionStateChanged({ get_weak(), &TerminalPage::_ConnectionStateChangedHandler });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -2876,11 +2878,14 @@ namespace winrt::TerminalApp::implementation
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Displays a dialog stating the "Touch Keyboard and Handwriting Panel
|
// - Displays a dialog stating the "Touch Keyboard and Handwriting Panel
|
||||||
// Service" is disabled.
|
// Service" is disabled.
|
||||||
void TerminalPage::ShowKeyboardServiceWarning()
|
void TerminalPage::ShowKeyboardServiceWarning() const
|
||||||
{
|
{
|
||||||
if (auto keyboardWarningInfoBar = FindName(L"KeyboardWarningInfoBar").try_as<MUX::Controls::InfoBar>())
|
if (!_IsMessageDismissed(InfoBarMessage::KeyboardServiceWarning))
|
||||||
{
|
{
|
||||||
keyboardWarningInfoBar.IsOpen(true);
|
if (const auto keyboardServiceWarningInfoBar = FindName(L"KeyboardServiceWarningInfoBar").try_as<MUX::Controls::InfoBar>())
|
||||||
|
{
|
||||||
|
keyboardServiceWarningInfoBar.IsOpen(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3242,4 +3247,99 @@ namespace winrt::TerminalApp::implementation
|
||||||
}
|
}
|
||||||
return profile;
|
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:
|
||||||
|
// - <none>
|
||||||
|
winrt::fire_and_forget TerminalPage::_ConnectionStateChangedHandler(const IInspectable& sender, const IInspectable& /*args*/) const
|
||||||
|
{
|
||||||
|
if (const auto coreState{ sender.try_as<winrt::Microsoft::Terminal::Control::ICoreState>() })
|
||||||
|
{
|
||||||
|
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<MUX::Controls::InfoBar>())
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void TerminalPage::_CloseOnExitInfoDismissHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/) const
|
||||||
|
{
|
||||||
|
_DismissMessage(InfoBarMessage::CloseOnExitInfo);
|
||||||
|
if (const auto infoBar = FindName(L"CloseOnExitInfoBar").try_as<MUX::Controls::InfoBar>())
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void TerminalPage::_KeyboardServiceWarningInfoDismissHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/) const
|
||||||
|
{
|
||||||
|
_DismissMessage(InfoBarMessage::KeyboardServiceWarning);
|
||||||
|
if (const auto infoBar = FindName(L"KeyboardServiceWarningInfoBar").try_as<MUX::Controls::InfoBar>())
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
// - <none>
|
||||||
|
void TerminalPage::_DismissMessage(const InfoBarMessage& message)
|
||||||
|
{
|
||||||
|
auto dismissedMessages = ApplicationState::SharedInstance().DismissedMessages();
|
||||||
|
if (!dismissedMessages)
|
||||||
|
{
|
||||||
|
dismissedMessages = winrt::single_threaded_vector<InfoBarMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
dismissedMessages.Append(message);
|
||||||
|
ApplicationState::SharedInstance().DismissedMessages(dismissedMessages);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
|
|
||||||
winrt::TerminalApp::TaskbarState TaskbarState() const;
|
winrt::TerminalApp::TaskbarState TaskbarState() const;
|
||||||
|
|
||||||
void ShowKeyboardServiceWarning();
|
void ShowKeyboardServiceWarning() const;
|
||||||
winrt::hstring KeyboardServiceDisabledText();
|
winrt::hstring KeyboardServiceDisabledText();
|
||||||
|
|
||||||
winrt::fire_and_forget IdentifyWindow();
|
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::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
|
#pragma region ActionHandlers
|
||||||
// These are all defined in AppActionHandlers.cpp
|
// These are all defined in AppActionHandlers.cpp
|
||||||
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
|
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
|
||||||
|
|
|
@ -114,13 +114,33 @@
|
||||||
PreviewKeyDown="_KeyDownHandler"
|
PreviewKeyDown="_KeyDownHandler"
|
||||||
Visibility="Collapsed" />
|
Visibility="Collapsed" />
|
||||||
|
|
||||||
<mux:InfoBar x:Name="KeyboardWarningInfoBar"
|
<StackPanel>
|
||||||
x:Load="False"
|
<mux:InfoBar x:Name="KeyboardServiceWarningInfoBar"
|
||||||
IsClosable="True"
|
x:Load="False"
|
||||||
IsIconVisible="True"
|
IsClosable="True"
|
||||||
IsOpen="False"
|
IsIconVisible="True"
|
||||||
Message="{x:Bind KeyboardServiceDisabledText, Mode=OneWay}"
|
IsOpen="False"
|
||||||
Severity="Warning" />
|
Message="{x:Bind KeyboardServiceDisabledText, Mode=OneWay}"
|
||||||
|
Severity="Warning">
|
||||||
|
<mux:InfoBar.ActionButton>
|
||||||
|
<Button x:Uid="InfoBarDismissButton"
|
||||||
|
Click="_KeyboardServiceWarningInfoDismissHandler" />
|
||||||
|
</mux:InfoBar.ActionButton>
|
||||||
|
</mux:InfoBar>
|
||||||
|
|
||||||
|
<mux:InfoBar x:Name="CloseOnExitInfoBar"
|
||||||
|
x:Uid="CloseOnExitInfoBar"
|
||||||
|
x:Load="False"
|
||||||
|
IsClosable="True"
|
||||||
|
IsIconVisible="True"
|
||||||
|
IsOpen="False"
|
||||||
|
Severity="Informational">
|
||||||
|
<mux:InfoBar.ActionButton>
|
||||||
|
<Button x:Uid="InfoBarDismissButton"
|
||||||
|
Click="_CloseOnExitInfoDismissHandler" />
|
||||||
|
</mux:InfoBar.ActionButton>
|
||||||
|
</mux:InfoBar>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
A TeachingTip with IsLightDismissEnabled="True" will immediately
|
A TeachingTip with IsLightDismissEnabled="True" will immediately
|
||||||
|
|
|
@ -28,7 +28,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
#define MTSM_APPLICATION_STATE_FIELDS(X) \
|
#define MTSM_APPLICATION_STATE_FIELDS(X) \
|
||||||
X(std::unordered_set<winrt::guid>, GeneratedProfiles, "generatedProfiles") \
|
X(std::unordered_set<winrt::guid>, GeneratedProfiles, "generatedProfiles") \
|
||||||
X(Windows::Foundation::Collections::IVector<Model::WindowLayout>, PersistedWindowLayouts, "persistedWindowLayouts") \
|
X(Windows::Foundation::Collections::IVector<Model::WindowLayout>, PersistedWindowLayouts, "persistedWindowLayouts") \
|
||||||
X(Windows::Foundation::Collections::IVector<hstring>, RecentCommands, "recentCommands")
|
X(Windows::Foundation::Collections::IVector<hstring>, RecentCommands, "recentCommands") \
|
||||||
|
X(Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage>, DismissedMessages, "dismissedMessages")
|
||||||
|
|
||||||
struct WindowLayout : WindowLayoutT<WindowLayout>
|
struct WindowLayout : WindowLayoutT<WindowLayout>
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,12 @@ import "GlobalAppSettings.idl";
|
||||||
|
|
||||||
namespace Microsoft.Terminal.Settings.Model
|
namespace Microsoft.Terminal.Settings.Model
|
||||||
{
|
{
|
||||||
|
enum InfoBarMessage
|
||||||
|
{
|
||||||
|
CloseOnExitInfo = 0,
|
||||||
|
KeyboardServiceWarning
|
||||||
|
};
|
||||||
|
|
||||||
runtimeclass WindowLayout
|
runtimeclass WindowLayout
|
||||||
{
|
{
|
||||||
WindowLayout();
|
WindowLayout();
|
||||||
|
@ -24,5 +30,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
Windows.Foundation.Collections.IVector<WindowLayout> PersistedWindowLayouts { get; set; };
|
Windows.Foundation.Collections.IVector<WindowLayout> PersistedWindowLayouts { get; set; };
|
||||||
|
|
||||||
Windows.Foundation.Collections.IVector<String> RecentCommands { get; set; };
|
Windows.Foundation.Collections.IVector<String> RecentCommands { get; set; };
|
||||||
|
|
||||||
|
Windows.Foundation.Collections.IVector<InfoBarMessage> DismissedMessages { get; set; };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,3 +500,11 @@ JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::IntenseStyle)
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage)
|
||||||
|
{
|
||||||
|
JSON_MAPPINGS(2) = {
|
||||||
|
pair_type{ "closeOnExitInfo", ValueType::CloseOnExitInfo },
|
||||||
|
pair_type{ "keyboardServiceWarning", ValueType::KeyboardServiceWarning },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue