2019-05-03 00:29:04 +02:00
|
|
|
/********************************************************
|
|
|
|
* *
|
|
|
|
* Copyright (C) Microsoft. All rights reserved. *
|
|
|
|
* *
|
|
|
|
********************************************************/
|
|
|
|
#include "pch.h"
|
|
|
|
#include "NonClientIslandWindow.h"
|
2019-11-05 00:45:40 +01:00
|
|
|
#include "../types/inc/utils.hpp"
|
2020-03-05 22:28:55 +01:00
|
|
|
#include "TerminalThemeHelpers.h"
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
using namespace winrt::Windows::UI;
|
|
|
|
using namespace winrt::Windows::UI::Composition;
|
|
|
|
using namespace winrt::Windows::UI::Xaml;
|
|
|
|
using namespace winrt::Windows::UI::Xaml::Hosting;
|
|
|
|
using namespace winrt::Windows::Foundation::Numerics;
|
2019-11-05 00:45:40 +01:00
|
|
|
using namespace ::Microsoft::Console;
|
2019-05-03 00:29:04 +02:00
|
|
|
using namespace ::Microsoft::Console::Types;
|
|
|
|
|
2020-03-10 16:37:49 +01:00
|
|
|
static constexpr int AutohideTaskbarSize = 2;
|
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
NonClientIslandWindow::NonClientIslandWindow(const ElementTheme& requestedTheme) noexcept :
|
2019-06-11 22:27:09 +02:00
|
|
|
IslandWindow{},
|
2020-05-16 00:43:00 +02:00
|
|
|
_backgroundBrushColor{ 0, 0, 0 },
|
2019-11-05 00:45:40 +01:00
|
|
|
_theme{ requestedTheme },
|
2019-05-03 00:29:04 +02:00
|
|
|
_isMaximized{ false }
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NonClientIslandWindow::~NonClientIslandWindow()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-04-25 00:22:40 +02:00
|
|
|
static constexpr const wchar_t* dragBarClassName{ L"DRAG_BAR_WINDOW_CLASS" };
|
|
|
|
|
|
|
|
[[nodiscard]] LRESULT __stdcall NonClientIslandWindow::_StaticInputSinkWndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
|
|
|
|
{
|
|
|
|
WINRT_ASSERT(window);
|
|
|
|
|
|
|
|
if (WM_NCCREATE == message)
|
|
|
|
{
|
|
|
|
auto cs = reinterpret_cast<CREATESTRUCT*>(lparam);
|
|
|
|
auto nonClientIslandWindow{ reinterpret_cast<NonClientIslandWindow*>(cs->lpCreateParams) };
|
|
|
|
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(nonClientIslandWindow));
|
|
|
|
// fall through to default window procedure
|
|
|
|
}
|
|
|
|
else if (auto nonClientIslandWindow{ reinterpret_cast<NonClientIslandWindow*>(GetWindowLongPtr(window, GWLP_USERDATA)) })
|
|
|
|
{
|
|
|
|
return nonClientIslandWindow->_InputSinkMessageHandler(message, wparam, lparam);
|
|
|
|
}
|
|
|
|
|
|
|
|
return DefWindowProc(window, message, wparam, lparam);
|
|
|
|
}
|
|
|
|
|
|
|
|
void NonClientIslandWindow::MakeWindow() noexcept
|
|
|
|
{
|
|
|
|
IslandWindow::MakeWindow();
|
|
|
|
|
|
|
|
static ATOM dragBarWindowClass{ []() {
|
|
|
|
WNDCLASSEX wcEx{};
|
|
|
|
wcEx.cbSize = sizeof(wcEx);
|
|
|
|
wcEx.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
|
|
|
wcEx.lpszClassName = dragBarClassName;
|
|
|
|
wcEx.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
|
|
|
|
wcEx.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
|
|
|
wcEx.lpfnWndProc = &NonClientIslandWindow::_StaticInputSinkWndProc;
|
|
|
|
wcEx.hInstance = wil::GetModuleInstanceHandle();
|
|
|
|
wcEx.cbWndExtra = sizeof(NonClientIslandWindow*);
|
|
|
|
return RegisterClassEx(&wcEx);
|
|
|
|
}() };
|
|
|
|
|
|
|
|
// The drag bar window is a child window of the top level window that is put
|
|
|
|
// right on top of the drag bar. The XAML island window "steals" our mouse
|
|
|
|
// messages which makes it hard to implement a custom drag area. By putting
|
|
|
|
// a window on top of it, we prevent it from "stealing" the mouse messages.
|
|
|
|
_dragBarWindow.reset(CreateWindowExW(WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP,
|
|
|
|
dragBarClassName,
|
|
|
|
L"",
|
|
|
|
WS_CHILD,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
2020-06-10 17:15:26 +02:00
|
|
|
GetHandle(),
|
2020-04-25 00:22:40 +02:00
|
|
|
nullptr,
|
|
|
|
wil::GetModuleInstanceHandle(),
|
|
|
|
this));
|
|
|
|
THROW_HR_IF_NULL(E_UNEXPECTED, _dragBarWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Function Description:
|
|
|
|
// - The window procedure for the drag bar forwards clicks on its client area to its parent as non-client clicks.
|
2020-04-25 01:46:01 +02:00
|
|
|
LRESULT NonClientIslandWindow::_InputSinkMessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
|
2020-04-25 00:22:40 +02:00
|
|
|
{
|
|
|
|
std::optional<UINT> nonClientMessage{ std::nullopt };
|
|
|
|
|
|
|
|
// translate WM_ messages on the window to WM_NC* on the top level window
|
|
|
|
switch (message)
|
|
|
|
{
|
|
|
|
case WM_LBUTTONDOWN:
|
|
|
|
nonClientMessage = WM_NCLBUTTONDOWN;
|
|
|
|
break;
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
|
|
nonClientMessage = WM_NCLBUTTONDBLCLK;
|
|
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
|
|
nonClientMessage = WM_NCLBUTTONUP;
|
|
|
|
break;
|
|
|
|
case WM_RBUTTONDOWN:
|
|
|
|
nonClientMessage = WM_NCRBUTTONDOWN;
|
|
|
|
break;
|
|
|
|
case WM_RBUTTONDBLCLK:
|
|
|
|
nonClientMessage = WM_NCRBUTTONDBLCLK;
|
|
|
|
break;
|
|
|
|
case WM_RBUTTONUP:
|
|
|
|
nonClientMessage = WM_NCRBUTTONUP;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nonClientMessage.has_value())
|
|
|
|
{
|
|
|
|
const POINT clientPt{ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) };
|
|
|
|
POINT screenPt{ clientPt };
|
|
|
|
if (ClientToScreen(_dragBarWindow.get(), &screenPt))
|
|
|
|
{
|
2020-06-10 17:15:26 +02:00
|
|
|
auto parentWindow{ GetHandle() };
|
2020-04-25 00:22:40 +02:00
|
|
|
|
2020-06-11 00:56:36 +02:00
|
|
|
const LPARAM newLparam = MAKELPARAM(screenPt.x, screenPt.y);
|
2020-04-25 00:22:40 +02:00
|
|
|
// Hit test the parent window at the screen coordinates the user clicked in the drag input sink window,
|
|
|
|
// then pass that click through as an NC click in that location.
|
2020-06-11 00:56:36 +02:00
|
|
|
const LRESULT hitTest{ SendMessage(parentWindow, WM_NCHITTEST, 0, newLparam) };
|
|
|
|
SendMessage(parentWindow, nonClientMessage.value(), hitTest, newLparam);
|
2020-04-25 00:22:40 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return DefWindowProc(_dragBarWindow.get(), message, wparam, lparam);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Resizes and shows/hides the drag bar input sink window.
|
|
|
|
// This window is used to capture clicks on the non-client area.
|
|
|
|
void NonClientIslandWindow::_ResizeDragBarWindow() noexcept
|
|
|
|
{
|
|
|
|
const til::rectangle rect{ _GetDragAreaRect() };
|
|
|
|
if (_IsTitlebarVisible() && rect.size().area() > 0)
|
|
|
|
{
|
|
|
|
SetWindowPos(_dragBarWindow.get(),
|
|
|
|
HWND_TOP,
|
|
|
|
rect.left<int>(),
|
|
|
|
rect.top<int>() + _GetTopBorderHeight(),
|
|
|
|
rect.width<int>(),
|
|
|
|
rect.height<int>(),
|
|
|
|
SWP_NOACTIVATE | SWP_SHOWWINDOW);
|
|
|
|
SetLayeredWindowAttributes(_dragBarWindow.get(), 0, 255, LWA_ALPHA);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetWindowPos(_dragBarWindow.get(), HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-12 21:46:27 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Called when the app's size changes. When that happens, the size of the drag
|
|
|
|
// bar may have changed. If it has, we'll need to update the WindowRgn of the
|
|
|
|
// interop window.
|
|
|
|
// Arguments:
|
|
|
|
// - <unused>
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
2019-11-05 00:45:40 +01:00
|
|
|
void NonClientIslandWindow::_OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable /*sender*/,
|
2020-04-25 00:22:40 +02:00
|
|
|
winrt::Windows::UI::Xaml::SizeChangedEventArgs /*eventArgs*/)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2020-04-25 00:22:40 +02:00
|
|
|
_ResizeDragBarWindow();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back
Don't do anything in NCPAINT. If you do, you have to do everything. But the
whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
your normal paint. So just do that dummy.
* This doesn't transition across monitors.
* This has a window style change I think is wrong.
* I'm not sure the margins change is important.
* The window style was _not_ important
* Still getting a black xaml islands area (the HRGN) when we switch to high DPI
* I don't know if this affects anything.
* heyo this works.
I'm not entirely sure why. But if we only update the titlebar drag region when
that actually changes, it's a _lot_ smoother. I'm not super happy with the
duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
I can't figure that out.
* Add more comments and cleanup
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d9216c6710c2a7f81840d76f8130cd73b8.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
2019-07-19 00:21:33 +02:00
|
|
|
void NonClientIslandWindow::OnAppInitialized()
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back
Don't do anything in NCPAINT. If you do, you have to do everything. But the
whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
your normal paint. So just do that dummy.
* This doesn't transition across monitors.
* This has a window style change I think is wrong.
* I'm not sure the margins change is important.
* The window style was _not_ important
* Still getting a black xaml islands area (the HRGN) when we switch to high DPI
* I don't know if this affects anything.
* heyo this works.
I'm not entirely sure why. But if we only update the titlebar drag region when
that actually changes, it's a _lot_ smoother. I'm not super happy with the
duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
I can't figure that out.
* Add more comments and cleanup
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d9216c6710c2a7f81840d76f8130cd73b8.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
2019-07-19 00:21:33 +02:00
|
|
|
IslandWindow::OnAppInitialized();
|
|
|
|
}
|
|
|
|
|
|
|
|
void NonClientIslandWindow::Initialize()
|
|
|
|
{
|
|
|
|
IslandWindow::Initialize();
|
|
|
|
|
2019-11-06 19:56:54 +01:00
|
|
|
_UpdateFrameMargins();
|
2019-11-05 00:45:40 +01:00
|
|
|
|
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back
Don't do anything in NCPAINT. If you do, you have to do everything. But the
whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
your normal paint. So just do that dummy.
* This doesn't transition across monitors.
* This has a window style change I think is wrong.
* I'm not sure the margins change is important.
* The window style was _not_ important
* Still getting a black xaml islands area (the HRGN) when we switch to high DPI
* I don't know if this affects anything.
* heyo this works.
I'm not entirely sure why. But if we only update the titlebar drag region when
that actually changes, it's a _lot_ smoother. I'm not super happy with the
duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
I can't figure that out.
* Add more comments and cleanup
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d9216c6710c2a7f81840d76f8130cd73b8.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
2019-07-19 00:21:33 +02:00
|
|
|
// Set up our grid of content. We'll use _rootGrid as our root element.
|
|
|
|
// There will be two children of this grid - the TitlebarControl, and the
|
|
|
|
// "client content"
|
|
|
|
_rootGrid.Children().Clear();
|
|
|
|
Controls::RowDefinition titlebarRow{};
|
|
|
|
Controls::RowDefinition contentRow{};
|
|
|
|
titlebarRow.Height(GridLengthHelper::Auto());
|
|
|
|
|
|
|
|
_rootGrid.RowDefinitions().Append(titlebarRow);
|
|
|
|
_rootGrid.RowDefinitions().Append(contentRow);
|
|
|
|
|
|
|
|
// Create our titlebar control
|
|
|
|
_titlebar = winrt::TerminalApp::TitlebarControl{ reinterpret_cast<uint64_t>(GetHandle()) };
|
|
|
|
_dragBar = _titlebar.DragBar();
|
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
_dragBar.SizeChanged({ this, &NonClientIslandWindow::_OnDragBarSizeChanged });
|
|
|
|
_rootGrid.SizeChanged({ this, &NonClientIslandWindow::_OnDragBarSizeChanged });
|
2019-05-03 00:29:04 +02:00
|
|
|
|
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back
Don't do anything in NCPAINT. If you do, you have to do everything. But the
whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
your normal paint. So just do that dummy.
* This doesn't transition across monitors.
* This has a window style change I think is wrong.
* I'm not sure the margins change is important.
* The window style was _not_ important
* Still getting a black xaml islands area (the HRGN) when we switch to high DPI
* I don't know if this affects anything.
* heyo this works.
I'm not entirely sure why. But if we only update the titlebar drag region when
that actually changes, it's a _lot_ smoother. I'm not super happy with the
duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
I can't figure that out.
* Add more comments and cleanup
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d9216c6710c2a7f81840d76f8130cd73b8.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
2019-07-19 00:21:33 +02:00
|
|
|
_rootGrid.Children().Append(_titlebar);
|
|
|
|
|
|
|
|
Controls::Grid::SetRow(_titlebar, 0);
|
2020-05-22 01:27:33 +02:00
|
|
|
|
|
|
|
// GH#3440 - When the titlebar is loaded (officially added to our UI tree),
|
|
|
|
// then make sure to update it's visual state to reflect if we're in the
|
|
|
|
// maximized state on launch.
|
|
|
|
_titlebar.Loaded([this](auto&&, auto&&) { _OnMaximizeChange(); });
|
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back
Don't do anything in NCPAINT. If you do, you have to do everything. But the
whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
your normal paint. So just do that dummy.
* This doesn't transition across monitors.
* This has a window style change I think is wrong.
* I'm not sure the margins change is important.
* The window style was _not_ important
* Still getting a black xaml islands area (the HRGN) when we switch to high DPI
* I don't know if this affects anything.
* heyo this works.
I'm not entirely sure why. But if we only update the titlebar drag region when
that actually changes, it's a _lot_ smoother. I'm not super happy with the
duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
I can't figure that out.
* Add more comments and cleanup
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d9216c6710c2a7f81840d76f8130cd73b8.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
2019-07-19 00:21:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Set the content of the "client area" of our window to the given content.
|
|
|
|
// Arguments:
|
|
|
|
// - content: the new UI element to use as the client content
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void NonClientIslandWindow::SetContent(winrt::Windows::UI::Xaml::UIElement content)
|
|
|
|
{
|
|
|
|
_clientContent = content;
|
|
|
|
|
|
|
|
_rootGrid.Children().Append(content);
|
|
|
|
|
|
|
|
// SetRow only works on FrameworkElement's, so cast it to a FWE before
|
|
|
|
// calling. We know that our content is a Grid, so we don't need to worry
|
|
|
|
// about this.
|
|
|
|
const auto fwe = content.try_as<winrt::Windows::UI::Xaml::FrameworkElement>();
|
|
|
|
if (fwe)
|
|
|
|
{
|
|
|
|
Controls::Grid::SetRow(fwe, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Set the content of the "titlebar area" of our window to the given content.
|
|
|
|
// Arguments:
|
|
|
|
// - content: the new UI element to use as the titlebar content
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void NonClientIslandWindow::SetTitlebarContent(winrt::Windows::UI::Xaml::UIElement content)
|
|
|
|
{
|
|
|
|
_titlebar.Content(content);
|
Update the dragbar when the titlebar content size changes (#4845)
## Summary of the Pull Request
Add a `SizeChanged` handler to the titlebar content UI element. It's possible that this element's size will change after the dragbar's. When that happens, the drag bar won't send another `SizeChanged` event, because the dragbar's _size_ didn't change, only it's position.
## References
We originally duped this issue to #4166, but after #4829 fixed that issue, this one persisted. They're all related, and _look_ like dupes, but they weren't.
## PR Checklist
* [x] Closes #4288
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
I had a solid 100% repro that doesn't repro anymore.
I've maximized, restored, resized, and generally played with the window a bunch.
2020-03-09 18:54:33 +01:00
|
|
|
|
|
|
|
// GH#4288 - add a SizeChanged handler to this content. It's possible that
|
|
|
|
// this element's size will change after the dragbar's. When that happens,
|
|
|
|
// the drag bar won't send another SizeChanged event, because the dragbar's
|
|
|
|
// _size_ didn't change, only it's position.
|
|
|
|
const auto fwe = content.try_as<winrt::Windows::UI::Xaml::FrameworkElement>();
|
|
|
|
if (fwe)
|
|
|
|
{
|
|
|
|
fwe.SizeChanged({ this, &NonClientIslandWindow::_OnDragBarSizeChanged });
|
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// Method Description:
|
|
|
|
// - This method computes the height of the little border above the title bar
|
|
|
|
// and returns it. If the border is disabled, then this method will return 0.
|
|
|
|
// Return Value:
|
|
|
|
// - the height of the border above the title bar or 0 if it's disabled
|
|
|
|
int NonClientIslandWindow::_GetTopBorderHeight() const noexcept
|
|
|
|
{
|
2020-11-03 18:40:02 +01:00
|
|
|
// No border when maximized or fullscreen.
|
|
|
|
// Yet we still need it in the focus mode to allow dragging (GH#7012)
|
|
|
|
if (_isMaximized || _fullscreen)
|
2019-11-05 00:45:40 +01:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return topBorderVisibleHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
RECT NonClientIslandWindow::_GetDragAreaRect() const noexcept
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2020-04-25 00:22:40 +02:00
|
|
|
if (_dragBar && _dragBar.Visibility() == Visibility::Visible)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-25 22:06:11 +02:00
|
|
|
const auto scale = GetCurrentDpiScale();
|
|
|
|
const auto transform = _dragBar.TransformToVisual(_rootGrid);
|
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back
Don't do anything in NCPAINT. If you do, you have to do everything. But the
whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
your normal paint. So just do that dummy.
* This doesn't transition across monitors.
* This has a window style change I think is wrong.
* I'm not sure the margins change is important.
* The window style was _not_ important
* Still getting a black xaml islands area (the HRGN) when we switch to high DPI
* I don't know if this affects anything.
* heyo this works.
I'm not entirely sure why. But if we only update the titlebar drag region when
that actually changes, it's a _lot_ smoother. I'm not super happy with the
duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
I can't figure that out.
* Add more comments and cleanup
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d9216c6710c2a7f81840d76f8130cd73b8.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
2019-07-19 00:21:33 +02:00
|
|
|
const auto logicalDragBarRect = winrt::Windows::Foundation::Rect{
|
|
|
|
0.0f,
|
|
|
|
0.0f,
|
|
|
|
static_cast<float>(_dragBar.ActualWidth()),
|
|
|
|
static_cast<float>(_dragBar.ActualHeight())
|
|
|
|
};
|
2019-06-25 22:06:11 +02:00
|
|
|
const auto clientDragBarRect = transform.TransformBounds(logicalDragBarRect);
|
|
|
|
RECT dragBarRect = {
|
|
|
|
static_cast<LONG>(clientDragBarRect.X * scale),
|
|
|
|
static_cast<LONG>(clientDragBarRect.Y * scale),
|
|
|
|
static_cast<LONG>((clientDragBarRect.Width + clientDragBarRect.X) * scale),
|
|
|
|
static_cast<LONG>((clientDragBarRect.Height + clientDragBarRect.Y) * scale),
|
|
|
|
};
|
|
|
|
return dragBarRect;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-06-25 22:06:11 +02:00
|
|
|
return RECT{};
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
2019-11-05 00:45:40 +01:00
|
|
|
// - Called when the size of the window changes for any reason. Updates the
|
|
|
|
// XAML island to match our new sizing and also updates the maximize icon
|
|
|
|
// if the window went from maximized to restored or the opposite.
|
2019-06-25 22:06:11 +02:00
|
|
|
void NonClientIslandWindow::OnSize(const UINT width, const UINT height)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
_UpdateMaximizedState();
|
|
|
|
|
|
|
|
if (_interopWindowHandle)
|
2019-06-25 22:06:11 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
_UpdateIslandPosition(width, height);
|
2019-06-25 22:06:11 +02:00
|
|
|
}
|
2021-10-06 13:34:53 +02:00
|
|
|
|
|
|
|
// GH#11367: We need to do this,
|
|
|
|
// otherwise the titlebar may still be partially visible
|
|
|
|
// when we move between different DPI monitors.
|
|
|
|
RefreshCurrentDPI();
|
|
|
|
_UpdateFrameMargins();
|
2019-11-05 00:45:40 +01:00
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// Method Description:
|
|
|
|
// - Checks if the window has been maximized or restored since the last time.
|
|
|
|
// If it has been maximized or restored, then it updates the _isMaximized
|
|
|
|
// flags and notifies of the change by calling
|
|
|
|
// NonClientIslandWindow::_OnMaximizeChange.
|
|
|
|
void NonClientIslandWindow::_UpdateMaximizedState()
|
|
|
|
{
|
|
|
|
const auto windowStyle = GetWindowStyle(_window.get());
|
|
|
|
const auto newIsMaximized = WI_IsFlagSet(windowStyle, WS_MAXIMIZE);
|
|
|
|
|
|
|
|
if (_isMaximized != newIsMaximized)
|
2019-05-20 21:49:28 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
_isMaximized = newIsMaximized;
|
|
|
|
_OnMaximizeChange();
|
2019-05-20 21:49:28 +02:00
|
|
|
}
|
2019-11-05 00:45:40 +01:00
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// Method Description:
|
|
|
|
// - Called when the the windows goes from restored to maximized or from
|
|
|
|
// maximized to restored. Updates the maximize button's icon and the frame
|
|
|
|
// margins.
|
|
|
|
void NonClientIslandWindow::_OnMaximizeChange() noexcept
|
|
|
|
{
|
|
|
|
if (_titlebar)
|
|
|
|
{
|
|
|
|
const auto windowStyle = GetWindowStyle(_window.get());
|
|
|
|
const auto isIconified = WI_IsFlagSet(windowStyle, WS_ICONIC);
|
|
|
|
|
|
|
|
const auto state = _isMaximized ? winrt::TerminalApp::WindowVisualState::WindowVisualStateMaximized :
|
|
|
|
isIconified ? winrt::TerminalApp::WindowVisualState::WindowVisualStateIconified :
|
|
|
|
winrt::TerminalApp::WindowVisualState::WindowVisualStateNormal;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
_titlebar.SetWindowVisualState(state);
|
|
|
|
}
|
|
|
|
CATCH_LOG();
|
|
|
|
}
|
|
|
|
|
|
|
|
// no frame margin when maximized
|
2019-11-06 19:56:54 +01:00
|
|
|
_UpdateFrameMargins();
|
2019-11-05 00:45:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Called when the size of the window changes for any reason. Updates the
|
|
|
|
// sizes of our child XAML Islands to match our new sizing.
|
|
|
|
void NonClientIslandWindow::_UpdateIslandPosition(const UINT windowWidth, const UINT windowHeight)
|
|
|
|
{
|
Shift the island up by 1px when maximized (#10746)
For inexplicable reasons, the top row of pixels on our tabs, new tab
button, and caption buttons is totally unclickable. The mouse simply
refuses to interact with them. So when we're maximized, on certain
monitor configurations, this results in the top row of pixels not
reacting to clicks at all.
To obey Fitt's Law, we're gonna hackily shift the entire island up one
pixel. That will result in the top row of pixels in the window actually
being the _second_ row of pixels for those buttons, which will make them
clickable. It's perhaps not the right fix, but it works.
After discussion, we think this is a fine fix for this. We don't think
anyone's going to miss the top row of pixels on the TabView. The original
bug is painful enough for the subset of users it impacts that this is an
acceptable trade. Should a better fix be found, we can absolutely do that
instead.
Closes #7422
2021-07-29 00:15:22 +02:00
|
|
|
const auto originalTopHeight = _GetTopBorderHeight();
|
|
|
|
// GH#7422
|
|
|
|
// !! BODGY !!
|
|
|
|
//
|
|
|
|
// For inexplicable reasons, the top row of pixels on our tabs, new tab
|
|
|
|
// button, and caption buttons is totally un-clickable. The mouse simply
|
|
|
|
// refuses to interact with them. So when we're maximized, on certain
|
|
|
|
// monitor configurations, this results in the top row of pixels not
|
|
|
|
// reacting to clicks at all. To obey Fitt's Law, we're gonna shift
|
|
|
|
// the entire island up one pixel. That will result in the top row of pixels
|
|
|
|
// in the window actually being the _second_ row of pixels for those
|
|
|
|
// buttons, which will make them clickable. It's perhaps not the right fix,
|
|
|
|
// but it works.
|
|
|
|
// _GetTopBorderHeight() returns 0 when we're maximized.
|
|
|
|
const short topBorderHeight = ::base::saturated_cast<short>((originalTopHeight == 0) ? -1 : originalTopHeight);
|
2019-11-05 00:45:40 +01:00
|
|
|
|
|
|
|
const COORD newIslandPos = { 0, topBorderHeight };
|
|
|
|
|
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back
Don't do anything in NCPAINT. If you do, you have to do everything. But the
whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
your normal paint. So just do that dummy.
* This doesn't transition across monitors.
* This has a window style change I think is wrong.
* I'm not sure the margins change is important.
* The window style was _not_ important
* Still getting a black xaml islands area (the HRGN) when we switch to high DPI
* I don't know if this affects anything.
* heyo this works.
I'm not entirely sure why. But if we only update the titlebar drag region when
that actually changes, it's a _lot_ smoother. I'm not super happy with the
duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
I can't figure that out.
* Add more comments and cleanup
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d9216c6710c2a7f81840d76f8130cd73b8.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
2019-07-19 00:21:33 +02:00
|
|
|
winrt::check_bool(SetWindowPos(_interopWindowHandle,
|
|
|
|
HWND_BOTTOM,
|
2019-11-05 00:45:40 +01:00
|
|
|
newIslandPos.X,
|
|
|
|
newIslandPos.Y,
|
|
|
|
windowWidth,
|
|
|
|
windowHeight - topBorderHeight,
|
2020-10-14 00:40:56 +02:00
|
|
|
SWP_SHOWWINDOW | SWP_NOACTIVATE));
|
2019-11-05 00:45:40 +01:00
|
|
|
|
|
|
|
// This happens when we go from maximized to restored or the opposite
|
|
|
|
// because topBorderHeight changes.
|
|
|
|
if (!_oldIslandPos.has_value() || _oldIslandPos.value() != newIslandPos)
|
|
|
|
{
|
|
|
|
// The drag bar's position changed compared to the client area because
|
|
|
|
// the island moved but we will not be notified about this in the
|
|
|
|
// NonClientIslandWindow::OnDragBarSizeChanged method because this
|
|
|
|
// method is only called when the position of the drag bar changes
|
|
|
|
// **inside** the island which is not the case here.
|
2020-04-25 00:22:40 +02:00
|
|
|
_ResizeDragBarWindow();
|
2019-11-05 00:45:40 +01:00
|
|
|
|
|
|
|
_oldIslandPos = { newIslandPos };
|
|
|
|
}
|
2019-07-12 21:46:27 +02:00
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// Method Description:
|
2019-11-05 00:45:40 +01:00
|
|
|
// - Returns the height of the little space at the top of the window used to
|
|
|
|
// resize the window.
|
2019-05-03 00:29:04 +02:00
|
|
|
// Return Value:
|
2019-11-05 00:45:40 +01:00
|
|
|
// - the height of the window's top resize handle
|
|
|
|
int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
// there isn't a SM_CYPADDEDBORDER for the Y axis
|
|
|
|
return ::GetSystemMetricsForDpi(SM_CXPADDEDBORDER, _currentDpi) +
|
|
|
|
::GetSystemMetricsForDpi(SM_CYSIZEFRAME, _currentDpi);
|
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// Method Description:
|
|
|
|
// - Responds to the WM_NCCALCSIZE message by calculating and creating the new
|
|
|
|
// window frame.
|
|
|
|
[[nodiscard]] LRESULT NonClientIslandWindow::_OnNcCalcSize(const WPARAM wParam, const LPARAM lParam) noexcept
|
|
|
|
{
|
2020-06-22 23:51:34 +02:00
|
|
|
if (!wParam)
|
2019-11-05 00:45:40 +01:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// Store the original top before the default window proc applies the
|
|
|
|
// default frame.
|
|
|
|
const auto originalTop = params->rgrc[0].top;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-03-10 16:37:49 +01:00
|
|
|
const auto originalSize = params->rgrc[0];
|
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// apply the default frame
|
2020-06-22 23:51:34 +02:00
|
|
|
const auto ret = DefWindowProc(_window.get(), WM_NCCALCSIZE, wParam, lParam);
|
2019-11-05 00:45:40 +01:00
|
|
|
if (ret != 0)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
return ret;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2020-03-10 16:37:49 +01:00
|
|
|
auto newSize = params->rgrc[0];
|
|
|
|
// Re-apply the original top from before the size of the default frame was applied.
|
|
|
|
newSize.top = originalTop;
|
2019-12-16 21:58:38 +01:00
|
|
|
|
|
|
|
// WM_NCCALCSIZE is called before WM_SIZE
|
|
|
|
_UpdateMaximizedState();
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
|
2020-03-10 16:37:49 +01:00
|
|
|
// We don't need this correction when we're fullscreen. We will have the
|
|
|
|
// WS_POPUP size, so we don't have to worry about borders, and the default
|
|
|
|
// frame will be fine.
|
|
|
|
if (_isMaximized && !_fullscreen)
|
2019-12-16 21:58:38 +01:00
|
|
|
{
|
|
|
|
// When a window is maximized, its size is actually a little bit more
|
|
|
|
// than the monitor's work area. The window is positioned and sized in
|
|
|
|
// such a way that the resize handles are outside of the monitor and
|
|
|
|
// then the window is clipped to the monitor so that the resize handle
|
|
|
|
// do not appear because you don't need them (because you can't resize
|
|
|
|
// a window when it's maximized unless you restore it).
|
2020-03-10 16:37:49 +01:00
|
|
|
newSize.top += _GetResizeHandleHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
// GH#1438 - Attempt to detect if there's an autohide taskbar, and if there
|
|
|
|
// is, reduce our size a bit on the side with the taskbar, so the user can
|
|
|
|
// still mouse-over the taskbar to reveal it.
|
2020-04-01 23:19:04 +02:00
|
|
|
// GH#5209 - make sure to use MONITOR_DEFAULTTONEAREST, so that this will
|
|
|
|
// still find the right monitor even when we're restoring from minimized.
|
|
|
|
HMONITOR hMon = MonitorFromWindow(_window.get(), MONITOR_DEFAULTTONEAREST);
|
2020-03-10 16:37:49 +01:00
|
|
|
if (hMon && (_isMaximized || _fullscreen))
|
|
|
|
{
|
|
|
|
MONITORINFO monInfo{ 0 };
|
|
|
|
monInfo.cbSize = sizeof(MONITORINFO);
|
|
|
|
GetMonitorInfo(hMon, &monInfo);
|
|
|
|
|
|
|
|
// First, check if we have an auto-hide taskbar at all:
|
|
|
|
APPBARDATA autohide{ 0 };
|
|
|
|
autohide.cbSize = sizeof(autohide);
|
|
|
|
UINT state = (UINT)SHAppBarMessage(ABM_GETSTATE, &autohide);
|
|
|
|
if (WI_IsFlagSet(state, ABS_AUTOHIDE))
|
|
|
|
{
|
|
|
|
// This helper can be used to determine if there's a auto-hide
|
|
|
|
// taskbar on the given edge of the monitor we're currently on.
|
|
|
|
auto hasAutohideTaskbar = [&monInfo](const UINT edge) -> bool {
|
|
|
|
APPBARDATA data{ 0 };
|
|
|
|
data.cbSize = sizeof(data);
|
|
|
|
data.uEdge = edge;
|
|
|
|
data.rc = monInfo.rcMonitor;
|
|
|
|
HWND hTaskbar = (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAREX, &data);
|
|
|
|
return hTaskbar != nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
const bool onTop = hasAutohideTaskbar(ABE_TOP);
|
|
|
|
const bool onBottom = hasAutohideTaskbar(ABE_BOTTOM);
|
|
|
|
const bool onLeft = hasAutohideTaskbar(ABE_LEFT);
|
|
|
|
const bool onRight = hasAutohideTaskbar(ABE_RIGHT);
|
|
|
|
|
|
|
|
// If there's a taskbar on any side of the monitor, reduce our size
|
|
|
|
// a little bit on that edge.
|
|
|
|
//
|
|
|
|
// Note to future code archeologists:
|
|
|
|
// This doesn't seem to work for fullscreen on the primary display.
|
|
|
|
// However, testing a bunch of other apps with fullscreen modes
|
|
|
|
// and an auto-hiding taskbar has shown that _none_ of them
|
|
|
|
// reveal the taskbar from fullscreen mode. This includes Edge,
|
ci: run spell check in CI, fix remaining issues (#4799)
This commit introduces a github action to check our spelling and fixes
the following misspelled words so that we come up green.
It also renames TfEditSes to TfEditSession, because Ses is not a word.
currently, excerpt, fallthrough, identified, occurred, propagate,
provided, rendered, resetting, separate, succeeded, successfully,
terminal, transferred, adheres, breaks, combining, preceded,
architecture, populated, previous, setter, visible, window, within,
appxmanifest, hyphen, control, offset, powerpoint, suppress, parsing,
prioritized, aforementioned, check in, build, filling, indices, layout,
mapping, trying, scroll, terabyte, vetoes, viewport, whose
2020-03-25 19:02:53 +01:00
|
|
|
// Firefox, Chrome, Sublime Text, PowerPoint - none seemed to
|
2020-03-10 16:37:49 +01:00
|
|
|
// support this.
|
|
|
|
//
|
|
|
|
// This does however work fine for maximized.
|
|
|
|
if (onTop)
|
|
|
|
{
|
|
|
|
// Peculiarly, when we're fullscreen,
|
|
|
|
newSize.top += AutohideTaskbarSize;
|
|
|
|
}
|
|
|
|
if (onBottom)
|
|
|
|
{
|
|
|
|
newSize.bottom -= AutohideTaskbarSize;
|
|
|
|
}
|
|
|
|
if (onLeft)
|
|
|
|
{
|
|
|
|
newSize.left += AutohideTaskbarSize;
|
|
|
|
}
|
|
|
|
if (onRight)
|
|
|
|
{
|
|
|
|
newSize.right -= AutohideTaskbarSize;
|
|
|
|
}
|
|
|
|
}
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
}
|
2019-11-05 00:45:40 +01:00
|
|
|
|
2020-03-10 16:37:49 +01:00
|
|
|
params->rgrc[0] = newSize;
|
2019-12-16 21:58:38 +01:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
return 0;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
2019-11-05 00:45:40 +01:00
|
|
|
// - Hit test the frame for resizing and moving.
|
|
|
|
// Arguments:
|
|
|
|
// - ptMouse: the mouse point being tested, in absolute (NOT WINDOW) coordinates.
|
2019-05-03 00:29:04 +02:00
|
|
|
// Return Value:
|
2019-11-05 00:45:40 +01:00
|
|
|
// - 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
|
|
|
|
[[nodiscard]] LRESULT NonClientIslandWindow::_OnNcHitTest(POINT ptMouse) const noexcept
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
// This will handle the left, right and bottom parts of the frame because
|
|
|
|
// we didn't change them.
|
|
|
|
LPARAM lParam = MAKELONG(ptMouse.x, ptMouse.y);
|
|
|
|
const auto originalRet = DefWindowProc(_window.get(), WM_NCHITTEST, 0, lParam);
|
|
|
|
if (originalRet != HTCLIENT)
|
|
|
|
{
|
2021-04-26 21:36:23 +02:00
|
|
|
// If we're the quake window, suppress resizing on any side except the
|
|
|
|
// bottom. I don't believe that this actually works on the top. That's
|
|
|
|
// handled below.
|
|
|
|
if (IsQuakeWindow())
|
|
|
|
{
|
|
|
|
switch (originalRet)
|
|
|
|
{
|
|
|
|
case HTBOTTOMRIGHT:
|
|
|
|
case HTRIGHT:
|
|
|
|
case HTTOPRIGHT:
|
|
|
|
case HTTOP:
|
|
|
|
case HTTOPLEFT:
|
|
|
|
case HTLEFT:
|
|
|
|
case HTBOTTOMLEFT:
|
|
|
|
return HTCLIENT;
|
|
|
|
}
|
|
|
|
}
|
2019-11-05 00:45:40 +01:00
|
|
|
return originalRet;
|
|
|
|
}
|
2019-06-25 22:06:11 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// At this point, we know that the cursor is inside the client area so it
|
|
|
|
// has to be either the little border at the top of our custom title bar,
|
|
|
|
// the drag bar or something else in the XAML island. But the XAML Island
|
|
|
|
// handles WM_NCHITTEST on its own so actually it cannot be the XAML
|
|
|
|
// Island. Then it must be the drag bar or the little border at the top
|
|
|
|
// which the user can use to move or resize the window.
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
RECT rcWindow;
|
|
|
|
winrt::check_bool(::GetWindowRect(_window.get(), &rcWindow));
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
const auto resizeBorderHeight = _GetResizeHandleHeight();
|
|
|
|
const auto isOnResizeBorder = ptMouse.y < rcWindow.top + resizeBorderHeight;
|
|
|
|
|
|
|
|
// the top of the drag bar is used to resize the window
|
|
|
|
if (!_isMaximized && isOnResizeBorder)
|
|
|
|
{
|
2021-04-26 21:36:23 +02:00
|
|
|
// However, if we're the quake window, then just return HTCAPTION so we
|
|
|
|
// don't get a resize handle on the top.
|
|
|
|
return IsQuakeWindow() ? HTCAPTION : HTTOP;
|
2019-11-05 00:45:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return HTCAPTION;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2020-04-25 00:22:40 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Sets the cursor to the sizing cursor when we hit-test the top sizing border.
|
|
|
|
// We need to do this because we've covered it up with a child window.
|
|
|
|
[[nodiscard]] LRESULT NonClientIslandWindow::_OnSetCursor(WPARAM wParam, LPARAM lParam) const noexcept
|
|
|
|
{
|
|
|
|
if (LOWORD(lParam) == HTCLIENT)
|
|
|
|
{
|
|
|
|
// Get the cursor position from the _last message_ and not from
|
|
|
|
// `GetCursorPos` (which returns the cursor position _at the
|
|
|
|
// moment_) because if we're lagging behind the cursor's position,
|
|
|
|
// we still want to get the cursor position that was associated
|
|
|
|
// with that message at the time it was sent to handle the message
|
|
|
|
// correctly.
|
|
|
|
const auto screenPtLparam{ GetMessagePos() };
|
2020-06-10 17:15:26 +02:00
|
|
|
const LRESULT hitTest{ SendMessage(GetHandle(), WM_NCHITTEST, 0, screenPtLparam) };
|
2020-04-25 00:22:40 +02:00
|
|
|
if (hitTest == HTTOP)
|
|
|
|
{
|
|
|
|
// We have to set the vertical resize cursor manually on
|
|
|
|
// the top resize handle because Windows thinks that the
|
|
|
|
// cursor is on the client area because it asked the asked
|
|
|
|
// the drag window with `WM_NCHITTEST` and it returned
|
|
|
|
// `HTCLIENT`.
|
|
|
|
// We don't want to modify the drag window's `WM_NCHITTEST`
|
|
|
|
// handling to return `HTTOP` because otherwise, the system
|
|
|
|
// would resize the drag window instead of the top level
|
|
|
|
// window!
|
|
|
|
SetCursor(LoadCursor(nullptr, IDC_SIZENS));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// reset cursor
|
|
|
|
SetCursor(LoadCursor(nullptr, IDC_ARROW));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-10 17:15:26 +02:00
|
|
|
return DefWindowProc(GetHandle(), WM_SETCURSOR, wParam, lParam);
|
2020-04-25 00:22:40 +02:00
|
|
|
}
|
2020-01-08 22:19:23 +01:00
|
|
|
// Method Description:
|
2021-08-09 20:27:20 +02:00
|
|
|
// - Get the dimensions of our non-client area, as a rect where each component
|
|
|
|
// represents that side.
|
|
|
|
// - The .left will be a negative number, to represent that the actual side of
|
|
|
|
// the non-client area is outside the border of our window. It's roughly 8px (
|
|
|
|
// * DPI scaling) to the left of the visible border.
|
|
|
|
// - The .right component will be positive, indicating that the nonclient border
|
|
|
|
// is in the positive-x direction from the edge of our client area.
|
|
|
|
// - This DOES NOT include our titlebar! It's in the client area for us.
|
2020-01-08 22:19:23 +01:00
|
|
|
// Arguments:
|
2021-08-09 20:27:20 +02:00
|
|
|
// - dpi: the scaling that we should use to calculate the border sizes.
|
|
|
|
// Return Value:
|
|
|
|
// - a RECT whose components represent the margins of the nonclient area,
|
|
|
|
// relative to the client area.
|
|
|
|
RECT NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
|
2020-01-08 22:19:23 +01:00
|
|
|
{
|
|
|
|
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
|
|
|
RECT islandFrame{};
|
|
|
|
|
|
|
|
// If we failed to get the correct window size for whatever reason, log
|
|
|
|
// the error and go on. We'll use whatever the control proposed as the
|
|
|
|
// size of our window, which will be at least close.
|
|
|
|
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
|
|
|
|
|
|
|
islandFrame.top = -topBorderVisibleHeight;
|
2021-08-09 20:27:20 +02:00
|
|
|
return islandFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Gets the difference between window and client area size.
|
|
|
|
// Arguments:
|
|
|
|
// - dpi: dpi of a monitor on which the window is placed
|
|
|
|
// Return Value
|
|
|
|
// - The size difference
|
|
|
|
SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
|
|
|
|
{
|
|
|
|
const auto islandFrame{ GetNonClientFrame(dpi) };
|
2020-01-08 22:19:23 +01:00
|
|
|
|
Correct for the size of the tabs when calculating our initial window size (#4825)
## Summary of the Pull Request
This fixes our calculation for the initial size of the window. WE weren't accounting for the height of the tabs, so the `initialRows` was consistently wrong.
## PR Checklist
* [x] Closes #2061
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
For the tabs below the titlebar case, there's 6px (unscaled) of space that I cannot account for. I seriously have no idea where it's coming from. When we end up creating the first `TermControl` after startup, there's an inexplicable `6*scale` difference between the height of the `tabContent` and the `SwapChainPanel`'s size.
## Validation Steps Performed
Checked all six of the following cases:
* 1.0 DPI scaling, Tabs in Titlebar
* 1.25 DPI scaling, Tabs in Titlebar
* 1.0 DPI scaling, Tabs NOT in Titlebar, always show tabs
* 1.0 DPI scaling, Tabs NOT in Titlebar, DON'T always show tabs
* 1.25 DPI scaling, Tabs NOT in Titlebar, always show tabs
* 1.25 DPI scaling, Tabs NOT in Titlebar, DON'T always show tabs
2020-03-11 21:29:36 +01:00
|
|
|
// If we have a titlebar, this is being called after we've initialized, and
|
|
|
|
// we can just ask that titlebar how big it wants to be.
|
2020-01-08 22:19:23 +01:00
|
|
|
const auto titleBarHeight = _titlebar ? static_cast<LONG>(_titlebar.ActualHeight()) : 0;
|
|
|
|
|
|
|
|
return {
|
|
|
|
islandFrame.right - islandFrame.left,
|
|
|
|
islandFrame.bottom - islandFrame.top + titleBarHeight
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Updates the borders of our window frame, using DwmExtendFrameIntoClientArea.
|
|
|
|
// Arguments:
|
|
|
|
// - <none>
|
|
|
|
// Return Value:
|
|
|
|
// - the HRESULT returned by DwmExtendFrameIntoClientArea.
|
2019-11-06 19:56:54 +01:00
|
|
|
void NonClientIslandWindow::_UpdateFrameMargins() const noexcept
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2021-09-20 19:08:13 +02:00
|
|
|
MARGINS margins = { 0, 0, 0, 0 };
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2021-09-20 19:08:13 +02:00
|
|
|
// GH#603: When we're in Focus Mode, hide the titlebar, by setting it to a single
|
|
|
|
// pixel tall. Otherwise, the titlebar will be visible underneath controls with
|
|
|
|
// vintage opacity set.
|
|
|
|
//
|
|
|
|
// We can't set it to all 0's unfortunately.
|
|
|
|
if (_borderless)
|
|
|
|
{
|
|
|
|
margins.cyTopHeight = 1;
|
|
|
|
}
|
|
|
|
else if (_GetTopBorderHeight() != 0)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
RECT frame = {};
|
|
|
|
winrt::check_bool(::AdjustWindowRectExForDpi(&frame, GetWindowStyle(_window.get()), FALSE, 0, _currentDpi));
|
|
|
|
|
|
|
|
// We removed the whole top part of the frame (see handling of
|
|
|
|
// WM_NCCALCSIZE) so the top border is missing now. We add it back here.
|
|
|
|
// Note #1: You might wonder why we don't remove just the title bar instead
|
|
|
|
// of removing the whole top part of the frame and then adding the little
|
|
|
|
// top border back. I tried to do this but it didn't work: DWM drew the
|
|
|
|
// whole title bar anyways on top of the window. It seems that DWM only
|
|
|
|
// wants to draw either nothing or the whole top part of the frame.
|
|
|
|
// Note #2: For some reason if you try to set the top margin to just the
|
|
|
|
// top border height (what we want to do), then there is a transparency
|
|
|
|
// bug when the window is inactive, so I've decided to add the whole top
|
|
|
|
// part of the frame instead and then we will hide everything that we
|
|
|
|
// don't need (that is, the whole thing but the little 1 pixel wide border
|
|
|
|
// at the top) in the WM_PAINT handler. This eliminates the transparency
|
|
|
|
// bug and it's what a lot of Win32 apps that customize the title bar do
|
|
|
|
// so it should work fine.
|
|
|
|
margins.cyTopHeight = -frame.top;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-11-06 19:56:54 +01:00
|
|
|
// Extend the frame into the client area. microsoft/terminal#2735 - Just log
|
|
|
|
// the failure here, don't crash. If DWM crashes for any reason, calling
|
|
|
|
// THROW_IF_FAILED() will cause us to take a trip upstate. Just log, and
|
|
|
|
// we'll fix ourselves when DWM comes back.
|
|
|
|
LOG_IF_FAILED(DwmExtendFrameIntoClientArea(_window.get(), &margins));
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Handle window messages from the message loop.
|
|
|
|
// Arguments:
|
|
|
|
// - message: A window message ID identifying the message.
|
|
|
|
// - wParam: The contents of this parameter depend on the value of the message parameter.
|
|
|
|
// - lParam: The contents of this parameter depend on the value of the message parameter.
|
|
|
|
// Return Value:
|
|
|
|
// - The return value is the result of the message processing and depends on the
|
|
|
|
// message sent.
|
2019-06-11 22:27:09 +02:00
|
|
|
[[nodiscard]] LRESULT NonClientIslandWindow::MessageHandler(UINT const message,
|
|
|
|
WPARAM const wParam,
|
|
|
|
LPARAM const lParam) noexcept
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
switch (message)
|
|
|
|
{
|
2020-04-25 00:22:40 +02:00
|
|
|
case WM_SETCURSOR:
|
|
|
|
return _OnSetCursor(wParam, lParam);
|
2020-03-06 23:14:35 +01:00
|
|
|
case WM_DISPLAYCHANGE:
|
|
|
|
// GH#4166: When the DPI of the monitor changes out from underneath us,
|
|
|
|
// resize our drag bar, to reflect its newly scaled size.
|
2020-04-25 00:22:40 +02:00
|
|
|
_ResizeDragBarWindow();
|
2020-03-06 23:14:35 +01:00
|
|
|
return 0;
|
2019-05-03 00:29:04 +02:00
|
|
|
case WM_NCCALCSIZE:
|
2019-11-05 00:45:40 +01:00
|
|
|
return _OnNcCalcSize(wParam, lParam);
|
2019-05-03 00:29:04 +02:00
|
|
|
case WM_NCHITTEST:
|
2019-11-05 00:45:40 +01:00
|
|
|
return _OnNcHitTest({ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) });
|
|
|
|
case WM_PAINT:
|
|
|
|
return _OnPaint();
|
2020-06-11 00:56:36 +02:00
|
|
|
case WM_NCRBUTTONUP:
|
|
|
|
// The `DefWindowProc` function doesn't open the system menu for some
|
|
|
|
// reason so we have to do it ourselves.
|
|
|
|
if (wParam == HTCAPTION)
|
|
|
|
{
|
2021-09-10 20:25:43 +02:00
|
|
|
OpenSystemMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
2020-06-11 00:56:36 +02:00
|
|
|
}
|
|
|
|
break;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-07-12 21:46:27 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
return IslandWindow::MessageHandler(message, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
2020-04-25 00:22:40 +02:00
|
|
|
// - This method is called when the window receives the WM_PAINT message.
|
|
|
|
// - It paints the client area with the color of the title bar to hide the
|
|
|
|
// system's title bar behind the XAML Islands window during a resize.
|
|
|
|
// Indeed, the XAML Islands window doesn't resize at the same time than
|
|
|
|
// the top level window
|
|
|
|
// (see https://github.com/microsoft/microsoft-ui-xaml/issues/759).
|
2019-11-05 00:45:40 +01:00
|
|
|
// Return Value:
|
|
|
|
// - The value returned from the window proc.
|
|
|
|
[[nodiscard]] LRESULT NonClientIslandWindow::_OnPaint() noexcept
|
|
|
|
{
|
|
|
|
if (!_titlebar)
|
2019-06-25 22:06:11 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
return 0;
|
2019-06-25 22:06:11 +02:00
|
|
|
}
|
2019-07-12 21:46:27 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
PAINTSTRUCT ps{ 0 };
|
|
|
|
const auto hdc = wil::BeginPaint(_window.get(), &ps);
|
|
|
|
if (!hdc)
|
2019-06-25 22:06:11 +02:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2019-07-12 21:46:27 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
const auto topBorderHeight = _GetTopBorderHeight();
|
|
|
|
|
|
|
|
if (ps.rcPaint.top < topBorderHeight)
|
2019-06-25 22:06:11 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
RECT rcTopBorder = ps.rcPaint;
|
|
|
|
rcTopBorder.bottom = topBorderHeight;
|
|
|
|
|
|
|
|
// To show the original top border, we have to paint on top of it with
|
|
|
|
// the alpha component set to 0. This page recommends to paint the area
|
|
|
|
// in black using the stock BLACK_BRUSH to do this:
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/dwm/customframe#extending-the-client-frame
|
|
|
|
::FillRect(hdc.get(), &rcTopBorder, GetStockBrush(BLACK_BRUSH));
|
2019-06-25 22:06:11 +02:00
|
|
|
}
|
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
if (ps.rcPaint.bottom > topBorderHeight)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
RECT rcRest = ps.rcPaint;
|
|
|
|
rcRest.top = topBorderHeight;
|
|
|
|
|
|
|
|
const auto backgroundBrush = _titlebar.Background();
|
2021-08-23 18:40:25 +02:00
|
|
|
const auto backgroundSolidBrush = backgroundBrush.try_as<Media::SolidColorBrush>();
|
|
|
|
const auto backgroundAcrylicBrush = backgroundBrush.try_as<Media::AcrylicBrush>();
|
|
|
|
|
|
|
|
til::color backgroundColor = Colors::Black();
|
|
|
|
if (backgroundSolidBrush)
|
|
|
|
{
|
|
|
|
backgroundColor = backgroundSolidBrush.Color();
|
|
|
|
}
|
|
|
|
else if (backgroundAcrylicBrush)
|
|
|
|
{
|
|
|
|
backgroundColor = backgroundAcrylicBrush.FallbackColor();
|
|
|
|
}
|
2019-11-05 00:45:40 +01:00
|
|
|
|
2020-05-16 00:43:00 +02:00
|
|
|
if (!_backgroundBrush || backgroundColor != _backgroundBrushColor)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
// Create brush for titlebar color.
|
2020-05-16 00:43:00 +02:00
|
|
|
_backgroundBrush = wil::unique_hbrush(CreateSolidBrush(backgroundColor));
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-11-05 00:45:40 +01:00
|
|
|
|
|
|
|
// To hide the original title bar, we have to paint on top of it with
|
|
|
|
// the alpha component set to 255. This is a hack to do it with GDI.
|
|
|
|
// See NonClientIslandWindow::_UpdateFrameMargins for more information.
|
|
|
|
HDC opaqueDc;
|
|
|
|
BP_PAINTPARAMS params = { sizeof(params), BPPF_NOCLIP | BPPF_ERASE };
|
|
|
|
HPAINTBUFFER buf = BeginBufferedPaint(hdc.get(), &rcRest, BPBF_TOPDOWNDIB, ¶ms, &opaqueDc);
|
|
|
|
if (!buf || !opaqueDc)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2021-11-05 20:26:59 +01:00
|
|
|
// MSFT:34673647 - BeginBufferedPaint can fail, but it probably
|
|
|
|
// shouldn't bring the whole Terminal down with it. So don't
|
|
|
|
// throw_last_error here.
|
|
|
|
LOG_LAST_ERROR();
|
|
|
|
return 0;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
::FillRect(opaqueDc, &rcRest, _backgroundBrush.get());
|
2020-03-20 21:35:12 +01:00
|
|
|
::BufferedPaintSetAlpha(buf, nullptr, 255);
|
2019-11-05 00:45:40 +01:00
|
|
|
::EndBufferedPaint(buf, TRUE);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
return 0;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
2019-11-05 00:45:40 +01:00
|
|
|
// - This method is called when the window receives the WM_NCCREATE message.
|
2019-05-03 00:29:04 +02:00
|
|
|
// Return Value:
|
2019-11-05 00:45:40 +01:00
|
|
|
// - The value returned from the window proc.
|
|
|
|
[[nodiscard]] LRESULT NonClientIslandWindow::_OnNcCreate(WPARAM wParam, LPARAM lParam) noexcept
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
const auto ret = IslandWindow::_OnNcCreate(wParam, lParam);
|
2020-06-22 23:51:34 +02:00
|
|
|
if (!ret)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2020-06-22 23:51:34 +02:00
|
|
|
return FALSE;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2020-06-22 17:38:07 +02:00
|
|
|
// This is a hack to make the window borders dark instead of light.
|
|
|
|
// It must be done before WM_NCPAINT so that the borders are rendered with
|
|
|
|
// the correct theme.
|
|
|
|
// For more information, see GH#6620.
|
|
|
|
LOG_IF_FAILED(TerminalTrySetDarkTheme(_window.get(), true));
|
2019-10-02 19:27:07 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
2019-10-02 19:27:07 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
// Method Description:
|
|
|
|
// - Called when the app wants to change its theme. We'll update the frame
|
|
|
|
// theme to match the new theme.
|
|
|
|
// Arguments:
|
|
|
|
// - requestedTheme: the ElementTheme to use as the new theme for the UI
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void NonClientIslandWindow::OnApplicationThemeChanged(const ElementTheme& requestedTheme)
|
|
|
|
{
|
|
|
|
IslandWindow::OnApplicationThemeChanged(requestedTheme);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-05 00:45:40 +01:00
|
|
|
_theme = requestedTheme;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
|
2020-07-13 19:40:20 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Enable or disable borderless mode. When entering borderless mode, we'll
|
|
|
|
// need to manually hide the entire titlebar.
|
|
|
|
// - See also IslandWindow::_SetIsBorderless, which does similar, but different work.
|
|
|
|
// Arguments:
|
|
|
|
// - borderlessEnabled: If true, we're entering borderless mode. If false, we're leaving.
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void NonClientIslandWindow::_SetIsBorderless(const bool borderlessEnabled)
|
|
|
|
{
|
|
|
|
_borderless = borderlessEnabled;
|
|
|
|
|
|
|
|
// Explicitly _don't_ call IslandWindow::_SetIsBorderless. That version will
|
|
|
|
// change the window styles appropriately for the window with the default
|
|
|
|
// titlebar, but for the tabs-in-titlebar mode, we can just get rid of the
|
|
|
|
// title bar entirely.
|
|
|
|
|
|
|
|
if (_titlebar)
|
|
|
|
{
|
|
|
|
_titlebar.Visibility(_IsTitlebarVisible() ? Visibility::Visible : Visibility::Collapsed);
|
|
|
|
}
|
|
|
|
|
2021-09-20 19:08:13 +02:00
|
|
|
// Update the margins when entering/leaving focus mode, so we can prevent
|
|
|
|
// the titlebar from showing through transparent terminal controls
|
|
|
|
_UpdateFrameMargins();
|
|
|
|
|
2020-07-13 19:40:20 +02:00
|
|
|
// GH#4224 - When the auto-hide taskbar setting is enabled, then we don't
|
|
|
|
// always get another window message to trigger us to remove the drag bar.
|
|
|
|
// So, make sure to update the size of the drag region here, so that it
|
|
|
|
// _definitely_ goes away.
|
|
|
|
_ResizeDragBarWindow();
|
|
|
|
|
|
|
|
// Resize the window, with SWP_FRAMECHANGED, to trigger user32 to
|
|
|
|
// recalculate the non/client areas
|
|
|
|
const til::rectangle windowPos{ GetWindowRect() };
|
|
|
|
SetWindowPos(GetHandle(),
|
|
|
|
HWND_TOP,
|
|
|
|
windowPos.left<int>(),
|
|
|
|
windowPos.top<int>(),
|
|
|
|
windowPos.width<int>(),
|
|
|
|
windowPos.height<int>(),
|
2020-10-14 00:40:56 +02:00
|
|
|
SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE);
|
2020-07-13 19:40:20 +02:00
|
|
|
}
|
|
|
|
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
// Method Description:
|
|
|
|
// - Enable or disable fullscreen mode. When entering fullscreen mode, we'll
|
|
|
|
// need to manually hide the entire titlebar.
|
|
|
|
// - See also IslandWindow::_SetIsFullscreen, which does additional work.
|
|
|
|
// Arguments:
|
|
|
|
// - fullscreenEnabled: If true, we're entering fullscreen mode. If false, we're leaving.
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void NonClientIslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
|
|
|
|
{
|
|
|
|
IslandWindow::_SetIsFullscreen(fullscreenEnabled);
|
2020-05-28 18:53:01 +02:00
|
|
|
if (_titlebar)
|
|
|
|
{
|
2020-07-13 19:40:20 +02:00
|
|
|
_titlebar.Visibility(_IsTitlebarVisible() ? Visibility::Visible : Visibility::Collapsed);
|
2020-05-28 18:53:01 +02:00
|
|
|
}
|
2020-03-13 23:20:39 +01:00
|
|
|
// GH#4224 - When the auto-hide taskbar setting is enabled, then we don't
|
|
|
|
// always get another window message to trigger us to remove the drag bar.
|
|
|
|
// So, make sure to update the size of the drag region here, so that it
|
|
|
|
// _definitely_ goes away.
|
2020-04-25 00:22:40 +02:00
|
|
|
_ResizeDragBarWindow();
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Returns true if the titlebar is visible. For things like fullscreen mode,
|
2020-07-13 19:40:20 +02:00
|
|
|
// borderless mode (aka "focus mode"), this will return false.
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
// Arguments:
|
|
|
|
// - <none>
|
|
|
|
// Return Value:
|
|
|
|
// - true iff the titlebar is visible
|
|
|
|
bool NonClientIslandWindow::_IsTitlebarVisible() const
|
|
|
|
{
|
2020-07-13 19:40:20 +02:00
|
|
|
return !(_fullscreen || _borderless);
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
}
|