Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a setting to auto focus an error pane #8145

Closed
wants to merge 25 commits into from
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
af9e4d5
osc 9;4 implementation
PankajBhojwani Oct 27, 2020
606490f
spelling
PankajBhojwani Oct 27, 2020
0decbea
Merge branch 'main' of https://github.com/microsoft/terminal into dev…
PankajBhojwani Oct 27, 2020
4e6f6fe
address comments
PankajBhojwani Oct 27, 2020
da83748
add paused state
PankajBhojwani Oct 27, 2020
3d0ed84
use last focused tab's progress and state
PankajBhojwani Oct 27, 2020
f08c962
use split string
PankajBhojwani Oct 28, 2020
5f83dfd
use sender instead of args, some name changes
PankajBhojwani Oct 28, 2020
ab99ed5
remove all references to SetTaskbarProgressEventArgs, validation for …
PankajBhojwani Oct 29, 2020
4125052
tests
PankajBhojwani Oct 29, 2020
a900678
conflict with main
PankajBhojwani Oct 29, 2020
0aa5667
get the taskbar state and progress from the last active control
PankajBhojwani Oct 29, 2020
e69d0af
addressing comments, cleanups
PankajBhojwani Oct 30, 2020
57d8e07
com ptr
PankajBhojwani Oct 30, 2020
e8343cd
setting for focusing the error pane
PankajBhojwani Nov 3, 2020
5f02710
control emits event when it wants to be focused, pane catches it and …
PankajBhojwani Nov 4, 2020
c1c13fd
conflict
PankajBhojwani Nov 4, 2020
0e936da
merging main etc
PankajBhojwani Nov 4, 2020
5d724bc
merging main, fixing conflicts
PankajBhojwani Nov 4, 2020
4ab32ec
send event when tab changes
PankajBhojwani Nov 4, 2020
5aff81a
check if control exists before using it
PankajBhojwani Nov 4, 2020
fd935fa
propagating changes from base branch
PankajBhojwani Nov 4, 2020
48bea49
actually focus the control that sends the error state
PankajBhojwani Nov 5, 2020
b89a755
add comments
PankajBhojwani Nov 5, 2020
72dd094
Merge branch 'dev/pabhoj/taskbar_progress' of https://github.com/micr…
PankajBhojwani Nov 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actions/spell-check/dictionary/apis.txt
Original file line number Diff line number Diff line change
@@ -31,6 +31,8 @@ IInheritable
IMap
IObject
IStorage
ITaskbar
llabs
LCID
llabs
lround
@@ -39,6 +41,7 @@ NCHITTEST
NCLBUTTONDBLCLK
NCRBUTTONDBLCLK
NOAGGREGATION
NOPROGRESS
NOREDIRECTIONBITMAP
oaidl
ocidl
@@ -58,6 +61,7 @@ sregex
STDCPP
strchr
syscall
TBPF
THEMECHANGED
tmp
tx
42 changes: 42 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.cpp
Original file line number Diff line number Diff line change
@@ -633,6 +633,22 @@ namespace winrt::TerminalApp::implementation
return _root->CalcSnappedDimension(widthOrHeight, dimension);
}

// Method Description:
// - Gets the user's setting for whether the control that sent an error state
// should be automatically focused
// Return Value:
// - The value of the "autoFocusErrorPane" setting
bool AppLogic::GetAutoFocusErrorPane()
{
if (!_loadedInitialSettings)
{
// Load settings if we haven't already
LoadSettings();
}

return _settings.GlobalSettings().AutoFocusErrorPane();
}

// Method Description:
// - Attempt to load the settings. If we fail for any reason, returns an error.
// Return Value:
@@ -1001,6 +1017,32 @@ 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)
{
return _root->GetLastActiveControlTaskbarState();
}
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)
{
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
5 changes: 5 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.h
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ namespace winrt::TerminalApp::implementation
bool GetShowTabsInTitlebar();
bool GetInitialAlwaysOnTop();
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
bool GetAutoFocusErrorPane();

Windows::UI::Xaml::UIElement GetRoot() noexcept;

@@ -50,6 +51,9 @@ namespace winrt::TerminalApp::implementation

void WindowCloseButtonClicked();

size_t GetLastActiveControlTaskbarState();
size_t GetLastActiveControlTaskbarProgress();

winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);

// -------------------------------- WinRT Events ---------------------------------
@@ -108,6 +112,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::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
};
}

5 changes: 5 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.idl
Original file line number Diff line number Diff line change
@@ -51,6 +51,10 @@ namespace TerminalApp
Single CalcSnappedDimension(Boolean widthOrHeight, Single dimension);
void TitlebarClicked();
void WindowCloseButtonClicked();
Boolean GetAutoFocusErrorPane();

