This PR represents the start of the work on Cascading User + default settings, #754. Cascading settings will be done in two parts: * [ ] Layered Default+User settings (this PR) * [ ] Dynamic Profile Generation (#2603). Until _both_ are done, _neither are going in. The dynamic profiles PR will target this PR when it's ready, but will go in as a separate commit into master. This PR covers adding one primary feature: the settings are now in two separate files: * a static `defaults.json` that ships with the package (the "default settings") * a `profiles.json` with the user's customizations (the "user settings) User settings are _layered_ upon the settings in the defaults settings. ## References Other things that might be related here: * #1378 - This seems like it's definitely fixed. The default keybindings are _much_ cleaner, and without the save-on-load behavior, the user's keybindings will be left in a good state * #1398 - This might have honestly been solved by #2475 ## PR Checklist * [x] Closes #754 * [x] Closes #1378 * [x] Closes #2566 * [x] I work here * [x] Tests added/passed * [x] Requires documentation to be updated - it **ABSOLUTELY DOES** ## Detailed Description of the Pull Request / Additional comments 1. We start by taking all of the `FromJson` functions in Profile, ColorScheme, Globals, etc, and converting them to `LayerJson` methods. These are effectively the same, with the change that instead of building a new object, they are simply layering the values on top of `this` object. 2. Next, we add tests for layering properties like that. 3. Now, we add a `defaults.json` to the package. This is the file the users can refer to as our default settings. 4. We then take that `defaults.json` and stamp it into an auto generated `.h` file, so we can use it's data without having to worry about reading it from disk. 5. We then change the `LoadAll` function in `CascadiaSettings`. Now, the function does two loads - one from the defaults, and then a second load from the `profiles.json` file, layering the settings from each source upon the previous values. 6. If the `profiles.json` file doesn't exist, we'll create it from a hardcoded `userDefaults.json`, which is stamped in similar to how `defaults.json` is. 7. We also add support for _unbinding_ keybindings that might exist in the `defaults.json`, but the user doesn't want to be bound to anything. 8. We add support for _hiding_ a profile, which is useful if a user doesn't want one of the default profiles to appear in the list of profiles. ## TODO: * [x] Still need to make Alt+Click work on the settings button * [x] Need to write some user documentation on how the new settings model works * [x] Fix the pair of tests I broke (re: Duplicate profiles) <hr> * Create profiles by layering them * Update test to layer multiple times on the same profile * Add support for layering an array of profiles, but break a couple tests * Add a defaults.json to the package * Layer colorschemes * Moves tests into individual classes * adds support for layering a colorscheme on top of another * Layer an array of color schemes * oh no, this was missed with #2481 must have committed without staging this change, uh oh. Not like those tests actually work so nbd * Layer keybindings * Read settings from defaults.json + profiles.json, layer appropriately This is like 80% of #754. Needs tests. * Add tests for keybindings * add support to unbind a key with `null` or `"unbound"` or `"garbage"` * Layer or clear optional properties * Add a helper to get an optional variable for a bunch of different types In the end, I think we need to ask _was this worth it_ * Do this with the stretch mode too * Add back in the GUID check for profiles * Add some tests for global settings layering * M A D W I T H P O W E R Add a MsBuild target to auto-generate a header with the defaults.json as a string in the file. That way, we can _always_ load the defaults. Literally impossible to not. * When the user's profile.json doesn't exist, create it from a template * Re-order profiles to match the order set in the user's profiles.json * Add tests for re-ordering profiles to match user ordering * Add support for hiding profiles using `"hidden": true` * Use the hardcoded defaults.json for the exception->"use defaults" case * Somehow I messed up the git submodules? * woo documentation * Fix a Terminal.App.Unit.Tests failure * signed/unsigned is hard * Use Alt+Settings button to open the default settings * Missed a signed/unsigned * Some very preliminary PR feedback * More PR feedback Use the wil helper for the exe path Move jsonutils into their own file kill some dead code * Add templates to these bois * remove some code for generating defaults, reorder defaults.json a tad * Make guid a std::optional * Large block of PR feedback * Remove some dead code * add some comments * tag some todos * stl is love, stl is life * add `-noprofile` * Fix the crash that dustin found * -Encoding ASCII * Set a profile's default scheme to Campbell * Fix the tests I regressed * Update UsingJsonSetting.md to reflect that changes from these PRs * Change how GenerateGuidForProfile works * Make AppKeyBindings do its own serialization * Remove leftover dead code from the previous commit * Fix up an enormous number of PR nits * Fix a typo; Update the defaults to match #2378 * Tiny nits * Some typos, PR nits * Fix this broken defaults case
181 lines
9.5 KiB
XML
181 lines
9.5 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||
<Import Project="$(SolutionDir)\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||
<Import Project="$(OpenConsoleDir)\src\common.build.pre.props" />
|
||
|
||
<!-- ========================= Headers ======================== -->
|
||
<ItemGroup>
|
||
<ClInclude Include="precomp.h" />
|
||
<ClInclude Include="JsonTestClass.h" />
|
||
</ItemGroup>
|
||
|
||
<!-- ========================= Cpp Files ======================== -->
|
||
<ItemGroup>
|
||
<ClCompile Include="SettingsTests.cpp" />
|
||
<ClCompile Include="ProfileTests.cpp" />
|
||
<ClCompile Include="ColorSchemeTests.cpp" />
|
||
<ClCompile Include="KeyBindingsTests.cpp" />
|
||
<ClCompile Include="TabTests.cpp" />
|
||
<ClCompile Include="precomp.cpp">
|
||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||
</ClCompile>
|
||
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
|
||
you want to use jsoncpp -->
|
||
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
|
||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||
</ClCompile>
|
||
</ItemGroup>
|
||
|
||
<!-- ========================= Project References ======================== -->
|
||
<ItemGroup>
|
||
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj" />
|
||
<ProjectReference Include="$(OpenConsoleDir)\src\types\lib\types.vcxproj" />
|
||
|
||
<!-- If you don't reference these projects here, the
|
||
_ConsoleGenerateAdditionalWinmdManifests step won't gather the winmd's -->
|
||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
|
||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\TerminalApp.vcxproj" />
|
||
</ItemGroup>
|
||
|
||
<!-- ========================= Globals ======================== -->
|
||
<PropertyGroup>
|
||
<ProjectGuid>{CA5CAD1A-b11c-4ddb-a4fe-c3afae9b5506}</ProjectGuid>
|
||
<Keyword>Win32Proj</Keyword>
|
||
<RootNamespace>TerminalAppLocalTests</RootNamespace>
|
||
<ProjectName>LocalTests_TerminalApp</ProjectName>
|
||
<TargetName>TerminalApp.LocalTests</TargetName>
|
||
<WindowsTargetPlatformMinVersion>10.0.18362.0</WindowsTargetPlatformMinVersion>
|
||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||
</PropertyGroup>
|
||
|
||
<!-- ====================== Compiler & Linker Flags ===================== -->
|
||
<ItemDefinitionGroup>
|
||
<ClCompile>
|
||
<AdditionalIncludeDirectories>..;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalApp\lib\Generated Files";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
|
||
|
||
<!-- Manually disable unreachable code warning, because jconcpp has a ton of that. -->
|
||
<DisableSpecificWarnings>4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||
</ClCompile>
|
||
<Link>
|
||
<AdditionalDependencies>WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||
</Link>
|
||
</ItemDefinitionGroup>
|
||
|
||
<PropertyGroup>
|
||
<GenerateManifest>true</GenerateManifest>
|
||
<EmbedManifest>true</EmbedManifest>
|
||
</PropertyGroup>
|
||
|
||
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
|
||
<Import Project="$(OpenConsoleDir)src\common.build.dll.props" />
|
||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||
<Import Project="$(OpenConsoleDir)src\common.build.tests.props" />
|
||
|
||
<PropertyGroup>
|
||
<!-- Manually change our outdir to be in a subdirectory. We don't really want
|
||
to put our output in the bin root, because if we do, we'll copy
|
||
TerminalApp.winmd to the bin root, and then every subsequent mdmerge step
|
||
(in _any_ cppwinrt project) will automatically try to pick up
|
||
TerminalApp.winmd as a dependency (which is just wrong). This MUST be done
|
||
after importing common.build.post.props-->
|
||
<OutDir>$(OpenConsoleDir)\bin\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir>
|
||
<IntDir>$(OpenConsoleDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||
</PropertyGroup>
|
||
|
||
<PropertyGroup>
|
||
<_CppWinrtBinRoot>"$(OpenConsoleDir)$(Platform)\$(Configuration)\"</_CppWinrtBinRoot>
|
||
<!-- From Microsoft.UI.Xaml.targets -->
|
||
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
|
||
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
|
||
<_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\runtimes\win10-$(Native-Platform)\native\"</_MUXBinRoot>
|
||
</PropertyGroup>
|
||
|
||
<!-- We actually can just straight up reference MUX here, it's fine -->
|
||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
|
||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||
|
||
<!-- This project will generate individual sxs manifests for each of our winrt libraries -->
|
||
<Import Project="$(OpenConsoleDir)\build\rules\GenerateSxsManifestsFromWinmds.targets" />
|
||
|
||
<!-- This is important: actually add the _LocalTestsGenerateCombinedManifests
|
||
target to the list of targets to run. -->
|
||
<PropertyGroup>
|
||
<BeforeLinkTargets Condition="'$(WindowsTargetPlatformVersion)' >= '10.0.18362.0'">
|
||
$(BeforeLinkTargets);
|
||
_LocalTestsGenerateCombinedManifests;
|
||
_LocalTestsBuildAppxManifest;
|
||
_LocalTestsCopyDependencies;
|
||
</BeforeLinkTargets>
|
||
</PropertyGroup>
|
||
|
||
<!-- Step 1: Combine all our SxS manifests into a single SxS manifest. TAEF
|
||
needs us to specify a single activation context at runtime, so we need a
|
||
single file with all our types in it.-->
|
||
<Target Name="_LocalTestsGenerateCombinedManifests"
|
||
Inputs="@(_ConsoleWinmdManifest)"
|
||
Outputs="$(OutDir)$(TargetName).manifest"
|
||
DependsOnTargets="_ConsoleGenerateAdditionalWinmdManifests">
|
||
|
||
<Exec Command="mt.exe -manifest @(_ConsoleWinmdManifest, ' -manifest ') -out:$(OutDir)$(TargetName).manifest" />
|
||
</Target>
|
||
|
||
<!-- Step 2: Take our combined SxS manifest, and use it to build an
|
||
Appxmanifest.xml. We'll use the Appxmanifest.prototype.xml in this project's
|
||
directory as a base, and the script will tak all our activatableClasses and
|
||
turn them into appxmanifest-compatible Extensions -->
|
||
<Target Name="_LocalTestsBuildAppxManifest"
|
||
Inputs="$(OutDir)$(TargetName).manifest"
|
||
Outputs="$(OutDir)$(TargetName).AppxManifest.xml"
|
||
DependsOnTargets="_LocalTestsGenerateCombinedManifests">
|
||
|
||
<Exec Command="powershell.exe -noprofile –ExecutionPolicy Unrestricted $(OpenConsoleDir)\tools\GenerateAppxFromManifest.ps1 -SxSManifest $(OutDir)$(TargetName).manifest -AppxManifestPrototype $(TargetName).AppxManifest.prototype.xml -OutPath $(OutDir)$(TargetName).AppxManifest.xml" />
|
||
|
||
</Target>
|
||
|
||
<!-- Step 3: Manually copy all our dependent DLLs into our OutDir. For SxS
|
||
activation to work, they all need to be in the same directory as our test dll.
|
||
This is using code that's heavliy cribbed from WindowsTerminal.vcxproj, which
|
||
is already cribbed from the GetPackagingOutputs in
|
||
Microsoft.*.AppxPackage.targets. We're filtering this list down to the dlls,
|
||
pris and xbfs, because this list _can_ contain directories, which will make
|
||
the Copy task explode. -->
|
||
|
||
<PropertyGroup>
|
||
<_ContinueOnError Condition="'$(BuildingProject)' == 'true'">true</_ContinueOnError>
|
||
<_ContinueOnError Condition="'$(BuildingProject)' != 'true'">false</_ContinueOnError>
|
||
</PropertyGroup>
|
||
|
||
<!-- First gather the files... -->
|
||
<Target Name="MyGetPackagingOutputs" Returns="@(MyPackagingOutputs)">
|
||
<MSBuild
|
||
Projects="@(ProjectReferenceWithConfiguration)"
|
||
Targets="GetPackagingOutputs"
|
||
BuildInParallel="$(BuildInParallel)"
|
||
Properties="%(ProjectReferenceWithConfiguration.SetConfiguration); %(ProjectReferenceWithConfiguration.SetPlatform)"
|
||
Condition="'@(ProjectReferenceWithConfiguration)' != ''
|
||
and '%(ProjectReferenceWithConfiguration.BuildReference)' == 'true'
|
||
and '%(ProjectReferenceWithConfiguration.ReferenceOutputAssembly)' == 'true'"
|
||
ContinueOnError="$(_ContinueOnError)">
|
||
<Output TaskParameter="TargetOutputs" ItemName="_PackagingOutputsFromOtherProjects"/>
|
||
</MSBuild>
|
||
|
||
<ItemGroup>
|
||
<MyPackagingOutputs Include="@(_PackagingOutputsFromOtherProjects)" Condition="'%(Extension)'=='.dll' Or '%(Extension)'=='.pri' Or '%(Extension)'=='.xbf'" />
|
||
</ItemGroup>
|
||
</Target>
|
||
|
||
<!-- Then copy the files to our outdir -->
|
||
<Target Name="_LocalTestsCopyDependencies"
|
||
DependsOnTargets="MyGetPackagingOutputs">
|
||
|
||
<Copy SourceFiles="@(MyPackagingOutputs)"
|
||
SkipUnchangedFiles="true"
|
||
DestinationFolder="$(OutDir)"
|
||
/>
|
||
</Target>
|
||
|
||
</Project>
|