Allow trailing semicolon when parsing OSC 9;4 (#10024)

## Summary of the Pull Request
When we parse OSC 9;4, allow a trailing semicolon (i.e. allow `9;4;` or something like `9;4;3;`). 

## PR Checklist
* [x] Closes #9960 
* [X] Tests added/passed

## Validation Steps Performed
OSC 9;4 sequences with or without trailing semicolons work
This commit is contained in:
PankajBhojwani 2021-05-05 11:12:55 -07:00 committed by GitHub
parent 22fd06e19b
commit f518235599
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 8 deletions

View file

@ -67,7 +67,7 @@ namespace Microsoft::Terminal::Core
virtual bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept = 0;
virtual bool EndHyperlink() noexcept = 0;
virtual bool SetTaskbarProgress(const size_t state, const size_t progress) noexcept = 0;
virtual bool SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) noexcept = 0;
virtual bool SetWorkingDirectory(std::wstring_view uri) noexcept = 0;
virtual std::wstring_view GetWorkingDirectory() noexcept = 0;

View file

@ -17,6 +17,8 @@
#include "../../cascadia/terminalcore/ITerminalApi.hpp"
#include "../../cascadia/terminalcore/ITerminalInput.hpp"
static constexpr size_t TaskbarMinProgress{ 10 };
// You have to forward decl the ICoreSettings here, instead of including the header.
// If you include the header, there will be compilation errors with other
// headers that include Terminal.hpp
@ -125,7 +127,7 @@ public:
bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept override;
bool EndHyperlink() noexcept override;
bool SetTaskbarProgress(const size_t state, const size_t progress) noexcept override;
bool SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) noexcept override;
bool SetWorkingDirectory(std::wstring_view uri) noexcept override;
std::wstring_view GetWorkingDirectory() noexcept override;

View file

@ -629,10 +629,43 @@ bool Terminal::EndHyperlink() noexcept
// - progress: indicates the progress value
// Return Value:
// - true
bool Terminal::SetTaskbarProgress(const size_t state, const size_t progress) noexcept
bool Terminal::SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) noexcept
{
_taskbarState = state;
_taskbarProgress = progress;
_taskbarState = static_cast<size_t>(state);
switch (state)
{
case DispatchTypes::TaskbarState::Clear:
// Always set progress to 0 in this case
_taskbarProgress = 0;
break;
case DispatchTypes::TaskbarState::Set:
// Always set progress to the value given in this case
_taskbarProgress = progress;
break;
case DispatchTypes::TaskbarState::Indeterminate:
// Leave the progress value unchanged in this case
break;
case DispatchTypes::TaskbarState::Error:
case DispatchTypes::TaskbarState::Paused:
// In these 2 cases, if the given progress value is 0, then
// leave the progress value unchanged, unless the current progress
// value is 0, in which case set it to a 'minimum' value (10 in our case);
// if the given progress value is greater than 0, then set the progress value
if (progress == 0)
{
if (_taskbarProgress == 0)
{
_taskbarProgress = TaskbarMinProgress;
}
}
else
{
_taskbarProgress = progress;
}
break;
}
if (_pfnTaskbarProgressChanged)
{
_pfnTaskbarProgressChanged();

View file

@ -510,7 +510,7 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
{
// A state parameter is defined, parse it out
const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), state);
if (!stateSuccess)
if (!stateSuccess && !til::at(parts, 1).empty())
{
return false;
}
@ -518,7 +518,7 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
{
// A progress parameter is also defined, parse it out
const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), progress);
if (!progressSuccess)
if (!progressSuccess && !til::at(parts, 2).empty())
{
return false;
}
@ -535,7 +535,7 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
// progress is greater than the maximum allowed value, clamp it to the max
progress = TaskbarMaxProgress;
}
return _terminalApi.SetTaskbarProgress(state, progress);
return _terminalApi.SetTaskbarProgress(static_cast<DispatchTypes::TaskbarState>(state), progress);
}
// 9 is SetWorkingDirectory, which informs the terminal about the current working directory.
else if (subParam == 9)

View file

@ -388,6 +388,30 @@ void TerminalCoreUnitTests::TerminalApiTest::SetTaskbarProgress()
// Additional params should be ignored, state and progress still set normally
VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow<size_t>(1));
VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow<size_t>(80));
// Edge cases + trailing semicolon testing
stateMachine.ProcessString(L"\x1b]9;4;2;\x9c");
// String should be processed correctly despite the trailing semicolon,
// taskbar progress should remain unchanged from previous value
VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow<size_t>(2));
VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow<size_t>(80));
stateMachine.ProcessString(L"\x1b]9;4;3;75\x9c");
// Given progress value should be ignored because this is the indeterminate state,
// so the progress value should remain unchanged
VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow<size_t>(3));
VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow<size_t>(80));
stateMachine.ProcessString(L"\x1b]9;4;0;50\x9c");
// Taskbar progress should be 0 (the given value should be ignored)
VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow<size_t>(0));
VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow<size_t>(0));
stateMachine.ProcessString(L"\x1b]9;4;2;\x9c");
// String should be processed correctly despite the trailing semicolon,
// taskbar progress should be set to a 'minimum', non-zero value
VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow<size_t>(2));
VERIFY_IS_GREATER_THAN(term.GetTaskbarProgress(), gsl::narrow<size_t>(0));
}
void TerminalCoreUnitTests::TerminalApiTest::SetWorkingDirectory()

View file

@ -249,6 +249,15 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes
Scrollback = 3
};
enum class TaskbarState : size_t
{
Clear = 0,
Set = 1,
Error = 2,
Indeterminate = 3,
Paused = 4
};
enum GraphicsOptions : size_t
{
Off = 0,