From af9e4d500d34f6de293542b9fdf8abb1ab5ef77a Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 27 Oct 2020 10:44:04 -0400 Subject: [PATCH 01/20] osc 9;4 implementation --- src/cascadia/TerminalApp/AppLogic.h | 1 + src/cascadia/TerminalApp/AppLogic.idl | 1 + src/cascadia/TerminalApp/TerminalPage.cpp | 14 +++++++ src/cascadia/TerminalApp/TerminalPage.h | 3 ++ src/cascadia/TerminalApp/TerminalPage.idl | 1 + src/cascadia/TerminalControl/TermControl.cpp | 16 +++++++ src/cascadia/TerminalControl/TermControl.h | 20 +++++++++ src/cascadia/TerminalControl/TermControl.idl | 7 ++++ src/cascadia/TerminalCore/ITerminalApi.hpp | 2 + src/cascadia/TerminalCore/Terminal.cpp | 10 +++++ src/cascadia/TerminalCore/Terminal.hpp | 4 ++ src/cascadia/TerminalCore/TerminalApi.cpp | 13 ++++++ .../TerminalCore/TerminalDispatch.cpp | 12 ++++++ .../TerminalCore/TerminalDispatch.hpp | 2 + src/cascadia/WindowsTerminal/AppHost.cpp | 11 +++++ src/cascadia/WindowsTerminal/AppHost.h | 1 + src/cascadia/WindowsTerminal/IslandWindow.cpp | 39 +++++++++++++++++ src/cascadia/WindowsTerminal/IslandWindow.h | 5 +++ src/cascadia/WindowsTerminal/pch.h | 1 + src/terminal/adapter/ITermDispatch.hpp | 2 + src/terminal/adapter/adaptDispatch.cpp | 10 +++++ src/terminal/adapter/adaptDispatch.hpp | 2 + .../parser/OutputStateMachineEngine.cpp | 42 +++++++++++++++++++ .../parser/OutputStateMachineEngine.hpp | 5 +++ 24 files changed, 224 insertions(+) diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index a6dfd3251cd..b10ffd27472 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -109,6 +109,7 @@ namespace winrt::TerminalApp::implementation FORWARDED_TYPED_EVENT(FocusModeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FocusModeChanged); FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged); FORWARDED_TYPED_EVENT(AlwaysOnTopChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, AlwaysOnTopChanged); + FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs, _root, SetTaskbarProgress); }; } diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 683a038bbd9..1d06dd885a4 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -62,5 +62,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler FocusModeChanged; event Windows.Foundation.TypedEventHandler FullscreenChanged; event Windows.Foundation.TypedEventHandler AlwaysOnTopChanged; + event Windows.Foundation.TypedEventHandler SetTaskbarProgress; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 2b9be96ef29..2e7677fc980 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1125,6 +1125,9 @@ namespace winrt::TerminalApp::implementation term.OpenHyperlink({ this, &TerminalPage::_OpenHyperlinkHandler }); + // Add an event handler for when the terminal wants to set a progress indicator on the taskbar + term.SetTaskbarProgress({ this, &TerminalPage::_SetTaskbarProgressHandler }); + // Bind Tab events to the TermControl and the Tab's Pane hostingTab.Initialize(term); @@ -1854,6 +1857,16 @@ namespace winrt::TerminalApp::implementation return control.CopySelectionToClipboard(singleLine, formats); } + // Method Description: + // - Send an event (which will be caught by AppHost) to set the progress indicator on the taskbar + // Arguments: + // - sender (not used) + // - eventArgs: the arguments specifying how to set the progress indicator + void TerminalPage::_SetTaskbarProgressHandler(const IInspectable /*sender*/, const Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs eventArgs) + { + _setTaskbarProgressHandlers(*this, eventArgs); + } + // Method Description: // - Paste text from the Windows Clipboard to the focused terminal void TerminalPage::_PasteText() @@ -2582,4 +2595,5 @@ namespace winrt::TerminalApp::implementation DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, FocusModeChanged, _focusModeChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, FullscreenChanged, _fullscreenChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, AlwaysOnTopChanged, _alwaysOnTopChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); + DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, SetTaskbarProgress, _setTaskbarProgressHandlers, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs); } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 2001eaaf1d4..e4597892155 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -70,6 +70,7 @@ namespace winrt::TerminalApp::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(FocusModeChanged, _focusModeChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(FullscreenChanged, _fullscreenChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(AlwaysOnTopChanged, _alwaysOnTopChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); + DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs); TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs); private: @@ -179,6 +180,8 @@ namespace winrt::TerminalApp::implementation void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri); bool _CopyText(const bool singleLine, const Windows::Foundation::IReference& formats); + void _SetTaskbarProgressHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs eventArgs); + void _PasteText(); fire_and_forget _LaunchSettings(const Microsoft::Terminal::Settings::Model::SettingsTarget target); diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index 7fb5cb29ac1..24fdd6cb01f 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -34,5 +34,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler FullscreenChanged; event Windows.Foundation.TypedEventHandler AlwaysOnTopChanged; event Windows.Foundation.TypedEventHandler Initialized; + event Windows.Foundation.TypedEventHandler SetTaskbarProgress; } } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index fc33c7603c7..ec6e550e0fa 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -104,6 +104,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation auto pfnCopyToClipboard = std::bind(&TermControl::_CopyToClipboard, this, std::placeholders::_1); _terminal->SetCopyToClipboardCallback(pfnCopyToClipboard); + auto pfnSetTaskbarProgress = std::bind(&TermControl::_SetTaskbarProgress, this, std::placeholders::_1, std::placeholders::_2); + _terminal->SetTaskbarProgressCallback(pfnSetTaskbarProgress); + // This event is explicitly revoked in the destructor: does not need weak_ref auto onReceiveOutputFn = [this](const hstring str) { _terminal->Write(str); @@ -2273,6 +2276,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _tsfTryRedrawCanvas->Run(); } + // Method Description: + // - Sends an event (which will be caught by TerminalPage and forwarded to AppHost after) + // to set the progress indicator on the taskbar + // Arguments: + // - state: the state with which to set the progress indicator + // - progress: the progress with which to set the progress indicator (only used if state is 1) + void TermControl::_SetTaskbarProgress(const size_t state, const size_t progress) + { + auto setTaskbarProgressArgs = winrt::make_self(state, progress); + _setTaskbarProgressHandlers(*this, *setTaskbarProgressArgs); + } + hstring TermControl::Title() { hstring hstr{ _terminal->GetConsoleTitle() }; @@ -3029,5 +3044,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); + DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, TerminalControl::SetTaskbarProgressEventArgs); // clang-format on } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 3d16738e020..e50661e8766 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -7,6 +7,7 @@ #include "CopyToClipboardEventArgs.g.h" #include "PasteFromClipboardEventArgs.g.h" #include "OpenHyperlinkEventArgs.g.h" +#include "SetTaskbarProgressEventArgs.g.h" #include #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" @@ -81,6 +82,22 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation hstring _uri; }; + struct SetTaskbarProgressEventArgs : + public SetTaskbarProgressEventArgsT + { + public: + SetTaskbarProgressEventArgs(size_t state, size_t progress) : + _state(state), + _progress(progress) {} + + size_t State() { return _state; }; + size_t Progress() { return _progress; }; + + private: + size_t _state; + size_t _progress; + }; + struct TermControl : TermControlT { TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection); @@ -148,6 +165,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); + DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, TerminalControl::SetTaskbarProgressEventArgs); + TYPED_EVENT(WarningBell, IInspectable, IInspectable); TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); @@ -268,6 +287,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _CopyToClipboard(const std::wstring_view& wstr); void _TerminalScrollPositionChanged(const int viewTop, const int viewHeight, const int bufferSize); void _TerminalCursorPositionChanged(); + void _SetTaskbarProgress(const size_t state, const size_t progress); void _MouseScrollHandler(const double mouseDelta, const Windows::Foundation::Point point, const bool isLeftButtonPressed); void _MouseZoomHandler(const double delta); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index d8bc580e0e9..3addd2372b7 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -45,6 +45,12 @@ namespace Microsoft.Terminal.TerminalControl String Uri { get; }; } + runtimeclass SetTaskbarProgressEventArgs + { + Int64 State { get; }; + Int64 Progress { get; }; + } + [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener { TermControl(Microsoft.Terminal.TerminalControl.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); @@ -60,6 +66,7 @@ namespace Microsoft.Terminal.TerminalControl event Windows.Foundation.TypedEventHandler CopyToClipboard; event Windows.Foundation.TypedEventHandler PasteFromClipboard; event Windows.Foundation.TypedEventHandler OpenHyperlink; + event Windows.Foundation.TypedEventHandler SetTaskbarProgress; event Windows.Foundation.TypedEventHandler WarningBell; event Windows.Foundation.TypedEventHandler Initialized; diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index fda9cef77cc..f9f0f06868d 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -63,6 +63,8 @@ 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; + protected: ITerminalApi() = default; }; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 20e16bed96e..42fe0b51903 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -1005,6 +1005,16 @@ void Terminal::SetBackgroundCallback(std::function pfn) no _pfnBackgroundColorChanged.swap(pfn); } +// Method Description: +// - Allows settings a callback for settings the taskbar progress indicator +// Arguments: +// - pfn: a function callback that takes 2 size_t parameters, one indicating the progress state +// and the other indicating the progress value +void Microsoft::Terminal::Core::Terminal::SetTaskbarProgressCallback(std::function pfn) noexcept +{ + _pfnSetTaskbarProgress.swap(pfn); +} + void Terminal::_InitializeColorTable() try { diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index b1f6c25e920..3a4eb026f43 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -115,6 +115,8 @@ class Microsoft::Terminal::Core::Terminal final : 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; #pragma endregion #pragma region ITerminalInput @@ -183,6 +185,7 @@ class Microsoft::Terminal::Core::Terminal final : void SetScrollPositionChangedCallback(std::function pfn) noexcept; void SetCursorPositionChangedCallback(std::function pfn) noexcept; void SetBackgroundCallback(std::function pfn) noexcept; + void SetTaskbarProgressCallback(std::function pfn) noexcept; void SetCursorOn(const bool isOn); bool IsCursorBlinkingAllowed() const noexcept; @@ -216,6 +219,7 @@ class Microsoft::Terminal::Core::Terminal final : std::function _pfnBackgroundColorChanged; std::function _pfnCursorPositionChanged; std::function)> _pfnTabColorChanged; + std::function _pfnSetTaskbarProgress; std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine; std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 8ed4094184f..e8eeea3f5f3 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -600,3 +600,16 @@ bool Terminal::EndHyperlink() noexcept _buffer->SetCurrentAttributes(attr); return true; } + +// Method Description: +// - Updates the taskbar progress indicator +// Arguments: +// - state: indicates the progress state +// - progress: indicates the progress value +// Return Value: +// - true +bool Terminal::SetTaskbarProgress(const size_t state, const size_t progress) noexcept +{ + _pfnSetTaskbarProgress(state, progress); + return true; +} diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index a035febf152..77024c3eadb 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -399,6 +399,18 @@ bool TerminalDispatch::EndHyperlink() noexcept return _terminalApi.EndHyperlink(); } +// Method Description: +// - Updates the taskbar progress indicator +// Arguments: +// - state: indicates the progress state +// - progress: indicates the progress value +// Return Value: +// - true +bool TerminalDispatch::SetTaskbarProgress(const size_t state, const size_t progress) noexcept +{ + return _terminalApi.SetTaskbarProgress(state, progress); +} + // Routine Description: // - Support routine for routing private mode parameters to be set/reset as flags // Arguments: diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index 5e409161d26..82d2f181c9d 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -67,6 +67,8 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) noexcept override; bool EndHyperlink() noexcept override; + bool SetTaskbarProgress(const size_t state, const size_t progress) noexcept override; + private: ::Microsoft::Terminal::Core::ITerminalApi& _terminalApi; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index d0b6a3aa734..0bbb188dac1 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -79,6 +79,16 @@ bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, cons return false; } +// Method Description: +// - Event handler to update the taskbar progress indicator +// Arguments: +// - sender: not used +// - args: contains the progress state/value needed to set the taskbar progress +void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs& args) +{ + _window->SetTaskbarProgress(args.State(), args.Progress()); +} + // Method Description: // - Retrieve any commandline args passed on the commandline, and pass them to // the app logic for processing. @@ -171,6 +181,7 @@ void AppHost::Initialize() _logic.TitleChanged({ this, &AppHost::AppTitleChanged }); _logic.LastTabClosed({ this, &AppHost::LastTabClosed }); + _logic.SetTaskbarProgress({ this, &AppHost::SetTaskbarProgress }); _window->UpdateTitle(_logic.Title()); diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 4bdc45c5d29..a014b519066 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -18,6 +18,7 @@ class AppHost void LastTabClosed(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::LastTabClosedEventArgs& args); void Initialize(); bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down); + void SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs& args); private: bool _useNonClientArea; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 92f10833d5a..4de44a80218 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -258,6 +258,16 @@ void IslandWindow::Initialize() _rootGrid = winrt::Windows::UI::Xaml::Controls::Grid(); _source.Content(_rootGrid); + + // initialize the taskbar object + HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&_taskbar)); + if (SUCCEEDED(hr)) + { + if (SUCCEEDED(_taskbar->HrInit())) + { + _taskbarInitialized = true; + } + } } void IslandWindow::OnSize(const UINT width, const UINT height) @@ -503,6 +513,35 @@ void IslandWindow::SetAlwaysOnTop(const bool alwaysOnTop) } } +// Method Description: +// - Sets the taskbar progress indicator +// Arguments: +// - state: indicates the progress state +// - progress: indicates the progress value +void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress) +{ + if (_taskbarInitialized) + { + switch (state) + { + case 0: + // removes the taskbar progress indicator + _taskbar->SetProgressState(_window.get(), TBPF_NOPROGRESS); + break; + case 1: + // sets the progress value to value given by the 'progress' parameter + _taskbar->SetProgressValue(_window.get(), progress, 100); + break; + case 2: + // sets the progress indicator to an error state + _taskbar->SetProgressState(_window.get(), TBPF_ERROR); + break; + default: + break; + } + } +} + // From GdiEngine::s_SetWindowLongWHelper void _SetWindowLongWHelper(const HWND hWnd, const int nIndex, const LONG dwNewLong) noexcept { diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 8e6a4fcc943..51134681fa8 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -35,6 +35,8 @@ class IslandWindow : void FullscreenChanged(const bool fullscreen); void SetAlwaysOnTop(const bool alwaysOnTop); + void SetTaskbarProgress(const size_t state, const size_t progress); + #pragma endregion DECLARE_EVENT(DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); @@ -74,6 +76,9 @@ class IslandWindow : LONG _getDesiredWindowStyle() const; + ITaskbarList3* _taskbar; + bool _taskbarInitialized{ false }; + private: // This minimum width allows for width the tabs fit static constexpr long minimumWidth = 460L; diff --git a/src/cascadia/WindowsTerminal/pch.h b/src/cascadia/WindowsTerminal/pch.h index 7d82654a5e6..5b2830575ab 100644 --- a/src/cascadia/WindowsTerminal/pch.h +++ b/src/cascadia/WindowsTerminal/pch.h @@ -29,6 +29,7 @@ Module Name: #include #include #include +#include // Manually include til after we include Windows.Foundation to give it winrt superpowers #define BLOCK_TIL diff --git a/src/terminal/adapter/ITermDispatch.hpp b/src/terminal/adapter/ITermDispatch.hpp index 9be6e3146b7..5feccdd851c 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -122,6 +122,8 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch virtual bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) = 0; virtual bool EndHyperlink() = 0; + + virtual bool SetTaskbarProgress(const size_t state, const size_t progress) = 0; }; inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() {} #pragma warning(pop) diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 25e896f601f..196dbd48cc5 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2383,6 +2383,16 @@ bool AdaptDispatch::EndHyperlink() return _pConApi->PrivateEndHyperlink(); } +// Method Description: +// - Ascribes to the ITermDispatch interface +// - Not actually used in conhost +// Return Value: +// - false (so that the command gets flushed to terminal) +bool AdaptDispatch::SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) +{ + return false; +} + // Routine Description: // - Determines whether we should pass any sequence that manipulates // TerminalInput's input generator through the PTY. It encapsulates diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index 6644c3e0228..3389575876a 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -123,6 +123,8 @@ namespace Microsoft::Console::VirtualTerminal bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override; bool EndHyperlink() override; + bool SetTaskbarProgress(const size_t state, const size_t progress) override; + private: enum class ScrollDirection { diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 81d2ab48142..a5c2f91e816 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -647,6 +647,8 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, bool queryClipboard = false; std::vector tableIndexes; std::vector colors; + size_t state = 0; + size_t progress = 0; switch (parameter) { @@ -672,6 +674,9 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, case OscActionCodes::Hyperlink: success = _ParseHyperlink(string, params, uri); break; + case OscActionCodes::SetTaskbarProgress: + success = _GetTaskbarProgress(string, state, progress); + break; default: // If no functions to call, overall dispatch was a failure. success = false; @@ -739,6 +744,9 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, success = _dispatch->AddHyperlink(uri, params); } break; + case OscActionCodes::SetTaskbarProgress: + success = _dispatch->SetTaskbarProgress(state, progress); + break; default: // If no functions to call, overall dispatch was a failure. success = false; @@ -924,6 +932,40 @@ bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string, return false; } +// Routine Description: +// - OSC 9 ; 4 ; state ; progress ST +// state: the state to set the taskbar progress indicator to +// progress: the progress value to set the taskbar progress indicator with +// - Parses out the 'state' and 'progress' parameters from the OSC string so +// that we can use them to set the taskbar progress indicator +// Arguments: +// - string: the string to parse +// - state: where to store the state value once we parse it +// - progress: where to store the progress value once we parse it +// Return Value: +// - true if we succesfully parsed the string, false otherwise +bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view string, + size_t& state, + size_t& progress) const +{ + const size_t midPos = string.find(';'); + if (midPos != std::wstring::npos) + { + const auto subParam = string.substr(0, midPos); + if (std::stoi(til::u16u8(subParam)) == 4) + { + const auto stateAndProgress = string.substr(midPos + 1); + const size_t delimPos = stateAndProgress.find(';'); + const auto stateStr = stateAndProgress.substr(0, delimPos); + const auto progressStr = stateAndProgress.substr(delimPos + 1); + state = std::stoi(til::u16u8(stateStr)); + progress = std::stoi(til::u16u8(progressStr)); + return true; + } + } + return false; +} + // Routine Description: // - OSC 10, 11, 12 ; spec ST // spec: The colors are specified by name or RGB specification as per XParseColor diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index 2d64f22e063..1f11bc1f851 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -160,6 +160,7 @@ namespace Microsoft::Console::VirtualTerminal SetWindowProperty = 3, // Not implemented SetColor = 4, Hyperlink = 8, + SetTaskbarProgress = 9, SetForegroundColor = 10, SetBackgroundColor = 11, SetCursorColor = 12, @@ -188,6 +189,10 @@ namespace Microsoft::Console::VirtualTerminal std::wstring& params, std::wstring& uri) const; + bool _GetTaskbarProgress(const std::wstring_view string, + size_t& state, + size_t& progress) const; + void _ClearLastChar() noexcept; }; } From 606490f374f5eab1136dbc8a529fd36c3ea82a0f Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 27 Oct 2020 11:01:48 -0400 Subject: [PATCH 02/20] spelling --- .github/actions/spell-check/dictionary/apis.txt | 3 +++ src/terminal/parser/OutputStateMachineEngine.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/actions/spell-check/dictionary/apis.txt b/.github/actions/spell-check/dictionary/apis.txt index 5d2e25b804d..2cbbfa8669f 100644 --- a/.github/actions/spell-check/dictionary/apis.txt +++ b/.github/actions/spell-check/dictionary/apis.txt @@ -24,6 +24,7 @@ IExplorer IMap IObject IStorage +ITaskbar llabs LCID lround @@ -32,6 +33,7 @@ NCHITTEST NCLBUTTONDBLCLK NCRBUTTONDBLCLK NOAGGREGATION +NOPROGRESS NOREDIRECTIONBITMAP oaidl ocidl @@ -51,6 +53,7 @@ spsc STDCPP strchr syscall +TBPF tmp tx userenv diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index a5c2f91e816..3aff77cd8d6 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -943,7 +943,7 @@ bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string, // - state: where to store the state value once we parse it // - progress: where to store the progress value once we parse it // Return Value: -// - true if we succesfully parsed the string, false otherwise +// - true if we successfully parsed the string, false otherwise bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view string, size_t& state, size_t& progress) const From 4e6f6fe3551fa52a0c0a29e0df1d050844ea92a7 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 27 Oct 2020 15:02:27 -0400 Subject: [PATCH 03/20] address comments --- src/cascadia/TerminalControl/TermControl.idl | 4 ++-- src/cascadia/WindowsTerminal/IslandWindow.cpp | 3 +++ src/terminal/adapter/adaptDispatch.cpp | 2 +- src/terminal/adapter/adaptDispatch.hpp | 2 +- src/terminal/adapter/termDispatch.hpp | 2 ++ src/terminal/parser/OutputStateMachineEngine.cpp | 4 ++++ src/terminal/parser/ut_parser/OutputEngineTest.cpp | 5 +++++ 7 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 3addd2372b7..c589762d41a 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -47,8 +47,8 @@ namespace Microsoft.Terminal.TerminalControl runtimeclass SetTaskbarProgressEventArgs { - Int64 State { get; }; - Int64 Progress { get; }; + UInt64 State { get; }; + UInt64 Progress { get; }; } [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 4de44a80218..0a3157a8c83 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -536,6 +536,9 @@ void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress) // sets the progress indicator to an error state _taskbar->SetProgressState(_window.get(), TBPF_ERROR); break; + case 3: + // sets the progress indicator to an indeterminate state + _taskbar->SetProgressState(_window.get(), TBPF_INDETERMINATE); default: break; } diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 196dbd48cc5..f9115812dbd 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2388,7 +2388,7 @@ bool AdaptDispatch::EndHyperlink() // - Not actually used in conhost // Return Value: // - false (so that the command gets flushed to terminal) -bool AdaptDispatch::SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) +bool AdaptDispatch::SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) noexcept { return false; } diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index 3389575876a..e0945e6b4a6 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -123,7 +123,7 @@ namespace Microsoft::Console::VirtualTerminal bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override; bool EndHyperlink() override; - bool SetTaskbarProgress(const size_t state, const size_t progress) override; + bool SetTaskbarProgress(const size_t state, const size_t progress) noexcept override; private: enum class ScrollDirection diff --git a/src/terminal/adapter/termDispatch.hpp b/src/terminal/adapter/termDispatch.hpp index cb400814f4c..8cc4086b7e9 100644 --- a/src/terminal/adapter/termDispatch.hpp +++ b/src/terminal/adapter/termDispatch.hpp @@ -116,4 +116,6 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons bool AddHyperlink(const std::wstring_view /*uri*/, const std::wstring_view /*params*/) noexcept override { return false; } bool EndHyperlink() noexcept override { return false; } + + bool SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) noexcept override { return false; } }; diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 3aff77cd8d6..da01eb92bbe 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -960,6 +960,10 @@ bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view strin const auto progressStr = stateAndProgress.substr(delimPos + 1); state = std::stoi(til::u16u8(stateStr)); progress = std::stoi(til::u16u8(progressStr)); + if (state < 0 || state > 3 || progress < 0 || progress > 100) + { + return false; + } return true; } } diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index 63e39a52d77..201a30754b6 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -1456,6 +1456,11 @@ class StatefulDispatch final : public TermDispatch return true; } + bool SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) noexcept override + { + return true; + } + size_t _cursorDistance; size_t _line; size_t _column; From da837481b2ec1de6e58a54a56bc0f0382678e30b Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 27 Oct 2020 15:26:28 -0400 Subject: [PATCH 04/20] add paused state --- src/cascadia/WindowsTerminal/AppHost.cpp | 2 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 3 +++ src/terminal/parser/OutputStateMachineEngine.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 0bbb188dac1..506c0fb35b2 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -86,7 +86,7 @@ bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, cons // - args: contains the progress state/value needed to set the taskbar progress void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs& args) { - _window->SetTaskbarProgress(args.State(), args.Progress()); + _window->SetTaskbarProgress(gsl::narrow(args.State()), gsl::narrow(args.Progress())); } // Method Description: diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 0a3157a8c83..0d3b49c2599 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -539,6 +539,9 @@ void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress) case 3: // sets the progress indicator to an indeterminate state _taskbar->SetProgressState(_window.get(), TBPF_INDETERMINATE); + case 4: + // sets the progress indicator to a pause state + _taskbar->SetProgressState(_window.get(), TBPF_PAUSED); default: break; } diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index da01eb92bbe..06ca4e5d78c 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -960,7 +960,7 @@ bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view strin const auto progressStr = stateAndProgress.substr(delimPos + 1); state = std::stoi(til::u16u8(stateStr)); progress = std::stoi(til::u16u8(progressStr)); - if (state < 0 || state > 3 || progress < 0 || progress > 100) + if (state < 0 || state > 4 || progress < 0 || progress > 100) { return false; } From 3d0ed8480c7f1f732f1ea54d568907b3a20e1b8c Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 27 Oct 2020 17:00:19 -0400 Subject: [PATCH 05/20] use last focused tab's progress and state --- src/cascadia/TerminalApp/Tab.cpp | 1 + src/cascadia/TerminalControl/TermControl.cpp | 21 +++++++++++++++---- src/cascadia/TerminalControl/TermControl.h | 5 +++++ src/cascadia/TerminalControl/TermControl.idl | 2 ++ src/cascadia/WindowsTerminal/IslandWindow.cpp | 3 +++ 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index 2f9cc705838..6ef7be7342d 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -185,6 +185,7 @@ namespace winrt::TerminalApp::implementation if (lastFocusedControl) { lastFocusedControl.Focus(FocusState::Programmatic); + lastFocusedControl.SendTaskbarProgressEvent(); } } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index ec6e550e0fa..75f9aa1dc16 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -76,7 +76,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _lastMouseClickTimestamp{}, _lastMouseClickPos{}, _selectionNeedsToBeCopied{ false }, - _searchBox{ nullptr } + _searchBox{ nullptr }, + _taskbarState{ 0 }, + _taskbarProgress{ 0 } { _EnsureStaticInitialization(); InitializeComponent(); @@ -2277,15 +2279,17 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } // Method Description: - // - Sends an event (which will be caught by TerminalPage and forwarded to AppHost after) + // - Sets our internal knowledge of the taskbar's state and progress, then + // sends an event (which will be caught by TerminalPage and forwarded to AppHost after) // to set the progress indicator on the taskbar // Arguments: // - state: the state with which to set the progress indicator // - progress: the progress with which to set the progress indicator (only used if state is 1) void TermControl::_SetTaskbarProgress(const size_t state, const size_t progress) { - auto setTaskbarProgressArgs = winrt::make_self(state, progress); - _setTaskbarProgressHandlers(*this, *setTaskbarProgressArgs); + _taskbarState = state; + _taskbarProgress = progress; + SendTaskbarProgressEvent(); } hstring TermControl::Title() @@ -3034,6 +3038,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation return coreColor.has_value() ? Windows::Foundation::IReference(coreColor.value()) : nullptr; } + // Method Description: + // - Sends an event (which will be caught by TerminalPage and forwarded to AppHost after) + // to set the progress indicator on the taskbar + void TermControl::SendTaskbarProgressEvent() + { + auto setTaskbarProgressArgs = winrt::make_self(_taskbarState, _taskbarProgress); + _setTaskbarProgressHandlers(*this, *setTaskbarProgressArgs); + } + // -------------------------------- WinRT Events --------------------------------- // Winrt events need a method for adding a callback to the event and removing the callback. // These macros will define them both for you. diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index e50661e8766..4376775cda4 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -156,6 +156,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation Windows::Foundation::IReference TabColor() noexcept; + void SendTaskbarProgressEvent(); + // clang-format off // -------------------------------- WinRT Events --------------------------------- DECLARE_EVENT(TitleChanged, _titleChangedHandlers, TerminalControl::TitleChangedEventArgs); @@ -232,6 +234,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // Track the last hyperlink ID we hovered over uint16_t _lastHoveredId; + size_t _taskbarState; + size_t _taskbarProgress; + using Timestamp = uint64_t; // imported from WinUser diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index c589762d41a..e24889db76e 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -97,6 +97,8 @@ namespace Microsoft.Terminal.TerminalControl void SendInput(String input); void ToggleRetroEffect(); + void SendTaskbarProgressEvent(); + Windows.Foundation.IReference TabColor { get; }; event Windows.Foundation.TypedEventHandler TabColorChanged; } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 0d3b49c2599..851d89a054d 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -530,11 +530,13 @@ void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress) break; case 1: // sets the progress value to value given by the 'progress' parameter + _taskbar->SetProgressState(_window.get(), TBPF_NORMAL); _taskbar->SetProgressValue(_window.get(), progress, 100); break; case 2: // sets the progress indicator to an error state _taskbar->SetProgressState(_window.get(), TBPF_ERROR); + _taskbar->SetProgressValue(_window.get(), progress, 100); break; case 3: // sets the progress indicator to an indeterminate state @@ -542,6 +544,7 @@ void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress) case 4: // sets the progress indicator to a pause state _taskbar->SetProgressState(_window.get(), TBPF_PAUSED); + _taskbar->SetProgressValue(_window.get(), progress, 100); default: break; } From f08c962b0500bbfb2c423df6a9f0277040872018 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 28 Oct 2020 11:28:19 -0400 Subject: [PATCH 06/20] use split string --- src/cascadia/WindowsTerminal/IslandWindow.cpp | 2 ++ .../parser/OutputStateMachineEngine.cpp | 30 ++++++++----------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 851d89a054d..3f27fc7788f 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -541,10 +541,12 @@ void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress) case 3: // sets the progress indicator to an indeterminate state _taskbar->SetProgressState(_window.get(), TBPF_INDETERMINATE); + break; case 4: // sets the progress indicator to a pause state _taskbar->SetProgressState(_window.get(), TBPF_PAUSED); _taskbar->SetProgressValue(_window.get(), progress, 100); + break; default: break; } diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 06ca4e5d78c..4923e17773b 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -938,6 +938,8 @@ bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string, // progress: the progress value to set the taskbar progress indicator with // - Parses out the 'state' and 'progress' parameters from the OSC string so // that we can use them to set the taskbar progress indicator +// - This follows the ConEmu style, more details here: +// https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC // Arguments: // - string: the string to parse // - state: where to store the state value once we parse it @@ -948,26 +950,18 @@ bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view strin size_t& state, size_t& progress) const { - const size_t midPos = string.find(';'); - if (midPos != std::wstring::npos) + const auto parts = Utils::SplitString(string, L';'); + if (parts.size() != 3 || std::stoi(til::u16u8(parts.at(0))) != 4) { - const auto subParam = string.substr(0, midPos); - if (std::stoi(til::u16u8(subParam)) == 4) - { - const auto stateAndProgress = string.substr(midPos + 1); - const size_t delimPos = stateAndProgress.find(';'); - const auto stateStr = stateAndProgress.substr(0, delimPos); - const auto progressStr = stateAndProgress.substr(delimPos + 1); - state = std::stoi(til::u16u8(stateStr)); - progress = std::stoi(til::u16u8(progressStr)); - if (state < 0 || state > 4 || progress < 0 || progress > 100) - { - return false; - } - return true; - } + return false; } - return false; + state = std::stoi(til::u16u8(parts.at(1))); + progress = std::stoi(til::u16u8(parts.at(2))); + if (state < 0 || state > 4 || progress < 0 || progress > 100) + { + return false; + } + return true; } // Routine Description: From 5f83dfd5b2d38e325a7f4a9062e02f137795c8f6 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 28 Oct 2020 17:32:31 -0400 Subject: [PATCH 07/20] use sender instead of args, some name changes --- src/cascadia/TerminalApp/Tab.cpp | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 4 +-- src/cascadia/TerminalControl/TermControl.cpp | 36 ++++++++------------ src/cascadia/TerminalControl/TermControl.h | 9 ++--- src/cascadia/TerminalControl/TermControl.idl | 4 ++- src/cascadia/TerminalCore/Terminal.cpp | 18 ++++++++-- src/cascadia/TerminalCore/Terminal.hpp | 10 ++++-- src/cascadia/TerminalCore/TerminalApi.cpp | 4 ++- src/cascadia/WindowsTerminal/AppHost.cpp | 5 +-- 9 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index 6ef7be7342d..5ec7b1ec989 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -185,7 +185,7 @@ namespace winrt::TerminalApp::implementation if (lastFocusedControl) { lastFocusedControl.Focus(FocusState::Programmatic); - lastFocusedControl.SendTaskbarProgressEvent(); + lastFocusedControl.TaskbarProgressChanged(); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 4a03b887a12..5a5841f90a1 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1877,9 +1877,9 @@ namespace winrt::TerminalApp::implementation // Arguments: // - sender (not used) // - eventArgs: the arguments specifying how to set the progress indicator - void TerminalPage::_SetTaskbarProgressHandler(const IInspectable /*sender*/, const Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs eventArgs) + void TerminalPage::_SetTaskbarProgressHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs eventArgs) { - _setTaskbarProgressHandlers(*this, eventArgs); + _setTaskbarProgressHandlers(sender, eventArgs); } // Method Description: diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 75f9aa1dc16..244e3e0e544 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -76,9 +76,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _lastMouseClickTimestamp{}, _lastMouseClickPos{}, _selectionNeedsToBeCopied{ false }, - _searchBox{ nullptr }, - _taskbarState{ 0 }, - _taskbarProgress{ 0 } + _searchBox{ nullptr } { _EnsureStaticInitialization(); InitializeComponent(); @@ -106,8 +104,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation auto pfnCopyToClipboard = std::bind(&TermControl::_CopyToClipboard, this, std::placeholders::_1); _terminal->SetCopyToClipboardCallback(pfnCopyToClipboard); - auto pfnSetTaskbarProgress = std::bind(&TermControl::_SetTaskbarProgress, this, std::placeholders::_1, std::placeholders::_2); - _terminal->SetTaskbarProgressCallback(pfnSetTaskbarProgress); + auto pfnTaskbarProgressChanged = std::bind(&TermControl::TaskbarProgressChanged, this); + _terminal->TaskbarProgressChangedCallback(pfnTaskbarProgressChanged); // This event is explicitly revoked in the destructor: does not need weak_ref auto onReceiveOutputFn = [this](const hstring str) { @@ -2278,20 +2276,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _tsfTryRedrawCanvas->Run(); } - // Method Description: - // - Sets our internal knowledge of the taskbar's state and progress, then - // sends an event (which will be caught by TerminalPage and forwarded to AppHost after) - // to set the progress indicator on the taskbar - // Arguments: - // - state: the state with which to set the progress indicator - // - progress: the progress with which to set the progress indicator (only used if state is 1) - void TermControl::_SetTaskbarProgress(const size_t state, const size_t progress) - { - _taskbarState = state; - _taskbarProgress = progress; - SendTaskbarProgressEvent(); - } - hstring TermControl::Title() { hstring hstr{ _terminal->GetConsoleTitle() }; @@ -3041,12 +3025,22 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // Method Description: // - Sends an event (which will be caught by TerminalPage and forwarded to AppHost after) // to set the progress indicator on the taskbar - void TermControl::SendTaskbarProgressEvent() + void TermControl::TaskbarProgressChanged() { - auto setTaskbarProgressArgs = winrt::make_self(_taskbarState, _taskbarProgress); + auto setTaskbarProgressArgs = winrt::make_self(_terminal->GetTaskbarState(), _terminal->GetTaskbarProgress()); _setTaskbarProgressHandlers(*this, *setTaskbarProgressArgs); } + const size_t TermControl::GetTaskbarState() const noexcept + { + return _terminal->GetTaskbarState(); + } + + const size_t TermControl::GetTaskbarProgress() const noexcept + { + return _terminal->GetTaskbarProgress(); + } + // -------------------------------- WinRT Events --------------------------------- // Winrt events need a method for adding a callback to the event and removing the callback. // These macros will define them both for you. diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 4376775cda4..2984c5a6992 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -156,7 +156,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation Windows::Foundation::IReference TabColor() noexcept; - void SendTaskbarProgressEvent(); + void TaskbarProgressChanged(); + const size_t GetTaskbarState() const noexcept; + const size_t GetTaskbarProgress() const noexcept; // clang-format off // -------------------------------- WinRT Events --------------------------------- @@ -169,7 +171,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, TerminalControl::SetTaskbarProgressEventArgs); - TYPED_EVENT(WarningBell, IInspectable, IInspectable); TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); TYPED_EVENT(Initialized, TerminalControl::TermControl, Windows::UI::Xaml::RoutedEventArgs); @@ -234,9 +235,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // Track the last hyperlink ID we hovered over uint16_t _lastHoveredId; - size_t _taskbarState; - size_t _taskbarProgress; - using Timestamp = uint64_t; // imported from WinUser @@ -292,7 +290,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _CopyToClipboard(const std::wstring_view& wstr); void _TerminalScrollPositionChanged(const int viewTop, const int viewHeight, const int bufferSize); void _TerminalCursorPositionChanged(); - void _SetTaskbarProgress(const size_t state, const size_t progress); void _MouseScrollHandler(const double mouseDelta, const Windows::Foundation::Point point, const bool isLeftButtonPressed); void _MouseZoomHandler(const double delta); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index e24889db76e..cded4a42f87 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -97,7 +97,9 @@ namespace Microsoft.Terminal.TerminalControl void SendInput(String input); void ToggleRetroEffect(); - void SendTaskbarProgressEvent(); + void TaskbarProgressChanged(); + UInt64 GetTaskbarState(); + UInt64 GetTaskbarProgress(); Windows.Foundation.IReference TabColor { get; }; event Windows.Foundation.TypedEventHandler TabColorChanged; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 42fe0b51903..166c492b838 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -48,7 +48,9 @@ Terminal::Terminal() : _snapOnInput{ true }, _altGrAliasing{ true }, _blockSelection{ false }, - _selection{ std::nullopt } + _selection{ std::nullopt }, + _taskbarState{ 0 }, + _taskbarProgress{ 0 } { auto dispatch = std::make_unique(*this); auto engine = std::make_unique(std::move(dispatch)); @@ -1010,9 +1012,9 @@ void Terminal::SetBackgroundCallback(std::function pfn) no // Arguments: // - pfn: a function callback that takes 2 size_t parameters, one indicating the progress state // and the other indicating the progress value -void Microsoft::Terminal::Core::Terminal::SetTaskbarProgressCallback(std::function pfn) noexcept +void Microsoft::Terminal::Core::Terminal::TaskbarProgressChangedCallback(std::function pfn) noexcept { - _pfnSetTaskbarProgress.swap(pfn); + _pfnTaskbarProgressChanged.swap(pfn); } void Terminal::_InitializeColorTable() @@ -1057,3 +1059,13 @@ BlinkingState& Terminal::GetBlinkingState() const noexcept { return _blinkingState; } + +const size_t Microsoft::Terminal::Core::Terminal::GetTaskbarState() const noexcept +{ + return _taskbarState; +} + +const size_t Microsoft::Terminal::Core::Terminal::GetTaskbarProgress() const noexcept +{ + return _taskbarProgress; +} diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 3a4eb026f43..22400244982 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -185,7 +185,7 @@ class Microsoft::Terminal::Core::Terminal final : void SetScrollPositionChangedCallback(std::function pfn) noexcept; void SetCursorPositionChangedCallback(std::function pfn) noexcept; void SetBackgroundCallback(std::function pfn) noexcept; - void SetTaskbarProgressCallback(std::function pfn) noexcept; + void TaskbarProgressChangedCallback(std::function pfn) noexcept; void SetCursorOn(const bool isOn); bool IsCursorBlinkingAllowed() const noexcept; @@ -194,6 +194,9 @@ class Microsoft::Terminal::Core::Terminal final : Microsoft::Console::Render::BlinkingState& GetBlinkingState() const noexcept; + const size_t GetTaskbarState() const noexcept; + const size_t GetTaskbarProgress() const noexcept; + #pragma region TextSelection // These methods are defined in TerminalSelection.cpp enum class SelectionExpansionMode @@ -219,7 +222,7 @@ class Microsoft::Terminal::Core::Terminal final : std::function _pfnBackgroundColorChanged; std::function _pfnCursorPositionChanged; std::function)> _pfnTabColorChanged; - std::function _pfnSetTaskbarProgress; + std::function _pfnTaskbarProgressChanged; std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine; std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput; @@ -239,6 +242,9 @@ class Microsoft::Terminal::Core::Terminal final : bool _altGrAliasing; bool _suppressApplicationTitle; + size_t _taskbarState; + size_t _taskbarProgress; + #pragma region Text Selection // a selection is represented as a range between two COORDs (start and end) // the pivot is the COORD that remains selected when you extend a selection in any direction diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index e8eeea3f5f3..fa8c5ca4658 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -610,6 +610,8 @@ bool Terminal::EndHyperlink() noexcept // - true bool Terminal::SetTaskbarProgress(const size_t state, const size_t progress) noexcept { - _pfnSetTaskbarProgress(state, progress); + _taskbarState = state; + _taskbarProgress = progress; + _pfnTaskbarProgressChanged(); return true; } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 506c0fb35b2..707a6280393 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -84,9 +84,10 @@ bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, cons // Arguments: // - sender: not used // - args: contains the progress state/value needed to set the taskbar progress -void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs& args) +void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs& /*args*/) { - _window->SetTaskbarProgress(gsl::narrow(args.State()), gsl::narrow(args.Progress())); + auto control = sender.try_as(); + _window->SetTaskbarProgress(gsl::narrow(control.GetTaskbarState()), gsl::narrow(control.GetTaskbarProgress())); } // Method Description: From ab99ed5f8ddd50df841992c95481522e885bf2b0 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 29 Oct 2020 11:56:26 -0400 Subject: [PATCH 08/20] remove all references to SetTaskbarProgressEventArgs, validation for state and progress params --- src/cascadia/TerminalApp/AppLogic.h | 2 +- src/cascadia/TerminalApp/AppLogic.idl | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 4 ++-- src/cascadia/TerminalApp/TerminalPage.h | 4 ++-- src/cascadia/TerminalApp/TerminalPage.idl | 2 +- src/cascadia/TerminalControl/TermControl.cpp | 5 ++--- src/cascadia/TerminalControl/TermControl.h | 19 +------------------ src/cascadia/TerminalControl/TermControl.idl | 8 +------- src/cascadia/TerminalCore/TerminalApi.cpp | 5 ++++- .../TerminalCore/TerminalDispatch.cpp | 13 ++++++++++++- .../TerminalCore/TerminalDispatch.hpp | 3 +++ src/cascadia/WindowsTerminal/AppHost.cpp | 2 +- src/cascadia/WindowsTerminal/AppHost.h | 2 +- src/cascadia/WindowsTerminal/IslandWindow.cpp | 2 ++ .../parser/OutputStateMachineEngine.cpp | 19 ++++++++++++++----- 15 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index b10ffd27472..a9d304fb79c 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -109,7 +109,7 @@ namespace winrt::TerminalApp::implementation FORWARDED_TYPED_EVENT(FocusModeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FocusModeChanged); FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged); FORWARDED_TYPED_EVENT(AlwaysOnTopChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, AlwaysOnTopChanged); - FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs, _root, SetTaskbarProgress); + FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress); }; } diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 1d06dd885a4..61f731d9548 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -62,6 +62,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler FocusModeChanged; event Windows.Foundation.TypedEventHandler FullscreenChanged; event Windows.Foundation.TypedEventHandler AlwaysOnTopChanged; - event Windows.Foundation.TypedEventHandler SetTaskbarProgress; + event Windows.Foundation.TypedEventHandler SetTaskbarProgress; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 5a5841f90a1..b332276827c 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1877,7 +1877,7 @@ namespace winrt::TerminalApp::implementation // Arguments: // - sender (not used) // - eventArgs: the arguments specifying how to set the progress indicator - void TerminalPage::_SetTaskbarProgressHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs eventArgs) + void TerminalPage::_SetTaskbarProgressHandler(const IInspectable sender, const IInspectable eventArgs) { _setTaskbarProgressHandlers(sender, eventArgs); } @@ -2652,5 +2652,5 @@ namespace winrt::TerminalApp::implementation DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, FocusModeChanged, _focusModeChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, FullscreenChanged, _fullscreenChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, AlwaysOnTopChanged, _alwaysOnTopChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); - DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, SetTaskbarProgress, _setTaskbarProgressHandlers, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs); + DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TerminalPage, SetTaskbarProgress, _setTaskbarProgressHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 00d6da9df1e..240cd9ce90c 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -78,7 +78,7 @@ namespace winrt::TerminalApp::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(FocusModeChanged, _focusModeChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(FullscreenChanged, _fullscreenChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(AlwaysOnTopChanged, _alwaysOnTopChangedHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); - DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs); + DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs); private: @@ -190,7 +190,7 @@ namespace winrt::TerminalApp::implementation void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri); bool _CopyText(const bool singleLine, const Windows::Foundation::IReference& formats); - void _SetTaskbarProgressHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs eventArgs); + void _SetTaskbarProgressHandler(const IInspectable sender, const IInspectable eventArgs); void _PasteText(); diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index 24fdd6cb01f..7cf92f55327 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -34,6 +34,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler FullscreenChanged; event Windows.Foundation.TypedEventHandler AlwaysOnTopChanged; event Windows.Foundation.TypedEventHandler Initialized; - event Windows.Foundation.TypedEventHandler SetTaskbarProgress; + event Windows.Foundation.TypedEventHandler SetTaskbarProgress; } } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 244e3e0e544..8fa3867fd3e 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -3027,8 +3027,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // to set the progress indicator on the taskbar void TermControl::TaskbarProgressChanged() { - auto setTaskbarProgressArgs = winrt::make_self(_terminal->GetTaskbarState(), _terminal->GetTaskbarProgress()); - _setTaskbarProgressHandlers(*this, *setTaskbarProgressArgs); + _setTaskbarProgressHandlers(*this, nullptr); } const size_t TermControl::GetTaskbarState() const noexcept @@ -3051,6 +3050,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); - DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, TerminalControl::SetTaskbarProgressEventArgs); + DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, IInspectable); // clang-format on } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 2984c5a6992..de0ed46a721 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -7,7 +7,6 @@ #include "CopyToClipboardEventArgs.g.h" #include "PasteFromClipboardEventArgs.g.h" #include "OpenHyperlinkEventArgs.g.h" -#include "SetTaskbarProgressEventArgs.g.h" #include #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" @@ -82,22 +81,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation hstring _uri; }; - struct SetTaskbarProgressEventArgs : - public SetTaskbarProgressEventArgsT - { - public: - SetTaskbarProgressEventArgs(size_t state, size_t progress) : - _state(state), - _progress(progress) {} - - size_t State() { return _state; }; - size_t Progress() { return _progress; }; - - private: - size_t _state; - size_t _progress; - }; - struct TermControl : TermControlT { TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection); @@ -169,7 +152,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); - DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, TerminalControl::SetTaskbarProgressEventArgs); + DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, IInspectable); TYPED_EVENT(WarningBell, IInspectable, IInspectable); TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index cded4a42f87..0ee1b358c10 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -45,12 +45,6 @@ namespace Microsoft.Terminal.TerminalControl String Uri { get; }; } - runtimeclass SetTaskbarProgressEventArgs - { - UInt64 State { get; }; - UInt64 Progress { get; }; - } - [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener { TermControl(Microsoft.Terminal.TerminalControl.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); @@ -66,7 +60,7 @@ namespace Microsoft.Terminal.TerminalControl event Windows.Foundation.TypedEventHandler CopyToClipboard; event Windows.Foundation.TypedEventHandler PasteFromClipboard; event Windows.Foundation.TypedEventHandler OpenHyperlink; - event Windows.Foundation.TypedEventHandler SetTaskbarProgress; + event Windows.Foundation.TypedEventHandler SetTaskbarProgress; event Windows.Foundation.TypedEventHandler WarningBell; event Windows.Foundation.TypedEventHandler Initialized; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index fa8c5ca4658..cccd9856a8c 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -612,6 +612,9 @@ bool Terminal::SetTaskbarProgress(const size_t state, const size_t progress) noe { _taskbarState = state; _taskbarProgress = progress; - _pfnTaskbarProgressChanged(); + if (_pfnTaskbarProgressChanged) + { + _pfnTaskbarProgressChanged(); + } return true; } diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 77024c3eadb..b6c0cab49e7 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -408,7 +408,18 @@ bool TerminalDispatch::EndHyperlink() noexcept // - true bool TerminalDispatch::SetTaskbarProgress(const size_t state, const size_t progress) noexcept { - return _terminalApi.SetTaskbarProgress(state, progress); + auto clampedProgress = progress; + if (state > TaskbarMaxState) + { + // state is out of bounds, return false + return false; + } + if (progress > TaskbarMaxProgress) + { + // progress is greater than the maximum allowed value, clamp it to the max + clampedProgress = TaskbarMaxProgress; + } + return _terminalApi.SetTaskbarProgress(state, clampedProgress); } // Routine Description: diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index 82d2f181c9d..566c88e534a 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -4,6 +4,9 @@ #include "../../terminal/adapter/termDispatch.hpp" #include "ITerminalApi.hpp" +static constexpr size_t TaskbarMaxState{ 4 }; +static constexpr size_t TaskbarMaxProgress{ 100 }; + class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatch { public: diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 707a6280393..2f65ff7f535 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -84,7 +84,7 @@ bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, cons // Arguments: // - sender: not used // - args: contains the progress state/value needed to set the taskbar progress -void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs& /*args*/) +void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/) { auto control = sender.try_as(); _window->SetTaskbarProgress(gsl::narrow(control.GetTaskbarState()), gsl::narrow(control.GetTaskbarProgress())); diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index a014b519066..23e7c534d94 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -18,7 +18,7 @@ class AppHost void LastTabClosed(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::LastTabClosedEventArgs& args); void Initialize(); bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down); - void SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::TerminalControl::SetTaskbarProgressEventArgs& args); + void SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); private: bool _useNonClientArea; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 3f27fc7788f..fc36dedffcc 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -515,6 +515,8 @@ void IslandWindow::SetAlwaysOnTop(const bool alwaysOnTop) // Method Description: // - Sets the taskbar progress indicator +// - We follow the ConEmu style for the state and progress values, +// more details at https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC // Arguments: // - state: indicates the progress state // - progress: indicates the progress value diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 4923e17773b..593a8f607e6 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -951,15 +951,24 @@ bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view strin size_t& progress) const { const auto parts = Utils::SplitString(string, L';'); - if (parts.size() != 3 || std::stoi(til::u16u8(parts.at(0))) != 4) + if (parts.size() < 1 || std::stoi(til::u16u8(parts.at(0))) != 4) { return false; } - state = std::stoi(til::u16u8(parts.at(1))); - progress = std::stoi(til::u16u8(parts.at(2))); - if (state < 0 || state > 4 || progress < 0 || progress > 100) + if (parts.size() == 1) { - return false; + state = 0; + progress = 0; + } + else if (parts.size() == 2) + { + state = std::stoi(til::u16u8(parts.at(1))); + progress = 0; + } + else + { + state = std::stoi(til::u16u8(parts.at(1))); + progress = std::stoi(til::u16u8(parts.at(2))); } return true; } From 4125052c6bddcb4210491dcfbeb6a9619ea30e0e Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 29 Oct 2020 12:27:40 -0400 Subject: [PATCH 09/20] tests --- .../TerminalApiTest.cpp | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp index 08a58ef60d3..c10bac728a6 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp @@ -38,6 +38,8 @@ namespace TerminalCoreUnitTests TEST_METHOD(AddHyperlink); TEST_METHOD(AddHyperlinkCustomId); TEST_METHOD(AddHyperlinkCustomIdDifferentUri); + + TEST_METHOD(SetTaskbarProgress); }; }; @@ -339,3 +341,38 @@ void TerminalCoreUnitTests::TerminalApiTest::AddHyperlinkCustomIdDifferentUri() VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(oldAttributes.GetHyperlinkId()), L"test.url"); VERIFY_ARE_NOT_EQUAL(oldAttributes.GetHyperlinkId(), tbi.GetCurrentAttributes().GetHyperlinkId()); } + +void TerminalCoreUnitTests::TerminalApiTest::SetTaskbarProgress() +{ + Terminal term; + DummyRenderTarget emptyRT; + term.Create({ 100, 100 }, 0, emptyRT); + + auto& stateMachine = *(term._stateMachine); + + // Initial values for taskbar state and progress should be 0 + VERIFY_ARE_EQUAL(term.GetTaskbarState(), 0); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 0); + + // Set some values for taskbar state and progress through state machine + stateMachine.ProcessString(L"\x1b]9;4;1;50\x9c"); + VERIFY_ARE_EQUAL(term.GetTaskbarState(), 1); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 50); + + // Reset to 0 + stateMachine.ProcessString(L"\x1b]9;4;0;0\x9c"); + VERIFY_ARE_EQUAL(term.GetTaskbarState(), 0); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 0); + + // Set an out of bounds value for state + stateMachine.ProcessString(L"\x1b]9;4;5;50\x9c"); + // Nothing should have changed (dispatch should have returned false) + VERIFY_ARE_EQUAL(term.GetTaskbarState(), 0); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 0); + + // Set an out of bounds value for progress + stateMachine.ProcessString(L"\x1b]9;4;1;999\x9c"); + // Progress should have been clamped to 100 + VERIFY_ARE_EQUAL(term.GetTaskbarState(), 1); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 100); +} From 0aa56671f9795672b661fc6ef3073f895db088c6 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Thu, 29 Oct 2020 17:12:46 -0400 Subject: [PATCH 10/20] get the taskbar state and progress from the last active control --- src/cascadia/TerminalApp/AppLogic.cpp | 18 +++++++++++ src/cascadia/TerminalApp/AppLogic.h | 3 ++ src/cascadia/TerminalApp/AppLogic.idl | 3 ++ src/cascadia/TerminalApp/TerminalPage.cpp | 24 ++++++++++++-- src/cascadia/TerminalApp/TerminalPage.h | 3 ++ src/cascadia/TerminalApp/TerminalPage.idl | 3 ++ src/cascadia/TerminalControl/TermControl.cpp | 6 ++-- src/cascadia/TerminalControl/TermControl.h | 2 +- .../TerminalApiTest.cpp | 32 +++++++++++++------ src/cascadia/WindowsTerminal/AppHost.cpp | 8 +++-- 10 files changed, 83 insertions(+), 19 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 72d7dae9cf2..6c0d4c71a50 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -990,6 +990,24 @@ namespace winrt::TerminalApp::implementation } } + size_t AppLogic::GetLastActiveControlTaskbarState() + { + if (_root) + { + return _root->GetLastActiveControlTaskbarState(); + } + return {}; + } + + size_t AppLogic::GetLastActiveControlTaskbarProgress() + { + if (_root) + { + return _root->GetLastActiveControlTaskbarProgress(); + } + return {}; + } + // 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 diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index a9d304fb79c..f630cffc11f 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -51,6 +51,9 @@ namespace winrt::TerminalApp::implementation void WindowCloseButtonClicked(); + size_t GetLastActiveControlTaskbarState(); + size_t GetLastActiveControlTaskbarProgress(); + winrt::Windows::Foundation::IAsyncOperation ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog); // -------------------------------- WinRT Events --------------------------------- diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 61f731d9548..76cb8862fd9 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -51,6 +51,9 @@ namespace TerminalApp void TitlebarClicked(); void WindowCloseButtonClicked(); + UInt64 GetLastActiveControlTaskbarState(); + UInt64 GetLastActiveControlTaskbarProgress(); + // See IDialogPresenter and TerminalPage's DialogPresenter for more // information. Windows.Foundation.IAsyncOperation ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 2c5129087df..9fd90319c86 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1871,9 +1871,9 @@ namespace winrt::TerminalApp::implementation // Arguments: // - sender (not used) // - eventArgs: the arguments specifying how to set the progress indicator - void TerminalPage::_SetTaskbarProgressHandler(const IInspectable sender, const IInspectable eventArgs) + void TerminalPage::_SetTaskbarProgressHandler(const IInspectable /*sender*/, const IInspectable /*eventArgs*/) { - _setTaskbarProgressHandlers(sender, eventArgs); + _setTaskbarProgressHandlers(*this, nullptr); } // Method Description: @@ -2235,6 +2235,26 @@ namespace winrt::TerminalApp::implementation _dialogPresenter = dialogPresenter; } + size_t TerminalPage::GetLastActiveControlTaskbarState() + { + const auto tab = _GetFocusedTab(); + if (tab) + { + return tab->GetActiveTerminalControl().GetTaskbarState(); + } + return {}; + } + + size_t TerminalPage::GetLastActiveControlTaskbarProgress() + { + const auto tab = _GetFocusedTab(); + if (tab) + { + return tab->GetActiveTerminalControl().GetTaskbarProgress(); + } + return {}; + } + // Method Description: // - This is the method that App will call when the titlebar // has been clicked. It dismisses any open flyouts. diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index b6358c8cdca..e666d3c2fdb 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -71,6 +71,9 @@ namespace winrt::TerminalApp::implementation winrt::TerminalApp::IDialogPresenter DialogPresenter() const; void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter); + size_t GetLastActiveControlTaskbarState(); + size_t GetLastActiveControlTaskbarProgress(); + // -------------------------------- WinRT Events --------------------------------- DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs); diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index 7cf92f55327..d5ae6410ea3 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -27,6 +27,9 @@ namespace TerminalApp // and because of GH#5224. IDialogPresenter DialogPresenter; + UInt64 GetLastActiveControlTaskbarState(); + UInt64 GetLastActiveControlTaskbarProgress(); + event Windows.Foundation.TypedEventHandler TitleChanged; event Windows.Foundation.TypedEventHandler LastTabClosed; event Windows.Foundation.TypedEventHandler SetTitleBarContent; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 657f995e2b0..67b3e6dbb71 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -107,8 +107,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation auto pfnCopyToClipboard = std::bind(&TermControl::_CopyToClipboard, this, std::placeholders::_1); _terminal->SetCopyToClipboardCallback(pfnCopyToClipboard); - auto pfnTaskbarProgressChanged = std::bind(&TermControl::TaskbarProgressChanged, this); - _terminal->TaskbarProgressChangedCallback(pfnTaskbarProgressChanged); + _terminal->TaskbarProgressChangedCallback([&]() { TermControl::TaskbarProgressChanged(); }); // This event is explicitly revoked in the destructor: does not need weak_ref auto onReceiveOutputFn = [this](const hstring str) { @@ -3070,8 +3069,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // Method Description: // - Sends an event (which will be caught by TerminalPage and forwarded to AppHost after) // to set the progress indicator on the taskbar - void TermControl::TaskbarProgressChanged() + winrt::fire_and_forget TermControl::TaskbarProgressChanged() { + co_await resume_foreground(Dispatcher(), CoreDispatcherPriority::High); _setTaskbarProgressHandlers(*this, nullptr); } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 7e1769b0fc6..029de58fec4 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -141,7 +141,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation Windows::Foundation::IReference TabColor() noexcept; - void TaskbarProgressChanged(); + winrt::fire_and_forget TaskbarProgressChanged(); const size_t GetTaskbarState() const noexcept; const size_t GetTaskbarProgress() const noexcept; diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp index c10bac728a6..2060e444c2e 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp @@ -351,28 +351,40 @@ void TerminalCoreUnitTests::TerminalApiTest::SetTaskbarProgress() auto& stateMachine = *(term._stateMachine); // Initial values for taskbar state and progress should be 0 - VERIFY_ARE_EQUAL(term.GetTaskbarState(), 0); - VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 0); + VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(0)); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(0)); // Set some values for taskbar state and progress through state machine stateMachine.ProcessString(L"\x1b]9;4;1;50\x9c"); - VERIFY_ARE_EQUAL(term.GetTaskbarState(), 1); - VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 50); + VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(1)); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(50)); // Reset to 0 stateMachine.ProcessString(L"\x1b]9;4;0;0\x9c"); - VERIFY_ARE_EQUAL(term.GetTaskbarState(), 0); - VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 0); + VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(0)); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(0)); // Set an out of bounds value for state stateMachine.ProcessString(L"\x1b]9;4;5;50\x9c"); // Nothing should have changed (dispatch should have returned false) - VERIFY_ARE_EQUAL(term.GetTaskbarState(), 0); - VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 0); + VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(0)); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(0)); // Set an out of bounds value for progress stateMachine.ProcessString(L"\x1b]9;4;1;999\x9c"); // Progress should have been clamped to 100 - VERIFY_ARE_EQUAL(term.GetTaskbarState(), 1); - VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), 100); + VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(1)); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(100)); + + // Don't specify any params + stateMachine.ProcessString(L"\x1b]9;4\x9c"); + // State and progress should both be reset to 0 + VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(0)); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(0)); + + // Specify additional params + stateMachine.ProcessString(L"\x1b]9;4;1;80;123\x9c"); + // Additional params should be ignored, state and progress still set normally + VERIFY_ARE_EQUAL(term.GetTaskbarState(), gsl::narrow(1)); + VERIFY_ARE_EQUAL(term.GetTaskbarProgress(), gsl::narrow(80)); } diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 2f65ff7f535..a0ea93ae8a2 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -84,10 +84,12 @@ bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, cons // Arguments: // - sender: not used // - args: contains the progress state/value needed to set the taskbar progress -void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/) +void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { - auto control = sender.try_as(); - _window->SetTaskbarProgress(gsl::narrow(control.GetTaskbarState()), gsl::narrow(control.GetTaskbarProgress())); + if (_logic) + { + _window->SetTaskbarProgress(_logic.GetLastActiveControlTaskbarState(), _logic.GetLastActiveControlTaskbarProgress()); + } } // Method Description: From e69d0af3810fae67dc258fae3ae5130c866b4f11 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 30 Oct 2020 11:01:56 -0400 Subject: [PATCH 11/20] addressing comments, cleanups --- .../actions/spell-check/dictionary/apis.txt | 3 --- src/cascadia/TerminalApp/AppLogic.cpp | 8 ++++++ src/cascadia/TerminalApp/TerminalPage.cpp | 8 ++++++ src/cascadia/TerminalControl/TermControl.cpp | 8 ++++++ src/cascadia/TerminalCore/Terminal.cpp | 8 ++++++ src/cascadia/WindowsTerminal/AppHost.cpp | 4 ++- .../parser/OutputStateMachineEngine.cpp | 27 ++++++++++++++++--- 7 files changed, 58 insertions(+), 8 deletions(-) diff --git a/.github/actions/spell-check/dictionary/apis.txt b/.github/actions/spell-check/dictionary/apis.txt index 9c808b4fd5f..6a59957ae45 100644 --- a/.github/actions/spell-check/dictionary/apis.txt +++ b/.github/actions/spell-check/dictionary/apis.txt @@ -60,11 +60,8 @@ sregex STDCPP strchr syscall -<<<<<<< HEAD TBPF -======= THEMECHANGED ->>>>>>> 2ea4742f07ce8eed721a1136d2eec780ac01b995 tmp tx UPDATEINIFILE diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 6c0d4c71a50..f42ebf59c5b 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -990,6 +990,10 @@ namespace winrt::TerminalApp::implementation } } + // Method Description: + // - Gets the taskbar state value from the last active control + // Return Value: + // - The taskbar state of the last active control size_t AppLogic::GetLastActiveControlTaskbarState() { if (_root) @@ -999,6 +1003,10 @@ namespace winrt::TerminalApp::implementation return {}; } + // Method Description: + // - Gets the taskbar progress value from the last active control + // Return Value: + // - The taskbar progress of the last active control size_t AppLogic::GetLastActiveControlTaskbarProgress() { if (_root) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 9fd90319c86..8977cdde2a9 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2235,6 +2235,10 @@ namespace winrt::TerminalApp::implementation _dialogPresenter = dialogPresenter; } + // Method Description: + // - Gets the taskbar state value from the last active control + // Return Value: + // - The taskbar state of the last active control size_t TerminalPage::GetLastActiveControlTaskbarState() { const auto tab = _GetFocusedTab(); @@ -2245,6 +2249,10 @@ namespace winrt::TerminalApp::implementation return {}; } + // Method Description: + // - Gets the taskbar progress value from the last active control + // Return Value: + // - The taskbar progress of the last active control size_t TerminalPage::GetLastActiveControlTaskbarProgress() { const auto tab = _GetFocusedTab(); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 67b3e6dbb71..07df042b92f 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -3075,11 +3075,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _setTaskbarProgressHandlers(*this, nullptr); } + // Method Description: + // - Gets the internal taskbar state value + // Return Value: + // - The taskbar state of this control const size_t TermControl::GetTaskbarState() const noexcept { return _terminal->GetTaskbarState(); } + // Method Description: + // - Gets the internal taskbar progress value + // Return Value: + // - The taskbar progress of this control const size_t TermControl::GetTaskbarProgress() const noexcept { return _terminal->GetTaskbarProgress(); diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index aace7dfdb06..05e4da5fdd6 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -1181,11 +1181,19 @@ BlinkingState& Terminal::GetBlinkingState() const noexcept return _blinkingState; } +// Method Description: +// - Gets the internal taskbar state value +// Return Value: +// - The taskbar state const size_t Microsoft::Terminal::Core::Terminal::GetTaskbarState() const noexcept { return _taskbarState; } +// Method Description: +// - Gets the internal taskbar progress value +// Return Value: +// - The taskbar progress const size_t Microsoft::Terminal::Core::Terminal::GetTaskbarProgress() const noexcept { return _taskbarProgress; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index a0ea93ae8a2..f8121fec82c 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -81,9 +81,11 @@ bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, cons // Method Description: // - Event handler to update the taskbar progress indicator +// - Upon receiving the event, we ask the underlying logic for the taskbar state/progress values +// of the last active control // Arguments: // - sender: not used -// - args: contains the progress state/value needed to set the taskbar progress +// - args: not used void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/) { if (_logic) diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 593a8f607e6..72b9c23841a 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -951,10 +951,15 @@ bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view strin size_t& progress) const { const auto parts = Utils::SplitString(string, L';'); - if (parts.size() < 1 || std::stoi(til::u16u8(parts.at(0))) != 4) + + unsigned int subParam = 0; + const auto subParamSuccess = Utils::StringToUint(til::at(parts, 0), subParam); + + if (parts.size() < 1 || !subParamSuccess || subParam != 4) { return false; } + if (parts.size() == 1) { state = 0; @@ -962,13 +967,27 @@ bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view strin } else if (parts.size() == 2) { - state = std::stoi(til::u16u8(parts.at(1))); + unsigned int localState = 0; + const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), localState); + if (!stateSuccess) + { + return false; + } + state = localState; progress = 0; } else { - state = std::stoi(til::u16u8(parts.at(1))); - progress = std::stoi(til::u16u8(parts.at(2))); + unsigned int localState = 0; + unsigned int localProgress = 0; + const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), localState); + const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), localProgress); + if (!stateSuccess || !progressSuccess) + { + return false; + } + state = localState; + progress = localProgress; } return true; } From 57d8e0798e05a0186bb2f4ec360828ec9e3a1e58 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 30 Oct 2020 16:07:48 -0400 Subject: [PATCH 12/20] com ptr --- src/cascadia/WindowsTerminal/IslandWindow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 51134681fa8..3d985a74154 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -76,7 +76,7 @@ class IslandWindow : LONG _getDesiredWindowStyle() const; - ITaskbarList3* _taskbar; + wil::com_ptr _taskbar; bool _taskbarInitialized{ false }; private: From 4ab32ec42116d8d15921b64fb895501046623590 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 4 Nov 2020 15:01:12 -0500 Subject: [PATCH 13/20] send event when tab changes --- src/cascadia/TerminalApp/TerminalTab.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index 567d48a7ba1..dcddb42b843 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -105,6 +105,7 @@ namespace winrt::TerminalApp::implementation if (lastFocusedControl) { lastFocusedControl.Focus(_focusState); + lastFocusedControl.TaskbarProgressChanged(); } } } From 5aff81a220c4051627448674465834a3aeaab1a1 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 4 Nov 2020 15:04:52 -0500 Subject: [PATCH 14/20] check if control exists before using it --- src/cascadia/TerminalApp/TerminalPage.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 814b85564f5..acd2e48f2f2 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2282,7 +2282,11 @@ namespace winrt::TerminalApp::implementation // - The taskbar state of the last active control size_t TerminalPage::GetLastActiveControlTaskbarState() { - return _GetActiveControl().GetTaskbarState(); + if (auto control{ _GetActiveControl() }) + { + return control.GetTaskbarState(); + } + return {}; } // Method Description: @@ -2291,7 +2295,11 @@ namespace winrt::TerminalApp::implementation // - The taskbar progress of the last active control size_t TerminalPage::GetLastActiveControlTaskbarProgress() { - return _GetActiveControl().GetTaskbarProgress(); + if (auto control{ _GetActiveControl() }) + { + return control.GetTaskbarProgress(); + } + return {}; } // Method Description: From f19b818eb04ef11d9f6b10f946a85add943b33e1 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 6 Nov 2020 12:53:41 -0500 Subject: [PATCH 15/20] con emu action --- .../TerminalCore/TerminalDispatch.cpp | 51 ++++++++++++++++--- .../TerminalCore/TerminalDispatch.hpp | 2 +- src/terminal/adapter/ITermDispatch.hpp | 2 +- src/terminal/adapter/adaptDispatch.cpp | 2 +- src/terminal/adapter/adaptDispatch.hpp | 2 +- src/terminal/adapter/termDispatch.hpp | 2 +- .../parser/OutputStateMachineEngine.cpp | 10 ++-- .../parser/OutputStateMachineEngine.hpp | 2 +- .../parser/ut_parser/OutputEngineTest.cpp | 2 +- 9 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index b6c0cab49e7..9b46f357ecb 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -3,6 +3,9 @@ #include "pch.h" #include "TerminalDispatch.hpp" +#include "../../types/inc/utils.hpp" + +using namespace Microsoft::Console; using namespace ::Microsoft::Terminal::Core; using namespace ::Microsoft::Console::VirtualTerminal; @@ -400,15 +403,49 @@ bool TerminalDispatch::EndHyperlink() noexcept } // Method Description: -// - Updates the taskbar progress indicator +// - Performs a ConEmu action +// - Currently, the only action we support is setting the taskbar state/progress // Arguments: -// - state: indicates the progress state -// - progress: indicates the progress value +// - string: contains the parameters that define which action we do // Return Value: // - true -bool TerminalDispatch::SetTaskbarProgress(const size_t state, const size_t progress) noexcept +bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept { - auto clampedProgress = progress; + unsigned int state = 0; + unsigned int progress = 0; + + const auto parts = Utils::SplitString(string, L';'); + + unsigned int subParam = 0; + const auto subParamSuccess = Utils::StringToUint(til::at(parts, 0), subParam); + + // For now, the only ConEmu action we support is setting the taskbar state/progress, + // which has a subparam value of 4 + if (parts.size() < 1 || !subParamSuccess || subParam != 4) + { + return false; + } + + if (parts.size() == 2) + { + // A state parameter is defined, parse it out + const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), state); + if (!stateSuccess) + { + return false; + } + } + else if (parts.size() > 2) + { + // Both state and progress are defined, parse them out + const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), state); + const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), progress); + if (!stateSuccess || !progressSuccess) + { + return false; + } + } + if (state > TaskbarMaxState) { // state is out of bounds, return false @@ -417,9 +454,9 @@ bool TerminalDispatch::SetTaskbarProgress(const size_t state, const size_t progr if (progress > TaskbarMaxProgress) { // progress is greater than the maximum allowed value, clamp it to the max - clampedProgress = TaskbarMaxProgress; + progress = TaskbarMaxProgress; } - return _terminalApi.SetTaskbarProgress(state, clampedProgress); + return _terminalApi.SetTaskbarProgress(state, progress); } // Routine Description: diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index 566c88e534a..5b0bce31f9c 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -70,7 +70,7 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) noexcept override; bool EndHyperlink() noexcept override; - bool SetTaskbarProgress(const size_t state, const size_t progress) noexcept override; + bool DoConEmuAction(const std::wstring_view string) noexcept override; private: ::Microsoft::Terminal::Core::ITerminalApi& _terminalApi; diff --git a/src/terminal/adapter/ITermDispatch.hpp b/src/terminal/adapter/ITermDispatch.hpp index 5feccdd851c..d7c2991ec1a 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -123,7 +123,7 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch virtual bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) = 0; virtual bool EndHyperlink() = 0; - virtual bool SetTaskbarProgress(const size_t state, const size_t progress) = 0; + virtual bool DoConEmuAction(const std::wstring_view string) = 0; }; inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() {} #pragma warning(pop) diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index f9115812dbd..177648520de 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2388,7 +2388,7 @@ bool AdaptDispatch::EndHyperlink() // - Not actually used in conhost // Return Value: // - false (so that the command gets flushed to terminal) -bool AdaptDispatch::SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) noexcept +bool AdaptDispatch::DoConEmuAction(const std::wstring_view /*string*/) noexcept { return false; } diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index e0945e6b4a6..aafb267d266 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -123,7 +123,7 @@ namespace Microsoft::Console::VirtualTerminal bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override; bool EndHyperlink() override; - bool SetTaskbarProgress(const size_t state, const size_t progress) noexcept override; + bool DoConEmuAction(const std::wstring_view string) noexcept override; private: enum class ScrollDirection diff --git a/src/terminal/adapter/termDispatch.hpp b/src/terminal/adapter/termDispatch.hpp index 8cc4086b7e9..9083d2475b8 100644 --- a/src/terminal/adapter/termDispatch.hpp +++ b/src/terminal/adapter/termDispatch.hpp @@ -117,5 +117,5 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons bool AddHyperlink(const std::wstring_view /*uri*/, const std::wstring_view /*params*/) noexcept override { return false; } bool EndHyperlink() noexcept override { return false; } - bool SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) noexcept override { return false; } + bool DoConEmuAction(const std::wstring_view /*string*/) noexcept override { return false; } }; diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 72b9c23841a..a226c63d03d 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -647,8 +647,6 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, bool queryClipboard = false; std::vector tableIndexes; std::vector colors; - size_t state = 0; - size_t progress = 0; switch (parameter) { @@ -674,8 +672,8 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, case OscActionCodes::Hyperlink: success = _ParseHyperlink(string, params, uri); break; - case OscActionCodes::SetTaskbarProgress: - success = _GetTaskbarProgress(string, state, progress); + case OscActionCodes::ConEmuAction: + success = true; break; default: // If no functions to call, overall dispatch was a failure. @@ -744,8 +742,8 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, success = _dispatch->AddHyperlink(uri, params); } break; - case OscActionCodes::SetTaskbarProgress: - success = _dispatch->SetTaskbarProgress(state, progress); + case OscActionCodes::ConEmuAction: + success = _dispatch->DoConEmuAction(string); break; default: // If no functions to call, overall dispatch was a failure. diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index 1f11bc1f851..9a6bf8b30b7 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -160,7 +160,7 @@ namespace Microsoft::Console::VirtualTerminal SetWindowProperty = 3, // Not implemented SetColor = 4, Hyperlink = 8, - SetTaskbarProgress = 9, + ConEmuAction = 9, SetForegroundColor = 10, SetBackgroundColor = 11, SetCursorColor = 12, diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index 201a30754b6..6ce4de358e7 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -1456,7 +1456,7 @@ class StatefulDispatch final : public TermDispatch return true; } - bool SetTaskbarProgress(const size_t /*state*/, const size_t /*progress*/) noexcept override + bool DoConEmuAction(const std::wstring_view /*string*/) noexcept override { return true; } From f931acc23ef78b7afe72450996a90322719481de Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Fri, 6 Nov 2020 12:58:44 -0500 Subject: [PATCH 16/20] spel --- src/cascadia/TerminalCore/TerminalDispatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 9b46f357ecb..42984a2a199 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -420,7 +420,7 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept const auto subParamSuccess = Utils::StringToUint(til::at(parts, 0), subParam); // For now, the only ConEmu action we support is setting the taskbar state/progress, - // which has a subparam value of 4 + // which has a sub param value of 4 if (parts.size() < 1 || !subParamSuccess || subParam != 4) { return false; From c694192fd419401502ca4d0429af5642b04df6d9 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Mon, 9 Nov 2020 10:10:58 -0500 Subject: [PATCH 17/20] _GetTaskbarProgress no longer needed --- .../parser/OutputStateMachineEngine.cpp | 60 ------------------- .../parser/OutputStateMachineEngine.hpp | 4 -- 2 files changed, 64 deletions(-) diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index a226c63d03d..52096b27c5e 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -930,66 +930,6 @@ bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string, return false; } -// Routine Description: -// - OSC 9 ; 4 ; state ; progress ST -// state: the state to set the taskbar progress indicator to -// progress: the progress value to set the taskbar progress indicator with -// - Parses out the 'state' and 'progress' parameters from the OSC string so -// that we can use them to set the taskbar progress indicator -// - This follows the ConEmu style, more details here: -// https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC -// Arguments: -// - string: the string to parse -// - state: where to store the state value once we parse it -// - progress: where to store the progress value once we parse it -// Return Value: -// - true if we successfully parsed the string, false otherwise -bool OutputStateMachineEngine::_GetTaskbarProgress(const std::wstring_view string, - size_t& state, - size_t& progress) const -{ - const auto parts = Utils::SplitString(string, L';'); - - unsigned int subParam = 0; - const auto subParamSuccess = Utils::StringToUint(til::at(parts, 0), subParam); - - if (parts.size() < 1 || !subParamSuccess || subParam != 4) - { - return false; - } - - if (parts.size() == 1) - { - state = 0; - progress = 0; - } - else if (parts.size() == 2) - { - unsigned int localState = 0; - const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), localState); - if (!stateSuccess) - { - return false; - } - state = localState; - progress = 0; - } - else - { - unsigned int localState = 0; - unsigned int localProgress = 0; - const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), localState); - const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), localProgress); - if (!stateSuccess || !progressSuccess) - { - return false; - } - state = localState; - progress = localProgress; - } - return true; -} - // Routine Description: // - OSC 10, 11, 12 ; spec ST // spec: The colors are specified by name or RGB specification as per XParseColor diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index 9a6bf8b30b7..b1ebd19b87f 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -189,10 +189,6 @@ namespace Microsoft::Console::VirtualTerminal std::wstring& params, std::wstring& uri) const; - bool _GetTaskbarProgress(const std::wstring_view string, - size_t& state, - size_t& progress) const; - void _ClearLastChar() noexcept; }; } From fc9fedf1b33b134013990e1d6c6ae93d63e677e2 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 18 Nov 2020 16:04:08 -0500 Subject: [PATCH 18/20] com_ptr, nits --- src/cascadia/TerminalApp/TerminalPage.cpp | 4 ++-- src/cascadia/TerminalControl/TermControl.cpp | 4 ++-- src/cascadia/TerminalControl/TermControl.h | 4 ++-- src/cascadia/TerminalControl/TermControl.idl | 4 ++-- .../TerminalCore/TerminalDispatch.cpp | 21 ++++++++----------- src/cascadia/WindowsTerminal/IslandWindow.cpp | 9 ++++---- src/cascadia/WindowsTerminal/IslandWindow.h | 1 - 7 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index e194fdea6d1..2c56c7d29f6 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2386,7 +2386,7 @@ namespace winrt::TerminalApp::implementation { if (auto control{ _GetActiveControl() }) { - return control.GetTaskbarState(); + return control.TaskbarState(); } return {}; } @@ -2399,7 +2399,7 @@ namespace winrt::TerminalApp::implementation { if (auto control{ _GetActiveControl() }) { - return control.GetTaskbarProgress(); + return control.TaskbarProgress(); } return {}; } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 7b6001df5bd..01eee9c2698 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -3106,7 +3106,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - Gets the internal taskbar state value // Return Value: // - The taskbar state of this control - const size_t TermControl::GetTaskbarState() const noexcept + const size_t TermControl::TaskbarState() const noexcept { return _terminal->GetTaskbarState(); } @@ -3115,7 +3115,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - Gets the internal taskbar progress value // Return Value: // - The taskbar progress of this control - const size_t TermControl::GetTaskbarProgress() const noexcept + const size_t TermControl::TaskbarProgress() const noexcept { return _terminal->GetTaskbarProgress(); } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index eb5738b6d9e..4e2ebba54ce 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -159,8 +159,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation Windows::Foundation::IReference TabColor() noexcept; winrt::fire_and_forget TaskbarProgressChanged(); - const size_t GetTaskbarState() const noexcept; - const size_t GetTaskbarProgress() const noexcept; + const size_t TaskbarState() const noexcept; + const size_t TaskbarProgress() const noexcept; // clang-format off // -------------------------------- WinRT Events --------------------------------- diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 9d4b94289ac..22a3345d311 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -107,8 +107,8 @@ namespace Microsoft.Terminal.TerminalControl void ToggleRetroEffect(); void TaskbarProgressChanged(); - UInt64 GetTaskbarState(); - UInt64 GetTaskbarProgress(); + UInt64 TaskbarState { get; }; + UInt64 TaskbarProgress { get; }; Windows.Foundation.IReference TabColor { get; }; event Windows.Foundation.TypedEventHandler TabColorChanged; diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 42984a2a199..8d873f1102f 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -415,18 +415,16 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept unsigned int progress = 0; const auto parts = Utils::SplitString(string, L';'); - unsigned int subParam = 0; - const auto subParamSuccess = Utils::StringToUint(til::at(parts, 0), subParam); // For now, the only ConEmu action we support is setting the taskbar state/progress, // which has a sub param value of 4 - if (parts.size() < 1 || !subParamSuccess || subParam != 4) + if (parts.size() < 1 || !Utils::StringToUint(til::at(parts, 0), subParam) || subParam != 4) { return false; } - if (parts.size() == 2) + if (parts.size() >= 2) { // A state parameter is defined, parse it out const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), state); @@ -434,15 +432,14 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept { return false; } - } - else if (parts.size() > 2) - { - // Both state and progress are defined, parse them out - const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), state); - const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), progress); - if (!stateSuccess || !progressSuccess) + if (parts.size() >= 3) { - return false; + // A progress parameter is also defined, parse it out + const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), progress); + if (!progressSuccess) + { + return false; + } } } diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 0cdd884dbc7..9f4d9c92c16 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -263,12 +263,11 @@ void IslandWindow::Initialize() _source.Content(_rootGrid); // initialize the taskbar object - HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&_taskbar)); - if (SUCCEEDED(hr)) + if (auto taskbar = wil::CoCreateInstanceNoThrow(CLSID_TaskbarList)) { - if (SUCCEEDED(_taskbar->HrInit())) + if (SUCCEEDED(taskbar->HrInit())) { - _taskbarInitialized = true; + _taskbar = std::move(taskbar); } } } @@ -595,7 +594,7 @@ void IslandWindow::SetAlwaysOnTop(const bool alwaysOnTop) // - progress: indicates the progress value void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress) { - if (_taskbarInitialized) + if (_taskbar) { switch (state) { diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index f81029b23b7..882e1525891 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -77,7 +77,6 @@ class IslandWindow : LONG _getDesiredWindowStyle() const; wil::com_ptr _taskbar; - bool _taskbarInitialized{ false }; void _OnGetMinMaxInfo(const WPARAM wParam, const LPARAM lParam); long _calculateTotalSize(const bool isWidth, const long clientSize, const long nonClientSize); From bf2051bee31c82d84b82bc92ec75c1eb613642d7 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 18 Nov 2020 16:28:27 -0500 Subject: [PATCH 19/20] narrow cast --- src/cascadia/TerminalApp/TerminalPage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 2c56c7d29f6..deb5bc53aa5 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2386,7 +2386,7 @@ namespace winrt::TerminalApp::implementation { if (auto control{ _GetActiveControl() }) { - return control.TaskbarState(); + return gsl::narrow_cast(control.TaskbarState()); } return {}; } @@ -2399,7 +2399,7 @@ namespace winrt::TerminalApp::implementation { if (auto control{ _GetActiveControl() }) { - return control.TaskbarProgress(); + return gsl::narrow_cast(control.TaskbarProgress()); } return {}; } From 378dd7fc6b2cd6296b4bf1d11bb0b24a963dae44 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Wed, 18 Nov 2020 16:49:43 -0500 Subject: [PATCH 20/20] narrow 2 --- src/cascadia/WindowsTerminal/AppHost.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index b5cf636603a..2e5339fa220 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -90,7 +90,9 @@ void AppHost::SetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& { if (_logic) { - _window->SetTaskbarProgress(_logic.GetLastActiveControlTaskbarState(), _logic.GetLastActiveControlTaskbarProgress()); + const auto state = gsl::narrow_cast(_logic.GetLastActiveControlTaskbarState()); + const auto progress = gsl::narrow_cast(_logic.GetLastActiveControlTaskbarProgress()); + _window->SetTaskbarProgress(state, progress); } }