Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add input scope startup setting #17953

Merged
merged 2 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/actions/spelling/expect/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ INLINEPREFIX
inproc
Inputkeyinfo
Inputreadhandledata
INPUTSCOPE
INSERTMODE
INTERACTIVITYBASE
INTERCEPTCOPYPASTE
Expand Down Expand Up @@ -1290,6 +1291,7 @@ parms
PATCOPY
pathcch
PATTERNID
pbstr
pcb
pcch
PCCHAR
Expand Down Expand Up @@ -1375,9 +1377,11 @@ POSTCHARBREAKS
POSX
POSXSCROLL
POSYSCROLL
ppbstr
PPEB
ppf
ppidl
pprg
PPROC
ppropvar
ppsi
Expand Down Expand Up @@ -1693,6 +1697,7 @@ srcsrv
SRCSRVTRG
srctool
srect
SRGS
srvinit
srvpipe
ssa
Expand Down Expand Up @@ -1839,7 +1844,6 @@ triaging
TRIMZEROHEADINGS
trx
tsa
tsattrs
tsgr
tsm
TStr
Expand Down Expand Up @@ -1967,10 +1971,8 @@ vswhere
vtapp
VTE
VTID
vtio
vtmode
vtpipeterm
vtpt
VTRGB
VTRGBTo
vtseq
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalControl/EventArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ namespace Microsoft.Terminal.Control
Console,
};

enum DefaultInputScope
{
Default,
AlphanumericHalfWidth,
};

runtimeclass FontSizeChangedArgs
{
Int32 Width { get; };
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/IControlSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace Microsoft.Terminal.Control
Boolean DisablePartialInvalidation { get; };
Boolean SoftwareRendering { get; };
Microsoft.Terminal.Control.TextMeasurement TextMeasurement { get; };
Microsoft.Terminal.Control.DefaultInputScope DefaultInputScope { get; };
Boolean ShowMarks { get; };
Boolean UseBackgroundImageForWindow { get; };
Boolean RightClickContextMenu { get; };
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}