UInt64 GetLastActiveControlTaskbarState();
UInt64 GetLastActiveControlTaskbarProgress();

// See IDialogPresenter and TerminalPage's DialogPresenter for more
// information.
@@ -63,5 +67,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FullscreenChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> AlwaysOnTopChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
}
}
20 changes: 20 additions & 0 deletions src/cascadia/TerminalApp/Pane.cpp
Original file line number Diff line number Diff line change
@@ -45,6 +45,7 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus

_connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler });
_warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler });
_controlWantsFocusToken = _control.ControlWantsFocus({ this, &Pane::_ControlWantsFocusHandler });

// On the first Pane's creation, lookup resources we'll use to theme the
// Pane, including the brushed to use for the focused/unfocused border
@@ -388,6 +389,18 @@ void Pane::_ControlGotFocusHandler(winrt::Windows::Foundation::IInspectable cons
_GotFocusHandlers(shared_from_this());
}

// Event Description:
// - Called when our control requests focus. We'll use this to trigger our PaneWantsFocus callback,
// the tab that's hosting us should have registered a callback which will mark this pane as
// active and tell TerminalPage to focus that tab
// Arguments:
// - <unused>
void Pane::_ControlWantsFocusHandler(winrt::Windows::Foundation::IInspectable const& /*sender*/,
winrt::Windows::Foundation::IInspectable const& /*e*/)
{
_PaneWantsFocusHandlers(shared_from_this());
}

// Method Description:
// - Fire our Closed event to tell our parent that we should be removed.
// Arguments:
@@ -655,6 +668,7 @@ void Pane::_CloseChild(const bool closeFirst)
// Add our new event handler before revoking the old one.
_connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler });
_warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler });
_controlWantsFocusToken = _control.ControlWantsFocus({ this, &Pane::_ControlWantsFocusHandler });

// Revoke the old event handlers. Remove both the handlers for the panes
// themselves closing, and remove their handlers for their controls
@@ -666,6 +680,8 @@ void Pane::_CloseChild(const bool closeFirst)
remainingChild->_control.ConnectionStateChanged(remainingChild->_connectionStateChangedToken);
closedChild->_control.WarningBell(closedChild->_warningBellToken);
remainingChild->_control.WarningBell(remainingChild->_warningBellToken);
closedChild->_control.ControlWantsFocus(closedChild->_controlWantsFocusToken);
remainingChild->_control.ControlWantsFocus(remainingChild->_controlWantsFocusToken);

// If either of our children was focused, we want to take that focus from
// them.
@@ -757,6 +773,7 @@ void Pane::_CloseChild(const bool closeFirst)
oldSecond->Closed(oldSecondToken);
closedChild->_control.ConnectionStateChanged(closedChild->_connectionStateChangedToken);
closedChild->_control.WarningBell(closedChild->_warningBellToken);
closedChild->_control.ControlWantsFocus(closedChild->_controlWantsFocusToken);

// Reset our UI:
_root.Children().Clear();
@@ -1459,6 +1476,8 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitState
_connectionStateChangedToken.value = 0;
_control.WarningBell(_warningBellToken);
_warningBellToken.value = 0;
_control.ControlWantsFocus(_controlWantsFocusToken);
_controlWantsFocusToken.value = 0;

// Remove our old GotFocus handler from the control. We don't what the
// control telling us that it's now focused, we want it telling its new
@@ -2069,3 +2088,4 @@ std::optional<SplitState> Pane::PreCalculateAutoSplit(const std::shared_ptr<Pane
}

DEFINE_EVENT(Pane, GotFocus, _GotFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
DEFINE_EVENT(Pane, PaneWantsFocus, _PaneWantsFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/Pane.h
Original file line number Diff line number Diff line change
@@ -77,6 +77,7 @@ class Pane : public std::enable_shared_from_this<Pane>

WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
DECLARE_EVENT(GotFocus, _GotFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
DECLARE_EVENT(PaneWantsFocus, _PaneWantsFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);

private:
struct SnapSizeResult;
@@ -100,6 +101,7 @@ class Pane : public std::enable_shared_from_this<Pane>
winrt::event_token _firstClosedToken{ 0 };
winrt::event_token _secondClosedToken{ 0 };
winrt::event_token _warningBellToken{ 0 };
winrt::event_token _controlWantsFocusToken{ 0 };

winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;

@@ -135,6 +137,8 @@ class Pane : public std::enable_shared_from_this<Pane>
winrt::Windows::Foundation::IInspectable const& e);
void _ControlGotFocusHandler(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void _ControlWantsFocusHandler(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::Foundation::IInspectable const& e);

std::pair<float, float> _CalcChildrenSizes(const float fullSize) const;
SnapChildrenSizeResult _CalcSnappedChildrenSizes(const bool widthOrHeight, const float fullSize) const;
54 changes: 54 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
@@ -701,6 +701,20 @@ namespace winrt::TerminalApp::implementation
}
});

