Skip to content

Commit

Permalink
Implement UI for choosing default terminal inside Settings page (#9907)
Browse files Browse the repository at this point in the history
Implement dropdown menu for choosing a default terminal application from inside the Windows Terminal Settings UI

## PR Checklist
* [x] Closes #9463 
* [x] I work here.
* [x] Manual tests passed
* [x] MicrosoftDocs/terminal#314 (and cross reference #9462)

## Detailed Description of the Pull Request / Additional comments
- Adds dropdown menu and a template card for displaying the available default applications (using the same lookup code as the console property sheet `console.dll`)
- Adds model to TSM for adapting the data for display and binding on XAML
- Lookup occurs on every page reload. Persistence only happens on Save Changes.
- Manifest changed for Terminal to add capability to opt-out of registry redirection so we can edit this setting

## Validation Steps Performed
- [x] Flipped the menu and pressed Save Changes and launched cmd from run box... it moved between the two.
- [x] Flipped system theme from light to dark and ensured secondary color looked good
- [x] Flipped the status with a different mechanism (conhost propsheet) and then reopened settings page and confirmed it loaded the updated status
  • Loading branch information
miniksa authored Apr 28, 2021
1 parent 810ce69 commit b7fa328
Show file tree
Hide file tree
Showing 23 changed files with 474 additions and 89 deletions.
5 changes: 5 additions & 0 deletions .github/actions/spelling/dictionary/apis.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ ACCESSDENIED
alignof
bitfield
bitfields
BUILDNUMBER
CLASSNOTAVAILABLE
cmdletbinding
colspan
Expand All @@ -16,6 +17,7 @@ dcomp
DERR
dlldata
DONTADDTORECENT
DWORDLONG
environstrings
EXPCMDFLAGS
EXPCMDSTATE
Expand Down Expand Up @@ -56,6 +58,7 @@ istream
IStringable
ITab
ITaskbar
IUri
IVirtual
LCID
llabs
Expand All @@ -77,6 +80,8 @@ NOREDIRECTIONBITMAP
ntprivapi
oaidl
ocidl
osver
OSVERSIONINFOEXW
otms
OUTLINETEXTMETRICW
overridable
Expand Down
2 changes: 2 additions & 0 deletions .github/actions/spelling/dictionary/microsoft.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ systemroot
taskkill
tasklist
tdbuildteamid
unvirtualized
VCRT
vcruntime
Virtualization
visualstudio
vscode
VSTHRD
Expand Down
2 changes: 2 additions & 0 deletions .github/actions/spelling/expect/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ blog
Blt
BLUESCROLL
bmp
BODGY
BOLDFONT
BOOLIFY
bools
Expand Down Expand Up @@ -676,6 +677,7 @@ dwmapi
dword
dwrite
dwriteglyphrundescriptionclustermap
dwl
dxgi
dxgidwm
dxinterop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
<ItemGroup>
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\Microsoft.Terminal.Settings.ModelLib.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)\src\types\lib\types.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\propslib\propslib.vcxproj" />

<!-- If you don't reference these projects here, the
_ConsoleGenerateAdditionalWinmdManifests step won't gather the winmd's -->
Expand Down
27 changes: 10 additions & 17 deletions src/cascadia/TerminalSettingsEditor/Launch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

INITIALIZE_BINDABLE_ENUM_SETTING(LaunchMode, LaunchMode, LaunchMode, L"Globals_LaunchMode", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(WindowingBehavior, WindowingMode, WindowingMode, L"Globals_WindowingBehavior", L"Content");

// BODGY
// Xaml code generator for x:Bind to this will fail to find UnloadObject() on Launch class.
// To work around, check it ourselves on construction and FindName to force load.
// It's specified as x:Load=false in the XAML. So it only loads if this passes.
if (CascadiaSettings::IsDefaultTerminalAvailable())
{
FindName(L"DefaultTerminalDropdown");
}
}

void Launch::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::LaunchPageNavigationState>();
_State.Settings().RefreshDefaultTerminals();
}

IInspectable Launch::CurrentDefaultProfile()
Expand All @@ -37,21 +47,4 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
const auto profile{ winrt::unbox_value<Model::Profile>(value) };
_State.Settings().GlobalSettings().DefaultProfile(profile.Guid());
}

// TODO GH#9463 - Complete hookup of Terminal UX to choose defapp.
Windows::Foundation::Collections::IObservableVector<IInspectable> Launch::DefaultTerminals()
{
Windows::Foundation::Collections::IObservableVector<IInspectable> vec;
return vec;
}

IInspectable Launch::CurrentDefaultTerminal()
{
return nullptr;
}

void Launch::CurrentDefaultTerminal(const IInspectable& value)
{
value;
}
}
4 changes: 0 additions & 4 deletions src/cascadia/TerminalSettingsEditor/Launch.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
IInspectable CurrentDefaultProfile();
void CurrentDefaultProfile(const IInspectable& value);