_interactivity.UpdateSettings();
{
const auto inputScope = settings.DefaultInputScope();
const auto alpha = inputScope == DefaultInputScope::AlphanumericHalfWidth;
::Microsoft::Console::TSF::Handle::SetDefaultScopeAlphanumericHalfWidth(alpha);
}
if (_automationPeer)
{
_automationPeer.SetControlPadding(Core::Padding{
Expand Down
14 changes: 0 additions & 14 deletions src/cascadia/TerminalSettingsEditor/GlobalAppearance.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,6 @@
</Page.Resources>

<StackPanel Style="{StaticResource SettingsStackStyle}">
<!-- Language -->
<local:SettingContainer x:Uid="Globals_Language"
Visibility="{x:Bind ViewModel.LanguageSelectorAvailable}">
<ComboBox ItemsSource="{x:Bind ViewModel.LanguageList}"
SelectedItem="{x:Bind ViewModel.CurrentLanguage, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Text="{x:Bind local:GlobalAppearanceViewModel.LanguageDisplayConverter((x:String))}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</local:SettingContainer>

<!-- Theme -->
<local:SettingContainer x:Uid="Globals_Theme">
<ComboBox AutomationProperties.AccessibilityView="Content"
Expand Down
163 changes: 0 additions & 163 deletions src/cascadia/TerminalSettingsEditor/GlobalAppearanceViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "EnumEntry.h"

#include <LibraryResources.h>
#include <WtExeUtils.h>

using namespace winrt;
using namespace winrt::Windows::UI::Xaml;
Expand All @@ -18,28 +17,6 @@ using namespace winrt::Windows::Foundation::Collections;

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
// For ComboBox an empty SelectedItem string denotes no selection.
// What we want instead is for "Use system language" to be selected by default.
// --> "und" is synonymous for "Use system language".
constexpr std::wstring_view systemLanguageTag{ L"und" };

static constexpr std::array appLanguageTags{
L"en-US",
L"de-DE",
L"es-ES",
L"fr-FR",
L"it-IT",
L"ja",
L"ko",
L"pt-BR",
L"qps-PLOC",
L"qps-PLOCA",
L"qps-PLOCM",
L"ru",
L"zh-Hans",
L"zh-Hant",
};

constexpr std::wstring_view systemThemeName{ L"system" };
constexpr std::wstring_view darkThemeName{ L"dark" };
constexpr std::wstring_view lightThemeName{ L"light" };
Expand All @@ -56,146 +33,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_UpdateThemeList();
}

winrt::hstring GlobalAppearanceViewModel::LanguageDisplayConverter(const winrt::hstring& tag)
{
if (tag == systemLanguageTag)
{
return RS_(L"Globals_LanguageDefault");
}

winrt::Windows::Globalization::Language language{ tag };
return language.NativeName();
}

// Returns whether the language selector is available/shown.
//
// winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride()
// doesn't work for unpackaged applications. The corresponding code in TerminalApp is disabled.
// It would be confusing for our users if we presented a dysfunctional language selector.
bool GlobalAppearanceViewModel::LanguageSelectorAvailable()
{
return IsPackaged();
}

// Returns the list of languages the user may override the application language with.
// The returned list are BCP 47 language tags like {"und", "en-US", "de-DE", "es-ES", ...}.
// "und" is short for "undefined" and is synonymous for "Use system language" in this code.
winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> GlobalAppearanceViewModel::LanguageList()
{
if (_languageList)
{
return _languageList;
}

if (!LanguageSelectorAvailable())
{
_languageList = {};
return _languageList;
}

// In order to return the language list this code does the following:
// [1] Get all possible languages we want to allow the user to choose.
// We have to acquire languages from multiple sources, creating duplicates. See below at [1].
// [2] Sort languages by their ASCII tags, forcing the UI in a consistent/stable order.
// I wanted to sort the localized language names initially, but it turned out to be complex.
// [3] Remove potential duplicates in our language list from [1].
// We don't want to have en-US twice in the list, do we?
// [4] Optionally remove unwanted language tags (like pseudo-localizations).

std::vector<winrt::hstring> tags;

// [1]:
{
// ManifestLanguages contains languages the app ships with.
// Unfortunately, we cannot use this source. Our manifest must contain the
// ~100 languages that are localized for the shell extension and start menu
// presentation so we align with Windows display languages for those surfaces.
// However, the actual content of our application is limited to a much smaller
// subset of approximately 14 languages. As such, we will code the limited
// subset of languages that we support for selection within the Settings
// dropdown to steer users towards the ones that we can display in the app.

// As per the function definition, the first item
// is always "Use system language" ("und").
tags.emplace_back(systemLanguageTag);

// Add our hard-coded languages after the system definition.
for (const auto& v : appLanguageTags)
{
tags.push_back(v);
}
}

// NOTE: The size of tags is always >0, due to tags[0] being hard-coded to "und".
const auto tagsBegin = ++tags.begin();
const auto tagsEnd = tags.end();

// [2]:
std::sort(tagsBegin, tagsEnd);

// I'd love for both, std::unique and std::remove_if, to occur in a single loop,
// but the code turned out to be complex and even less maintainable, so I gave up.
{
// [3] part 1:
auto it = std::unique(tagsBegin, tagsEnd);

// The qps- languages are useful for testing ("pseudo-localization").
// --> Leave them in if debug features are enabled.
if (!_GlobalSettings.DebugFeaturesEnabled())
{
// [4] part 1:
it = std::remove_if(tagsBegin, it, [](const winrt::hstring& tag) -> bool {
return til::starts_with(tag, L"qps-");
});
}

// [3], [4] part 2 (completing the so called "erase-remove idiom"):
tags.erase(it, tagsEnd);
}

_languageList = winrt::single_threaded_observable_vector(std::move(tags));
return _languageList;
}

winrt::Windows::Foundation::IInspectable GlobalAppearanceViewModel::CurrentLanguage()
{
if (_currentLanguage)
{
return _currentLanguage;
}

if (!LanguageSelectorAvailable())
{
_currentLanguage = {};
return _currentLanguage;
}

// NOTE: PrimaryLanguageOverride throws if this instance is unpackaged.
auto currentLanguage = winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride();
if (currentLanguage.empty())
{
currentLanguage = systemLanguageTag;
}

_currentLanguage = winrt::box_value(currentLanguage);
return _currentLanguage;
}

void GlobalAppearanceViewModel::CurrentLanguage(const winrt::Windows::Foundation::IInspectable& tag)
{
_currentLanguage = tag;

const auto currentLanguage = winrt::unbox_value<winrt::hstring>(_currentLanguage);
if (currentLanguage == systemLanguageTag)
{
_GlobalSettings.ClearLanguage();
}
else
{
_GlobalSettings.Language(currentLanguage);
}
}

// Function Description:
// - Updates the list of all themes available to choose from.
void GlobalAppearanceViewModel::_UpdateThemeList()
Expand Down
12 changes: 0 additions & 12 deletions src/cascadia/TerminalSettingsEditor/GlobalAppearanceViewModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
GETSET_BINDABLE_ENUM_SETTING(TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, _GlobalSettings.TabWidthMode);

public:
// LanguageDisplayConverter maps the given BCP 47 tag to a localized string.
// For instance "en-US" produces "English (United States)", while "de-DE" produces
// "Deutsch (Deutschland)". This works independently of the user's locale.
static winrt::hstring LanguageDisplayConverter(const winrt::hstring& tag);

bool LanguageSelectorAvailable();
winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> LanguageList();
winrt::Windows::Foundation::IInspectable CurrentLanguage();
void CurrentLanguage(const winrt::Windows::Foundation::IInspectable& tag);

winrt::Windows::Foundation::IInspectable CurrentTheme();
void CurrentTheme(const winrt::Windows::Foundation::IInspectable& tag);
static winrt::hstring ThemeNameConverter(const Model::Theme& theme);
Expand All @@ -52,8 +42,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

private:
Model::GlobalAppSettings _GlobalSettings;
winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> _languageList;
winrt::Windows::Foundation::IInspectable _currentLanguage;
winrt::Windows::Foundation::IInspectable _currentTheme;

void _UpdateThemeList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ namespace Microsoft.Terminal.Settings.Editor
{
GlobalAppearanceViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings);

static String LanguageDisplayConverter(String tag);
Boolean LanguageSelectorAvailable { get; };
Windows.Foundation.Collections.IObservableVector<String> LanguageList { get; };
IInspectable CurrentLanguage;

IInspectable CurrentTheme;
static String ThemeNameConverter(Microsoft.Terminal.Settings.Model.Theme theme);
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Model.Theme> ThemeList { get; };
Expand Down
23 changes: 23 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Launch.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,29 @@
</ComboBox>
</local:SettingContainer>

<!-- Language -->
<local:SettingContainer x:Uid="Globals_Language"
Visibility="{x:Bind ViewModel.LanguageSelectorAvailable}">
<ComboBox ItemsSource="{x:Bind ViewModel.LanguageList}"
SelectedItem="{x:Bind ViewModel.CurrentLanguage, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Text="{x:Bind local:LaunchViewModel.LanguageDisplayConverter((x:String))}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</local:SettingContainer>

<!-- Language -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not language, but different

Suggested change
<!-- Language -->
<!-- Default Input Scope -->

<local:SettingContainer x:Uid="Globals_DefaultInputScope">
<ComboBox AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind ViewModel.DefaultInputScopeList}"
SelectedItem="{x:Bind ViewModel.CurrentDefaultInputScope, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>

<!-- Start on User Login -->
<local:SettingContainer x:Uid="Globals_StartOnUserLogin">
<ToggleSwitch IsOn="{x:Bind ViewModel.StartOnUserLogin, Mode=TwoWay}"
Expand Down
Loading
Loading