// When the tab wants focus, we check if its not already focused and focus it
// if so
newTabImpl->TabWantsFocus([weakTab, weakThis{ get_weak() }]() {
auto page{ weakThis.get() };
auto tab{ weakTab.get() };

if (page && tab && tab->FocusState() == Windows::UI::Xaml::FocusState::Unfocused)
{
page->_tabView.SelectedItem(tab->TabViewItem());
const auto idx = tab->TabViewIndex();
page->_UpdatedSelectedTab(idx);
}
});

auto tabViewItem = newTabImpl->TabViewItem();
_tabView.TabItems().Append(tabViewItem);
_ReapplyCompactTabSize();
@@ -1118,6 +1132,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);

@@ -1882,6 +1899,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 IInspectable /*eventArgs*/)
{
_setTaskbarProgressHandlers(sender, nullptr);
}

// Method Description:
// - Paste text from the Windows Clipboard to the focused terminal
void TerminalPage::_PasteText()
@@ -2263,6 +2290,32 @@ 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()
{
if (auto control{ _GetActiveControl() })
{
return control.GetTaskbarState();
}
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()
{
if (auto control{ _GetActiveControl() })
{
return control.GetTaskbarProgress();
}
return {};
}

// Method Description:
// - This is the method that App will call when the titlebar
// has been clicked. It dismisses any open flyouts.
@@ -2712,4 +2765,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::Windows::Foundation::IInspectable);
}
6 changes: 6 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
@@ -71,13 +71,17 @@ 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);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTitleBarContent, _setTitleBarContentHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement);
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::Windows::Foundation::IInspectable);
TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs);

private:
@@ -191,6 +195,8 @@ namespace winrt::TerminalApp::implementation
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
bool _CopyText(const bool singleLine, const Windows::Foundation::IReference<Microsoft::Terminal::TerminalControl::CopyFormat>& formats);

void _SetTaskbarProgressHandler(const IInspectable sender, const IInspectable eventArgs);

void _PasteText();

fire_and_forget _LaunchSettings(const Microsoft::Terminal::Settings::Model::SettingsTarget target);
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.idl
Original file line number Diff line number Diff line change
@@ -27,12 +27,16 @@ namespace TerminalApp
// and because of GH#5224.
IDialogPresenter DialogPresenter;

UInt64 GetLastActiveControlTaskbarState();
UInt64 GetLastActiveControlTaskbarProgress();

event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FullscreenChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> AlwaysOnTopChanged;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.RoutedEventArgs> Initialized;
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
}
}
18 changes: 18 additions & 0 deletions src/cascadia/TerminalApp/TerminalTab.cpp
Original file line number Diff line number Diff line change
@@ -105,6 +105,7 @@ namespace winrt::TerminalApp::implementation
if (lastFocusedControl)
{
lastFocusedControl.Focus(_focusState);
lastFocusedControl.TaskbarProgressChanged();
}
}
}
@@ -482,6 +483,22 @@ namespace winrt::TerminalApp::implementation
}
}
});

// Add a PaneWantsFocus event handler to the pane. If the pane wants focus,
// we mark it as the active one in this tab's pane tree and inform TerminalPage
// to focus this tab.
pane->PaneWantsFocus([weakThis](std::shared_ptr<Pane> sender) {
// Do nothing if the Tab's lifetime is expired
auto tab{ weakThis.get() };

if (tab)
{
tab->_UpdateActivePane(sender);
tab->_RecalculateAndApplyTabColor();
tab->_TabWantsFocusHandlers();
}

});
}

// Method Description:
@@ -1019,4 +1036,5 @@ namespace winrt::TerminalApp::implementation
DEFINE_EVENT(TerminalTab, ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
DEFINE_EVENT(TerminalTab, ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
DEFINE_EVENT(TerminalTab, ColorCleared, _colorCleared, winrt::delegate<>);
DEFINE_EVENT(TerminalTab, TabWantsFocus, _TabWantsFocusHandlers, winrt::delegate<>);
}
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/TerminalTab.h
Original file line number Diff line number Diff line change
@@ -69,6 +69,7 @@ namespace winrt::TerminalApp::implementation
DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
DECLARE_EVENT(ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
DECLARE_EVENT(ColorCleared, _colorCleared, winrt::delegate<>);
DECLARE_EVENT(TabWantsFocus, _TabWantsFocusHandlers, winrt::delegate<>);

private:
std::shared_ptr<Pane> _rootPane{ nullptr };
Loading