Windows::Foundation::Collections::IObservableVector<IInspectable> DefaultTerminals();
IInspectable CurrentDefaultTerminal();
void CurrentDefaultTerminal(const IInspectable& value);

WINRT_PROPERTY(Editor::LaunchPageNavigationState, State, nullptr);

GETSET_BINDABLE_ENUM_SETTING(LaunchMode, Model::LaunchMode, State().Settings().GlobalSettings, LaunchMode);
Expand Down
3 changes: 0 additions & 3 deletions src/cascadia/TerminalSettingsEditor/Launch.idl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ namespace Microsoft.Terminal.Settings.Editor

IInspectable CurrentDefaultProfile;

IInspectable CurrentDefaultTerminal;
IObservableVector<IInspectable> DefaultTerminals { get; };

IInspectable CurrentLaunchMode;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> LaunchModeList { get; };

Expand Down
63 changes: 55 additions & 8 deletions src/cascadia/TerminalSettingsEditor/Launch.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,63 @@
</local:SettingContainer>

<!-- Default Terminal -->
<!-- TODO GH#9463 - Complete hookup of Terminal UX to choose defapp. -->
<!--
<local:SettingContainer x:Uid="Globals_DefaultTerminal">
<local:SettingContainer x:Name="DefaultTerminalDropdown"
x:Uid="Globals_DefaultTerminal"
x:Load="false">
<ComboBox x:Name="DefaultTerminal"
x:Load="False"
ItemsSource="{x:Bind DefaultTerminals, Mode=OneWay}"
SelectedItem="{x:Bind CurrentDefaultTerminal, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}" />
ItemsSource="{x:Bind State.Settings.DefaultTerminals, Mode=OneWay}"
SelectedItem="{x:Bind State.Settings.CurrentDefaultTerminal, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="SettingsModel:DefaultTerminal">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ColumnSpacing="8">

<Grid.ColumnDefinitions>
<!-- icon -->
<ColumnDefinition Width="24" />
<!-- profile name and author -->
<ColumnDefinition Width="*" />
<!-- version -->
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>

<Grid.RowDefinitions>
<!-- profile name -->
<RowDefinition Height="*" />
<!-- author and version -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<IconSourceElement Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Width="24"
Height="24"
VerticalAlignment="Center"
IconSource="{x:Bind Icon, Mode=OneWay, Converter={StaticResource IconSourceConverter}}" />

<TextBlock Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Text="{x:Bind Name}" />

<TextBlock Grid.Row="1"
Grid.Column="1"
Foreground="{StaticResource SystemBaseMediumColor}"
Text="{x:Bind Author}" />

<TextBlock Grid.Row="1"
Grid.Column="2"
Foreground="{StaticResource SystemBaseMediumColor}"
Text="{x:Bind Version}" />

</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</local:SettingContainer>
-->

<!-- Start on User Login -->
<local:SettingContainer x:Uid="Globals_StartOnUserLogin">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@
<comment>A description for what the default profile is and when it's used.</comment>
</data>
<data name="Globals_DefaultTerminal.Header" xml:space="preserve">
<value>Default terminal</value>
<value>Default terminal application</value>
<comment>Header for a drop down that permits the user to select which installed Terminal application will launch when command line tools like CMD are run from the Windows Explorer run box or start menu or anywhere else that they do not already have a graphical window assigned.</comment>
</data>
<data name="Globals_DefaultTerminal.HelpText" xml:space="preserve">
Expand Down
85 changes: 84 additions & 1 deletion src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) :
_allProfiles{ winrt::single_threaded_observable_vector<Model::Profile>() },
_activeProfiles{ winrt::single_threaded_observable_vector<Model::Profile>() },
_warnings{ winrt::single_threaded_vector<SettingsLoadWarnings>() },
_deserializationErrorMessage{ L"" }
_deserializationErrorMessage{ L"" },
_defaultTerminals{ winrt::single_threaded_observable_vector<Model::DefaultTerminal>() },
_currentDefaultTerminal{ nullptr }
{
if (addDynamicProfiles)
{
Expand Down Expand Up @@ -82,6 +84,9 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
settings->_userSettings = _userSettings;
settings->_defaultSettings = _defaultSettings;

settings->_defaultTerminals = _defaultTerminals;
settings->_currentDefaultTerminal = _currentDefaultTerminal;

_CopyProfileInheritanceTree(settings);

return *settings;
Expand Down Expand Up @@ -999,3 +1004,81 @@ winrt::hstring CascadiaSettings::ApplicationVersion()

return RS_(L"ApplicationVersionUnknown");
}

// Method Description:
// - Forces a refresh of all default terminal state
// Arguments:
// - <none>
// Return Value:
// - <none> - Updates internal state
void CascadiaSettings::RefreshDefaultTerminals()
{
_defaultTerminals.Clear();

for (const auto& term : Model::DefaultTerminal::Available())
{
_defaultTerminals.Append(term);
}

_currentDefaultTerminal = Model::DefaultTerminal::Current();
}

// Helper to do the version check
static bool _isOnBuildWithDefTerm() noexcept
{
OSVERSIONINFOEXW osver{ 0 };
osver.dwOSVersionInfoSize = sizeof(osver);
osver.dwBuildNumber = 21359;

DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);

return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask);
}

