From 2c666aa292f78befa2db4013860092c27c866ccb Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Thu, 21 Aug 2025 17:05:27 -0700 Subject: [PATCH 1/2] Clear Name, Source, and Commandline from Profiles.Defaults (#19225) The Name, Source, and Commandline profile settings should not be allowed to be set on the Profiles.Defaults object. This just enforces that by clearing them (as is done with Guid). These profile settings are omitted from the settings UI's profile defaults page. Closes #19202 --- .../CascadiaSettingsSerialization.cpp | 4 ++ .../DeserializationTests.cpp | 27 +++++--- .../MediaResourceTests.cpp | 34 +++++----- .../UnitTests_SettingsModel/ProfileTests.cpp | 62 +++++++++++++++++++ 4 files changed, 98 insertions(+), 29 deletions(-) diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp index 7b2a7f17c9..7d369a9828 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp @@ -839,7 +839,11 @@ void SettingsLoader::_parse(const OriginTag origin, const winrt::hstring& source settings.baseLayerProfile = Profile::FromJson(json.profileDefaults); // Remove the `guid` member from the default settings. // That will hyper-explode, so just don't let them do that. + // Also remove name, source, and commandline; those are not valid for the profiles defaults object. settings.baseLayerProfile->ClearGuid(); + settings.baseLayerProfile->ClearName(); + settings.baseLayerProfile->ClearSource(); + settings.baseLayerProfile->ClearCommandline(); settings.baseLayerProfile->Origin(OriginTag::ProfilesDefaults); } diff --git a/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp b/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp index 72c6b80256..c253a17493 100644 --- a/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp +++ b/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp @@ -1788,16 +1788,18 @@ namespace SettingsModelUnitTests "profiles": { "defaults": { - "name": "PROFILE DEFAULTS" + "tabTitle": "PROFILE DEFAULTS TAB TITLE" }, "list": [ { "guid": "{61c54bbd-1111-5271-96e7-009a87ff44bf}", - "name": "CMD" + "name": "CMD", + "tabTitle": "CMD Tab Title" }, { "guid": "{61c54bbd-2222-5271-96e7-009a87ff44bf}", - "name": "PowerShell" + "name": "PowerShell", + "tabTitle": "PowerShell Tab Title" }, { "guid": "{61c54bbd-3333-5271-96e7-009a87ff44bf}" @@ -1816,25 +1818,30 @@ namespace SettingsModelUnitTests // test profiles VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Name(), copyImpl->AllProfiles().GetAt(0).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).TabTitle(), copyImpl->AllProfiles().GetAt(0).TabTitle()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).Name(), copyImpl->AllProfiles().GetAt(1).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).TabTitle(), copyImpl->AllProfiles().GetAt(1).TabTitle()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(2).Name(), copyImpl->AllProfiles().GetAt(2).Name()); - VERIFY_ARE_EQUAL(settings->ProfileDefaults().Name(), copyImpl->ProfileDefaults().Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(2).TabTitle(), copyImpl->AllProfiles().GetAt(2).TabTitle()); + VERIFY_ARE_EQUAL(settings->ProfileDefaults().TabTitle(), copyImpl->ProfileDefaults().TabTitle()); // Modifying profile.defaults should... - VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasName(), copyImpl->ProfileDefaults().HasName()); - copyImpl->ProfileDefaults().Name(L"changed value"); + VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasTabTitle(), copyImpl->ProfileDefaults().HasTabTitle()); + copyImpl->ProfileDefaults().TabTitle(L"changed value"); - // ...keep the same name for the first two profiles + // ...keep the same name and tab title for the first two profiles VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Name(), copyImpl->AllProfiles().GetAt(0).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).TabTitle(), copyImpl->AllProfiles().GetAt(0).TabTitle()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).Name(), copyImpl->AllProfiles().GetAt(1).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).TabTitle(), copyImpl->AllProfiles().GetAt(1).TabTitle()); // ...but change the name for the one that inherited it from profile.defaults - VERIFY_ARE_NOT_EQUAL(settings->AllProfiles().GetAt(2).Name(), copyImpl->AllProfiles().GetAt(2).Name()); + VERIFY_ARE_NOT_EQUAL(settings->AllProfiles().GetAt(2).TabTitle(), copyImpl->AllProfiles().GetAt(2).TabTitle()); // profile.defaults should be different between the two graphs - VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasName(), copyImpl->ProfileDefaults().HasName()); - VERIFY_ARE_NOT_EQUAL(settings->ProfileDefaults().Name(), copyImpl->ProfileDefaults().Name()); + VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasTabTitle(), copyImpl->ProfileDefaults().HasTabTitle()); + VERIFY_ARE_NOT_EQUAL(settings->ProfileDefaults().TabTitle(), copyImpl->ProfileDefaults().TabTitle()); Log::Comment(L"Test empty profiles.defaults"); static constexpr std::string_view emptyPDJson{ R"( diff --git a/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp b/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp index 16165dad8e..d10971906e 100644 --- a/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp +++ b/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp @@ -103,8 +103,9 @@ namespace SettingsModelUnitTests TEST_METHOD(RealResolverSpecialKeywords); TEST_METHOD(RealResolverUrlCases); - static constexpr std::wstring_view defaultsCommandline{ LR"(C:\Windows\System32\PING.EXE)" }; // Normalized by Profile (this is the casing that Windows stores on disk) + static constexpr std::wstring_view pingCommandline{ LR"(C:\Windows\System32\PING.EXE)" }; // Normalized by Profile (this is the casing that Windows stores on disk) static constexpr std::wstring_view overrideCommandline{ LR"(C:\Windows\System32\cscript.exe)" }; + static constexpr std::wstring_view cmdCommandline{ LR"(C:\Windows\System32\cmd.exe)" }; // The default commandline for a profile static constexpr std::wstring_view fragmentBasePath1{ LR"(C:\Windows\Media)" }; private: @@ -809,7 +810,6 @@ namespace SettingsModelUnitTests "profiles": { "defaults": { "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", } } })"); @@ -818,7 +818,7 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"Base") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); // Profile with commandline always has an icon - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } // The invalid resource came from the profile itself, which has its own commandline. @@ -856,7 +856,7 @@ namespace SettingsModelUnitTests VERIFY_ARE_EQUAL(overrideCommandline, icon.Resolved()); } - // The invalid resource came from the profile itself, which inherits a commandline from the parent (defaults, ping.exe) + // The invalid resource came from the profile itself, where the commandline is the default value (profile.commandline default value is CMD.exe) void MediaResourceTests::ProfileSpecifiesInvalidIconAndNoCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -871,8 +871,7 @@ namespace SettingsModelUnitTests "profiles": { "defaults": { "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", - }, + }, "list": [ { "guid": "{af9dec6c-1337-4278-897d-69ca04920b27}", @@ -887,10 +886,10 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileSpecifiesInvalidIconAndNoCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } - // The invalid resource came from the Defaults profile, which has the Defaults command line (PROFILE COMMANDLINE IGNORED) + // The invalid resource came from the Defaults profile, where the commandline falls back to the default value of CMD.exe (PROFILE COMMANDLINE IGNORED) void MediaResourceTests::ProfileInheritsInvalidIconAndHasCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -904,8 +903,7 @@ namespace SettingsModelUnitTests settings = createSettings(R"({ "profiles": { "defaults": { - "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", + "icon": "DoesNotMatter" }, "list": [ { @@ -921,10 +919,10 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileInheritsInvalidIconAndHasCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } - // The invalid resource came from the Defaults profile, which has the Defaults command line (PROFILE COMMANDLINE MISSING) + // The invalid resource came from the Defaults profile, which has the default command line of CMD.exe (PROFILE COMMANDLINE MISSING) void MediaResourceTests::ProfileInheritsInvalidIconAndHasNoCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -938,8 +936,7 @@ namespace SettingsModelUnitTests settings = createSettings(R"({ "profiles": { "defaults": { - "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", + "icon": "DoesNotMatter" }, "list": [ { @@ -954,7 +951,7 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileInheritsInvalidIconAndHasNoCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } // The invalid resource came from the profile itself, which has its own commandline. @@ -992,7 +989,7 @@ namespace SettingsModelUnitTests VERIFY_ARE_EQUAL(overrideCommandline, icon.Resolved()); } - // The invalid resource came from the profile itself, which inherits a commandline from the parent (defaults, ping.exe) + // The invalid resource came from the profile itself, where the commandline falls back to the default value of CMD.exe void MediaResourceTests::ProfileSpecifiesNullIconAndHasNoCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -1006,8 +1003,7 @@ namespace SettingsModelUnitTests settings = createSettings(R"({ "profiles": { "defaults": { - "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", + "icon": "DoesNotMatter" }, "list": [ { @@ -1023,7 +1019,7 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileSpecifiesNullIconAndHasNoCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); // Profile with commandline always has an icon - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } #pragma endregion diff --git a/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp b/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp index 56816de6e7..7697715b8f 100644 --- a/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp +++ b/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp @@ -30,6 +30,7 @@ namespace SettingsModelUnitTests TEST_METHOD(DuplicateProfileTest); TEST_METHOD(TestGenGuidsForProfiles); TEST_METHOD(TestCorrectOldDefaultShellPaths); + TEST_METHOD(ProfileDefaultsProhibitedSettings); }; void ProfileTests::ProfileGeneratesGuid() @@ -470,4 +471,65 @@ namespace SettingsModelUnitTests VERIFY_ARE_EQUAL(L"%SystemRoot%\\System32\\cmd.exe", allProfiles.GetAt(2).Commandline()); VERIFY_ARE_EQUAL(L"cmd.exe", allProfiles.GetAt(3).Commandline()); } + + void ProfileTests::ProfileDefaultsProhibitedSettings() + { + static constexpr std::string_view userProfiles{ R"({ + "profiles": { + "defaults": + { + "guid": "{00000000-0000-0000-0000-000000000000}", + "name": "Default Profile Name", + "source": "Default Profile Source", + "commandline": "foo.exe" + }, + "list": + [ + { + "name" : "PowerShell", + "commandline": "powershell.exe", + "guid" : "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}" + }, + { + "name": "Profile with just a name" + }, + { + "guid": "{a0776706-1fa6-4439-b46c-287a65c084d5}", + } + ] + } + })" }; + + const auto settings = winrt::make_self(userProfiles); + + // Profile Defaults should not have a GUID, name, source, or commandline. + const auto profileDefaults = settings->ProfileDefaults(); + VERIFY_IS_FALSE(profileDefaults.HasGuid()); + VERIFY_IS_FALSE(profileDefaults.HasName()); + VERIFY_IS_FALSE(profileDefaults.HasSource()); + VERIFY_IS_FALSE(profileDefaults.HasCommandline()); + + const auto allProfiles = settings->AllProfiles(); + VERIFY_ARE_EQUAL(3u, allProfiles.Size()); + + // Profile settings should be set to the ones set at that layer + VERIFY_ARE_EQUAL(L"PowerShell", allProfiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", allProfiles.GetAt(0).Commandline()); + VERIFY_ARE_EQUAL(Utils::GuidFromString(L"{61c54bbd-c2c6-5271-96e7-009a87ff44bf}"), static_cast(allProfiles.GetAt(0).Guid())); + VERIFY_IS_FALSE(allProfiles.GetAt(0).HasSource()); + + // Profile should not inherit the values attempted to be set on the Profiles Defaults layer + // This profile only has a name set + VERIFY_ARE_EQUAL(L"Profile with just a name", allProfiles.GetAt(1).Name()); + VERIFY_ARE_NOT_EQUAL(Utils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}"), static_cast(allProfiles.GetAt(1).Guid())); + VERIFY_ARE_NOT_EQUAL(L"Default Profile Source", allProfiles.GetAt(1).Source()); + VERIFY_ARE_NOT_EQUAL(L"foo.exe", allProfiles.GetAt(1).Commandline()); + + // Profile should not inherit the values attempted to be set on the Profiles Defaults layer + // This profile only has a guid set + VERIFY_ARE_NOT_EQUAL(L"Default Profile Name", allProfiles.GetAt(2).Name()); + VERIFY_ARE_NOT_EQUAL(Utils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}"), static_cast(allProfiles.GetAt(2).Guid())); + VERIFY_ARE_NOT_EQUAL(L"Default Profile Source", allProfiles.GetAt(2).Source()); + VERIFY_ARE_NOT_EQUAL(L"foo.exe", allProfiles.GetAt(2).Commandline()); + } } From 7578209be5a0bb6aa567234e480de1a2312b2205 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Thu, 21 Aug 2025 17:06:20 -0700 Subject: [PATCH 2/2] Add telemetry for settings UI traffic (#19156) ## Summary of the Pull Request Adds a telemetry provider to the Terminal.Settings.Editor project as well as new telemetry events to track traffic through the settings UI. Specifically, the following events were added: - `NavigatedToPage`: Event emitted when the user navigates to a page in the settings UI - Has a `PageId` parameter that includes the identifier of the page that was navigated to - (conditionally added when PageId = `page.editColorScheme`) `SchemeName` parameter tracks the name of the color scheme that's being edited - conditionally added when PageId = `page.extensions`: - `ExtensionPackageCount`: The number of extension packages displayed - `ProfilesModifiedCount`: The number of profiles modified by enabled extensions - `ProfilesAddedCount`: The number of profiles added by enabled extensions - `ColorSchemesAddedCount`: The number of color schemes added by enabled extensions - conditionally added when PageId = `page.extensions.extensionView`: - `FragmentSource`: The source of the fragment included in this extension package - `FragmentCount`: The number of fragments included in this extension package - `Enabled`: The enabled status of the extension - (conditionally added when PageID = `page.newTabMenu`) if the page is representing a folder view - conditionally added when PageID = `page.profile.*`: - `IsProfileDefaults`: if the modified profile is the profile.defaults object - `ProfileGuid`: the guid of the profile that was navigated to - `ProfileSource`: the source of the profile that was navigated to - conditionally added when PageID = `page.profile` (aka the base profile page): - `Orphaned`: tracks if the profile was orphaned - `Hidden`: tracks if the profile is hidden - (conditionally added when PageID = `page.profile.appearance`) `HasBackgroundImage`: `if the profile has a background image defined` - (conditionally added when PageID = `page.profile.appearance`) `HasUnfocusedAppearance`: `if the profile has an unfocused appearance defined` - `AddNewProfile`: Event emitted when the user adds a new profile `IsExtensionView` parameter tracks if the page is representing a view of an extension - Has a `Type` parameter that represents the type of the creation method (i.e. empty profile, duplicate) - `ResetApplicationState`: Event emitted when the user resets their application state (via the UI) - `ResetToDefaultSettings`: Event emitted when the user resets their settings to their default value (via the UI) - `OpenJson`: Event emitted when the user clicks the Open JSON button in the settings UI - Has a `SettingsTarget` parameter that represents the target settings file (i.e. settings.json vs defaults.json) - `CreateUnfocusedAppearance`: Event emitted when the user creates an unfocused appearance for a profile - `IsProfileDefaults`: if the modified profile is the profile.defaults object - `ProfileGuid`: the guid of the profile that was navigated to - `ProfileSource`: the source of the profile that was navigated to - `DeleteProfile`: Event emitted when the user deletes a profile - also includes `ProfileGuid`, `ProfileSource`, `Orphaned` from the `NavigatedToPage` section above The page ids can be reused later as a serialized reference to the page. We already use the one for the extensions page for the "new" badge. --- .../TerminalSettingsEditor/Actions.cpp | 8 +++++ .../TerminalSettingsEditor/AddProfile.cpp | 28 ++++++++++++++- .../TerminalSettingsEditor/ColorSchemes.cpp | 8 +++++ .../TerminalSettingsEditor/Compatibility.cpp | 22 ++++++++++++ .../EditColorScheme.cpp | 12 ++++++- .../TerminalSettingsEditor/Extensions.cpp | 36 ++++++++++++++++--- .../GlobalAppearance.cpp | 8 +++++ .../TerminalSettingsEditor/Interaction.cpp | 8 +++++ .../TerminalSettingsEditor/Launch.cpp | 8 +++++ .../TerminalSettingsEditor/MainPage.cpp | 9 +++++ ...Microsoft.Terminal.Settings.Editor.vcxproj | 1 + ...t.Terminal.Settings.Editor.vcxproj.filters | 1 + .../TerminalSettingsEditor/NewTabMenu.cpp | 8 +++++ .../Profiles_Advanced.cpp | 11 ++++++ .../Profiles_Appearance.cpp | 23 ++++++++++++ .../TerminalSettingsEditor/Profiles_Base.cpp | 22 ++++++++++++ .../Profiles_Base_Orphaned.cpp | 10 ++++++ .../Profiles_Terminal.cpp | 11 ++++++ .../TerminalSettingsEditor/Rendering.cpp | 8 +++++ src/cascadia/TerminalSettingsEditor/Utils.cpp | 2 -- src/cascadia/TerminalSettingsEditor/init.cpp | 36 +++++++++++++++++++ src/cascadia/TerminalSettingsEditor/pch.h | 7 ++++ 22 files changed, 279 insertions(+), 8 deletions(-) create mode 100644 src/cascadia/TerminalSettingsEditor/init.cpp diff --git a/src/cascadia/TerminalSettingsEditor/Actions.cpp b/src/cascadia/TerminalSettingsEditor/Actions.cpp index dafc7b51da..f27d89eb27 100644 --- a/src/cascadia/TerminalSettingsEditor/Actions.cpp +++ b/src/cascadia/TerminalSettingsEditor/Actions.cpp @@ -66,6 +66,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } } }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("actions", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Actions::AddNew_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*eventArgs*/) diff --git a/src/cascadia/TerminalSettingsEditor/AddProfile.cpp b/src/cascadia/TerminalSettingsEditor/AddProfile.cpp index bb2156c646..03864e855e 100644 --- a/src/cascadia/TerminalSettingsEditor/AddProfile.cpp +++ b/src/cascadia/TerminalSettingsEditor/AddProfile.cpp @@ -29,11 +29,27 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void AddProfile::OnNavigatedTo(const NavigationEventArgs& e) { _State = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("addProfile", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void AddProfile::AddNewClick(const IInspectable& /*sender*/, const Windows::UI::Xaml::RoutedEventArgs& /*eventArgs*/) { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "AddNewProfile", + TraceLoggingDescription("Event emitted when the user adds a new profile"), + TraceLoggingValue("EmptyProfile", "Type", "The type of the creation method (i.e. empty profile, duplicate)"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _State.RequestAddNew(); } @@ -42,7 +58,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { if (const auto selected = Profiles().SelectedItem()) { - _State.RequestDuplicate(selected.try_as().Guid()); + const auto selectedProfile = selected.as(); + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "AddNewProfile", + TraceLoggingDescription("Event emitted when the user adds a new profile"), + TraceLoggingValue("Duplicate", "Type", "The type of the creation method (i.e. empty profile, duplicate)"), + TraceLoggingValue(!selectedProfile.Source().empty(), "SourceProfileHasSource", "True, if the source profile has a source (i.e. dynamic profile generator namespace, fragment). Otherwise, False, indicating it's based on a custom profile."), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + + _State.RequestDuplicate(selectedProfile.Guid()); } } diff --git a/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp b/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp index be932d2b90..899cc5f826 100644 --- a/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp +++ b/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp @@ -44,6 +44,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation ColorSchemeListView().Focus(FocusState::Programmatic); }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("colorSchemes", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void ColorSchemes::AddNew_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Compatibility.cpp b/src/cascadia/TerminalSettingsEditor/Compatibility.cpp index 9637992ae8..9fa7b81ecf 100644 --- a/src/cascadia/TerminalSettingsEditor/Compatibility.cpp +++ b/src/cascadia/TerminalSettingsEditor/Compatibility.cpp @@ -25,11 +25,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void CompatibilityViewModel::ResetApplicationState() { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "ResetApplicationState", + TraceLoggingDescription("Event emitted when the user resets their application state"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _settings.ResetApplicationState(); } void CompatibilityViewModel::ResetToDefaultSettings() { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "ResetToDefaultSettings", + TraceLoggingDescription("Event emitted when the user resets their settings to their default value"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _settings.ResetToDefaultSettings(); } @@ -41,6 +55,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Compatibility::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("compatibility", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Compatibility::ResetApplicationStateButton_Click(const Windows::Foundation::IInspectable& /*sender*/, const Windows::UI::Xaml::RoutedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp b/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp index ce24a89e48..1c1d5f0c84 100644 --- a/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp +++ b/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp @@ -42,7 +42,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { _ViewModel = e.Parameter().as(); - NameBox().Text(_ViewModel.Name()); + const auto schemeName = _ViewModel.Name(); + NameBox().Text(schemeName); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("colorSchemes.editColorScheme", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(schemeName.data(), "SchemeName", "The name of the color scheme that's being edited"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void EditColorScheme::ColorPickerChanged(const IInspectable& sender, diff --git a/src/cascadia/TerminalSettingsEditor/Extensions.cpp b/src/cascadia/TerminalSettingsEditor/Extensions.cpp index a3aec0ad7c..ecf2cc26ad 100644 --- a/src/cascadia/TerminalSettingsEditor/Extensions.cpp +++ b/src/cascadia/TerminalSettingsEditor/Extensions.cpp @@ -20,8 +20,6 @@ using namespace winrt::Windows::UI::Xaml::Navigation; namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { - static constexpr std::wstring_view ExtensionPageId{ L"page.extensions" }; - Extensions::Extensions() { InitializeComponent(); @@ -41,6 +39,36 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation vmImpl->ExtensionPackageIdentifierTemplateSelector(_extensionPackageIdentifierTemplateSelector); vmImpl->LazyLoadExtensions(); vmImpl->MarkAsVisited(); + + if (vmImpl->IsExtensionView()) + { + const auto currentPkgVM = vmImpl->CurrentExtensionPackage(); + const auto currentPkg = currentPkgVM.Package(); + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("extensions.extensionView", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(currentPkg.Source().c_str(), "FragmentSource", "The source of the fragment included in this extension package"), + TraceLoggingValue(currentPkgVM.FragmentExtensions().Size(), "FragmentCount", "The number of fragments included in this extension package"), + TraceLoggingValue(currentPkgVM.Enabled(), "Enabled", "The enabled status of the extension"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + } + else + { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("extensions", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(vmImpl->ExtensionPackages().Size(), "ExtensionPackageCount", "The number of extension packages displayed"), + TraceLoggingValue(vmImpl->ProfilesModified().Size(), "ProfilesModifiedCount", "The number of profiles modified by enabled extensions"), + TraceLoggingValue(vmImpl->ProfilesAdded().Size(), "ProfilesAddedCount", "The number of profiles added by enabled extensions"), + TraceLoggingValue(vmImpl->ColorSchemesAdded().Size(), "ColorSchemesAddedCount", "The number of color schemes added by enabled extensions"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + } } void Extensions::ExtensionNavigator_Click(const IInspectable& sender, const RoutedEventArgs& /*args*/) @@ -338,7 +366,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation bool ExtensionsViewModel::DisplayBadge() const noexcept { - return !Model::ApplicationState::SharedInstance().BadgeDismissed(ExtensionPageId); + return !Model::ApplicationState::SharedInstance().BadgeDismissed(L"page.extensions"); } // Returns true if the extension is enabled, false otherwise @@ -411,7 +439,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void ExtensionsViewModel::MarkAsVisited() { - Model::ApplicationState::SharedInstance().DismissBadge(ExtensionPageId); + Model::ApplicationState::SharedInstance().DismissBadge(L"page.extensions"); _NotifyChanges(L"DisplayBadge"); } diff --git a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp index acb0abcb34..2b220b2ddd 100644 --- a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp +++ b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp @@ -25,5 +25,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void GlobalAppearance::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("globalAppearance", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/Interaction.cpp b/src/cascadia/TerminalSettingsEditor/Interaction.cpp index 24199f0c1b..6015cbcea1 100644 --- a/src/cascadia/TerminalSettingsEditor/Interaction.cpp +++ b/src/cascadia/TerminalSettingsEditor/Interaction.cpp @@ -22,5 +22,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Interaction::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("interaction", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/Launch.cpp b/src/cascadia/TerminalSettingsEditor/Launch.cpp index 286ed7c814..9c0a933961 100644 --- a/src/cascadia/TerminalSettingsEditor/Launch.cpp +++ b/src/cascadia/TerminalSettingsEditor/Launch.cpp @@ -43,5 +43,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _ViewModel = e.Parameter().as(); auto innerViewModel{ winrt::get_self(_ViewModel) }; /* coroutine dispatch */ innerViewModel->PrepareStartOnUserLoginSettings(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("startup", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.cpp b/src/cascadia/TerminalSettingsEditor/MainPage.cpp index e3cf92717b..19345746aa 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.cpp +++ b/src/cascadia/TerminalSettingsEditor/MainPage.cpp @@ -374,6 +374,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation const auto altPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) || WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); const auto target = altPressed ? SettingsTarget::DefaultsFile : SettingsTarget::SettingsFile; + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "OpenJson", + TraceLoggingDescription("Event emitted when the user clicks the Open JSON button in the settings UI"), + TraceLoggingValue(target == SettingsTarget::DefaultsFile ? "DefaultsFile" : "SettingsFile", "SettingsTarget", "The target settings file"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + OpenJson.raise(nullptr, target); return; } diff --git a/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj b/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj index 20f1538978..fb19f08a75 100644 --- a/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj +++ b/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj @@ -234,6 +234,7 @@ + Actions.xaml diff --git a/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj.filters b/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj.filters index 97caa229d1..f49f4c9bc7 100644 --- a/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj.filters +++ b/src/cascadia/TerminalSettingsEditor/Microsoft.Terminal.Settings.Editor.vcxproj.filters @@ -9,6 +9,7 @@ + diff --git a/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp b/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp index 25b7f8ef77..1587740b68 100644 --- a/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp +++ b/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp @@ -44,6 +44,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void NewTabMenu::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue(_ViewModel.IsFolderView() ? "newTabMenu.folderView" : "newTabMenu", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void NewTabMenu::FolderPickerDialog_Opened(const IInspectable& /*sender*/, const Controls::ContentDialogOpenedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp index 29b9f89108..64bdecd1d4 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp @@ -29,6 +29,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation const auto args = e.Parameter().as(); _Profile = args.Profile(); _windowRoot = args.WindowRoot(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile.advanced", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Advanced::OnNavigatedFrom(const NavigationEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp index bbdd0a5aae..af21f342c4 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp @@ -44,6 +44,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // The Appearances object handles updating the values in the settings UI, but // we still need to listen to the changes here just to update the preview control _AppearanceViewModelChangedRevoker = _Profile.DefaultAppearance().PropertyChanged(winrt::auto_revoke, { this, &Profiles_Appearance::_onProfilePropertyChanged }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile.appearance", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingValue(_Profile.DefaultAppearance().BackgroundImageSettingsVisible(), "HasBackgroundImage", "If the profile has a background image defined"), + TraceLoggingValue(_Profile.HasUnfocusedAppearance(), "HasUnfocusedAppearance", "If the profile has an unfocused appearance defined"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Appearance::OnNavigatedFrom(const NavigationEventArgs& /*e*/) @@ -54,6 +67,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Profiles_Appearance::CreateUnfocusedAppearance_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "CreateUnfocusedAppearance", + TraceLoggingDescription("Event emitted when the user creates an unfocused appearance for a profile"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _Profile.CreateUnfocusedAppearance(); } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp index 88ba50e386..774ecbb34d 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp @@ -55,6 +55,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _Profile.FocusDeleteButton(false); } }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to. Set to {3ad42e7b-e073-5f3e-ac57-1c259ffa86a8} if the profiles.defaults object is being modified."), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Base::OnNavigatedFrom(const NavigationEventArgs& /*e*/) @@ -79,6 +90,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Profiles_Base::DeleteConfirmation_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "DeleteProfile", + TraceLoggingDescription("Event emitted when the user deletes a profile"), + TraceLoggingValue(to_hstring(_Profile.Guid()).c_str(), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingValue(false, "Orphaned", "Tracks if the profile is orphaned"), + TraceLoggingValue(_Profile.Hidden(), "Hidden", "Tracks if the profile is hidden"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + winrt::get_self(_Profile)->DeleteProfile(); } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp index bc27cc4c2d..dc1de90cb0 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp @@ -41,6 +41,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _Profile.FocusDeleteButton(false); } }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profileOrphaned", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Base_Orphaned::DeleteConfirmation_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp index 7d42d64d21..fd8899dff1 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp @@ -22,6 +22,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Profiles_Terminal::OnNavigatedTo(const NavigationEventArgs& e) { _Profile = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile.terminal", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Terminal::OnNavigatedFrom(const NavigationEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Rendering.cpp b/src/cascadia/TerminalSettingsEditor/Rendering.cpp index 5ce0d1285e..836d63ca20 100644 --- a/src/cascadia/TerminalSettingsEditor/Rendering.cpp +++ b/src/cascadia/TerminalSettingsEditor/Rendering.cpp @@ -17,5 +17,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Rendering::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("rendering", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/Utils.cpp b/src/cascadia/TerminalSettingsEditor/Utils.cpp index 5fc2fea999..07fde8471f 100644 --- a/src/cascadia/TerminalSettingsEditor/Utils.cpp +++ b/src/cascadia/TerminalSettingsEditor/Utils.cpp @@ -13,8 +13,6 @@ using namespace winrt::Windows::System; using namespace winrt::Windows::Foundation; using namespace winrt::Windows::UI::Xaml; -UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"Microsoft.Terminal.Settings.Editor/Resources"); - namespace winrt::Microsoft::Terminal::Settings { hstring GetSelectedItemTag(const winrt::Windows::Foundation::IInspectable& comboBoxAsInspectable) diff --git a/src/cascadia/TerminalSettingsEditor/init.cpp b/src/cascadia/TerminalSettingsEditor/init.cpp new file mode 100644 index 0000000000..bf25f63dc0 --- /dev/null +++ b/src/cascadia/TerminalSettingsEditor/init.cpp @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. + +#include "pch.h" +#include +#include + +// Note: Generate GUID using TlgGuid.exe tool +TRACELOGGING_DEFINE_PROVIDER( + g_hTerminalSettingsEditorProvider, + "Microsoft.Windows.Terminal.Settings.Editor", + // {1b16317d-b594-51f8-c552-5d50572b5efc} + (0x1b16317d, 0xb594, 0x51f8, 0xc5, 0x52, 0x5d, 0x50, 0x57, 0x2b, 0x5e, 0xfc), + TraceLoggingOptionMicrosoftTelemetry()); + +BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hInstDll); + TraceLoggingRegister(g_hTerminalSettingsEditorProvider); + Microsoft::Console::ErrorReporting::EnableFallbackFailureReporting(g_hTerminalSettingsEditorProvider); + break; + case DLL_PROCESS_DETACH: + if (g_hTerminalSettingsEditorProvider) + { + TraceLoggingUnregister(g_hTerminalSettingsEditorProvider); + } + break; + } + + return TRUE; +} + +UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"Microsoft.Terminal.Settings.Editor/Resources"); diff --git a/src/cascadia/TerminalSettingsEditor/pch.h b/src/cascadia/TerminalSettingsEditor/pch.h index d21e5321ef..cc4965ef9a 100644 --- a/src/cascadia/TerminalSettingsEditor/pch.h +++ b/src/cascadia/TerminalSettingsEditor/pch.h @@ -56,6 +56,13 @@ #include #include +// Including TraceLogging essentials for the binary +#include +#include +TRACELOGGING_DECLARE_PROVIDER(g_hTerminalSettingsEditorProvider); +#include +#include + #include #include #include