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

When the titlebar is clicked, dismiss the new tab flyout #2438

Merged
2 commits merged into from
Aug 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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