@@ -15,6 +15,7 @@ using namespace winrt;
15
15
using namespace winrt ::Windows::UI::Xaml;
16
16
using namespace winrt ::Windows::UI::Core;
17
17
using namespace winrt ::Microsoft::Terminal::Control;
18
+ using namespace winrt ::Microsoft::Terminal::TerminalConnection;
18
19
using namespace winrt ::Microsoft::Terminal::Settings::Model;
19
20
using namespace winrt ::Microsoft::UI::Xaml::Controls;
20
21
using namespace winrt ::Windows::System;
@@ -35,6 +36,7 @@ namespace winrt::TerminalApp::implementation
35
36
_activePane = nullptr ;
36
37
37
38
_closePaneMenuItem.Visibility (WUX::Visibility::Collapsed);
39
+ _restartConnectionMenuItem.Visibility (WUX::Visibility::Collapsed);
38
40
39
41
auto firstId = _nextPaneId;
40
42
@@ -890,6 +892,7 @@ namespace winrt::TerminalApp::implementation
890
892
control.TitleChanged (events.titleToken );
891
893
control.TabColorChanged (events.colorToken );
892
894
control.SetTaskbarProgress (events.taskbarToken );
895
+ control.ConnectionStateChanged (events.stateToken );
893
896
control.ReadOnlyChanged (events.readOnlyToken );
894
897
control.FocusFollowMouseRequested (events.focusToken );
895
898
@@ -949,6 +952,14 @@ namespace winrt::TerminalApp::implementation
949
952
}
950
953
});
951
954
955
+ events.stateToken = control.ConnectionStateChanged ([dispatcher, weakThis](auto &&, auto &&) -> winrt::fire_and_forget {
956
+ co_await wil::resume_foreground (dispatcher);
957
+ if (auto tab{ weakThis.get () })
958
+ {
959
+ tab->_UpdateConnectionClosedState ();
960
+ }
961
+ });
962
+
952
963
events.readOnlyToken = control.ReadOnlyChanged ([dispatcher, weakThis](auto &&, auto &&) -> winrt::fire_and_forget {
953
964
co_await wil::resume_foreground (dispatcher);
954
965
if (auto tab{ weakThis.get () })
@@ -1054,6 +1065,40 @@ namespace winrt::TerminalApp::implementation
1054
1065
_TaskbarProgressChangedHandlers (nullptr , nullptr );
1055
1066
}
1056
1067
1068
+ // Method Description:
1069
+ // - Set an indicator on the tab if any pane is in a closed connection state.
1070
+ // - Show/hide the Restart Connection context menu entry depending on active pane's state.
1071
+ // Arguments:
1072
+ // - <none>
1073
+ // Return Value:
1074
+ // - <none>
1075
+ void TerminalTab::_UpdateConnectionClosedState ()
1076
+ {
1077
+ ASSERT_UI_THREAD ();
1078
+
1079
+ if (_rootPane)
1080
+ {
1081
+ const bool isClosed = _rootPane->WalkTree ([&](const auto & p) {
1082
+ return p->IsConnectionClosed ();
1083
+ });
1084
+
1085
+ _tabStatus.IsConnectionClosed (isClosed);
1086
+ }
1087
+
1088
+ if (_activePane)
1089
+ {
1090
+ _restartConnectionMenuItem.Visibility (_activePane->IsConnectionClosed () ?
1091
+ WUX::Visibility::Visible :
1092
+ WUX::Visibility::Collapsed);
1093
+ }
1094
+ }
1095
+
1096
+ void TerminalTab::_RestartActivePaneConnection ()
1097
+ {
1098
+ ActionAndArgs restartConnection{ ShortcutAction::RestartConnection, nullptr };
1099
+ _dispatch.DoAction (*this , restartConnection);
1100
+ }
1101
+
1057
1102
// Method Description:
1058
1103
// - Mark the given pane as the active pane in this tab. All other panes
1059
1104
// will be marked as inactive. We'll also update our own UI state to
@@ -1072,6 +1117,7 @@ namespace winrt::TerminalApp::implementation
1072
1117
// Update our own title text to match the newly-active pane.
1073
1118
UpdateTitle ();
1074
1119
_UpdateProgressState ();
1120
+ _UpdateConnectionClosedState ();
1075
1121
1076
1122
// We need to move the pane to the top of our mru list
1077
1123
// If its already somewhere in the list, remove it first
@@ -1393,6 +1439,28 @@ namespace winrt::TerminalApp::implementation
1393
1439
Automation::AutomationProperties::SetHelpText (findMenuItem, findToolTip);
1394
1440
}
1395
1441
1442
+ Controls::MenuFlyoutItem restartConnectionMenuItem = _restartConnectionMenuItem;
1443
+ {
1444
+ // "Restart Connection"
1445
+ Controls::FontIcon restartConnectionSymbol;
1446
+ restartConnectionSymbol.FontFamily (Media::FontFamily{ L" Segoe Fluent Icons, Segoe MDL2 Assets" });
1447
+ restartConnectionSymbol.Glyph (L" \xE72C " );
1448
+
1449
+ restartConnectionMenuItem.Click ([weakThis](auto &&, auto &&) {
1450
+ if (auto tab{ weakThis.get () })
1451
+ {
1452
+ tab->_RestartActivePaneConnection ();
1453
+ }
1454
+ });
1455
+ restartConnectionMenuItem.Text (RS_ (L" RestartConnectionText" ));
1456
+ restartConnectionMenuItem.Icon (restartConnectionSymbol);
1457
+
1458
+ const auto restartConnectionToolTip = RS_ (L" RestartConnectionToolTip" );
1459
+
1460
+ WUX::Controls::ToolTipService::SetToolTip (restartConnectionMenuItem, box_value (restartConnectionToolTip));
1461
+ Automation::AutomationProperties::SetHelpText (restartConnectionMenuItem, restartConnectionToolTip);
1462
+ }
1463
+
1396
1464
// Build the menu
1397
1465
Controls::MenuFlyout contextMenuFlyout;
1398
1466
Controls::MenuFlyoutSeparator menuSeparator;
@@ -1403,6 +1471,7 @@ namespace winrt::TerminalApp::implementation
1403
1471
contextMenuFlyout.Items ().Append (moveTabToNewWindowMenuItem);
1404
1472
contextMenuFlyout.Items ().Append (exportTabMenuItem);
1405
1473
contextMenuFlyout.Items ().Append (findMenuItem);
1474
+ contextMenuFlyout.Items ().Append (restartConnectionMenuItem);
1406
1475
contextMenuFlyout.Items ().Append (menuSeparator);
1407
1476
1408
1477
// GH#5750 - When the context menu is dismissed with ESC, toss the focus
0 commit comments