terminal/src/cppwinrt.build.pre.props
Dustin L. Howett 52e60b95e4
Remove TerminalSettings from the TerminalSettingsModel project (#19262)
The idea with IControlSettings (and friends) was always that a consumer
of the terminal control could implement it in whatever way they pleased.

Windows Terminal (the application) was intended to be only one
consumer. It has a whole JSON settings model. Nobody wants to think
about JSON at the Terminal Control level. We could have an "adapter" in
TerminalApp, which spoke Terminal JSON Settings on one side and Terminal
Control on the other side.

That worked until we added the settings editor. The settings editor
needed to display a control, and that control's settings needed to be
based on the JSON settings. Oops. We took the expedient route of moving
the adapter into TerminalSettingsModel itself, and poking a bunch of
holes in it so that TerminalApp and TerminalSettingsEditor could tweak
it as needed.

Later, we doubled down on the control settings interface by having every
Terminal Control _make its own ControlSettings_ when we were going to do
the multi-process model. This reduced the number of IPC round trips for
every settings query to 0. Later we built color scheme previewing on top
of that--adding structs to carry color schemes and stuff which was
already in the Appearance config. Sheesh. Layers and layers and layers.

This pull request moves it back into its own library and strips it from
the surface of TerminalSettingsModel. It also deletes `ControlSettings`
and `struct CoreScheme`. That library is called
`TerminalSettingsAppAdapterLib`, and it contains a hidden WinRT
_implements_ type rather than a full-fledged activatable `runtimeclass`.
It also implements one-level inheritance on its own rather than using
IInheritable.

It adheres to the following principles:
- The control will never modify its settings in a way that is visible to
  the control's consumer; therefore, none of the properties have setters
- The settings should never contain things of interest only to the
  Application that the Application uses to communicate data _back to
  itself_ (see `ProfileName`, removed in 68b723c and `KeyBindings`,
  removed in fa09141). This generalizes to "we should never store stuff
  in an unrelated object passed between layers solely for the purpose of
  getting it back".

I made a few changes to the settings interface, including introducing a
new `ICoreScheme` interface that _only_ contains color scheme info. This
is designed to support the Preview/Set color scheme actions, which no
longer work by _app backing up the scheme and restoring it later._ All
of that machinery lives inside TermControl/ControlCore now.

`ICoreScheme` no longer supports `GetColorAtIndex`; you must read all 16
colors at the same time. I am not sorry. Every consumer did that
already, so now we have 15 fewer COM calls for every color scheme.

The new TerminalSettings is mostly consumed via
`com_ptr<TerminalSettings>`, so a bunch of `.` (projected) accesses had
to turn into `->` (com_ptr dereferencing) accesses.

I also realized, in the course of this work, that the old
TerminalSettings contained a partial hand-written reimplementation of
_every setting_ in `ControlProperties`. Every contributor had to add
every new setting to both places--why? I can't figure it out. I'm using
ControlProperties comprehensively now. I propagated any setting whose
default value was different from that in ControlProperties back to
ControlProperties.

This is part X in a series of pull requests that will remove all mention
of Microsoft.Terminal.Control and Microsoft.Terminal.Core from the
settings model. Once that is done, the settings model can consume _only_
the base WinRT types and build very early and test more easily.

Previewing is fun. I introduced a new place to stash an entire color
table on ControlCore, which we use to save the "active" colors while we
temporarily overwrite them. SetColorScheme is _also_ fun. We now have a
slot for overriding only the focused color scheme on ControlCore. It's
fine. It's clearer than "back up the focused appearance, overwrite the
focused appearance, create a child of the user's settings and apply the
color scheme to it, etc.".

There is a bug/design choice in color scheme overriding, which may or
may not matter: overlaying a color scheme on a terminal with an
unfocused appearance which _does not_ have its own color scheme will
result in the previously-deleted overridden focused color scheme peeking
through when the terminal is not focused.

I also got rid of our only in-product use of
`Terminal::CreateFromSettings` which required us to set `InitialRows`
and `InitialCols` on the incoming settings object (see core tenet 2).

Refs #19261
Refs #19314
Refs #19254
2025-09-03 14:01:36 -05:00

106 lines
4.8 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- this will trigger the use of a project-specific out dir -->
<OpenConsoleCppWinRTProject>true</OpenConsoleCppWinRTProject>
</PropertyGroup>
<Import Project="..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<PropertyGroup Label="Globals">
<CppWinRTEnabled>true</CppWinRTEnabled>
<CppWinRTOptimized>true</CppWinRTOptimized>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>17.0</MinimumVisualStudioVersion>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
</PropertyGroup>
<!-- These settings tell MsBuild to treat the project as a "Universal Windows"
application. This includes doing things like creating a separate
subdirectory for our binary output, and making sure that a wapproj looks
at the winmd we build to generate type info.
In general, cppwinrt projects all want this.
-->
<PropertyGroup Condition="'$(OpenConsoleUniversalApp)'=='true'">
<MinimalCoreWin>true</MinimalCoreWin>
<AppContainerApplication>true</AppContainerApplication>
<WindowsStoreApp>true</WindowsStoreApp>
<ApplicationType>Windows Store</ApplicationType>
<UseCrtSDKReference Condition="'$(EnableHybridCRT)'=='true'">false</UseCrtSDKReference> <!-- The SDK reference breaks the Hybrid CRT -->
</PropertyGroup>
<PropertyGroup Condition="'$(OpenConsoleUniversalApp)'!='true'">
<!-- Some of our projects include the cppwinrt build options to
just build cppwinrt things, but don't want the store bits
in full swing. MinimalCoreWin != false means "don't let me
use win32 APIs"
-->
<MinimalCoreWin>false</MinimalCoreWin>
</PropertyGroup>
<!-- This is magic that tells msbuild to link against the Desktop platform
instead of the App platform. This you definitely want, because we're not
building a true universal "app", we're building a desktop application
with xaml.
Linking against the App CRT will require the VCRT forwarders to be dropped next to the final binary for
desktop situations, but it will let non-desktop situations work since there is no redist off desktop.
The forwarders can be found at https://github.com/microsoft/vcrt-forwarders and are already included
in our CascadiaPackage project.
-->
<PropertyGroup>
<!-- We have to use the Desktop platform for Hybrid CRT to work. -->
<_VC_Target_Library_Platform>Desktop</_VC_Target_Library_Platform>
<_NoWinAPIFamilyApp>true</_NoWinAPIFamilyApp>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)common.build.pre.props" />
<!-- Overrides for common build settings -->
<ItemDefinitionGroup>
<ClCompile>
<!-- C++/WinRT hard-codes pch.h -->
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
<!-- Big objects for C++/WinRT. -->
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
<DisableSpecificWarnings>5104;28204;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<PreprocessorDefinitions>WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem Condition="'%(SubSystem)'==''">Console</SubSystem>
<GenerateWindowsMetadata>$(CppWinRTGenerateWindowsMetadata)</GenerateWindowsMetadata>
<GenerateWindowsMetadata Condition="'%(GenerateWindowsMetadata)'==''">true</GenerateWindowsMetadata>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenConsoleDir)\src\cascadia\WinRTUtils\inc;$(OpenConsoleDir)src\cascadia\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AppContainer>false</AppContainer>
</Link>
</ItemDefinitionGroup>
<!-- DLLs -->
<ItemDefinitionGroup Condition="'$(ConfigurationType)'=='DynamicLibrary'">
<ClCompile>
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<ModuleDefinitionFile Condition="Exists('$(ProjectName).def')">$(ProjectName).def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
</Project>