Add a information popup about default terminals (#11397)
This commit adds a simple information popup about default terminals, guiding first-time Windows 11 users into changing the default terminal. ## Validation Steps Performed * Info bar pops up on Windows 11 ✔️ * Info bar can be dismissed persistently ✔️
This commit is contained in:
parent
e1c830dde0
commit
2b1468eaa2
|
@ -718,6 +718,9 @@
|
||||||
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
|
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
|
||||||
<value>Termination behavior can be configured in advanced profile settings.</value>
|
<value>Termination behavior can be configured in advanced profile settings.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
|
||||||
|
<value>Windows Terminal can be set as the default terminal application in your settings.</value>
|
||||||
|
</data>
|
||||||
<data name="InfoBarDismissButton.Content" xml:space="preserve">
|
<data name="InfoBarDismissButton.Content" xml:space="preserve">
|
||||||
<value>Don't show again</value>
|
<value>Don't show again</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -287,6 +287,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
_defaultPointerCursor = CoreWindow::GetForCurrentThread().PointerCursor();
|
_defaultPointerCursor = CoreWindow::GetForCurrentThread().PointerCursor();
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
|
|
||||||
|
ShowSetAsDefaultInfoBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description;
|
// Method Description;
|
||||||
|
@ -2893,6 +2895,29 @@ namespace winrt::TerminalApp::implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Displays a info popup guiding the user into setting their default terminal.
|
||||||
|
void TerminalPage::ShowSetAsDefaultInfoBar() const
|
||||||
|
{
|
||||||
|
if (!CascadiaSettings::IsDefaultTerminalAvailable() || _IsMessageDismissed(InfoBarMessage::SetAsDefault))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user has already configured any terminal for hand-off we
|
||||||
|
// shouldn't inform them again about the possibility to do so.
|
||||||
|
if (CascadiaSettings::IsDefaultTerminalSet())
|
||||||
|
{
|
||||||
|
_DismissMessage(InfoBarMessage::SetAsDefault);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto infoBar = FindName(L"SetAsDefaultInfoBar").try_as<MUX::Controls::InfoBar>())
|
||||||
|
{
|
||||||
|
infoBar.IsOpen(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Function Description:
|
// Function Description:
|
||||||
// - Helper function to get the OS-localized name for the "Touch Keyboard
|
// - Helper function to get the OS-localized name for the "Touch Keyboard
|
||||||
// and Handwriting Panel Service". If we can't open up the service for any
|
// and Handwriting Panel Service". If we can't open up the service for any
|
||||||
|
@ -3313,6 +3338,22 @@ namespace winrt::TerminalApp::implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Persists the user's choice not to show the information bar warning about "Windows Terminal can be set as your default terminal application"
|
||||||
|
// Then hides this information buffer.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void TerminalPage::_SetAsDefaultDismissHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/) const
|
||||||
|
{
|
||||||
|
_DismissMessage(InfoBarMessage::SetAsDefault);
|
||||||
|
if (const auto infoBar = FindName(L"SetAsDefaultInfoBar").try_as<MUX::Controls::InfoBar>())
|
||||||
|
{
|
||||||
|
infoBar.IsOpen(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Checks whether information bar message was dismissed earlier (in the application state)
|
// - Checks whether information bar message was dismissed earlier (in the application state)
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
@ -3342,13 +3383,20 @@ namespace winrt::TerminalApp::implementation
|
||||||
// - <none>
|
// - <none>
|
||||||
void TerminalPage::_DismissMessage(const InfoBarMessage& message)
|
void TerminalPage::_DismissMessage(const InfoBarMessage& message)
|
||||||
{
|
{
|
||||||
auto dismissedMessages = ApplicationState::SharedInstance().DismissedMessages();
|
const auto applicationState = ApplicationState::SharedInstance();
|
||||||
if (!dismissedMessages)
|
std::vector<InfoBarMessage> messages;
|
||||||
|
|
||||||
|
if (const auto values = applicationState.DismissedMessages())
|
||||||
{
|
{
|
||||||
dismissedMessages = winrt::single_threaded_vector<InfoBarMessage>();
|
messages.resize(values.Size());
|
||||||
|
values.GetMany(0, messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
dismissedMessages.Append(message);
|
if (std::none_of(messages.begin(), messages.end(), [&](const auto& m) { return m == message; }))
|
||||||
ApplicationState::SharedInstance().DismissedMessages(dismissedMessages);
|
{
|
||||||
|
messages.emplace_back(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
applicationState.DismissedMessages(std::move(messages));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
winrt::TerminalApp::TaskbarState TaskbarState() const;
|
winrt::TerminalApp::TaskbarState TaskbarState() const;
|
||||||
|
|
||||||
void ShowKeyboardServiceWarning() const;
|
void ShowKeyboardServiceWarning() const;
|
||||||
|
void ShowSetAsDefaultInfoBar() const;
|
||||||
winrt::hstring KeyboardServiceDisabledText();
|
winrt::hstring KeyboardServiceDisabledText();
|
||||||
|
|
||||||
winrt::fire_and_forget IdentifyWindow();
|
winrt::fire_and_forget IdentifyWindow();
|
||||||
|
@ -403,6 +404,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
winrt::fire_and_forget _ConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
|
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 _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;
|
void _KeyboardServiceWarningInfoDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
|
||||||
|
void _SetAsDefaultDismissHandler(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 bool _IsMessageDismissed(const winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage& message);
|
||||||
static void _DismissMessage(const winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage& message);
|
static void _DismissMessage(const winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage& message);
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,19 @@
|
||||||
Click="_CloseOnExitInfoDismissHandler" />
|
Click="_CloseOnExitInfoDismissHandler" />
|
||||||
</mux:InfoBar.ActionButton>
|
</mux:InfoBar.ActionButton>
|
||||||
</mux:InfoBar>
|
</mux:InfoBar>
|
||||||
|
|
||||||
|
<mux:InfoBar x:Name="SetAsDefaultInfoBar"
|
||||||
|
x:Uid="SetAsDefaultInfoBar"
|
||||||
|
x:Load="False"
|
||||||
|
IsClosable="True"
|
||||||
|
IsIconVisible="True"
|
||||||
|
IsOpen="False"
|
||||||
|
Severity="Informational">
|
||||||
|
<mux:InfoBar.ActionButton>
|
||||||
|
<Button x:Uid="InfoBarDismissButton"
|
||||||
|
Click="_SetAsDefaultDismissHandler" />
|
||||||
|
</mux:InfoBar.ActionButton>
|
||||||
|
</mux:InfoBar>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -8,7 +8,8 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
enum InfoBarMessage
|
enum InfoBarMessage
|
||||||
{
|
{
|
||||||
CloseOnExitInfo = 0,
|
CloseOnExitInfo = 0,
|
||||||
KeyboardServiceWarning
|
KeyboardServiceWarning,
|
||||||
|
SetAsDefault,
|
||||||
};
|
};
|
||||||
|
|
||||||
runtimeclass WindowLayout
|
runtimeclass WindowLayout
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
|
#include <WtExeUtils.h>
|
||||||
|
|
||||||
using namespace winrt::Microsoft::Terminal;
|
using namespace winrt::Microsoft::Terminal;
|
||||||
using namespace winrt::Microsoft::Terminal::Settings;
|
using namespace winrt::Microsoft::Terminal::Settings;
|
||||||
|
@ -837,6 +838,11 @@ winrt::hstring CascadiaSettings::ApplicationVersion()
|
||||||
// - True if OS supports default terminal. False otherwise.
|
// - True if OS supports default terminal. False otherwise.
|
||||||
bool CascadiaSettings::IsDefaultTerminalAvailable() noexcept
|
bool CascadiaSettings::IsDefaultTerminalAvailable() noexcept
|
||||||
{
|
{
|
||||||
|
if (!IsPackaged())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
OSVERSIONINFOEXW osver{};
|
OSVERSIONINFOEXW osver{};
|
||||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||||
osver.dwBuildNumber = 22000;
|
osver.dwBuildNumber = 22000;
|
||||||
|
@ -847,6 +853,11 @@ bool CascadiaSettings::IsDefaultTerminalAvailable() noexcept
|
||||||
return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE;
|
return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CascadiaSettings::IsDefaultTerminalSet() noexcept
|
||||||
|
{
|
||||||
|
return DefaultTerminal::HasCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Returns an iterable collection of all available terminals.
|
// - Returns an iterable collection of all available terminals.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
|
|
@ -134,6 +134,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
|
|
||||||
// defterm
|
// defterm
|
||||||
static bool IsDefaultTerminalAvailable() noexcept;
|
static bool IsDefaultTerminalAvailable() noexcept;
|
||||||
|
static bool IsDefaultTerminalSet() noexcept;
|
||||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::DefaultTerminal> DefaultTerminals() noexcept;
|
winrt::Windows::Foundation::Collections::IObservableVector<Model::DefaultTerminal> DefaultTerminals() noexcept;
|
||||||
Model::DefaultTerminal CurrentDefaultTerminal() noexcept;
|
Model::DefaultTerminal CurrentDefaultTerminal() noexcept;
|
||||||
void CurrentDefaultTerminal(const Model::DefaultTerminal& terminal);
|
void CurrentDefaultTerminal(const Model::DefaultTerminal& terminal);
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
Profile GetProfileForArgs(NewTerminalArgs newTerminalArgs);
|
Profile GetProfileForArgs(NewTerminalArgs newTerminalArgs);
|
||||||
|
|
||||||
static Boolean IsDefaultTerminalAvailable { get; };
|
static Boolean IsDefaultTerminalAvailable { get; };
|
||||||
|
static Boolean IsDefaultTerminalSet { get; };
|
||||||
IObservableVector<DefaultTerminal> DefaultTerminals { get; };
|
IObservableVector<DefaultTerminal> DefaultTerminals { get; };
|
||||||
DefaultTerminal CurrentDefaultTerminal;
|
DefaultTerminal CurrentDefaultTerminal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,16 @@ std::pair<std::vector<Model::DefaultTerminal>, Model::DefaultTerminal> DefaultTe
|
||||||
return { std::move(defaultTerminals), std::move(defaultTerminal) };
|
return { std::move(defaultTerminals), std::move(defaultTerminal) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DefaultTerminal::HasCurrent()
|
||||||
|
{
|
||||||
|
std::vector<DelegationConfig::DelegationPackage> allPackages;
|
||||||
|
DelegationConfig::DelegationPackage currentPackage;
|
||||||
|
LOG_IF_FAILED(DelegationConfig::s_GetAvailablePackages(allPackages, currentPackage));
|
||||||
|
|
||||||
|
// Good old conhost has a hardcoded GUID of {00000000-0000-0000-0000-000000000000}.
|
||||||
|
return currentPackage.terminal.clsid != CLSID{};
|
||||||
|
}
|
||||||
|
|
||||||
void DefaultTerminal::Current(const Model::DefaultTerminal& term)
|
void DefaultTerminal::Current(const Model::DefaultTerminal& term)
|
||||||
{
|
{
|
||||||
THROW_IF_FAILED(DelegationConfig::s_SetDefaultByPackage(winrt::get_self<DefaultTerminal>(term)->_pkg, true));
|
THROW_IF_FAILED(DelegationConfig::s_SetDefaultByPackage(winrt::get_self<DefaultTerminal>(term)->_pkg, true));
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
hstring Icon() const;
|
hstring Icon() const;
|
||||||
|
|
||||||
static std::pair<std::vector<Model::DefaultTerminal>, Model::DefaultTerminal> Available();
|
static std::pair<std::vector<Model::DefaultTerminal>, Model::DefaultTerminal> Available();
|
||||||
|
static bool HasCurrent();
|
||||||
static void Current(const Model::DefaultTerminal& term);
|
static void Current(const Model::DefaultTerminal& term);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -537,8 +537,9 @@ JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::IntenseStyle)
|
||||||
|
|
||||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage)
|
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage)
|
||||||
{
|
{
|
||||||
JSON_MAPPINGS(2) = {
|
JSON_MAPPINGS(3) = {
|
||||||
pair_type{ "closeOnExitInfo", ValueType::CloseOnExitInfo },
|
pair_type{ "closeOnExitInfo", ValueType::CloseOnExitInfo },
|
||||||
pair_type{ "keyboardServiceWarning", ValueType::KeyboardServiceWarning },
|
pair_type{ "keyboardServiceWarning", ValueType::KeyboardServiceWarning },
|
||||||
|
pair_type{ "setAsDefault", ValueType::SetAsDefault },
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue