Skip to content

Commit

Permalink
When the titlebar is clicked, dismiss the new tab flyout (#2438)
Browse files Browse the repository at this point in the history
* When the titlebar is clicked, dismiss the new tab flyout

  Fixes #2028.

* Fix this for the base IslandWindow as well
  • Loading branch information
zadjii-msft authored and msftbot[bot] committed Aug 16, 2019
1 parent fca0cd9 commit 24ea086
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 10 deletions.
17 changes: 17 additions & 0 deletions src/cascadia/TerminalApp/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,23 @@ namespace winrt::TerminalApp::implementation
return connection;
}

// Method Description:
// - Used to tell the app that the titlebar has been clicked. The App won't
// actually recieve any clicks in the titlebar area, so this is a helper
// to clue the app in that a click has happened. The App will use this as
// a indicator that it needs to dismiss any open flyouts.
// Arguments:
// - <none>
// Return Value:
// - <none>
void App::TitlebarClicked()
{
if (_newTabButton && _newTabButton.Flyout())
{
_newTabButton.Flyout().Hide();
}
}

// -------------------------------- 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.
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace winrt::TerminalApp::implementation
~App() = default;

hstring GetTitle();
void TitlebarClicked();

// -------------------------------- WinRT Events ---------------------------------
DECLARE_EVENT(TitleChanged, _titleChangeHandlers, winrt::Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/App.idl
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<App, Windows.UI.Xaml.ElementTheme> RequestedThemeChanged;

String GetTitle();

void TitlebarClicked();
}
}
5 changes: 5 additions & 0 deletions src/cascadia/WindowsTerminal/AppHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ void AppHost::Initialize()
// content in Create.
_app.SetTitleBarContent({ this, &AppHost::_UpdateTitleBarContent });
}

// Add an event handler to plumb clicks in the titlebar area down to the
// application layer.
_window->DragRegionClicked([this]() { _app.TitlebarClicked(); });

_app.RequestedThemeChanged({ this, &AppHost::_UpdateTheme });

_app.Create();
Expand Down
17 changes: 17 additions & 0 deletions src/cascadia/WindowsTerminal/IslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,21 @@ void IslandWindow::OnSize(const UINT width, const UINT height)
return 0; // eat the message
}
}

case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONUP:
case WM_NCMBUTTONDOWN:
case WM_NCMBUTTONUP:
case WM_NCRBUTTONDOWN:
case WM_NCRBUTTONUP:
case WM_NCXBUTTONDOWN:
case WM_NCXBUTTONUP:
{
// If we clicked in the titlebar, raise an event so the app host can
// dispatch an appropriate event.
_DragRegionClickedHandlers();
break;
}
case WM_MENUCHAR:
{
// GH#891: return this LRESULT here to prevent the app from making a
Expand Down Expand Up @@ -258,3 +273,5 @@ void IslandWindow::UpdateTheme(const winrt::Windows::UI::Xaml::ElementTheme& req
// drawing ourselves to match the new theme
::InvalidateRect(_window.get(), nullptr, false);
}

DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>);
3 changes: 3 additions & 0 deletions src/cascadia/WindowsTerminal/IslandWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "WindowUiaProvider.hpp"
#include <winrt/Microsoft.Terminal.TerminalControl.h>
#include <winrt/TerminalApp.h>
#include "../../cascadia/inc/cppwinrt_utils.h"

class IslandWindow :
public BaseWindow<IslandWindow>,
Expand Down Expand Up @@ -66,6 +67,8 @@ class IslandWindow :

#pragma endregion

DECLARE_EVENT(DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>);

protected:
void ForceResize()
{
Expand Down
29 changes: 21 additions & 8 deletions src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,22 @@ void NonClientIslandWindow::_UpdateDragRegion()
// - Hit test the frame for resizing and moving.
// Arguments:
// - ptMouse: the mouse point being tested, in absolute (NOT WINDOW) coordinates.
// - titlebarIsCaption: If true, we want to treat the titlebar area as
// HTCAPTION, otherwise we'll return HTNOWHERE for the titlebar.
// Return Value:
// - one of the values from
// https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-nchittest#return-value
// corresponding to the area of the window that was hit
// NOTE:
// Largely taken from code on:
// - Largely taken from code on:
// https://docs.microsoft.com/en-us/windows/desktop/dwm/customframe
[[nodiscard]] LRESULT NonClientIslandWindow::HitTestNCA(POINT ptMouse) const noexcept
// NOTE[2]: Concerning `titlebarIsCaption`
// - We want HTNOWHERE as the return value for WM_NCHITTEST, so that we can get
// mouse presses in the titlebar area. If we return HTCAPTION there, we won't
// get any mouse WMs. However, when we're handling the mouse events, we need
// to know if the mouse was in that are or not, so we'll return HTCAPTION in
// that handler, to differentiate from the rest of the window.
[[nodiscard]] LRESULT NonClientIslandWindow::HitTestNCA(POINT ptMouse, const bool titlebarIsCaption) const noexcept
{
// Get the window rectangle.
RECT rcWindow = BaseWindow::GetWindowRect();
Expand Down Expand Up @@ -311,10 +319,11 @@ void NonClientIslandWindow::_UpdateDragRegion()

// clang-format off
// Hit test (HTTOPLEFT, ... HTBOTTOMRIGHT)
const auto topHt = fOnResizeBorder ? HTTOP : (titlebarIsCaption ? HTCAPTION : HTNOWHERE);
LRESULT hitTests[3][3] = {
{ HTTOPLEFT, fOnResizeBorder ? HTTOP : HTCAPTION, HTTOPRIGHT },
{ HTLEFT, HTNOWHERE, HTRIGHT },
{ HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT },
{ HTTOPLEFT, topHt, HTTOPRIGHT },
{ HTLEFT, HTNOWHERE, HTRIGHT },
{ HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT },
};
// clang-format on

Expand Down Expand Up @@ -511,8 +520,7 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
// Handle hit testing in the NCA if not handled by DwmDefWindowProc.
if (lRet == 0)
{
lRet = HitTestNCA({ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) });

lRet = HitTestNCA({ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }, false);
if (lRet != HTNOWHERE)
{
return lRet;
Expand Down Expand Up @@ -594,9 +602,14 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
{
POINT point1 = {};
::GetCursorPos(&point1);
const auto region = HitTestNCA(point1);

const auto region = HitTestNCA(point1, true);
if (region == HTCAPTION)
{
// If we clicked in the titlebar, raise an event so the app host can
// dispatch an appropriate event.
_DragRegionClickedHandlers();

const auto longParam = MAKELPARAM(point1.x, point1.y);
::SetActiveWindow(_window.get());
::PostMessage(_window.get(), WM_SYSCOMMAND, SC_MOVE | HTCAPTION, longParam);
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/WindowsTerminal/NonClientIslandWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class NonClientIslandWindow : public IslandWindow

RECT GetDragAreaRect() const noexcept;

[[nodiscard]] LRESULT HitTestNCA(POINT ptMouse) const noexcept;
[[nodiscard]] LRESULT HitTestNCA(POINT ptMouse, const bool titlebarIsCaption) const noexcept;

[[nodiscard]] HRESULT _UpdateFrameMargins() const noexcept;

Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/inc/cppwinrt_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public: \
winrt::event_token name(args const& handler); \
void name(winrt::event_token const& token) noexcept; \
\
private: \
protected: \
winrt::event<args> eventHandler;

// This is a helper macro for defining the body of events.
Expand Down

0 comments on commit 24ea086

Please sign in to comment.