diff --git a/src/cascadia/TerminalApp/App.cpp b/src/cascadia/TerminalApp/App.cpp index 4a61d60fbe6..d03ecd42cda 100644 --- a/src/cascadia/TerminalApp/App.cpp +++ b/src/cascadia/TerminalApp/App.cpp @@ -582,6 +582,22 @@ namespace winrt::TerminalApp::implementation } } + // Method Description: + // - Used to tell the app that the 'X' button has been clicked and + // the user wants to close the app. We kick off the close warning + // experience. + // Arguments: + // - + // Return Value: + // - + void App::WindowCloseButtonClicked() + { + if (_root) + { + _root->CloseWindow(); + } + } + // Methods that proxy typed event handlers through TerminalPage winrt::event_token App::SetTitleBarContent(Windows::Foundation::TypedEventHandler const& handler) { diff --git a/src/cascadia/TerminalApp/App.h b/src/cascadia/TerminalApp/App.h index 1973fe5de73..f977fb7c3f9 100644 --- a/src/cascadia/TerminalApp/App.h +++ b/src/cascadia/TerminalApp/App.h @@ -38,6 +38,8 @@ namespace winrt::TerminalApp::implementation hstring Title(); void TitlebarClicked(); + void WindowCloseButtonClicked(); + // -------------------------------- 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/App.idl b/src/cascadia/TerminalApp/App.idl index 9e8981b1d33..662d23caff5 100644 --- a/src/cascadia/TerminalApp/App.idl +++ b/src/cascadia/TerminalApp/App.idl @@ -26,6 +26,7 @@ namespace TerminalApp Windows.Foundation.Point GetLaunchDimensions(UInt32 dpi); Boolean GetShowTabsInTitlebar(); void TitlebarClicked(); + void WindowCloseButtonClicked(); event Windows.Foundation.TypedEventHandler SetTitleBarContent; event Windows.Foundation.TypedEventHandler TitleChanged; diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 7a877b48872..333de0e2d37 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -63,7 +63,7 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_HandleCloseWindow(const IInspectable& /*sender*/, const TerminalApp::ActionEventArgs& args) { - _CloseWindow(); + CloseWindow(); args.Handled(true); } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 0b8f2a467dd..4dcfa7251e6 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -823,9 +823,9 @@ namespace winrt::TerminalApp::implementation } // Method Description: - // - Close the terminal app with keys. If there is more + // - Close the terminal app. If there is more // than one tab opened, show a warning dialog. - void TerminalPage::_CloseWindow() + void TerminalPage::CloseWindow() { if (_tabs.size() > 1) { diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index dd7f735ac09..c76eb2227a7 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -36,6 +36,8 @@ namespace winrt::TerminalApp::implementation void TitlebarClicked(); + void CloseWindow(); + // -------------------------------- 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); @@ -94,7 +96,6 @@ namespace winrt::TerminalApp::implementation void _SetFocusedTabIndex(int tabIndex); void _CloseFocusedTab(); void _CloseFocusedPane(); - void _CloseWindow(); void _CloseAllTabs(); // Todo: add more event implementations here diff --git a/src/cascadia/TerminalApp/TitlebarControl.cpp b/src/cascadia/TerminalApp/TitlebarControl.cpp index 0207705d81d..01369fc5028 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.cpp +++ b/src/cascadia/TerminalApp/TitlebarControl.cpp @@ -87,7 +87,7 @@ namespace winrt::TerminalApp::implementation void TitlebarControl::Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e) { - ::PostQuitMessage(0); + ::PostMessage(_window, WM_SYSCOMMAND, SC_CLOSE, 0); } void TitlebarControl::SetWindowVisualState(WindowVisualState visualState) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 78ef79f34e5..b055981538b 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -70,6 +70,10 @@ void AppHost::Initialize() _app.SetTitleBarContent({ this, &AppHost::_UpdateTitleBarContent }); } + // Register the 'X' button of the window for a warning experience of multiple + // tabs opened, this is consistent with Alt+F4 closing + _window->WindowCloseButtonClicked([this]() { _app.WindowCloseButtonClicked(); }); + // Add an event handler to plumb clicks in the titlebar area down to the // application layer. _window->DragRegionClicked([this]() { _app.TitlebarClicked(); }); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index ff560a55401..185dc259794 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -198,6 +198,14 @@ void IslandWindow::OnSize(const UINT width, const UINT height) // key that does not correspond to any mnemonic or accelerator key, return MAKELRESULT(0, MNC_CLOSE); } + case WM_CLOSE: + { + // If the user wants to close the app by clicking 'X' button, + // we hand off the close experience to the app layer. If all the tabs + // are closed, the window will be closed as well. + _windowCloseButtonClickedHandler(); + return 0; + } } // TODO: handle messages here... @@ -285,3 +293,4 @@ void IslandWindow::UpdateTheme(const winrt::Windows::UI::Xaml::ElementTheme& req } DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); +DEFINE_EVENT(IslandWindow, WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 98eb76db35b..3ff460f55a6 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -68,6 +68,7 @@ class IslandWindow : #pragma endregion DECLARE_EVENT(DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); + DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); protected: void ForceResize()