// Method Description:
// - Determines if we're on an OS platform that supports
// the default terminal handoff functionality.
// Arguments:
// - <none>
// Return Value:
// - True if OS supports default terminal. False otherwise.
bool CascadiaSettings::IsDefaultTerminalAvailable() noexcept
{
// Cached on first use since the OS version shouldn't change while we're running.
static bool isAvailable = _isOnBuildWithDefTerm();
return isAvailable;
}

// Method Description:
// - Returns an iterable collection of all available terminals.
// Arguments:
// - <none>
// Return Value:
// - an iterable collection of all available terminals that could be the default.
IObservableVector<winrt::Microsoft::Terminal::Settings::Model::DefaultTerminal> CascadiaSettings::DefaultTerminals() const noexcept
{
return _defaultTerminals;
}

// Method Description:
// - Returns the currently selected default terminal application
// Arguments:
// - <none>
// Return Value:
// - the selected default terminal application
winrt::Microsoft::Terminal::Settings::Model::DefaultTerminal CascadiaSettings::CurrentDefaultTerminal() const noexcept
{
return _currentDefaultTerminal;
}

// Method Description:
// - Sets the current default terminal application
// Arguments:
// - terminal - Terminal from `DefaultTerminals` list to set as default
// Return Value:
// - <none>
void CascadiaSettings::CurrentDefaultTerminal(winrt::Microsoft::Terminal::Settings::Model::DefaultTerminal terminal)
{
_currentDefaultTerminal = terminal;
}
10 changes: 10 additions & 0 deletions src/cascadia/TerminalSettingsModel/CascadiaSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

winrt::guid GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const;

void RefreshDefaultTerminals();

static bool IsDefaultTerminalAvailable() noexcept;
Windows::Foundation::Collections::IObservableVector<Model::DefaultTerminal> DefaultTerminals() const noexcept;
Model::DefaultTerminal CurrentDefaultTerminal() const noexcept;
void CurrentDefaultTerminal(Model::DefaultTerminal terminal);

private:
com_ptr<GlobalAppSettings> _globals;
Windows::Foundation::Collections::IObservableVector<Model::Profile> _allProfiles;
Expand All @@ -106,6 +113,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
Windows::Foundation::IReference<SettingsLoadErrors> _loadError;
hstring _deserializationErrorMessage;

Windows::Foundation::Collections::IObservableVector<Model::DefaultTerminal> _defaultTerminals;
Model::DefaultTerminal _currentDefaultTerminal;

std::vector<std::unique_ptr<::Microsoft::Terminal::Settings::Model::IDynamicProfileGenerator>> _profileGenerators;

std::string _userSettingsString;
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsModel/CascadiaSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import "GlobalAppSettings.idl";
import "Profile.idl";
import "TerminalWarnings.idl";
import "DefaultTerminal.idl";

namespace Microsoft.Terminal.Settings.Model
{
Expand Down Expand Up @@ -42,5 +43,10 @@ namespace Microsoft.Terminal.Settings.Model
void UpdateColorSchemeReferences(String oldName, String newName);

Guid GetProfileForArgs(NewTerminalArgs newTerminalArgs);

void RefreshDefaultTerminals();
static Boolean IsDefaultTerminalAvailable { get; };
Windows.Foundation.Collections.IObservableVector<DefaultTerminal> DefaultTerminals { get; };
DefaultTerminal CurrentDefaultTerminal;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,7 @@ const Json::Value& CascadiaSettings::_GetDisabledProfileSourcesJsonObject(const
// Method Description:
// - Write the current state of CascadiaSettings to our settings file
// - Create a backup file with the current contents, if one does not exist
// - Persists the default terminal handler choice to the registry
// Arguments:
// - <none>
// Return Value:
Expand All @@ -1348,6 +1349,9 @@ void CascadiaSettings::WriteSettingsToDisk() const

const auto styledString{ Json::writeString(wbuilder, ToJson()) };
_WriteSettings(styledString, settingsPath);

// Persists the default terminal choice
Model::DefaultTerminal::Current(_currentDefaultTerminal);
}

// Method Description:
Expand Down
Loading

0 comments on commit b7fa328

Please sign in to comment.