mirror of
https://github.com/microsoft/terminal.git
synced 2026-02-04 05:35:20 +00:00
Add --pos and --size cmdline args (#13730)
Adds `--pos`, and `--size` commandline arguments to `wt`. Closes #4620
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "pch.h"
|
||||
#include "AppCommandlineArgs.h"
|
||||
#include "../types/inc/utils.hpp"
|
||||
#include "TerminalSettingsModel/ModelSerializationHelpers.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
@@ -183,6 +184,15 @@ void AppCommandlineArgs::_buildParser()
|
||||
maximized->excludes(fullscreen);
|
||||
focus->excludes(fullscreen);
|
||||
|
||||
auto positionCallback = [this](std::string string) {
|
||||
_position = LaunchPositionFromString(string);
|
||||
};
|
||||
_app.add_option_function<std::string>("--pos", positionCallback, RS_A(L"CmdPositionDesc"));
|
||||
auto sizeCallback = [this](std::string string) {
|
||||
_size = SizeFromString(string);
|
||||
};
|
||||
_app.add_option_function<std::string>("--size", sizeCallback, RS_A(L"CmdSizeDesc"));
|
||||
|
||||
_app.add_option("-w,--window",
|
||||
_windowTarget,
|
||||
RS_A(L"CmdWindowTargetArgDesc"));
|
||||
@@ -709,7 +719,7 @@ void AppCommandlineArgs::_resetStateToDefault()
|
||||
// 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).
|
||||
// Same with _windowTarget.
|
||||
// Same with _windowTarget, _position and _size.
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
@@ -936,6 +946,16 @@ std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> AppComman
|
||||
return _launchMode;
|
||||
}
|
||||
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchPosition> AppCommandlineArgs::GetPosition() const noexcept
|
||||
{
|
||||
return _position;
|
||||
}
|
||||
|
||||
std::optional<til::size> AppCommandlineArgs::GetSize() const noexcept
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@@ -41,6 +41,8 @@ public:
|
||||
|
||||
std::optional<uint32_t> GetPersistedLayoutIdx() const noexcept;
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> GetLaunchMode() const noexcept;
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchPosition> GetPosition() const noexcept;
|
||||
std::optional<til::size> GetSize() const noexcept;
|
||||
|
||||
int ParseArgs(const winrt::Microsoft::Terminal::Settings::Model::ExecuteCommandlineArgs& args);
|
||||
void DisableHelpInExitMessage();
|
||||
@@ -119,6 +121,8 @@ private:
|
||||
|
||||
const Commandline* _currentCommandline{ nullptr };
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchMode> _launchMode{ std::nullopt };
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::LaunchPosition> _position{ std::nullopt };
|
||||
std::optional<til::size> _size{ std::nullopt };
|
||||
bool _isHandoffListener{ false };
|
||||
std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs> _startupActions;
|
||||
std::string _exitMessage;
|
||||
|
||||
@@ -633,12 +633,17 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
if (proposedSize.Width == 0 && proposedSize.Height == 0)
|
||||
if (_appArgs.GetSize().has_value() || (proposedSize.Width == 0 && proposedSize.Height == 0))
|
||||
{
|
||||
// Use the default profile to determine how big of a window we need.
|
||||
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, nullptr, nullptr) };
|
||||
|
||||
proposedSize = TermControl::GetProposedDimensions(settings.DefaultSettings(), dpi);
|
||||
const til::size emptySize{};
|
||||
const auto commandlineSize = _appArgs.GetSize().value_or(emptySize);
|
||||
proposedSize = TermControl::GetProposedDimensions(settings.DefaultSettings(),
|
||||
dpi,
|
||||
commandlineSize.width,
|
||||
commandlineSize.height);
|
||||
}
|
||||
|
||||
// GH#2061 - If the global setting "Always show tab bar" is
|
||||
@@ -738,6 +743,12 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Commandline args trump everything else
|
||||
if (_appArgs.GetPosition().has_value())
|
||||
{
|
||||
initialPosition = _appArgs.GetPosition().value();
|
||||
}
|
||||
|
||||
return {
|
||||
initialPosition.X ? initialPosition.X.Value() : defaultInitialX,
|
||||
initialPosition.Y ? initialPosition.Y.Value() : defaultInitialY
|
||||
|
||||
@@ -394,6 +394,12 @@
|
||||
<data name="CmdWindowTargetArgDesc" xml:space="preserve">
|
||||
<value>Specify a terminal window to run the given commandline in. "0" always refers to the current window. </value>
|
||||
</data>
|
||||
<data name="CmdPositionDesc" xml:space="preserve">
|
||||
<value>Specify the position for the terminal, in "x,y" format.</value>
|
||||
</data>
|
||||
<data name="CmdSizeDesc" xml:space="preserve">
|
||||
<value>Specify the number of columns and rows for the terminal, in "c,r" format.</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>
|
||||
|
||||
@@ -2032,15 +2032,26 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - dpi: The DPI we should create the terminal at. This affects things such
|
||||
// as font size, scrollbar and other control scaling, etc. Make sure the
|
||||
// caller knows what monitor the control is about to appear on.
|
||||
// - commandlineCols: Number of cols specified on the commandline
|
||||
// - commandlineRows: Number of rows specified on the commandline
|
||||
// Return Value:
|
||||
// - a size containing the requested dimensions in pixels.
|
||||
winrt::Windows::Foundation::Size TermControl::GetProposedDimensions(const IControlSettings& settings, const uint32_t dpi)
|
||||
winrt::Windows::Foundation::Size TermControl::GetProposedDimensions(const IControlSettings& settings,
|
||||
const uint32_t dpi,
|
||||
int32_t commandlineCols,
|
||||
int32_t commandlineRows)
|
||||
{
|
||||
// If the settings have negative or zero row or column counts, ignore those counts.
|
||||
// (The lower TerminalCore layer also has upper bounds as well, but at this layer
|
||||
// we may eventually impose different ones depending on how many pixels we can address.)
|
||||
const auto cols = ::base::saturated_cast<float>(std::max(settings.InitialCols(), 1));
|
||||
const auto rows = ::base::saturated_cast<float>(std::max(settings.InitialRows(), 1));
|
||||
const auto cols = ::base::saturated_cast<float>(std::max(commandlineCols > 0 ?
|
||||
commandlineCols :
|
||||
settings.InitialCols(),
|
||||
1));
|
||||
const auto rows = ::base::saturated_cast<float>(std::max(commandlineRows > 0 ?
|
||||
commandlineRows :
|
||||
settings.InitialRows(),
|
||||
1));
|
||||
|
||||
const winrt::Windows::Foundation::Size initialSize{ cols, rows };
|
||||
|
||||
|
||||
@@ -114,7 +114,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
const Windows::UI::Xaml::Thickness GetPadding();
|
||||
|
||||
static Windows::Foundation::Size GetProposedDimensions(const IControlSettings& settings, const uint32_t dpi);
|
||||
static Windows::Foundation::Size GetProposedDimensions(const IControlSettings& settings,
|
||||
const uint32_t dpi,
|
||||
int32_t commandlineCols,
|
||||
int32_t commandlineRows);
|
||||
static Windows::Foundation::Size GetProposedDimensions(const IControlSettings& settings, const uint32_t dpi, const winrt::Windows::Foundation::Size& initialSizeInChars);
|
||||
|
||||
void BellLightOn();
|
||||
|
||||
@@ -21,7 +21,10 @@ namespace Microsoft.Terminal.Control
|
||||
IControlAppearance unfocusedAppearance,
|
||||
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||
|
||||
static Windows.Foundation.Size GetProposedDimensions(IControlSettings settings, UInt32 dpi);
|
||||
static Windows.Foundation.Size GetProposedDimensions(IControlSettings settings,
|
||||
UInt32 dpi,
|
||||
Int32 commandlineCols,
|
||||
Int32 commandlineRows);
|
||||
|
||||
void UpdateControlSettings(IControlSettings settings);
|
||||
void UpdateControlSettings(IControlSettings settings, IControlAppearance unfocusedAppearance);
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
<ClInclude Include="VsDevShellGenerator.h" />
|
||||
<ClInclude Include="VsSetupConfiguration.h" />
|
||||
<ClInclude Include="WslDistroGenerator.h" />
|
||||
<ClInclude Include="ModelSerializationHelpers.h" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- ModelSerializationHelpers.h
|
||||
|
||||
Abstract:
|
||||
- Helper methods for serializing/de-serializing model data.
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Function Description:
|
||||
// - Helper for converting a pair of comma separated, potentially absent integer values
|
||||
// into the corresponding left and right values. The leftValue and rightValue functions
|
||||
// will be called back with the associated parsed integer value, assuming it's present.
|
||||
// (100, 100): leftValue and rightValue functions both called back with 100.
|
||||
// (100, ), (100, abc): leftValue function called back with 100
|
||||
// (, 100), (abc, 100): rightValue function called back with 100
|
||||
// (,): no function called back
|
||||
// (100, 100, 100): we only read the first two values, this is equivalent to (100, 100)
|
||||
// Arguments:
|
||||
// - string: The string to parse
|
||||
// - leftValue: Function called back with the value before the comma
|
||||
// - rightValue: Function called back with the value after the comma
|
||||
_TIL_INLINEPREFIX void ParseCommaSeparatedPair(const std::string& string,
|
||||
std::function<void(int32_t)> leftValue,
|
||||
std::function<void(int32_t)> rightValue)
|
||||
{
|
||||
static constexpr auto singleCharDelim = ',';
|
||||
std::stringstream tokenStream(string);
|
||||
std::string token;
|
||||
uint8_t index = 0;
|
||||
|
||||
// Get values till we run out of delimiter separated values in the stream
|
||||
// or we hit max number of allowable values (= 2)
|
||||
// Non-numeral values or empty string will be caught as exception and we do not assign them
|
||||
for (; std::getline(tokenStream, token, singleCharDelim) && (index < 2); index++)
|
||||
{
|
||||
try
|
||||
{
|
||||
int32_t value = std::stol(token);
|
||||
if (index == 0)
|
||||
{
|
||||
leftValue(value);
|
||||
}
|
||||
|
||||
if (index == 1)
|
||||
{
|
||||
rightValue(value);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See: ParseCommaSeparatedPair
|
||||
_TIL_INLINEPREFIX ::winrt::Microsoft::Terminal::Settings::Model::LaunchPosition LaunchPositionFromString(const std::string& string)
|
||||
{
|
||||
::winrt::Microsoft::Terminal::Settings::Model::LaunchPosition initialPosition;
|
||||
ParseCommaSeparatedPair(
|
||||
string,
|
||||
[&initialPosition](int32_t left) { initialPosition.X = left; },
|
||||
[&initialPosition](int32_t right) { initialPosition.Y = right; });
|
||||
return initialPosition;
|
||||
}
|
||||
|
||||
// See: ParseCommaSeparatedPair
|
||||
_TIL_INLINEPREFIX ::til::size SizeFromString(const std::string& string)
|
||||
{
|
||||
til::size size{};
|
||||
ParseCommaSeparatedPair(
|
||||
string,
|
||||
[&size](int32_t left) { size.width = left; },
|
||||
[&size](int32_t right) { size.height = right; });
|
||||
return size;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ Abstract:
|
||||
|
||||
#include "JsonUtils.h"
|
||||
#include "SettingsTypes.h"
|
||||
#include "ModelSerializationHelpers.h"
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Core::CursorStyle)
|
||||
{
|
||||
@@ -318,51 +319,12 @@ JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Control::CopyFormat)
|
||||
}
|
||||
};
|
||||
|
||||
// Type Description:
|
||||
// - Helper for converting the initial position string into
|
||||
// 2 coordinate values. We allow users to only provide one coordinate,
|
||||
// thus, we use comma as the separator:
|
||||
// (100, 100): standard input string
|
||||
// (, 100), (100, ): if a value is missing, we set this value as a default
|
||||
// (,): both x and y are set to default
|
||||
// (abc, 100): if a value is not valid, we treat it as default
|
||||
// (100, 100, 100): we only read the first two values, this is equivalent to (100, 100)
|
||||
template<>
|
||||
struct ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<::winrt::Microsoft::Terminal::Settings::Model::LaunchPosition>
|
||||
{
|
||||
::winrt::Microsoft::Terminal::Settings::Model::LaunchPosition FromJson(const Json::Value& json)
|
||||
{
|
||||
::winrt::Microsoft::Terminal::Settings::Model::LaunchPosition ret;
|
||||
auto initialPosition{ json.asString() };
|
||||
static constexpr auto singleCharDelim = ',';
|
||||
std::stringstream tokenStream(initialPosition);
|
||||
std::string token;
|
||||
uint8_t initialPosIndex = 0;
|
||||
|
||||
// Get initial position values till we run out of delimiter separated values in the stream
|
||||
// or we hit max number of allowable values (= 2)
|
||||
// Non-numeral values or empty string will be caught as exception and we do not assign them
|
||||
for (; std::getline(tokenStream, token, singleCharDelim) && (initialPosIndex < 2); initialPosIndex++)
|
||||
{
|
||||
try
|
||||
{
|
||||
int64_t position = std::stol(token);
|
||||
if (initialPosIndex == 0)
|
||||
{
|
||||
ret.X = position;
|
||||
}
|
||||
|
||||
if (initialPosIndex == 1)
|
||||
{
|
||||
ret.Y = position;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return LaunchPositionFromString(json.asString());
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json)
|
||||
|
||||
Reference in New Issue
Block a user