diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 59592b51f64..a835b5a0570 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -231,6 +231,32 @@ } ] }, + "OpenSettingsAction": { + "description": "Arguments corresponding to a Open Settings Action", + "allOf": [ + { + "$ref": "#/definitions/ShortcutAction" + }, + { + "properties": { + "action": { + "type": "string", + "pattern": "openSettings" + }, + "target": { + "type": "string", + "default": "settingsFile", + "description": "The settings file to open.", + "enum": [ + "settingsFile", + "defaultsFile", + "allFiles" + ] + } + } + } + ] + }, "Keybinding": { "additionalProperties": false, "properties": { @@ -245,6 +271,7 @@ { "$ref": "#/definitions/MoveFocusAction" }, { "$ref": "#/definitions/ResizePaneAction" }, { "$ref": "#/definitions/SplitPaneAction" }, + { "$ref": "#/definitions/OpenSettingsAction" }, { "type": "null" } ] }, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index b3af876bace..939eaaf3b41 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -14,3 +14,4 @@ #include "MoveFocusArgs.g.cpp" #include "AdjustFontSizeArgs.g.cpp" #include "SplitPaneArgs.g.cpp" +#include "OpenSettingsArgs.g.cpp" diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index cf21b68cb5a..031e7ca76a9 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -14,6 +14,7 @@ #include "MoveFocusArgs.g.h" #include "AdjustFontSizeArgs.g.h" #include "SplitPaneArgs.g.h" +#include "OpenSettingsArgs.g.h" #include "../../cascadia/inc/cppwinrt_utils.h" #include "Utils.h" @@ -381,6 +382,65 @@ namespace winrt::TerminalApp::implementation return { *args, {} }; } }; + + // Possible SettingsTarget values + // TODO:GH#2550/#3475 - move these to a centralized deserializing place + static constexpr std::string_view SettingsFileString{ "settingsFile" }; + static constexpr std::string_view DefaultsFileString{ "defaultsFile" }; + static constexpr std::string_view AllFilesString{ "allFiles" }; + + // Function Description: + // - Helper function for parsing a SettingsTarget from a string + // Arguments: + // - targetString: the string to attempt to parse + // Return Value: + // - The encoded SettingsTarget value, or SettingsTarget::SettingsFile if it was an invalid string + static TerminalApp::SettingsTarget ParseSettingsTarget(const std::string& targetString) + { + if (targetString == SettingsFileString) + { + return TerminalApp::SettingsTarget::SettingsFile; + } + else if (targetString == DefaultsFileString) + { + return TerminalApp::SettingsTarget::DefaultsFile; + } + else if (targetString == AllFilesString) + { + return TerminalApp::SettingsTarget::AllFiles; + } + // default behavior for invalid data + return TerminalApp::SettingsTarget::SettingsFile; + }; + + struct OpenSettingsArgs : public OpenSettingsArgsT + { + OpenSettingsArgs() = default; + GETSET_PROPERTY(TerminalApp::SettingsTarget, Target, TerminalApp::SettingsTarget::SettingsFile); + + static constexpr std::string_view TargetKey{ "target" }; + + public: + bool Equals(const IActionArgs& other) + { + auto otherAsUs = other.try_as(); + if (otherAsUs) + { + return otherAsUs->_Target == _Target; + } + return false; + }; + static FromJsonResult FromJson(const Json::Value& json) + { + // LOAD BEARING: Not using make_self here _will_ break you in the future! + auto args = winrt::make_self(); + if (auto targetString{ json[JsonKey(TargetKey)] }) + { + args->_Target = ParseSettingsTarget(targetString.asString()); + } + return { *args, {} }; + } + }; } namespace winrt::TerminalApp::factory_implementation diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index 96fa3abf587..881e35eafbe 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -37,6 +37,13 @@ namespace TerminalApp Duplicate = 1 }; + enum SettingsTarget + { + SettingsFile = 0, + DefaultsFile, + AllFiles + }; + [default_interface] runtimeclass NewTerminalArgs { NewTerminalArgs(); String Commandline; @@ -90,4 +97,9 @@ namespace TerminalApp NewTerminalArgs TerminalArgs { get; }; SplitType SplitMode { get; }; }; + + [default_interface] runtimeclass OpenSettingsArgs : IActionArgs + { + SettingsTarget Target { get; }; + }; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index d0e1c027f7f..5304816ae26 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -120,9 +120,11 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_HandleOpenSettings(const IInspectable& /*sender*/, const TerminalApp::ActionEventArgs& args) { - // TODO:GH#2557 Add an optional arg for opening the defaults here - _LaunchSettings(false); - args.Handled(true); + if (const auto& realArgs = args.ActionArgs().try_as()) + { + _LaunchSettings(realArgs.Target()); + args.Handled(true); + } } void TerminalPage::_HandlePasteText(const IInspectable& /*sender*/, diff --git a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp index f223236f56f..5d95d1ea249 100644 --- a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp @@ -109,6 +109,8 @@ static const std::map> argParse { ShortcutAction::SplitPane, winrt::TerminalApp::implementation::SplitPaneArgs::FromJson }, + { ShortcutAction::OpenSettings, winrt::TerminalApp::implementation::OpenSettingsArgs::FromJson }, + { ShortcutAction::Invalid, nullptr }, }; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 750d97a09b8..6d33779c687 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -669,7 +669,8 @@ namespace winrt::TerminalApp::implementation const bool altPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) || WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); - _LaunchSettings(altPressed); + const auto target = altPressed ? SettingsTarget::DefaultsFile : SettingsTarget::SettingsFile; + _LaunchSettings(target); } // Method Description: @@ -1532,7 +1533,7 @@ namespace winrt::TerminalApp::implementation // - Called when the settings button is clicked. ShellExecutes the settings // file, as to open it in the default editor for .json files. Does this in // a background thread, as to not hang/crash the UI thread. - fire_and_forget TerminalPage::_LaunchSettings(const bool openDefaults) + fire_and_forget TerminalPage::_LaunchSettings(const SettingsTarget target) { // This will switch the execution of the function to a background (not // UI) thread. This is IMPORTANT, because the Windows.Storage API's @@ -1540,13 +1541,26 @@ namespace winrt::TerminalApp::implementation // thread, because the main thread is a STA. co_await winrt::resume_background(); - const auto settingsPath = openDefaults ? CascadiaSettings::GetDefaultSettingsPath() : - CascadiaSettings::GetSettingsPath(); + auto openFile = [](const auto& filePath) { + HINSTANCE res = ShellExecute(nullptr, nullptr, filePath.c_str(), nullptr, nullptr, SW_SHOW); + if (static_cast(reinterpret_cast(res)) <= 32) + { + ShellExecute(nullptr, nullptr, L"notepad", filePath.c_str(), nullptr, SW_SHOW); + } + }; - HINSTANCE res = ShellExecute(nullptr, nullptr, settingsPath.c_str(), nullptr, nullptr, SW_SHOW); - if (static_cast(reinterpret_cast(res)) <= 32) - { - ShellExecute(nullptr, nullptr, L"notepad", settingsPath.c_str(), nullptr, SW_SHOW); + switch (target) + { + case SettingsTarget::DefaultsFile: + openFile(CascadiaSettings::GetDefaultSettingsPath()); + break; + case SettingsTarget::SettingsFile: + openFile(CascadiaSettings::GetSettingsPath()); + break; + case SettingsTarget::AllFiles: + openFile(CascadiaSettings::GetDefaultSettingsPath()); + openFile(CascadiaSettings::GetSettingsPath()); + break; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index f03a5d639c2..5fc557ab390 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -152,7 +152,7 @@ namespace winrt::TerminalApp::implementation void _PasteText(); static fire_and_forget PasteFromClipboard(winrt::Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs eventArgs); - fire_and_forget _LaunchSettings(const bool openDefaults); + fire_and_forget _LaunchSettings(const winrt::TerminalApp::SettingsTarget target); void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs); void _OnTabSelectionChanged(const IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& eventArgs); diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index 7e895de93e3..dd246e88aae 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -276,6 +276,7 @@ { "command": "toggleFullscreen", "keys": "f11" }, { "command": "openNewTabDropdown", "keys": "ctrl+shift+space" }, { "command": "openSettings", "keys": "ctrl+," }, + { "command": { "action": "openSettings", "target": "defaultFile" }, "keys": "ctrl+alt+," }, { "command": "find", "keys": "ctrl+shift+f" }, // Tab Management