Skip to content

Commit

Permalink
Add support for --fullscreen, --maximized (#6139)
Browse files Browse the repository at this point in the history
## 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`?"_:
![image](https://user-images.githubusercontent.com/18356694/82679939-3cffde00-9c11-11ea-8d88-03ec7db83e59.png)

## Validation Steps Performed
* Ran a bunch of commandlines to see what happened.
  • Loading branch information
zadjii-msft authored Jun 1, 2020
1 parent d92c829 commit 8987486
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 129 deletions.
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/,
const TerminalApp::ActionEventArgs& args)
{
_ToggleFullscreen();
ToggleFullscreen();
args.Handled(true);
}
}
24 changes: 24 additions & 0 deletions src/cascadia/TerminalApp/AppCommandlineArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() })
{
Expand All @@ -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();
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -604,3 +623,8 @@ void AppCommandlineArgs::ValidateStartupCommands()
_startupActions.push_front(*newTabAction);
}
}

std::optional<winrt::TerminalApp::LaunchMode> AppCommandlineArgs::GetLaunchMode() const noexcept
{
return _launchMode;
}
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/AppCommandlineArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class TerminalApp::AppCommandlineArgs final
const std::string& GetExitMessage();
bool ShouldExitEarly() const noexcept;

std::optional<winrt::TerminalApp::LaunchMode> GetLaunchMode() const noexcept;

private:
static const std::wregex _commandDelimiterRegex;

Expand Down Expand Up @@ -76,6 +78,8 @@ class TerminalApp::AppCommandlineArgs final
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;
Expand Down
122 changes: 108 additions & 14 deletions src/cascadia/TerminalApp/AppLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 0;

return result;
}

winrt::hstring AppLogic::ParseCommandlineMessage()
// 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)
{
if (_root)
auto commands = ::TerminalApp::AppCommandlineArgs::BuildCommands(args);

for (auto& cmdBlob : commands)
{
return _root->ParseCommandlineMessage();
// 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;
}
}
return { L"" };

// 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()
{
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
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Loading

0 comments on commit 8987486

Please sign in to comment.