mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-11 22:48:41 -06:00
Add support for --fullscreen, --maximized (#6139)
## Summary of the Pull Request Adds two new flags to the `wt.exe` alias: * `--maximized,-M`: Launch the new Terminal window maximized. This flag cannot be combined with `--fullscreen`. * `--fullscreen,-F`: Launch the new Terminal window fullscreen. This flag cannot be combined with `--maximized`. ## References * This builds on the work done in #6060. * The cmdline args megathread: #4632 ## PR Checklist * [x] Closes #5801 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments * I had to move the commandline arg parsing up a layer from `TerminalPage` to `AppLogic`, because `AppLogic` controls the Terminal's settings, including launch mode settings. This seems like a reasonable change, to put both the settings from the file and the commandline in the same place. - **Most of the diff is that movement of code** * _"What happens when you try to pass both flags, like `wtd -M -F new-tab`?"_:  ## Validation Steps Performed * Ran a bunch of commandlines to see what happened.
This commit is contained in:
parent
d92c8293ce
commit
8987486e85
@ -232,7 +232,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/,
|
||||
const TerminalApp::ActionEventArgs& args)
|
||||
{
|
||||
_ToggleFullscreen();
|
||||
ToggleFullscreen();
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,6 +157,7 @@ int AppCommandlineArgs::_handleExit(const CLI::App& command, const CLI::Error& e
|
||||
// - <none>
|
||||
void AppCommandlineArgs::_buildParser()
|
||||
{
|
||||
// -v,--version: Displays version info
|
||||
auto versionCallback = [this](int64_t /*count*/) {
|
||||
if (const auto appLogic{ winrt::TerminalApp::implementation::AppLogic::Current() })
|
||||
{
|
||||
@ -173,6 +174,20 @@ void AppCommandlineArgs::_buildParser()
|
||||
};
|
||||
_app.add_flag_function("-v,--version", versionCallback, RS_A(L"CmdVersionDesc"));
|
||||
|
||||
// Maximized and Fullscreen flags
|
||||
// -M,--maximized: Maximizes the window on launch
|
||||
// -F,--fullscreen: Fullscreens the window on launch
|
||||
auto maximizedCallback = [this](int64_t /*count*/) {
|
||||
_launchMode = winrt::TerminalApp::LaunchMode::MaximizedMode;
|
||||
};
|
||||
auto fullscreenCallback = [this](int64_t /*count*/) {
|
||||
_launchMode = winrt::TerminalApp::LaunchMode::FullscreenMode;
|
||||
};
|
||||
auto maximized = _app.add_flag_function("-M,--maximized", maximizedCallback, RS_A(L"CmdMaximizedDesc"));
|
||||
auto fullscreen = _app.add_flag_function("-F,--fullscreen", fullscreenCallback, RS_A(L"CmdFullscreenDesc"));
|
||||
maximized->excludes(fullscreen);
|
||||
|
||||
// Subcommands
|
||||
_buildNewTabParser();
|
||||
_buildSplitPaneParser();
|
||||
_buildFocusTabParser();
|
||||
@ -410,6 +425,10 @@ void AppCommandlineArgs::_resetStateToDefault()
|
||||
_focusTabIndex = -1;
|
||||
_focusNextTab = false;
|
||||
_focusPrevTab = false;
|
||||
|
||||
// DON'T clear _launchMode here! This will get called once for every
|
||||
// subcommand, so we don't want `wt -F new-tab ; split-pane` clearing out
|
||||
// the "global" fullscreen flag (-F).
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
@ -604,3 +623,8 @@ void AppCommandlineArgs::ValidateStartupCommands()
|
||||
_startupActions.push_front(*newTabAction);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<winrt::TerminalApp::LaunchMode> AppCommandlineArgs::GetLaunchMode() const noexcept
|
||||
{
|
||||
return _launchMode;
|
||||
}
|
||||
|
||||
@ -38,6 +38,8 @@ public:
|
||||
const std::string& GetExitMessage();
|
||||
bool ShouldExitEarly() const noexcept;
|
||||
|
||||
std::optional<winrt::TerminalApp::LaunchMode> GetLaunchMode() const noexcept;
|
||||
|
||||
private:
|
||||
static const std::wregex _commandDelimiterRegex;
|
||||
|
||||
@ -76,6 +78,8 @@ private:
|
||||
int _focusTabIndex{ -1 };
|
||||
bool _focusNextTab{ false };
|
||||
bool _focusPrevTab{ false };
|
||||
|
||||
std::optional<winrt::TerminalApp::LaunchMode> _launchMode{ std::nullopt };
|
||||
// Are you adding more args here? Make sure to reset them in _resetStateToDefault
|
||||
|
||||
std::deque<winrt::TerminalApp::ActionAndArgs> _startupActions;
|
||||
|
||||
@ -242,6 +242,17 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_root->SetSettings(_settings, false);
|
||||
_root->Loaded({ this, &AppLogic::_OnLoaded });
|
||||
_root->Initialized([this](auto&&, auto&&) {
|
||||
// GH#288 - When we finish initialization, if the user wanted us
|
||||
// launched _fullscreen_, toggle fullscreen mode. This will make sure
|
||||
// that the window size is _first_ set up as something sensible, so
|
||||
// leaving fullscreen returns to a reasonable size.
|
||||
const auto launchMode = this->GetLaunchMode();
|
||||
if (launchMode == LaunchMode::FullscreenMode)
|
||||
{
|
||||
_root->ToggleFullscreen();
|
||||
}
|
||||
});
|
||||
_root->Create();
|
||||
|
||||
_ApplyTheme(_settings->GlobalSettings().GetTheme());
|
||||
@ -529,7 +540,13 @@ namespace winrt::TerminalApp::implementation
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
return _settings->GlobalSettings().GetLaunchMode();
|
||||
// GH#4620/#5801 - If the user passed --maximized or --fullscreen on the
|
||||
// commandline, then use that to override the value from the settings.
|
||||
const auto valueFromSettings = _settings->GlobalSettings().GetLaunchMode();
|
||||
const auto valueFromCommandlineArgs = _appArgs.GetLaunchMode();
|
||||
return valueFromCommandlineArgs.has_value() ?
|
||||
valueFromCommandlineArgs.value() :
|
||||
valueFromSettings;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@ -934,31 +951,108 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
int32_t AppLogic::SetStartupCommandline(array_view<const winrt::hstring> actions)
|
||||
// Method Description:
|
||||
// - Sets the initial commandline to process on startup, and attempts to
|
||||
// parse it. Commands will be parsed into a list of ShortcutActions that
|
||||
// will be processed on TerminalPage::Create().
|
||||
// - This function will have no effective result after Create() is called.
|
||||
// - This function returns 0, unless a there was a non-zero result from
|
||||
// trying to parse one of the commands provided. In that case, no commands
|
||||
// after the failing command will be parsed, and the non-zero code
|
||||
// returned.
|
||||
// Arguments:
|
||||
// - args: an array of strings to process as a commandline. These args can contain spaces
|
||||
// Return Value:
|
||||
// - the result of the first command who's parsing returned a non-zero code,
|
||||
// or 0. (see AppLogic::_ParseArgs)
|
||||
int32_t AppLogic::SetStartupCommandline(array_view<const winrt::hstring> args)
|
||||
{
|
||||
if (_root)
|
||||
const auto result = _ParseArgs(args);
|
||||
if (result == 0)
|
||||
{
|
||||
return _root->SetStartupCommandline(actions);
|
||||
_appArgs.ValidateStartupCommands();
|
||||
_root->SetStartupActions(_appArgs.GetStartupActions());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempts to parse an array of commandline args into a list of
|
||||
// commands to execute, and then parses these commands. As commands are
|
||||
// successfully parsed, they will generate ShortcutActions for us to be
|
||||
// able to execute. If we fail to parse any commands, we'll return the
|
||||
// error code from the failure to parse that command, and stop processing
|
||||
// additional commands.
|
||||
// Arguments:
|
||||
// - args: an array of strings to process as a commandline. These args can contain spaces
|
||||
// Return Value:
|
||||
// - 0 if the commandline was successfully parsed
|
||||
int AppLogic::_ParseArgs(winrt::array_view<const hstring>& args)
|
||||
{
|
||||
auto commands = ::TerminalApp::AppCommandlineArgs::BuildCommands(args);
|
||||
|
||||
for (auto& cmdBlob : commands)
|
||||
{
|
||||
// On one hand, it seems like we should be able to have one
|
||||
// AppCommandlineArgs for parsing all of them, and collect the
|
||||
// results one at a time.
|
||||
//
|
||||
// On the other hand, re-using a CLI::App seems to leave state from
|
||||
// previous parsings around, so we could get mysterious behavior
|
||||
// where one command affects the values of the next.
|
||||
//
|
||||
// From https://cliutils.github.io/CLI11/book/chapters/options.html:
|
||||
// > If that option is not given, CLI11 will not touch the initial
|
||||
// > value. This allows you to set up defaults by simply setting
|
||||
// > your value beforehand.
|
||||
//
|
||||
// So we pretty much need the to either manually reset the state
|
||||
// each command, or build new ones.
|
||||
const auto result = _appArgs.ParseCommand(cmdBlob);
|
||||
|
||||
// If this succeeded, result will be 0. Otherwise, the caller should
|
||||
// exit(result), to exit the program.
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If all the args were successfully parsed, we'll have some commands
|
||||
// built in _appArgs, which we'll use when the application starts up.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - If there were any errors parsing the commandline that was used to
|
||||
// initialize the terminal, this will return a string containing that
|
||||
// message. If there were no errors, this message will be blank.
|
||||
// - If the user requested help on any command (using --help), this will
|
||||
// contain the help message.
|
||||
// - If the user requested the version number (using --version), this will
|
||||
// contain the version string.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the help text or error message for the provided commandline, if one
|
||||
// exists, otherwise the empty string.
|
||||
winrt::hstring AppLogic::ParseCommandlineMessage()
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
return _root->ParseCommandlineMessage();
|
||||
}
|
||||
return { L"" };
|
||||
return winrt::to_hstring(_appArgs.GetExitMessage());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns true if we should exit the application before even starting the
|
||||
// window. We might want to do this if we're displaying an error message or
|
||||
// the version string, or if we want to open the settings file.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - true iff we should exit the application before even starting the window
|
||||
bool AppLogic::ShouldExitEarly()
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
return _root->ShouldExitEarly();
|
||||
}
|
||||
return false;
|
||||
return _appArgs.ShouldExitEarly();
|
||||
}
|
||||
|
||||
winrt::hstring AppLogic::ApplicationDisplayName() const
|
||||
|
||||
@ -76,6 +76,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
std::atomic<bool> _settingsReloadQueued{ false };
|
||||
|
||||
::TerminalApp::AppCommandlineArgs _appArgs;
|
||||
int _ParseArgs(winrt::array_view<const hstring>& args);
|
||||
|
||||
fire_and_forget _ShowDialog(const winrt::Windows::Foundation::IInspectable& sender, winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
||||
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey, HRESULT settingsLoadedResult);
|
||||
void _ShowLoadWarningsDialog();
|
||||
|
||||
@ -259,6 +259,12 @@
|
||||
<data name="CmdVersionDesc" xml:space="preserve">
|
||||
<value>Display the application version</value>
|
||||
</data>
|
||||
<data name="CmdMaximizedDesc" xml:space="preserve">
|
||||
<value>Launch the window maximized</value>
|
||||
</data>
|
||||
<data name="CmdFullscreenDesc" xml:space="preserve">
|
||||
<value>Launch the window in fullscreen mode</value>
|
||||
</data>
|
||||
<data name="NewTabSplitButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.HelpText" xml:space="preserve">
|
||||
<value>Press the button to open a new terminal tab with your default profile. Open the flyout to select which profile you want to open.</value>
|
||||
</data>
|
||||
|
||||
@ -184,8 +184,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_startupState == StartupState::NotInitialized)
|
||||
{
|
||||
_startupState = StartupState::InStartup;
|
||||
_appArgs.ValidateStartupCommands();
|
||||
if (_appArgs.GetStartupActions().empty())
|
||||
if (_startupActions.empty())
|
||||
{
|
||||
_OpenNewTab(nullptr);
|
||||
|
||||
@ -208,7 +207,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::fire_and_forget TerminalPage::_ProcessStartupActions()
|
||||
{
|
||||
// If there are no actions left, do nothing.
|
||||
if (_appArgs.GetStartupActions().empty())
|
||||
if (_startupActions.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -218,7 +217,7 @@ namespace winrt::TerminalApp::implementation
|
||||
co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal);
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
for (const auto& action : _appArgs.GetStartupActions())
|
||||
for (const auto& action : _startupActions)
|
||||
{
|
||||
_actionDispatch->DoAction(action);
|
||||
}
|
||||
@ -237,14 +236,6 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_CompleteInitialization()
|
||||
{
|
||||
// GH#288 - When we finish initialization, if the user wanted us
|
||||
// launched _fullscreen_, toggle fullscreen mode. This will make sure
|
||||
// that the window size is _first_ set up as something sensible, so
|
||||
// leaving fullscreen returns to a reasonable size.
|
||||
if (_settings->GlobalSettings().GetLaunchMode() == winrt::TerminalApp::LaunchMode::FullscreenMode)
|
||||
{
|
||||
_ToggleFullscreen();
|
||||
}
|
||||
_startupState = StartupState::Initialized;
|
||||
_InitializedHandlers(*this, nullptr);
|
||||
}
|
||||
@ -1776,69 +1767,16 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets the initial commandline to process on startup, and attempts to
|
||||
// parse it. Commands will be parsed into a list of ShortcutActions that
|
||||
// will be processed on TerminalPage::Create().
|
||||
// - Sets the initial actions to process on startup. We'll make a copy of
|
||||
// this list, and process these actions when we're loaded.
|
||||
// - This function will have no effective result after Create() is called.
|
||||
// - This function returns 0, unless a there was a non-zero result from
|
||||
// trying to parse one of the commands provided. In that case, no commands
|
||||
// after the failing command will be parsed, and the non-zero code
|
||||
// returned.
|
||||
// Arguments:
|
||||
// - args: an array of strings to process as a commandline. These args can contain spaces
|
||||
// - actions: a list of Actions to process on startup.
|
||||
// Return Value:
|
||||
// - the result of the first command who's parsing returned a non-zero code,
|
||||
// or 0. (see TerminalPage::_ParseArgs)
|
||||
int32_t TerminalPage::SetStartupCommandline(winrt::array_view<const hstring> args)
|
||||
// - <none>
|
||||
void TerminalPage::SetStartupActions(std::deque<winrt::TerminalApp::ActionAndArgs>& actions)
|
||||
{
|
||||
return _ParseArgs(args);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempts to parse an array of commandline args into a list of
|
||||
// commands to execute, and then parses these commands. As commands are
|
||||
// successfully parsed, they will generate ShortcutActions for us to be
|
||||
// able to execute. If we fail to parse any commands, we'll return the
|
||||
// error code from the failure to parse that command, and stop processing
|
||||
// additional commands.
|
||||
// Arguments:
|
||||
// - args: an array of strings to process as a commandline. These args can contain spaces
|
||||
// Return Value:
|
||||
// - 0 if the commandline was successfully parsed
|
||||
int TerminalPage::_ParseArgs(winrt::array_view<const hstring>& args)
|
||||
{
|
||||
auto commands = ::TerminalApp::AppCommandlineArgs::BuildCommands(args);
|
||||
|
||||
for (auto& cmdBlob : commands)
|
||||
{
|
||||
// On one hand, it seems like we should be able to have one
|
||||
// AppCommandlineArgs for parsing all of them, and collect the
|
||||
// results one at a time.
|
||||
//
|
||||
// On the other hand, re-using a CLI::App seems to leave state from
|
||||
// previous parsings around, so we could get mysterious behavior
|
||||
// where one command affects the values of the next.
|
||||
//
|
||||
// From https://cliutils.github.io/CLI11/book/chapters/options.html:
|
||||
// > If that option is not given, CLI11 will not touch the initial
|
||||
// > value. This allows you to set up defaults by simply setting
|
||||
// > your value beforehand.
|
||||
//
|
||||
// So we pretty much need the to either manually reset the state
|
||||
// each command, or build new ones.
|
||||
const auto result = _appArgs.ParseCommand(cmdBlob);
|
||||
|
||||
// If this succeeded, result will be 0. Otherwise, the caller should
|
||||
// exit(result), to exit the program.
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If all the args were successfully parsed, we'll have some commands
|
||||
// built in _appArgs, which we'll use when the application starts up.
|
||||
return 0;
|
||||
_startupActions = actions;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@ -1877,7 +1815,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_ToggleFullscreen()
|
||||
void TerminalPage::ToggleFullscreen()
|
||||
{
|
||||
_toggleFullscreenHandlers(*this, nullptr);
|
||||
|
||||
@ -1886,37 +1824,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_UpdateTabView();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - If there were any errors parsing the commandline that was used to
|
||||
// initialize the terminal, this will return a string containing that
|
||||
// message. If there were no errors, this message will be blank.
|
||||
// - If the user requested help on any command (using --help), this will
|
||||
// contain the help message.
|
||||
// - If the user requested the version number (using --version), this will
|
||||
// contain the version string.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the help text or error message for the provided commandline, if one
|
||||
// exists, otherwise the empty string.
|
||||
winrt::hstring TerminalPage::ParseCommandlineMessage()
|
||||
{
|
||||
return winrt::to_hstring(_appArgs.GetExitMessage());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns true if we should exit the application before even starting the
|
||||
// window. We might want to do this if we're displaying an error message or
|
||||
// the version string, or if we want to open the settings file.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - true iff we should exit the application before even starting the window
|
||||
bool TerminalPage::ShouldExitEarly()
|
||||
{
|
||||
return _appArgs.ShouldExitEarly();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns a com_ptr to the implementation type of the tab at the given index
|
||||
// Arguments:
|
||||
|
||||
@ -49,9 +49,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void CloseWindow();
|
||||
|
||||
int32_t SetStartupCommandline(winrt::array_view<const hstring> args);
|
||||
winrt::hstring ParseCommandlineMessage();
|
||||
bool ShouldExitEarly();
|
||||
void ToggleFullscreen();
|
||||
|
||||
void SetStartupActions(std::deque<winrt::TerminalApp::ActionAndArgs>& actions);
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
|
||||
@ -92,8 +92,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Windows::UI::Xaml::Controls::Grid::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
||||
StartupState _startupState{ StartupState::NotInitialized };
|
||||
|
||||
::TerminalApp::AppCommandlineArgs _appArgs;
|
||||
int _ParseArgs(winrt::array_view<const hstring>& args);
|
||||
std::deque<winrt::TerminalApp::ActionAndArgs> _startupActions;
|
||||
winrt::fire_and_forget _ProcessStartupActions();
|
||||
|
||||
void _ShowAboutDialog();
|
||||
@ -166,8 +165,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::fire_and_forget _RefreshUIForSettingsReload();
|
||||
|
||||
void _ToggleFullscreen();
|
||||
|
||||
void _SetNonClientAreaColors(const Windows::UI::Color& selectedTabColor);
|
||||
void _ClearNonClientAreaColors();
|
||||
void _SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor);
|
||||
|
||||
@ -10,10 +10,6 @@ namespace TerminalApp
|
||||
{
|
||||
TerminalPage();
|
||||
|
||||
Int32 SetStartupCommandline(String[] commands);
|
||||
String ParseCommandlineMessage { get; };
|
||||
Boolean ShouldExitEarly { get; };
|
||||
|
||||
// XAML bound properties
|
||||
String ApplicationDisplayName { get; };
|
||||
String ApplicationVersion { get; };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user