Combine progress states in the tab, taskbar (#10755)
## Summary of the Pull Request ![background-progress-000](https://user-images.githubusercontent.com/18356694/126653006-3ad2fdae-67ae-4cdb-aa46-25d09217e365.gif) This PR causes the Terminal to combine taskbar states at the tab and window level, according to the [MSDN docs for `SetProgressState`](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group). This allows the Terminal's taskbar icon to continue showing progress information, even if you're in a pane/tab that _doesn't_ have progress state. This is helpful for cases where the user may be running a build in one tab, and working on something else in another. ## References * [`SetProgressState`](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group) * Progress mega: #6700 ## PR Checklist * [x] Closes #10090 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments This also fixes a related bug where transitioning from the "error" or "warning" state directly to the "indeterminate" state would cause the taskbar icon to get stuck in a bad state. ## Validation Steps Performed <details> <summary><code>progress.cmd</code></summary> ```cmd @echo off setlocal enabledelayedexpansion set _type=3 if (%1) == () ( set _type=3 ) else ( set _type=%1 ) if (%_type%) == (0) ( <NUL set /p =]9;4 echo Cleared progress ) if (%_type%) == (1) ( <NUL set /p =]9;4;1;25 echo Started progress (normal, 25^) ) if (%_type%) == (2) ( <NUL set /p =]9;4;2;50 echo Started progress (error, 50^) ) if (%_type%) == (3) ( @rem start indeterminate progress in the taskbar @rem this `<NUL set /p =` magic will output the text _without a newline_ <NUL set /p =]9;4;3 echo Started progress (indeterminate, {omitted}) ) if (%_type%) == (4) ( <NUL set /p =]9;4;4;75 echo Started progress (warning, 75^) ) ``` </details>
This commit is contained in:
parent
c55888f88d
commit
a14b6f89f6
|
@ -1129,28 +1129,11 @@ namespace winrt::TerminalApp::implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
winrt::TerminalApp::TaskbarState AppLogic::TaskbarState()
|
||||||
// - Gets the taskbar state value from the last active control
|
|
||||||
// Return Value:
|
|
||||||
// - The taskbar state of the last active control
|
|
||||||
uint64_t AppLogic::GetLastActiveControlTaskbarState()
|
|
||||||
{
|
{
|
||||||
if (_root)
|
if (_root)
|
||||||
{
|
{
|
||||||
return _root->GetLastActiveControlTaskbarState();
|
return _root->TaskbarState();
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method Description:
|
|
||||||
// - Gets the taskbar progress value from the last active control
|
|
||||||
// Return Value:
|
|
||||||
// - The taskbar progress of the last active control
|
|
||||||
uint64_t AppLogic::GetLastActiveControlTaskbarProgress()
|
|
||||||
{
|
|
||||||
if (_root)
|
|
||||||
{
|
|
||||||
return _root->GetLastActiveControlTaskbarProgress();
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,8 +90,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
|
|
||||||
void WindowCloseButtonClicked();
|
void WindowCloseButtonClicked();
|
||||||
|
|
||||||
uint64_t GetLastActiveControlTaskbarState();
|
winrt::TerminalApp::TaskbarState TaskbarState();
|
||||||
uint64_t GetLastActiveControlTaskbarProgress();
|
|
||||||
|
|
||||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,7 @@ namespace TerminalApp
|
||||||
void TitlebarClicked();
|
void TitlebarClicked();
|
||||||
void WindowCloseButtonClicked();
|
void WindowCloseButtonClicked();
|
||||||
|
|
||||||
UInt64 GetLastActiveControlTaskbarState();
|
TaskbarState TaskbarState{ get; };
|
||||||
UInt64 GetLastActiveControlTaskbarProgress();
|
|
||||||
|
|
||||||
FindTargetWindowResult FindTargetWindow(String[] args);
|
FindTargetWindowResult FindTargetWindow(String[] args);
|
||||||
|
|
||||||
|
|
|
@ -2548,6 +2548,29 @@ bool Pane::ContainsReadOnly() const
|
||||||
return _IsLeaf() ? _control.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly());
|
return _IsLeaf() ? _control.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - If we're a parent, place the taskbar state for all our leaves into the
|
||||||
|
// provided vector.
|
||||||
|
// - If we're a leaf, place our own state into the vector.
|
||||||
|
// Arguments:
|
||||||
|
// - states: a vector that will receive all the states of all leaves in the tree
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void Pane::CollectTaskbarStates(std::vector<winrt::TerminalApp::TaskbarState>& states)
|
||||||
|
{
|
||||||
|
if (_IsLeaf())
|
||||||
|
{
|
||||||
|
auto tbState{ winrt::make<winrt::TerminalApp::implementation::TaskbarState>(_control.TaskbarState(),
|
||||||
|
_control.TaskbarProgress()) };
|
||||||
|
states.push_back(tbState);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_firstChild->CollectTaskbarStates(states);
|
||||||
|
_secondChild->CollectTaskbarStates(states);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_EVENT(Pane, GotFocus, _GotFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
DEFINE_EVENT(Pane, GotFocus, _GotFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
||||||
DEFINE_EVENT(Pane, LostFocus, _LostFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
DEFINE_EVENT(Pane, LostFocus, _LostFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
||||||
DEFINE_EVENT(Pane, PaneRaiseBell, _PaneRaiseBellHandlers, winrt::Windows::Foundation::EventHandler<bool>);
|
DEFINE_EVENT(Pane, PaneRaiseBell, _PaneRaiseBellHandlers, winrt::Windows::Foundation::EventHandler<bool>);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../../cascadia/inc/cppwinrt_utils.h"
|
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||||
|
#include "TaskbarState.h"
|
||||||
|
|
||||||
// fwdecl unittest classes
|
// fwdecl unittest classes
|
||||||
namespace TerminalAppLocalTests
|
namespace TerminalAppLocalTests
|
||||||
|
@ -92,6 +93,8 @@ public:
|
||||||
|
|
||||||
bool ContainsReadOnly() const;
|
bool ContainsReadOnly() const;
|
||||||
|
|
||||||
|
void CollectTaskbarStates(std::vector<winrt::TerminalApp::TaskbarState>& states);
|
||||||
|
|
||||||
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
||||||
DECLARE_EVENT(GotFocus, _GotFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
DECLARE_EVENT(GotFocus, _GotFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
||||||
DECLARE_EVENT(LostFocus, _LostFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
DECLARE_EVENT(LostFocus, _LostFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
|
||||||
|
|
45
src/cascadia/TerminalApp/TaskbarState.cpp
Normal file
45
src/cascadia/TerminalApp/TaskbarState.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "TaskbarState.h"
|
||||||
|
#include "TaskbarState.g.cpp"
|
||||||
|
|
||||||
|
namespace winrt::TerminalApp::implementation
|
||||||
|
{
|
||||||
|
// Default to unset, 0%.
|
||||||
|
TaskbarState::TaskbarState() :
|
||||||
|
TaskbarState(0, 0){};
|
||||||
|
|
||||||
|
TaskbarState::TaskbarState(const uint64_t dispatchTypesState, const uint64_t progressParam) :
|
||||||
|
_State{ dispatchTypesState },
|
||||||
|
_Progress{ progressParam } {}
|
||||||
|
|
||||||
|
uint64_t TaskbarState::Priority() const
|
||||||
|
{
|
||||||
|
// This seemingly nonsensical ordering is from
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group
|
||||||
|
switch (_State)
|
||||||
|
{
|
||||||
|
case 0: // Clear = 0,
|
||||||
|
return 5;
|
||||||
|
case 1: // Set = 1,
|
||||||
|
return 3;
|
||||||
|
case 2: // Error = 2,
|
||||||
|
return 1;
|
||||||
|
case 3: // Indeterminate = 3,
|
||||||
|
return 4;
|
||||||
|
case 4: // Paused = 4
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
// Here, return 6, to definitely be greater than all the other valid values.
|
||||||
|
// This should never really happen.
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TaskbarState::ComparePriority(const winrt::TerminalApp::TaskbarState& lhs, const winrt::TerminalApp::TaskbarState& rhs)
|
||||||
|
{
|
||||||
|
return lhs.Priority() < rhs.Priority();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
src/cascadia/TerminalApp/TaskbarState.h
Normal file
34
src/cascadia/TerminalApp/TaskbarState.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "inc/cppwinrt_utils.h"
|
||||||
|
#include "TaskbarState.g.h"
|
||||||
|
|
||||||
|
// fwdecl unittest classes
|
||||||
|
namespace TerminalAppLocalTests
|
||||||
|
{
|
||||||
|
class TabTests;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace winrt::TerminalApp::implementation
|
||||||
|
{
|
||||||
|
struct TaskbarState : TaskbarStateT<TaskbarState>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TaskbarState();
|
||||||
|
TaskbarState(const uint64_t dispatchTypesState, const uint64_t progress);
|
||||||
|
|
||||||
|
static int ComparePriority(const winrt::TerminalApp::TaskbarState& lhs, const winrt::TerminalApp::TaskbarState& rhs);
|
||||||
|
|
||||||
|
uint64_t Priority() const;
|
||||||
|
|
||||||
|
WINRT_PROPERTY(uint64_t, State, 0);
|
||||||
|
WINRT_PROPERTY(uint64_t, Progress, 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace winrt::TerminalApp::factory_implementation
|
||||||
|
{
|
||||||
|
BASIC_FACTORY(TaskbarState);
|
||||||
|
}
|
15
src/cascadia/TerminalApp/TaskbarState.idl
Normal file
15
src/cascadia/TerminalApp/TaskbarState.idl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace TerminalApp
|
||||||
|
{
|
||||||
|
[default_interface] runtimeclass TaskbarState
|
||||||
|
{
|
||||||
|
TaskbarState();
|
||||||
|
TaskbarState(UInt64 dispatchTypesState, UInt64 progress);
|
||||||
|
|
||||||
|
UInt64 State{ get; };
|
||||||
|
UInt64 Progress{ get; };
|
||||||
|
UInt64 Priority { get; };
|
||||||
|
}
|
||||||
|
}
|
|
@ -90,6 +90,9 @@
|
||||||
<DependentUpon>TabBase.idl</DependentUpon>
|
<DependentUpon>TabBase.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TabPaletteItem.h" />
|
<ClInclude Include="TabPaletteItem.h" />
|
||||||
|
<ClInclude Include="TaskbarState.h">
|
||||||
|
<DependentUpon>TaskbarState.idl</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="TerminalTab.h">
|
<ClInclude Include="TerminalTab.h">
|
||||||
<DependentUpon>TerminalTab.idl</DependentUpon>
|
<DependentUpon>TerminalTab.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -166,6 +169,9 @@
|
||||||
<DependentUpon>TabBase.idl</DependentUpon>
|
<DependentUpon>TabBase.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="TabPaletteItem.cpp" />
|
<ClCompile Include="TabPaletteItem.cpp" />
|
||||||
|
<ClCompile Include="TaskbarState.cpp">
|
||||||
|
<DependentUpon>TaskbarState.idl</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="TerminalTab.cpp">
|
<ClCompile Include="TerminalTab.cpp">
|
||||||
<DependentUpon>TerminalTab.idl</DependentUpon>
|
<DependentUpon>TerminalTab.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -258,6 +264,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<Midl Include="TabBase.idl" />
|
<Midl Include="TabBase.idl" />
|
||||||
<Midl Include="TabPaletteItem.idl" />
|
<Midl Include="TabPaletteItem.idl" />
|
||||||
|
<Midl Include="TaskbarState.idl" />
|
||||||
<Midl Include="TerminalTab.idl" />
|
<Midl Include="TerminalTab.idl" />
|
||||||
<Midl Include="TerminalPage.idl">
|
<Midl Include="TerminalPage.idl">
|
||||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||||
|
|
|
@ -2077,29 +2077,35 @@ namespace winrt::TerminalApp::implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Gets the taskbar state value from the last active control
|
// - Get the combined taskbar state for the page. This is the combination of
|
||||||
|
// all the states of all the tabs, which are themselves a combination of
|
||||||
|
// all their panes. Taskbar states are given a priority based on the rules
|
||||||
|
// in:
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate
|
||||||
|
// under "How the Taskbar Button Chooses the Progress Indicator for a Group"
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The taskbar state of the last active control
|
// - A TaskbarState object representing the combined taskbar state and
|
||||||
uint64_t TerminalPage::GetLastActiveControlTaskbarState()
|
// progress percentage of all our tabs.
|
||||||
|
winrt::TerminalApp::TaskbarState TerminalPage::TaskbarState() const
|
||||||
{
|
{
|
||||||
if (auto control{ _GetActiveControl() })
|
auto state{ winrt::make<winrt::TerminalApp::implementation::TaskbarState>() };
|
||||||
{
|
|
||||||
return control.TaskbarState();
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method Description:
|
for (const auto& tab : _tabs)
|
||||||
// - Gets the taskbar progress value from the last active control
|
|
||||||
// Return Value:
|
|
||||||
// - The taskbar progress of the last active control
|
|
||||||
uint64_t TerminalPage::GetLastActiveControlTaskbarProgress()
|
|
||||||
{
|
|
||||||
if (auto control{ _GetActiveControl() })
|
|
||||||
{
|
{
|
||||||
return control.TaskbarProgress();
|
if (auto tabImpl{ _GetTerminalTabImpl(tab) })
|
||||||
|
{
|
||||||
|
auto tabState{ tabImpl->GetCombinedTaskbarState() };
|
||||||
|
// lowest priority wins
|
||||||
|
if (tabState.Priority() < state.Priority())
|
||||||
|
{
|
||||||
|
state = tabState;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
|
|
@ -85,8 +85,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
||||||
void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter);
|
void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter);
|
||||||
|
|
||||||
uint64_t GetLastActiveControlTaskbarState();
|
winrt::TerminalApp::TaskbarState TaskbarState() const;
|
||||||
uint64_t GetLastActiveControlTaskbarProgress();
|
|
||||||
|
|
||||||
void ShowKeyboardServiceWarning();
|
void ShowKeyboardServiceWarning();
|
||||||
winrt::hstring KeyboardServiceDisabledText();
|
winrt::hstring KeyboardServiceDisabledText();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
import "TaskbarState.idl";
|
||||||
|
|
||||||
namespace TerminalApp
|
namespace TerminalApp
|
||||||
{
|
{
|
||||||
|
@ -42,8 +43,7 @@ namespace TerminalApp
|
||||||
void ShowKeyboardServiceWarning();
|
void ShowKeyboardServiceWarning();
|
||||||
String KeyboardServiceDisabledText { get; };
|
String KeyboardServiceDisabledText { get; };
|
||||||
|
|
||||||
UInt64 GetLastActiveControlTaskbarState();
|
TaskbarState TaskbarState{ get; };
|
||||||
UInt64 GetLastActiveControlTaskbarProgress();
|
|
||||||
|
|
||||||
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
|
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
|
||||||
|
|
|
@ -177,10 +177,9 @@ namespace winrt::TerminalApp::implementation
|
||||||
{
|
{
|
||||||
lastFocusedControl.Focus(_focusState);
|
lastFocusedControl.Focus(_focusState);
|
||||||
|
|
||||||
// Update our own progress state, and fire an event signaling
|
// Update our own progress state. This will fire an event signaling
|
||||||
// that our taskbar progress changed.
|
// that our taskbar progress changed.
|
||||||
_UpdateProgressState();
|
_UpdateProgressState();
|
||||||
_TaskbarProgressChangedHandlers(lastFocusedControl, nullptr);
|
|
||||||
}
|
}
|
||||||
// When we gain focus, remove the bell indicator if it is active
|
// When we gain focus, remove the bell indicator if it is active
|
||||||
if (_tabStatus.BellIndicator())
|
if (_tabStatus.BellIndicator())
|
||||||
|
@ -675,6 +674,26 @@ namespace winrt::TerminalApp::implementation
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Get the combined taskbar state for the tab. This is the combination of
|
||||||
|
// all the states of all our panes. Taskbar states are given a priority
|
||||||
|
// based on the rules in:
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate
|
||||||
|
// under "How the Taskbar Button Chooses the Progress Indicator for a
|
||||||
|
// Group"
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - A TaskbarState object representing the combined taskbar state and
|
||||||
|
// progress percentage of all our panes.
|
||||||
|
winrt::TerminalApp::TaskbarState TerminalTab::GetCombinedTaskbarState() const
|
||||||
|
{
|
||||||
|
std::vector<winrt::TerminalApp::TaskbarState> states;
|
||||||
|
_rootPane->CollectTaskbarStates(states);
|
||||||
|
return states.empty() ? winrt::make<winrt::TerminalApp::implementation::TaskbarState>() :
|
||||||
|
*std::min_element(states.begin(), states.end(), TerminalApp::implementation::TaskbarState::ComparePriority);
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - This should be called on the UI thread. If you don't, then it might
|
// - This should be called on the UI thread. If you don't, then it might
|
||||||
// silently do nothing.
|
// silently do nothing.
|
||||||
|
@ -690,37 +709,39 @@ namespace winrt::TerminalApp::implementation
|
||||||
// - <none>
|
// - <none>
|
||||||
void TerminalTab::_UpdateProgressState()
|
void TerminalTab::_UpdateProgressState()
|
||||||
{
|
{
|
||||||
if (const auto& activeControl{ GetActiveTerminalControl() })
|
const auto state{ GetCombinedTaskbarState() };
|
||||||
{
|
|
||||||
const auto taskbarState = activeControl.TaskbarState();
|
|
||||||
// The progress of the control changed, but not necessarily the progress of the tab.
|
|
||||||
// Set the tab's progress ring to the active pane's progress
|
|
||||||
if (taskbarState > 0)
|
|
||||||
{
|
|
||||||
if (taskbarState == 3)
|
|
||||||
{
|
|
||||||
// 3 is the indeterminate state, set the progress ring as such
|
|
||||||
_tabStatus.IsProgressRingIndeterminate(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// any non-indeterminate state has a value, set the progress ring as such
|
|
||||||
_tabStatus.IsProgressRingIndeterminate(false);
|
|
||||||
|
|
||||||
const auto progressValue = gsl::narrow<uint32_t>(activeControl.TaskbarProgress());
|
const auto taskbarState = state.State();
|
||||||
_tabStatus.ProgressValue(progressValue);
|
// The progress of the control changed, but not necessarily the progress of the tab.
|
||||||
}
|
// Set the tab's progress ring to the active pane's progress
|
||||||
// Hide the tab icon (the progress ring is placed over it)
|
if (taskbarState > 0)
|
||||||
HideIcon(true);
|
{
|
||||||
_tabStatus.IsProgressRingActive(true);
|
if (taskbarState == 3)
|
||||||
|
{
|
||||||
|
// 3 is the indeterminate state, set the progress ring as such
|
||||||
|
_tabStatus.IsProgressRingIndeterminate(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Show the tab icon
|
// any non-indeterminate state has a value, set the progress ring as such
|
||||||
HideIcon(false);
|
_tabStatus.IsProgressRingIndeterminate(false);
|
||||||
_tabStatus.IsProgressRingActive(false);
|
|
||||||
|
const auto progressValue = gsl::narrow<uint32_t>(state.Progress());
|
||||||
|
_tabStatus.ProgressValue(progressValue);
|
||||||
}
|
}
|
||||||
|
// Hide the tab icon (the progress ring is placed over it)
|
||||||
|
HideIcon(true);
|
||||||
|
_tabStatus.IsProgressRingActive(true);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Show the tab icon
|
||||||
|
HideIcon(false);
|
||||||
|
_tabStatus.IsProgressRingActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire an event signaling that our taskbar progress changed.
|
||||||
|
_TaskbarProgressChangedHandlers(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
|
|
@ -83,6 +83,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
|
|
||||||
void TogglePaneReadOnly();
|
void TogglePaneReadOnly();
|
||||||
std::shared_ptr<Pane> GetActivePane() const;
|
std::shared_ptr<Pane> GetActivePane() const;
|
||||||
|
winrt::TerminalApp::TaskbarState GetCombinedTaskbarState() const;
|
||||||
|
|
||||||
winrt::TerminalApp::TerminalTabStatus TabStatus()
|
winrt::TerminalApp::TerminalTabStatus TabStatus()
|
||||||
{
|
{
|
||||||
|
|
|
@ -126,13 +126,14 @@ bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, cons
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - sender: not used
|
// - sender: not used
|
||||||
// - args: not used
|
// - args: not used
|
||||||
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*/)
|
||||||
{
|
{
|
||||||
if (_logic)
|
if (_logic)
|
||||||
{
|
{
|
||||||
const auto state = gsl::narrow_cast<size_t>(_logic.GetLastActiveControlTaskbarState());
|
const auto state = _logic.TaskbarState();
|
||||||
const auto progress = gsl::narrow_cast<size_t>(_logic.GetLastActiveControlTaskbarProgress());
|
_window->SetTaskbarProgress(gsl::narrow_cast<size_t>(state.State()),
|
||||||
_window->SetTaskbarProgress(state, progress);
|
gsl::narrow_cast<size_t>(state.Progress()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -776,7 +776,12 @@ void IslandWindow::SetTaskbarProgress(const size_t state, const size_t progress)
|
||||||
_taskbar->SetProgressValue(_window.get(), progress, 100);
|
_taskbar->SetProgressValue(_window.get(), progress, 100);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// sets the progress indicator to an indeterminate state
|
// sets the progress indicator to an indeterminate state.
|
||||||
|
// FIRST, set the progress to "no progress". That'll clear out any
|
||||||
|
// progress value from the previous state. Otherwise, a transition
|
||||||
|
// from (error,x%) or (warning,x%) to indeterminate will leave the
|
||||||
|
// progress value unchanged, and not show the spinner.
|
||||||
|
_taskbar->SetProgressState(_window.get(), TBPF_NOPROGRESS);
|
||||||
_taskbar->SetProgressState(_window.get(), TBPF_INDETERMINATE);
|
_taskbar->SetProgressState(_window.get(), TBPF_INDETERMINATE);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
|
Loading…
Reference in a new issue