2019-05-03 00:29:04 +02:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#include "pch.h"
|
|
|
|
#include "AppHost.h"
|
|
|
|
#include "../types/inc/Viewport.hpp"
|
2019-06-25 22:06:11 +02:00
|
|
|
#include "../types/inc/utils.hpp"
|
2020-01-27 16:34:12 +01:00
|
|
|
#include "../types/inc/User32Utils.hpp"
|
|
|
|
|
|
|
|
#include "resource.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-06-05 01:31:36 +02:00
|
|
|
using namespace ::Microsoft::Console;
|
2019-05-03 00:29:04 +02:00
|
|
|
using namespace ::Microsoft::Console::Types;
|
|
|
|
|
|
|
|
AppHost::AppHost() noexcept :
|
|
|
|
_app{},
|
2019-11-07 22:10:58 +01:00
|
|
|
_logic{ nullptr }, // don't make one, we're going to take a ref on app's
|
2019-05-03 00:29:04 +02:00
|
|
|
_window{ nullptr }
|
|
|
|
{
|
2019-11-07 22:10:58 +01:00
|
|
|
_logic = _app.Logic(); // get a ref to app's logic
|
|
|
|
|
|
|
|
_useNonClientArea = _logic.GetShowTabsInTitlebar();
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-01-27 16:34:12 +01:00
|
|
|
// If there were commandline args to our process, try and process them here.
|
|
|
|
// Do this before AppLogic::Create, otherwise this will have no effect
|
|
|
|
_HandleCommandlineArgs();
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
if (_useNonClientArea)
|
|
|
|
{
|
2019-11-07 22:10:58 +01:00
|
|
|
_window = std::make_unique<NonClientIslandWindow>(_logic.GetRequestedTheme());
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_window = std::make_unique<IslandWindow>();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tell the window to callback to us when it's about to handle a WM_CREATE
|
|
|
|
auto pfn = std::bind(&AppHost::_HandleCreateWindow,
|
|
|
|
this,
|
|
|
|
std::placeholders::_1,
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
std::placeholders::_2,
|
|
|
|
std::placeholders::_3);
|
2019-05-03 00:29:04 +02:00
|
|
|
_window->SetCreateCallback(pfn);
|
|
|
|
|
2020-01-08 22:19:23 +01:00
|
|
|
_window->SetSnapDimensionCallback(std::bind(&winrt::TerminalApp::AppLogic::CalcSnappedDimension,
|
|
|
|
_logic,
|
|
|
|
std::placeholders::_1,
|
|
|
|
std::placeholders::_2));
|
Manually pass mouse wheel messages to TermControls (#5131)
## Summary of the Pull Request
As we've learned in #979, not all touchpads are created equal. Some of them have bad drivers that makes scrolling inactive windows not work. For whatever reason, these devices think the Terminal is all one giant inactive window, so we don't get the mouse wheel events through the XAML stack. We do however get the event as a `WM_MOUSEWHEEL` on those devices (a message we don't get on devices with normally functioning trackpads).
This PR attempts to take that `WM_MOUSEWHEEL` and manually dispatch it to the `TermControl`, so we can at least scroll the terminal content.
Unfortunately, this solution is not very general purpose. This only works to scroll controls that manually implement our own `IMouseWheelListener` interface. As we add more controls, we'll need to continue manually implementing this interface, until the underlying XAML Islands bug is fixed. **I don't love this**. I'd rather have a better solution, but it seems that we can't synthesize a more general-purpose `PointerWheeled` event that could get routed through the XAML tree as normal.
## References
* #2606 and microsoft/microsoft-ui-xaml#2101 - these bugs are also tracking a similar "inactive windows" / "scaled mouse events" issue in XAML
## PR Checklist
* [x] Closes #979
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
I've also added a `til::point` conversion _to_ `winrt::Windows::Foundation::Point`, and some scaling operators for `point`
## Validation Steps Performed
* It works on my HP Spectre 2017 with a synaptics trackpad
- I also made sure to test that `tmux` works in panes on this laptop
* It works on my slaptop, and DOESN'T follow this hack codepath on this machine.
2020-04-01 18:58:16 +02:00
|
|
|
_window->MouseScrolled({ this, &AppHost::_WindowMouseWheeled });
|
2019-05-03 00:29:04 +02:00
|
|
|
_window->MakeWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
AppHost::~AppHost()
|
|
|
|
{
|
2019-06-27 00:15:01 +02:00
|
|
|
// destruction order is important for proper teardown here
|
|
|
|
_window = nullptr;
|
2019-06-25 22:06:11 +02:00
|
|
|
_app.Close();
|
2019-06-27 00:15:01 +02:00
|
|
|
_app = nullptr;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2020-06-12 00:41:16 +02:00
|
|
|
bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const bool down)
|
2020-03-05 21:35:46 +01:00
|
|
|
{
|
|
|
|
if (_logic)
|
|
|
|
{
|
2020-06-12 00:41:16 +02:00
|
|
|
return _logic.OnDirectKeyEvent(vkey, down);
|
2020-03-05 21:35:46 +01:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-01-27 16:34:12 +01:00
|
|
|
// Method Description:
|
|
|
|
// - Retrieve any commandline args passed on the commandline, and pass them to
|
|
|
|
// the app logic for processing.
|
|
|
|
// - If the logic determined there's an error while processing that commandline,
|
|
|
|
// display a message box to the user with the text of the error, and exit.
|
|
|
|
// * We display a message box because we're a Win32 application (not a
|
|
|
|
// console app), and the shell has undoubtedly returned to the foreground
|
|
|
|
// of the console. Text emitted here might mix unexpectedly with output
|
|
|
|
// from the shell process.
|
|
|
|
// Arguments:
|
|
|
|
// - <none>
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void AppHost::_HandleCommandlineArgs()
|
|
|
|
{
|
|
|
|
if (auto commandline{ GetCommandLineW() })
|
|
|
|
{
|
|
|
|
int argc = 0;
|
|
|
|
|
|
|
|
// Get the argv, and turn them into a hstring array to pass to the app.
|
|
|
|
wil::unique_any<LPWSTR*, decltype(&::LocalFree), ::LocalFree> argv{ CommandLineToArgvW(commandline, &argc) };
|
|
|
|
if (argv)
|
|
|
|
{
|
|
|
|
std::vector<winrt::hstring> args;
|
|
|
|
for (auto& elem : wil::make_range(argv.get(), argc))
|
|
|
|
{
|
|
|
|
args.emplace_back(elem);
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto result = _logic.SetStartupCommandline({ args });
|
2020-05-04 22:56:15 +02:00
|
|
|
const auto message = _logic.ParseCommandlineMessage();
|
2020-01-27 16:34:12 +01:00
|
|
|
if (!message.empty())
|
|
|
|
{
|
|
|
|
const auto displayHelp = result == 0;
|
|
|
|
const auto messageTitle = displayHelp ? IDS_HELP_DIALOG_TITLE : IDS_ERROR_DIALOG_TITLE;
|
|
|
|
const auto messageIcon = displayHelp ? MB_ICONWARNING : MB_ICONERROR;
|
|
|
|
// TODO:GH#4134: polish this dialog more, to make the text more
|
|
|
|
// like msiexec /?
|
|
|
|
MessageBoxW(nullptr,
|
|
|
|
message.data(),
|
|
|
|
GetStringResource(messageTitle).data(),
|
|
|
|
MB_OK | messageIcon);
|
|
|
|
|
2020-05-04 22:56:15 +02:00
|
|
|
if (_logic.ShouldExitEarly())
|
|
|
|
{
|
|
|
|
ExitProcess(result);
|
|
|
|
}
|
2020-01-27 16:34:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Initializes the XAML island, creates the terminal app, and sets the
|
|
|
|
// island's content to that of the terminal app's content. Also registers some
|
|
|
|
// callbacks with TermApp.
|
|
|
|
// !!! IMPORTANT!!!
|
|
|
|
// This must be called *AFTER* WindowsXamlManager::InitializeForCurrentThread.
|
|
|
|
// If it isn't, then we won't be able to create the XAML island.
|
|
|
|
// Arguments:
|
|
|
|
// - <none>
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void AppHost::Initialize()
|
|
|
|
{
|
|
|
|
_window->Initialize();
|
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
|
|
|
|
|
|
|
if (_useNonClientArea)
|
|
|
|
{
|
2020-02-10 21:40:01 +01:00
|
|
|
// Register our callback for when the app's non-client content changes.
|
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
|
|
|
// This has to be done _before_ App::Create, as the app might set the
|
|
|
|
// content in Create.
|
2019-11-07 22:10:58 +01:00
|
|
|
_logic.SetTitleBarContent({ this, &AppHost::_UpdateTitleBarContent });
|
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
|
|
|
}
|
2019-08-16 23:18:29 +02:00
|
|
|
|
2019-10-11 02:09:07 +02:00
|
|
|
// Register the 'X' button of the window for a warning experience of multiple
|
|
|
|
// tabs opened, this is consistent with Alt+F4 closing
|
2019-11-07 22:10:58 +01:00
|
|
|
_window->WindowCloseButtonClicked([this]() { _logic.WindowCloseButtonClicked(); });
|
2019-10-11 02:09:07 +02:00
|
|
|
|
2019-08-16 23:18:29 +02:00
|
|
|
// Add an event handler to plumb clicks in the titlebar area down to the
|
|
|
|
// application layer.
|
2019-11-07 22:10:58 +01:00
|
|
|
_window->DragRegionClicked([this]() { _logic.TitlebarClicked(); });
|
2019-08-16 23:18:29 +02:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
_logic.RequestedThemeChanged({ this, &AppHost::_UpdateTheme });
|
|
|
|
_logic.ToggleFullscreen({ this, &AppHost::_ToggleFullscreen });
|
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
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
_logic.Create();
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
_logic.TitleChanged({ this, &AppHost::AppTitleChanged });
|
|
|
|
_logic.LastTabClosed({ this, &AppHost::LastTabClosed });
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
_window->UpdateTitle(_logic.Title());
|
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
|
|
|
// Set up the content of the application. If the app has a custom titlebar,
|
|
|
|
// set that content as well.
|
2019-11-07 22:10:58 +01:00
|
|
|
_window->SetContent(_logic.GetRoot());
|
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
|
|
|
_window->OnAppInitialized();
|
Intentionally leak our Application, so that we DON'T crash on exit (#5629)
We've got a weird crash that happens terribly inconsistently, but pretty
readily on migrie's laptop, only in Debug mode. Apparently, there's some
weird ref-counting magic that goes on during teardown, and our
Application doesn't get closed quite right, which can cause us to crash
into the debugger. This of course, only happens on exit, and happens
somewhere in the `...XamlHost.dll` code.
Crazily, if we _manually leak the `Application`_ here, then the crash
doesn't happen. This doesn't matter, because we really want the
Application to live for _the entire lifetime of the process_, so the only
time when this object would actually need to get cleaned up is _during
exit_. So we can safely leak this `Application` object, and have it just
get cleaned up normally when our process exits.
* [x] I discussed this with @DHowett-MSFT and we both agree this is mental
* [x] I'm pretty sure there's not an actual bug on our repo for this
* [x] I verified on my machine where I can crash the terminal 100% of the time on exit in debug, this fixes it
* [x] I verified that it doesn't introduce a _new_ crash in Release on my machine
2020-04-30 21:36:02 +02:00
|
|
|
|
|
|
|
// THIS IS A HACK
|
|
|
|
//
|
|
|
|
// We've got a weird crash that happens terribly inconsistently, but pretty
|
|
|
|
// readily on migrie's laptop, only in Debug mode. Apparently, there's some
|
|
|
|
// weird ref-counting magic that goes on during teardown, and our
|
|
|
|
// Application doesn't get closed quite right, which can cause us to crash
|
|
|
|
// into the debugger. This of course, only happens on exit, and happens
|
|
|
|
// somewhere in the XamlHost.dll code.
|
|
|
|
//
|
|
|
|
// Crazily, if we _manually leak the Application_ here, then the crash
|
|
|
|
// doesn't happen. This doesn't matter, because we really want the
|
|
|
|
// Application to live for _the entire lifetime of the process_, so the only
|
|
|
|
// time when this object would actually need to get cleaned up is _during
|
|
|
|
// exit_. So we can safely leak this Application object, and have it just
|
|
|
|
// get cleaned up normally when our process exits.
|
|
|
|
::winrt::TerminalApp::App a{ _app };
|
|
|
|
::winrt::detach_abi(a);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Called when the app's title changes. Fires off a window message so we can
|
|
|
|
// update the window's title on the main thread.
|
|
|
|
// Arguments:
|
2019-09-04 23:34:06 +02:00
|
|
|
// - sender: unused
|
2019-05-03 00:29:04 +02:00
|
|
|
// - newTitle: the string to use as the new window title
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
2019-09-05 01:43:45 +02:00
|
|
|
void AppHost::AppTitleChanged(const winrt::Windows::Foundation::IInspectable& /*sender*/, winrt::hstring newTitle)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2020-01-27 19:23:13 +01:00
|
|
|
_window->UpdateTitle(newTitle);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-05-15 14:22:16 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Called when no tab is remaining to close the window.
|
|
|
|
// Arguments:
|
2019-09-04 23:34:06 +02:00
|
|
|
// - sender: unused
|
|
|
|
// - LastTabClosedEventArgs: unused
|
2019-05-15 14:22:16 +02:00
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
2019-09-05 01:43:45 +02:00
|
|
|
void AppHost::LastTabClosed(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::TerminalApp::LastTabClosedEventArgs& /*args*/)
|
2019-06-11 22:27:09 +02:00
|
|
|
{
|
2019-05-15 14:22:16 +02:00
|
|
|
_window->Close();
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Resize the window we're about to create to the appropriate dimensions, as
|
|
|
|
// specified in the settings. This will be called during the handling of
|
|
|
|
// WM_CREATE. We'll load the settings for the app, then get the proposed size
|
|
|
|
// of the terminal from the app. Using that proposed size, we'll resize the
|
|
|
|
// window we're creating, so that it'll match the values in the settings.
|
|
|
|
// Arguments:
|
|
|
|
// - hwnd: The HWND of the window we're about to create.
|
|
|
|
// - proposedRect: The location and size of the window that we're about to
|
|
|
|
// create. We'll use this rect to determine which monitor the window is about
|
|
|
|
// to appear on.
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
// - launchMode: A LaunchMode enum reference that indicates the launch mode
|
2019-05-03 00:29:04 +02:00
|
|
|
// Return Value:
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
// - None
|
|
|
|
void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::TerminalApp::LaunchMode& launchMode)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-11-07 22:10:58 +01:00
|
|
|
launchMode = _logic.GetLaunchMode();
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
|
2020-02-10 21:40:01 +01:00
|
|
|
// Acquire the actual initial position
|
2019-11-07 22:10:58 +01:00
|
|
|
winrt::Windows::Foundation::Point initialPosition = _logic.GetLaunchInitialPositions(proposedRect.left, proposedRect.top);
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
proposedRect.left = gsl::narrow_cast<long>(initialPosition.X);
|
|
|
|
proposedRect.top = gsl::narrow_cast<long>(initialPosition.Y);
|
|
|
|
|
|
|
|
long adjustedHeight = 0;
|
|
|
|
long adjustedWidth = 0;
|
2020-05-28 18:53:01 +02:00
|
|
|
|
|
|
|
// Find nearest monitor.
|
|
|
|
HMONITOR hmon = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);
|
|
|
|
|
|
|
|
// Get nearest monitor information
|
|
|
|
MONITORINFO monitorInfo;
|
|
|
|
monitorInfo.cbSize = sizeof(MONITORINFO);
|
|
|
|
GetMonitorInfo(hmon, &monitorInfo);
|
|
|
|
|
|
|
|
// This API guarantees that dpix and dpiy will be equal, but neither is an
|
|
|
|
// optional parameter so give two UINTs.
|
|
|
|
UINT dpix = USER_DEFAULT_SCREEN_DPI;
|
|
|
|
UINT dpiy = USER_DEFAULT_SCREEN_DPI;
|
|
|
|
// If this fails, we'll use the default of 96.
|
|
|
|
GetDpiForMonitor(hmon, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
|
|
|
|
|
|
|
|
// We need to check if the top left point of the titlebar of the window is within any screen
|
|
|
|
RECT offScreenTestRect;
|
|
|
|
offScreenTestRect.left = proposedRect.left;
|
|
|
|
offScreenTestRect.top = proposedRect.top;
|
|
|
|
offScreenTestRect.right = offScreenTestRect.left + 1;
|
|
|
|
offScreenTestRect.bottom = offScreenTestRect.top + 1;
|
|
|
|
|
|
|
|
bool isTitlebarIntersectWithMonitors = false;
|
|
|
|
EnumDisplayMonitors(
|
|
|
|
nullptr, &offScreenTestRect, [](HMONITOR, HDC, LPRECT, LPARAM lParam) -> BOOL {
|
|
|
|
auto intersectWithMonitor = reinterpret_cast<bool*>(lParam);
|
|
|
|
*intersectWithMonitor = true;
|
|
|
|
// Continue the enumeration
|
|
|
|
return FALSE;
|
|
|
|
},
|
|
|
|
reinterpret_cast<LPARAM>(&isTitlebarIntersectWithMonitors));
|
|
|
|
|
|
|
|
if (!isTitlebarIntersectWithMonitors)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2020-05-28 18:53:01 +02:00
|
|
|
// If the title bar is out-of-screen, we set the initial position to
|
|
|
|
// the top left corner of the nearest monitor
|
|
|
|
proposedRect.left = monitorInfo.rcWork.left;
|
|
|
|
proposedRect.top = monitorInfo.rcWork.top;
|
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-05-28 18:53:01 +02:00
|
|
|
auto initialSize = _logic.GetLaunchDimensions(dpix);
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
|
2020-05-28 18:53:01 +02:00
|
|
|
const short islandWidth = Utils::ClampToShortMax(
|
|
|
|
static_cast<long>(ceil(initialSize.X)), 1);
|
|
|
|
const short islandHeight = Utils::ClampToShortMax(
|
|
|
|
static_cast<long>(ceil(initialSize.Y)), 1);
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
|
2020-05-28 18:53:01 +02:00
|
|
|
// Get the size of a window we'd need to host that client rect. This will
|
|
|
|
// add the titlebar space.
|
|
|
|
const auto nonClientSize = _window->GetTotalNonClientExclusiveSize(dpix);
|
|
|
|
adjustedWidth = islandWidth + nonClientSize.cx;
|
|
|
|
adjustedHeight = islandHeight + nonClientSize.cy;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
const COORD origin{ gsl::narrow<short>(proposedRect.left),
|
|
|
|
gsl::narrow<short>(proposedRect.top) };
|
2019-06-05 01:31:36 +02:00
|
|
|
const COORD dimensions{ Utils::ClampToShortMax(adjustedWidth, 1),
|
|
|
|
Utils::ClampToShortMax(adjustedHeight, 1) };
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
const auto newPos = Viewport::FromDimensions(origin, dimensions);
|
2019-06-11 22:27:09 +02:00
|
|
|
bool succeeded = SetWindowPos(hwnd,
|
|
|
|
nullptr,
|
2019-05-03 00:29:04 +02:00
|
|
|
newPos.Left(),
|
|
|
|
newPos.Top(),
|
|
|
|
newPos.Width(),
|
|
|
|
newPos.Height(),
|
|
|
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
|
|
|
|
2020-02-10 21:40:01 +01:00
|
|
|
// Refresh the dpi of HWND because the dpi where the window will launch may be different
|
Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:
1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.
3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.
# Testing
To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
"initialPosition": "1000, 1000",
"launchMode": "default"
My test data:
I have already tested with the following variables:
1. showTabsInTitlebar true or false
2. The initial position of the top left corner of the window
3. Whether to launch maximized
4. The DPI of the monitor
Test data combination:
Non-client island window (showTabsInTitlebar true)
1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
launchMode: default
In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
(-100, 200), (-2000, 100), (0, 1119)
out-of-screen:
(200, -200): initialize to (0, 0)
(200, 1500): initialize to (0, 0)
(2000, -200): initialize to (1920, 0)
(2500, 2000): initialize to (1920, 0)
(4000 100): initialize to (1920, 0)
(-1000, -100): initialize to (-1920, 0)
(-3000, 100): initialize to (-1920, 0)
(10000, -10000): initialize to (1920, 0)
(-10000, 10000): initialize to (-1920, 0)
(0, -10000): initialize to (0, 0)
(0, -1): initialize to (0, 0)
(0, 1200): initialize to (0, 0)
launch mode: maximize
(100, 100)
(-1000, 100): On the left monitor
(0, -2000): On the primary monitor
(10000, 10000): On the primary monitor
2. Left monitor 200% DPI, primary monitor 100% DPI
In screen: (-1900, 100), (-3000, 100), (-1000, 100)
our-of-screen: (-8000, 100): initialize at (-1920, 0)
launch Maximized: (-100, 100): launch maximized on the left monitor
correctly
3. Left monitor 100% DPI, primary monitor 200% DPI
In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
out-of-screen: (-3000, 100): initialize at (-1920, 0)
launch maximized: (100, 100), (-1000, 100)
For client island window, the test data is the same as above.
Issues:
1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.
Closes #1043
2019-10-17 06:51:50 +02:00
|
|
|
// at this time
|
|
|
|
_window->RefreshCurrentDPI();
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// If we can't resize the window, that's really okay. We can just go on with
|
|
|
|
// the originally proposed window size.
|
|
|
|
LOG_LAST_ERROR_IF(!succeeded);
|
2019-09-05 22:38:42 +02:00
|
|
|
|
|
|
|
TraceLoggingWrite(
|
|
|
|
g_hWindowsTerminalProvider,
|
|
|
|
"WindowCreated",
|
|
|
|
TraceLoggingDescription("Event emitted upon creating the application window"),
|
|
|
|
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
|
|
|
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
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
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Called when the app wants to set its titlebar content. We'll take the
|
|
|
|
// UIElement and set the Content property of our Titlebar that element.
|
|
|
|
// Arguments:
|
|
|
|
// - sender: unused
|
|
|
|
// - arg: the UIElement to use as the new Titlebar content.
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
2019-09-04 23:34:06 +02:00
|
|
|
void AppHost::_UpdateTitleBarContent(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::UI::Xaml::UIElement& arg)
|
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
|
|
|
{
|
|
|
|
if (_useNonClientArea)
|
|
|
|
{
|
|
|
|
(static_cast<NonClientIslandWindow*>(_window.get()))->SetTitlebarContent(arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Called when the app wants to change its theme. We'll forward this to the
|
|
|
|
// IslandWindow, so it can update the root UI element of the entire XAML tree.
|
|
|
|
// Arguments:
|
|
|
|
// - sender: unused
|
|
|
|
// - arg: the ElementTheme to use as the new theme for the UI
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
2019-11-07 22:10:58 +01:00
|
|
|
void AppHost::_UpdateTheme(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::UI::Xaml::ElementTheme& arg)
|
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
|
|
|
{
|
2019-11-05 00:45:40 +01:00
|
|
|
_window->OnApplicationThemeChanged(arg);
|
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
|
|
|
}
|
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
|
|
|
|
|
|
|
void AppHost::_ToggleFullscreen(const winrt::Windows::Foundation::IInspectable&,
|
|
|
|
const winrt::TerminalApp::ToggleFullscreenEventArgs&)
|
|
|
|
{
|
|
|
|
_window->ToggleFullscreen();
|
|
|
|
}
|
Manually pass mouse wheel messages to TermControls (#5131)
## Summary of the Pull Request
As we've learned in #979, not all touchpads are created equal. Some of them have bad drivers that makes scrolling inactive windows not work. For whatever reason, these devices think the Terminal is all one giant inactive window, so we don't get the mouse wheel events through the XAML stack. We do however get the event as a `WM_MOUSEWHEEL` on those devices (a message we don't get on devices with normally functioning trackpads).
This PR attempts to take that `WM_MOUSEWHEEL` and manually dispatch it to the `TermControl`, so we can at least scroll the terminal content.
Unfortunately, this solution is not very general purpose. This only works to scroll controls that manually implement our own `IMouseWheelListener` interface. As we add more controls, we'll need to continue manually implementing this interface, until the underlying XAML Islands bug is fixed. **I don't love this**. I'd rather have a better solution, but it seems that we can't synthesize a more general-purpose `PointerWheeled` event that could get routed through the XAML tree as normal.
## References
* #2606 and microsoft/microsoft-ui-xaml#2101 - these bugs are also tracking a similar "inactive windows" / "scaled mouse events" issue in XAML
## PR Checklist
* [x] Closes #979
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
I've also added a `til::point` conversion _to_ `winrt::Windows::Foundation::Point`, and some scaling operators for `point`
## Validation Steps Performed
* It works on my HP Spectre 2017 with a synaptics trackpad
- I also made sure to test that `tmux` works in panes on this laptop
* It works on my slaptop, and DOESN'T follow this hack codepath on this machine.
2020-04-01 18:58:16 +02:00
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Called when the IslandWindow has received a WM_MOUSEWHEEL message. This can
|
|
|
|
// happen on some laptops, where their trackpads won't scroll inactive windows
|
|
|
|
// _ever_.
|
|
|
|
// - We're going to take that message and manually plumb it through to our
|
|
|
|
// TermControl's, or anything else that implements IMouseWheelListener.
|
|
|
|
// - See GH#979 for more details.
|
|
|
|
// Arguments:
|
|
|
|
// - coord: The Window-relative, logical coordinates location of the mouse during this event.
|
|
|
|
// - delta: the wheel delta that triggered this event.
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void AppHost::_WindowMouseWheeled(const til::point coord, const int32_t delta)
|
|
|
|
{
|
|
|
|
if (_logic)
|
|
|
|
{
|
|
|
|
// Find all the elements that are underneath the mouse
|
|
|
|
auto elems = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::FindElementsInHostCoordinates(coord, _logic.GetRoot());
|
|
|
|
for (const auto& e : elems)
|
|
|
|
{
|
|
|
|
// If that element has implemented IMouseWheelListener, call OnMouseWheel on that element.
|
|
|
|
if (auto control{ e.try_as<winrt::Microsoft::Terminal::TerminalControl::IMouseWheelListener>() })
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// Translate the event to the coordinate space of the control
|
|
|
|
// we're attempting to dispatch it to
|
|
|
|
const auto transform = e.TransformToVisual(nullptr);
|
|
|
|
const til::point controlOrigin{ til::math::flooring, transform.TransformPoint(til::point{ 0, 0 }) };
|
|
|
|
|
|
|
|
const til::point offsetPoint = coord - controlOrigin;
|
|
|
|
|
|
|
|
if (control.OnMouseWheel(offsetPoint, delta))
|
|
|
|
{
|
|
|
|
// If the element handled the mouse wheel event, don't
|
|
|
|
// continue to iterate over the remaining controls.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CATCH_LOG();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|