Merge remote-tracking branch 'origin/master' into dev/migrie/f/non-terminal-panes

# Conflicts:
#	src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj
This commit is contained in:
Mike Griese 2019-07-19 07:58:16 -05:00
commit 141d0d4d1c
38 changed files with 667 additions and 194 deletions

View file

@ -61,26 +61,13 @@ namespace winrt::TerminalApp::implementation
// - <none>
// Return Value:
// - <none>
void App::Create(uint64_t hWnd)
void App::Create()
{
// Assert that we've already loaded our settings. We have to do
// this as a MTA, before the app is Create()'d
WINRT_ASSERT(_loadedInitialSettings);
TraceLoggingRegister(g_hTerminalAppProvider);
_Create(hWnd);
}
App::~App()
{
TraceLoggingUnregister(g_hTerminalAppProvider);
}
// Method Description:
// - Create all of the initial UI elements of the Terminal app.
// * Initializes the first terminal control, using the default profile,
// and adds it to our list of tabs.
void App::_Create(uint64_t parentHwnd)
{
/* !!! TODO
This is not the correct way to host a XAML page. This exists today because we valued
getting a .xaml over tearing out all of the terminal logic and splitting it across App
@ -92,15 +79,21 @@ namespace winrt::TerminalApp::implementation
_root = terminalPage.as<winrt::Windows::UI::Xaml::Controls::Control>();
_tabContent = terminalPage->TabContent();
_tabRow = terminalPage->TabRow();
_tabView = terminalPage->TabView();
_newTabButton = terminalPage->NewTabButton();
_tabView = _tabRow.TabView();
_newTabButton = _tabRow.NewTabButton();
_minMaxCloseControl = terminalPage->MinMaxCloseControl();
_minMaxCloseControl.ParentWindowHandle(parentHwnd);
if (!_settings->GlobalSettings().GetShowTabsInTitlebar())
if (_settings->GlobalSettings().GetShowTabsInTitlebar())
{
_minMaxCloseControl.Visibility(Visibility::Collapsed);
// Remove the TabView from the page. We'll hang on to it, we need to
// put it in the titlebar.
uint32_t index = 0;
if (terminalPage->Root().Children().IndexOf(_tabRow, index))
{
terminalPage->Root().Children().RemoveAt(index);
}
// Inform the host that our titlebar content has changed.
_setTitleBarContentHandlers(*this, _tabRow);
}
// Event Bindings (Early)
@ -118,6 +111,14 @@ namespace winrt::TerminalApp::implementation
_tabContent.SizeChanged({ this, &App::_OnContentSizeChanged });
}
App::~App()
{
if (g_hTerminalAppProvider)
{
TraceLoggingUnregister(g_hTerminalAppProvider);
}
}
// Method Description:
// - Show a ContentDialog with a single button to dismiss. Uses the
// FrameworkElements provided as the title and content of this dialog, and
@ -456,16 +457,6 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::System::Launcher::LaunchUriAsync({ feedbackUriValue });
}
Windows::UI::Xaml::Controls::Border App::GetDragBar() noexcept
{
if (_minMaxCloseControl)
{
return _minMaxCloseControl.DragBar();
}
return nullptr;
}
// Method Description:
// - Called when the about button is clicked. See _ShowAboutDialog for more info.
// Arguments:
@ -493,6 +484,7 @@ namespace winrt::TerminalApp::implementation
bindings.NewTab([this]() { _OpenNewTab(std::nullopt); });
bindings.DuplicateTab([this]() { _DuplicateTabViewItem(); });
bindings.CloseTab([this]() { _CloseFocusedTab(); });
bindings.ClosePane([this]() { _CloseFocusedPane(); });
bindings.NewTabWithProfile([this](const auto index) { _OpenNewTab({ index }); });
bindings.ScrollUp([this]() { _Scroll(-1); });
bindings.ScrollDown([this]() { _Scroll(1); });
@ -743,13 +735,16 @@ namespace winrt::TerminalApp::implementation
}
// Method Description:
// - Update the current theme of the application. This will manually update
// all of the elements in our UI to match the given theme.
// - Update the current theme of the application. This will trigger our
// RequestedThemeChanged event, to have our host change the theme of the
// root of the application.
// Arguments:
// - newTheme: The ElementTheme to apply to our elements.
void App::_ApplyTheme(const Windows::UI::Xaml::ElementTheme& newTheme)
{
_root.RequestedTheme(newTheme);
// Propagate the event to the host layer, so it can update its own UI
_requestedThemeChangedHandlers(*this, newTheme);
}
UIElement App::GetRoot() noexcept
@ -918,7 +913,11 @@ namespace winrt::TerminalApp::implementation
// Initialize the new tab
// Create a Conhost connection based on the values in our settings object.
TerminalConnection::ITerminalConnection connection = TerminalConnection::ConhostConnection(settings.Commandline(), settings.StartingDirectory(), 30, 80, winrt::guid());
auto connection = TerminalConnection::ConhostConnection(settings.Commandline(),
settings.StartingDirectory(),
30,
80,
winrt::guid());
TermControl term{ settings, connection };
TermControlHost controlHost{ term };
@ -989,6 +988,17 @@ namespace winrt::TerminalApp::implementation
_RemoveTabViewItem(focusedTab->GetTabViewItem());
}
// Method Description:
// - Close the currently focused pane. If the pane is the last pane in the
// tab, the tab will also be closed. This will happen when we handle the
// tab's Closed event.
void App::_CloseFocusedPane()
{
int focusedTabIndex = _GetFocusedTabIndex();
std::shared_ptr<Tab> focusedTab{ _tabs[focusedTabIndex] };
focusedTab->ClosePane();
}
// Method Description:
// - Move the viewport of the terminal of the currently focused tab up or
// down a number of lines. Negative values of `delta` will move the
@ -1322,7 +1332,11 @@ namespace winrt::TerminalApp::implementation
const auto controlSettings = _settings->MakeSettings(realGuid);
// Create a Conhost connection based on the values in our settings object.
TerminalConnection::ITerminalConnection controlConnection = TerminalConnection::ConhostConnection(controlSettings.Commandline(), controlSettings.StartingDirectory(), 30, 80, winrt::guid());
auto controlConnection = TerminalConnection::ConhostConnection(controlSettings.Commandline(),
controlSettings.StartingDirectory(),
30,
80,
winrt::guid());
TermControl newControl{ controlSettings, controlConnection };
TermControlHost controlHost{ newControl };
@ -1449,4 +1463,6 @@ namespace winrt::TerminalApp::implementation
// These macros will define them both for you.
DEFINE_EVENT(App, TitleChanged, _titleChangeHandlers, TerminalControl::TitleChangedEventArgs);
DEFINE_EVENT(App, LastTabClosed, _lastTabClosedHandlers, winrt::TerminalApp::LastTabClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(App, SetTitleBarContent, _setTitleBarContentHandlers, TerminalApp::App, winrt::Windows::UI::Xaml::UIElement);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(App, RequestedThemeChanged, _requestedThemeChangedHandlers, TerminalApp::App, winrt::Windows::UI::Xaml::ElementTheme);
}

View file

@ -27,10 +27,7 @@ namespace winrt::TerminalApp::implementation
Windows::UI::Xaml::UIElement GetRoot() noexcept;
// Gets the current dragglable area in the non client region of the top level window
Windows::UI::Xaml::Controls::Border GetDragBar() noexcept;
void Create(uint64_t hParentWnd);
void Create();
void LoadSettings();
Windows::Foundation::Point GetLaunchDimensions(uint32_t dpi);
@ -43,6 +40,8 @@ namespace winrt::TerminalApp::implementation
// -------------------------------- WinRT Events ---------------------------------
DECLARE_EVENT(TitleChanged, _titleChangeHandlers, winrt::Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
DECLARE_EVENT(LastTabClosed, _lastTabClosedHandlers, winrt::TerminalApp::LastTabClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTitleBarContent, _setTitleBarContentHandlers, TerminalApp::App, winrt::Windows::UI::Xaml::UIElement);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(RequestedThemeChanged, _requestedThemeChangedHandlers, TerminalApp::App, winrt::Windows::UI::Xaml::ElementTheme);
private:
// If you add controls here, but forget to null them either here or in
@ -53,10 +52,9 @@ namespace winrt::TerminalApp::implementation
// (which is a root when the tabs are in the titlebar.)
Windows::UI::Xaml::Controls::Control _root{ nullptr };
Microsoft::UI::Xaml::Controls::TabView _tabView{ nullptr };
Windows::UI::Xaml::Controls::Grid _tabRow{ nullptr };
TerminalApp::TabRowControl _tabRow{ nullptr };
Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr };
Windows::UI::Xaml::Controls::SplitButton _newTabButton{ nullptr };
winrt::TerminalApp::MinMaxCloseControl _minMaxCloseControl{ nullptr };
std::vector<std::shared_ptr<Tab>> _tabs;
@ -71,7 +69,6 @@ namespace winrt::TerminalApp::implementation
std::atomic<bool> _settingsReloadQueued{ false };
void _Create(uint64_t parentHWnd);
void _CreateNewTabFlyout();
fire_and_forget _ShowDialog(const winrt::Windows::Foundation::IInspectable& titleElement,
@ -105,6 +102,7 @@ namespace winrt::TerminalApp::implementation
void _OpenNewTab(std::optional<int> profileIndex);
void _DuplicateTabViewItem();
void _CloseFocusedTab();
void _CloseFocusedPane();
void _SelectNextTab(const bool bMoveRight);
void _SelectTab(const int tabIndex);

View file

@ -4,8 +4,7 @@
namespace TerminalApp
{
delegate void LastTabClosedEventArgs();
[default_interface]
runtimeclass App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication
[default_interface] runtimeclass App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication
{
App();
@ -16,18 +15,19 @@ namespace TerminalApp
// then it might look like TermApp just failed to activate, which will
// cause you to chase down the rabbit hole of "why is TermApp not
// registered?" when it definitely is.
void Create(UInt64 hParentWnd);
void Create();
void LoadSettings();
Windows.UI.Xaml.UIElement GetRoot();
Windows.UI.Xaml.Controls.Border GetDragBar{ get; };
Windows.Foundation.Point GetLaunchDimensions(UInt32 dpi);
Boolean GetShowTabsInTitlebar();
event Microsoft.Terminal.TerminalControl.TitleChangedEventArgs TitleChanged;
event LastTabClosedEventArgs LastTabClosed;
event Windows.Foundation.TypedEventHandler<App, Windows.UI.Xaml.UIElement> SetTitleBarContent;
event Windows.Foundation.TypedEventHandler<App, Windows.UI.Xaml.ElementTheme> RequestedThemeChanged;
String GetTitle();
}

View file

@ -102,6 +102,9 @@ namespace winrt::TerminalApp::implementation
case ShortcutAction::CloseTab:
_CloseTabHandlers();
return true;
case ShortcutAction::ClosePane:
_ClosePaneHandlers();
return true;
case ShortcutAction::ScrollUp:
_ScrollUpHandlers();
@ -254,6 +257,7 @@ namespace winrt::TerminalApp::implementation
DEFINE_EVENT(AppKeyBindings, NewWindow, _NewWindowHandlers, TerminalApp::NewWindowEventArgs);
DEFINE_EVENT(AppKeyBindings, CloseWindow, _CloseWindowHandlers, TerminalApp::CloseWindowEventArgs);
DEFINE_EVENT(AppKeyBindings, CloseTab, _CloseTabHandlers, TerminalApp::CloseTabEventArgs);
DEFINE_EVENT(AppKeyBindings, ClosePane, _ClosePaneHandlers, TerminalApp::ClosePaneEventArgs);
DEFINE_EVENT(AppKeyBindings, SwitchToTab, _SwitchToTabHandlers, TerminalApp::SwitchToTabEventArgs);
DEFINE_EVENT(AppKeyBindings, NextTab, _NextTabHandlers, TerminalApp::NextTabEventArgs);
DEFINE_EVENT(AppKeyBindings, PrevTab, _PrevTabHandlers, TerminalApp::PrevTabEventArgs);

View file

@ -48,6 +48,7 @@ namespace winrt::TerminalApp::implementation
DECLARE_EVENT(NewWindow, _NewWindowHandlers, TerminalApp::NewWindowEventArgs);
DECLARE_EVENT(CloseWindow, _CloseWindowHandlers, TerminalApp::CloseWindowEventArgs);
DECLARE_EVENT(CloseTab, _CloseTabHandlers, TerminalApp::CloseTabEventArgs);
DECLARE_EVENT(ClosePane, _ClosePaneHandlers, TerminalApp::ClosePaneEventArgs);
DECLARE_EVENT(SwitchToTab, _SwitchToTabHandlers, TerminalApp::SwitchToTabEventArgs);
DECLARE_EVENT(NextTab, _NextTabHandlers, TerminalApp::NextTabEventArgs);
DECLARE_EVENT(PrevTab, _PrevTabHandlers, TerminalApp::PrevTabEventArgs);

View file

@ -30,6 +30,7 @@ namespace TerminalApp
NewWindow,
CloseWindow,
CloseTab,
ClosePane,
NextTab,
PrevTab,
SplitVertical,
@ -69,6 +70,7 @@ namespace TerminalApp
delegate void NewWindowEventArgs();
delegate void CloseWindowEventArgs();
delegate void CloseTabEventArgs();
delegate void ClosePaneEventArgs();
delegate void NextTabEventArgs();
delegate void PrevTabEventArgs();
delegate void SplitVerticalEventArgs();
@ -100,6 +102,7 @@ namespace TerminalApp
event NewWindowEventArgs NewWindow;
event CloseWindowEventArgs CloseWindow;
event CloseTabEventArgs CloseTab;
event ClosePaneEventArgs ClosePane;
event SwitchToTabEventArgs SwitchToTab;
event NextTabEventArgs NextTab;
event PrevTabEventArgs PrevTab;

View file

@ -30,6 +30,7 @@ static constexpr std::string_view NewTabWithProfile8Key{ "newTabProfile8" };
static constexpr std::string_view NewWindowKey{ "newWindow" };
static constexpr std::string_view CloseWindowKey{ "closeWindow" };
static constexpr std::string_view CloseTabKey{ "closeTab" };
static constexpr std::string_view ClosePaneKey{ "closePane" };
static constexpr std::string_view SwitchtoTabKey{ "switchToTab" };
static constexpr std::string_view NextTabKey{ "nextTab" };
static constexpr std::string_view PrevTabKey{ "prevTab" };
@ -87,6 +88,7 @@ static const std::map<std::string_view, ShortcutAction, std::less<>> commandName
{ NewWindowKey, ShortcutAction::NewWindow },
{ CloseWindowKey, ShortcutAction::CloseWindow },
{ CloseTabKey, ShortcutAction::CloseTab },
{ ClosePaneKey, ShortcutAction::ClosePane },
{ NextTabKey, ShortcutAction::NextTab },
{ PrevTabKey, ShortcutAction::PrevTab },
{ IncreaseFontSizeKey, ShortcutAction::IncreaseFontSize },

View file

@ -287,8 +287,8 @@ void CascadiaSettings::_CreateDefaultKeybindings()
KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift,
static_cast<int>('D') });
keyBindings.SetKeyBinding(ShortcutAction::CloseTab,
KeyChord{ KeyModifiers::Ctrl,
keyBindings.SetKeyBinding(ShortcutAction::ClosePane,
KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift,
static_cast<int>('W') });
keyBindings.SetKeyBinding(ShortcutAction::CopyText,

View file

@ -1,4 +1,6 @@
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// MinMaxCloseControl.xaml.cpp
// Implementation of the MinMaxCloseControl class
//
@ -8,6 +10,7 @@
#include "MinMaxCloseControl.h"
#include "MinMaxCloseControl.g.cpp"
using namespace winrt::Windows::UI::Xaml;
namespace winrt::TerminalApp::implementation
{
@ -16,59 +19,37 @@ namespace winrt::TerminalApp::implementation
InitializeComponent();
}
uint64_t MinMaxCloseControl::ParentWindowHandle() const
void MinMaxCloseControl::Maximize()
{
return reinterpret_cast<uint64_t>(_window);
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateMaximized", false);
}
void MinMaxCloseControl::ParentWindowHandle(uint64_t handle)
void MinMaxCloseControl::RestoreDown()
{
_window = reinterpret_cast<HWND>(handle);
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false);
}
void MinMaxCloseControl::_OnMaximize(byte flag)
// These event handlers simply forward each buttons click events up to the
// events we've exposed.
void MinMaxCloseControl::_MinimizeClick(winrt::Windows::Foundation::IInspectable const& sender,
RoutedEventArgs const& e)
{
if (_window)
{
POINT point1 = {};
::GetCursorPos(&point1);
const LPARAM lParam = MAKELPARAM(point1.x, point1.y);
WINDOWPLACEMENT placement = { sizeof(placement) };
::GetWindowPlacement(_window, &placement);
if (placement.showCmd == SW_SHOWNORMAL)
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateMaximized", false);
::PostMessage(_window, WM_SYSCOMMAND, SC_MAXIMIZE | flag, lParam);
}
else if (placement.showCmd == SW_SHOWMAXIMIZED)
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateNormal", false);
::PostMessage(_window, WM_SYSCOMMAND, SC_RESTORE | flag, lParam);
}
}
_minimizeClickHandlers(*this, e);
}
void MinMaxCloseControl::Maximize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
void MinMaxCloseControl::_MaximizeClick(winrt::Windows::Foundation::IInspectable const& sender,
RoutedEventArgs const& e)
{
_OnMaximize(HTMAXBUTTON);
_maximizeClickHandlers(*this, e);
}
void MinMaxCloseControl::_CloseClick(winrt::Windows::Foundation::IInspectable const& sender,
RoutedEventArgs const& e)
{
_closeClickHandlers(*this, e);
}
void MinMaxCloseControl::DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e)
{
_OnMaximize(HTCAPTION);
}
void MinMaxCloseControl::Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
if (_window)
{
::PostMessage(_window, WM_SYSCOMMAND, SC_MINIMIZE | HTMINBUTTON, 0);
}
}
void MinMaxCloseControl::Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
::PostQuitMessage(0);
}
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MinMaxCloseControl, MinimizeClick, _minimizeClickHandlers, TerminalApp::MinMaxCloseControl, RoutedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MinMaxCloseControl, MaximizeClick, _maximizeClickHandlers, TerminalApp::MinMaxCloseControl, RoutedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MinMaxCloseControl, CloseClick, _closeClickHandlers, TerminalApp::MinMaxCloseControl, RoutedEventArgs);
}

View file

@ -1,4 +1,6 @@
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// Declaration of the MainUserControl class.
//
@ -8,6 +10,7 @@
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Interop.h"
#include "MinMaxCloseControl.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
namespace winrt::TerminalApp::implementation
{
@ -15,17 +18,19 @@ namespace winrt::TerminalApp::implementation
{
MinMaxCloseControl();
void Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void Maximize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e);
void Maximize();
void RestoreDown();
uint64_t ParentWindowHandle() const;
void ParentWindowHandle(uint64_t handle);
void _MinimizeClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void _MaximizeClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void _CloseClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
private:
void _OnMaximize(byte flag);
HWND _window{ nullptr }; // non-owning handle; should not be freed in the dtor.
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(MinimizeClick, _minimizeClickHandlers, TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(MaximizeClick, _maximizeClickHandlers, TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CloseClick, _closeClickHandlers, TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs);
};
}

View file

@ -1,13 +1,17 @@
namespace TerminalApp
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
[default_interface]
runtimeclass MinMaxCloseControl : Windows.UI.Xaml.Controls.StackPanel
[default_interface] runtimeclass MinMaxCloseControl : Windows.UI.Xaml.Controls.StackPanel
{
MinMaxCloseControl();
Windows.UI.Xaml.Controls.Grid Content{ get; };
Windows.UI.Xaml.Controls.Border DragBar{ get; };
void Maximize();
void RestoreDown();
UInt64 ParentWindowHandle;
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MinimizeClick;
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MaximizeClick;
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> CloseClick;
}
}

View file

@ -1,4 +1,6 @@
<StackPanel
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<StackPanel
x:Class="TerminalApp.MinMaxCloseControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@ -129,13 +131,7 @@
</ResourceDictionary>
</StackPanel.Resources>
<Grid x:Name="Content"></Grid>
<Border Height="36.0"
MinWidth="160.0"
x:Name="DragBar"
Background="{ThemeResource SystemChromeLowColor}"
DoubleTapped="DragBar_DoubleTapped"/>
<Button Height="36.0" Width="45.0" x:Name="Minimize" Style="{StaticResource CaptionButton}" Click="Minimize_Click"
<Button Height="36.0" MinWidth="45.0" Width="45.0" x:Name="MinimizeButton" Style="{StaticResource CaptionButton}" Click="_MinimizeClick"
AutomationProperties.Name="Minimize">
<Button.Resources>
<ResourceDictionary>
@ -143,7 +139,7 @@
</ResourceDictionary>
</Button.Resources>
</Button>
<Button Height="36.0" Width="45.0" x:Name="Maximize" Style="{StaticResource CaptionButton}" Click="Maximize_Click"
<Button Height="36.0" MinWidth="45.0" Width="45.0" x:Name="MaximizeButton" Style="{StaticResource CaptionButton}" Click="_MaximizeClick"
AutomationProperties.Name="Maximize">
<Button.Resources>
<ResourceDictionary>
@ -152,7 +148,7 @@
</ResourceDictionary>
</Button.Resources>
</Button>
<Button Height="36.0" Width="45.0" x:Name="Close" Style="{StaticResource CaptionButton}" Click="Close_Click"
<Button Height="36.0" MinWidth="45.0" Width="45.0" x:Name="CloseButton" Style="{StaticResource CaptionButton}" Click="_CloseClick"
AutomationProperties.Name="Close">
<Button.Resources>
<ResourceDictionary>

View file

@ -339,6 +339,18 @@ void Pane::_ControlClosedHandler()
// }
}
// Method Description:
// - Fire our Closed event to tell our parent that we should be removed.
// Arguments:
// - <none>
// Return Value:
// - <none>
void Pane::Close()
{
// Fire our Closed event to tell our parent that we should be removed.
_closedHandlers();
}
// Method Description:
// - Get the root UIElement of this pane. There may be a single TermControl as a
// child, or an entire tree of grids and panes as children of this element.

View file

@ -55,6 +55,8 @@ public:
void SplitHorizontal(const GUID& profile, const winrt::TerminalApp::IControlHost& control);
void SplitVertical(const GUID& profile, const winrt::TerminalApp::IControlHost& control);
void Close();
DECLARE_EVENT(Closed, _closedHandlers, winrt::Microsoft::Terminal::TerminalControl::ConnectionClosedEventArgs);
private:

View file

@ -250,4 +250,18 @@ void Tab::NavigateFocus(const winrt::TerminalApp::Direction& direction)
_rootPane->NavigateFocus(direction);
}
// Method Description:
// - Closes the currently focused pane in this tab. If it's the last pane in
// this tab, our Closed event will be fired (at a later time) for anyone
// registered as a handler of our close event.
// Arguments:
// - <none>
// Return Value:
// - <none>
void Tab::ClosePane()
{
auto focused = _rootPane->GetFocusedPane();
focused->Close();
}
DEFINE_EVENT(Tab, Closed, _closedHandlers, ConnectionClosedEventArgs);

View file

@ -31,6 +31,8 @@ public:
winrt::hstring GetFocusedTitle() const;
void SetTabText(const winrt::hstring& text);
void ClosePane();
DECLARE_EVENT(Closed, _closedHandlers, winrt::Microsoft::Terminal::TerminalControl::ConnectionClosedEventArgs);
private:

View file

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "TabRowControl.h"
#include "TabRowControl.g.cpp"
using namespace winrt;
using namespace Windows::UI::Xaml;
namespace winrt::TerminalApp::implementation
{
TabRowControl::TabRowControl()
{
InitializeComponent();
}
// Method Description:
// - Bound in the Xaml editor to the [+] button.
// Arguments:
// <unused>
void TabRowControl::OnNewTabButtonClick(IInspectable const&, Controls::SplitButtonClickEventArgs const&)
{
}
}

View file

@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "winrt/Microsoft.UI.Xaml.Controls.h"
#include "TabRowControl.g.h"
namespace winrt::TerminalApp::implementation
{
struct TabRowControl : TabRowControlT<TabRowControl>
{
TabRowControl();
void OnNewTabButtonClick(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::SplitButtonClickEventArgs const& args);
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct TabRowControl : TabRowControlT<TabRowControl, implementation::TabRowControl>
{
};
}

View file

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
[default_interface] runtimeclass TabRowControl : Windows.UI.Xaml.Controls.Grid
{
TabRowControl();
Windows.UI.Xaml.Controls.SplitButton NewTabButton { get; };
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
}
}

View file

@ -0,0 +1,31 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Grid
x:Class="TerminalApp.TabRowControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<mux:TabView x:Name="TabView" VerticalAlignment="Bottom">
<mux:TabView.RightCustomContent>
<SplitButton
x:Name="NewTabButton"
Click="OnNewTabButtonClick"
Background="{ThemeResource SystemChromeLowColor}"
VerticalAlignment="Stretch"
HorizontalAlignment="Left">
<Viewbox MaxHeight="15"
MaxWidth="15">
<SymbolIcon Symbol="Add" />
</Viewbox>
</SplitButton>
</mux:TabView.RightCustomContent>
</mux:TabView>
</Grid>

View file

@ -30,6 +30,8 @@
<ClInclude Include="TerminalPage.h" />
<ClInclude Include="MinMaxCloseControl.h" />
<ClInclude Include="AppKeyBindings.h" />
<ClInclude Include="TitlebarControl.h" />
<ClInclude Include="TabRowControl.h" />
<ClInclude Include="App.h" />
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->

View file

@ -15,13 +15,4 @@ namespace winrt::TerminalApp::implementation
{
InitializeComponent();
}
// Method Description:
// - Bound in the Xaml editor to the [+] button.
// Arguments:
// - sender
// - event arguments
void TerminalPage::OnNewTabButtonClick(IInspectable const&, Controls::SplitButtonClickEventArgs const&)
{
}
}

View file

@ -12,8 +12,6 @@ namespace winrt::TerminalApp::implementation
struct TerminalPage : TerminalPageT<TerminalPage>
{
TerminalPage();
void OnNewTabButtonClick(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::SplitButtonClickEventArgs const& args);
};
}

View file

@ -3,8 +3,7 @@
namespace TerminalApp
{
[default_interface]
runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page
{
TerminalPage();
}

View file

@ -10,39 +10,13 @@ the MIT License. See LICENSE in the project root for license information. -->
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="Root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="TabRow" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<mux:TabView x:Name="TabView" Grid.Column="0" />
<SplitButton
x:Name="NewTabButton"
Grid.Column="1"
Click="OnNewTabButtonClick"
Background="{ThemeResource SystemChromeLowColor}"
VerticalAlignment="Stretch"
HorizontalAlignment="Left">
<Viewbox MaxHeight="15"
MaxWidth="15">
<SymbolIcon Symbol="Add" />
</Viewbox>
</SplitButton>
<local:MinMaxCloseControl
x:Name="MinMaxCloseControl"
Grid.Column="3"
HorizontalAlignment="Right" />
</Grid>
<local:TabRowControl x:Name="TabRow" Grid.Row="0" />
<Grid x:Name="TabContent" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Grid>

View file

@ -0,0 +1,89 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// TitlebarControl.xaml.cpp
// Implementation of the TitlebarControl class
//
#include "pch.h"
#include "TitlebarControl.h"
#include "TitlebarControl.g.cpp"
namespace winrt::TerminalApp::implementation
{
TitlebarControl::TitlebarControl(uint64_t handle) :
_window{ reinterpret_cast<HWND>(handle) }
{
InitializeComponent();
// Register our event handlers on the MMC buttons.
MinMaxCloseControl().MinimizeClick({ this, &TitlebarControl::Minimize_Click });
MinMaxCloseControl().MaximizeClick({ this, &TitlebarControl::Maximize_Click });
MinMaxCloseControl().CloseClick({ this, &TitlebarControl::Close_Click });
}
Windows::UI::Xaml::UIElement TitlebarControl::Content()
{
return ContentRoot().Children().Size() > 0 ? ContentRoot().Children().GetAt(0) : nullptr;
}
void TitlebarControl::Content(Windows::UI::Xaml::UIElement content)
{
ContentRoot().Children().Clear();
ContentRoot().Children().Append(content);
}
void TitlebarControl::Root_SizeChanged(const IInspectable& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e)
{
const auto windowWidth = ActualWidth();
const auto minMaxCloseWidth = MinMaxCloseControl().ActualWidth();
const auto dragBarMinWidth = DragBar().MinWidth();
const auto maxWidth = windowWidth - minMaxCloseWidth - dragBarMinWidth;
ContentRoot().MaxWidth(maxWidth);
}
void TitlebarControl::_OnMaximizeOrRestore(byte flag)
{
POINT point1 = {};
::GetCursorPos(&point1);
const LPARAM lParam = MAKELPARAM(point1.x, point1.y);
WINDOWPLACEMENT placement = { sizeof(placement) };
::GetWindowPlacement(_window, &placement);
if (placement.showCmd == SW_SHOWNORMAL)
{
MinMaxCloseControl().Maximize();
::PostMessage(_window, WM_SYSCOMMAND, SC_MAXIMIZE | flag, lParam);
}
else if (placement.showCmd == SW_SHOWMAXIMIZED)
{
MinMaxCloseControl().RestoreDown();
::PostMessage(_window, WM_SYSCOMMAND, SC_RESTORE | flag, lParam);
}
}
void TitlebarControl::Maximize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
_OnMaximizeOrRestore(HTMAXBUTTON);
}
void TitlebarControl::DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e)
{
_OnMaximizeOrRestore(HTCAPTION);
}
void TitlebarControl::Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
if (_window)
{
::PostMessage(_window, WM_SYSCOMMAND, SC_MINIMIZE | HTMINBUTTON, 0);
}
}
void TitlebarControl::Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
::PostQuitMessage(0);
}
}

View file

@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// Declaration of the MainUserControl class.
//
#pragma once
#include "winrt/Windows.UI.Xaml.h"
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Interop.h"
#include "TitlebarControl.g.h"
namespace winrt::TerminalApp::implementation
{
struct TitlebarControl : TitlebarControlT<TitlebarControl>
{
TitlebarControl(uint64_t handle);
Windows::UI::Xaml::UIElement Content();
void Content(Windows::UI::Xaml::UIElement content);
void Root_SizeChanged(const IInspectable& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e);
void Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void Maximize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e);
private:
void _OnMaximizeOrRestore(byte flag);
HWND _window{ nullptr }; // non-owning handle; should not be freed in the dtor.
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct TitlebarControl : TitlebarControlT<TitlebarControl, implementation::TitlebarControl>
{
};
}

View file

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
[default_interface] runtimeclass TitlebarControl : Windows.UI.Xaml.Controls.Grid
{
TitlebarControl(UInt64 parentWindowHandle);
Windows.UI.Xaml.UIElement Content;
Windows.UI.Xaml.Controls.Border DragBar { get; };
}
}

View file

@ -0,0 +1,45 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Grid
x:Class="TerminalApp.TitlebarControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="Root"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
SizeChanged="Root_SizeChanged"
d:DesignHeight="36"
Background="{ThemeResource SystemChromeLowColor}"
d:DesignWidth="400">
<!-- TODO:GH#1988
This xaml should probably be a template thing, where the background is a
resource that the app hosting this control can override. Then, it App.xaml,
we'd make sure to set the resource for our background to the appropriate
color. SystemControlForegroundAccentBrush also works nicely, to use the
accent color. (which is GH#1963)-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid x:Name="ContentRoot" Grid.Column="0" />
<Border
x:Name="DragBar"
Grid.Column="1"
MinWidth="45.0"
DoubleTapped="DragBar_DoubleTapped"/>
<local:MinMaxCloseControl
Grid.Column="2"
x:Name="MinMaxCloseControl"
HorizontalAlignment="Right" />
</Grid>

View file

@ -35,6 +35,12 @@
<Page Include="../TerminalPage.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../TitlebarControl.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../TabRowControl.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../RichTextBoxControlHost.xaml">
<SubType>Designer</SubType>
</Page>
@ -53,6 +59,12 @@
<DependentUpon>../TerminalPage.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="../TitlebarControl.h">
<DependentUpon>../TitlebarControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="../TabRowControl.h">
<DependentUpon>../TabRowControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="../RichTextBoxControlHost.h">
<DependentUpon>../RichTextBoxControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
@ -94,6 +106,12 @@
<DependentUpon>../TerminalPage.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="../TitlebarControl.cpp">
<DependentUpon>../TitlebarControl.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="../TabRowControl.cpp">
<DependentUpon>../TabRowControl.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="../RichTextBoxControlHost.cpp">
<DependentUpon>../RichTextBoxControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
@ -152,6 +170,14 @@
<DependentUpon>../TerminalPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../TitlebarControl.idl">
<DependentUpon>../TitlebarControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../TabRowControl.idl">
<DependentUpon>../TabRowControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../RichTextBoxControlHost.idl">
<DependentUpon>../RichTextBoxControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
@ -279,7 +305,7 @@
<Implementation>Microsoft.UI.Xaml.dll</Implementation>
<IsWinMDFile>true</IsWinMDFile>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<Private>false</Private>
<Private>true</Private>
</Reference>
<ReferenceCopyLocalPaths Include="$(_MUXRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.UI.Xaml.dll" />
<ReferenceCopyLocalPaths Include="$(_MUXRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.UI.Xaml.pri" />

View file

@ -61,15 +61,27 @@ AppHost::~AppHost()
void AppHost::Initialize()
{
_window->Initialize();
const auto handle = _window->GetHandle();
_app.Create(reinterpret_cast<uint64_t>(handle));
if (_useNonClientArea)
{
// Register our callbar for when the app's non-client content changes.
// This has to be done _before_ App::Create, as the app might set the
// content in Create.
_app.SetTitleBarContent({ this, &AppHost::_UpdateTitleBarContent });
}
_app.RequestedThemeChanged({ this, &AppHost::_UpdateTheme });
_app.Create();
_app.TitleChanged({ this, &AppHost::AppTitleChanged });
_app.LastTabClosed({ this, &AppHost::LastTabClosed });
AppTitleChanged(_app.GetTitle());
_window->OnAppInitialized(_app);
// Set up the content of the application. If the app has a custom titlebar,
// set that content as well.
_window->SetContent(_app.GetRoot());
_window->OnAppInitialized();
}
// Method Description:
@ -183,3 +195,32 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, const RECT proposedRect)
// the originally proposed window size.
LOG_LAST_ERROR_IF(!succeeded);
}
// 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>
void AppHost::_UpdateTitleBarContent(const winrt::TerminalApp::App&, const winrt::Windows::UI::Xaml::UIElement& arg)
{
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>
void AppHost::_UpdateTheme(const winrt::TerminalApp::App&, const winrt::Windows::UI::Xaml::ElementTheme& arg)
{
_window->UpdateTheme(arg);
}

View file

@ -25,4 +25,8 @@ private:
winrt::TerminalApp::App _app;
void _HandleCreateWindow(const HWND hwnd, const RECT proposedRect);
void _UpdateTitleBarContent(const winrt::TerminalApp::App& sender,
const winrt::Windows::UI::Xaml::UIElement& arg);
void _UpdateTheme(const winrt::TerminalApp::App&,
const winrt::Windows::UI::Xaml::ElementTheme& arg);
};

View file

@ -196,22 +196,41 @@ void IslandWindow::OnResize(const UINT width, const UINT height)
// - Called when the window is minimized to the taskbar.
void IslandWindow::OnMinimize()
{
// TODO MSFT#21315817 Stop rendering island content when the app is minimized.
// TODO GH#1989 Stop rendering island content when the app is minimized.
}
// Method Description:
// - Called when the window is restored from having been minimized.
void IslandWindow::OnRestore()
{
// TODO MSFT#21315817 Stop rendering island content when the app is minimized.
// TODO GH#1989 Stop rendering island content when the app is minimized.
}
void IslandWindow::OnAppInitialized(winrt::TerminalApp::App app)
void IslandWindow::SetContent(winrt::Windows::UI::Xaml::UIElement content)
{
_rootGrid.Children().Clear();
_rootGrid.Children().Append(app.GetRoot());
_rootGrid.Children().Append(content);
}
void IslandWindow::OnAppInitialized()
{
// Do a quick resize to force the island to paint
const auto size = GetPhysicalSize();
OnSize(size.cx, size.cy);
}
// Method Description:
// - Called when the app wants to change its theme. We'll update the root UI
// element of the entire XAML tree, so that all UI elements get the theme
// applied.
// Arguments:
// - arg: the ElementTheme to use as the new theme for the UI
// Return Value:
// - <none>
void IslandWindow::UpdateTheme(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme)
{
_rootGrid.RequestedTheme(requestedTheme);
// Invalidate the window rect, so that we'll repaint any elements we're
// drawing ourselves to match the new theme
::InvalidateRect(_window.get(), nullptr, false);
}

View file

@ -20,12 +20,15 @@ public:
void OnResize(const UINT width, const UINT height) override;
void OnMinimize() override;
void OnRestore() override;
virtual void OnAppInitialized(winrt::TerminalApp::App app);
virtual void OnAppInitialized();
virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content);
void Initialize();
virtual void Initialize();
void SetCreateCallback(std::function<void(const HWND, const RECT)> pfn) noexcept;
void UpdateTheme(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
protected:
void ForceResize()
{

View file

@ -42,17 +42,82 @@ NonClientIslandWindow::~NonClientIslandWindow()
// - <unused>
// Return Value:
// - <none>
void NonClientIslandWindow::OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable /*sender*/, winrt::Windows::UI::Xaml::SizeChangedEventArgs /*eventArgs*/)
void NonClientIslandWindow::OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable /*sender*/,
winrt::Windows::UI::Xaml::SizeChangedEventArgs /*eventArgs*/)
{
_UpdateDragRegion();
}
void NonClientIslandWindow::OnAppInitialized(winrt::TerminalApp::App app)
void NonClientIslandWindow::OnAppInitialized()
{
_dragBar = app.GetDragBar();
IslandWindow::OnAppInitialized();
}
void NonClientIslandWindow::Initialize()
{
IslandWindow::Initialize();
// 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();
_rootGrid.SizeChanged({ this, &NonClientIslandWindow::OnDragBarSizeChanged });
IslandWindow::OnAppInitialized(app);
_rootGrid.Children().Append(_titlebar);
Controls::Grid::SetRow(_titlebar, 0);
}
// 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);
// When the size of the titlebar content changes, we want to make sure to
// update the size of the drag region as well.
const auto fwe = content.try_as<winrt::Windows::UI::Xaml::FrameworkElement>();
if (fwe)
{
fwe.SizeChanged({ this, &NonClientIslandWindow::OnDragBarSizeChanged });
}
}
RECT NonClientIslandWindow::GetDragAreaRect() const noexcept
@ -61,7 +126,12 @@ RECT NonClientIslandWindow::GetDragAreaRect() const noexcept
{
const auto scale = GetCurrentDpiScale();
const auto transform = _dragBar.TransformToVisual(_rootGrid);
const auto logicalDragBarRect = winrt::Windows::Foundation::Rect{ 0.0f, 0.0f, static_cast<float>(_dragBar.ActualWidth()), static_cast<float>(_dragBar.ActualHeight()) };
const auto logicalDragBarRect = winrt::Windows::Foundation::Rect{
0.0f,
0.0f,
static_cast<float>(_dragBar.ActualWidth()),
static_cast<float>(_dragBar.ActualHeight())
};
const auto clientDragBarRect = transform.TransformBounds(logicalDragBarRect);
RECT dragBarRect = {
static_cast<LONG>(clientDragBarRect.X * scale),
@ -118,8 +188,14 @@ void NonClientIslandWindow::OnSize(const UINT width, const UINT height)
_rootGrid.Arrange(finalRect);
}
// I'm not sure that HWND_BOTTOM is any different than HWND_TOP for us.
winrt::check_bool(SetWindowPos(_interopWindowHandle, HWND_BOTTOM, xPos, yPos, windowsWidth, windowsHeight, SWP_SHOWWINDOW));
// I'm not sure that HWND_BOTTOM does anything differnet than HWND_TOP for us.
winrt::check_bool(SetWindowPos(_interopWindowHandle,
HWND_BOTTOM,
xPos,
yPos,
windowsWidth,
windowsHeight,
SWP_SHOWWINDOW));
}
// Method Description:
@ -143,6 +219,7 @@ void NonClientIslandWindow::_UpdateDragRegion()
const auto width = windowRect.right - windowRect.left;
const auto height = windowRect.bottom - windowRect.top;
const auto scale = GetCurrentDpiScale();
const auto dpi = ::GetDpiForWindow(_window.get());
const auto dragY = ::GetSystemMetricsForDpi(SM_CYDRAG, dpi);
@ -318,11 +395,14 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
// First get the monitor pointer from either the active window or the default location (0,0,0,0)
HMONITOR hMonitor = nullptr;
// NOTE: We must use the nearest monitor because sometimes the system moves the window around into strange spots while performing snap and Win+D operations.
// Those operations won't work correctly if we use MONITOR_DEFAULTTOPRIMARY.
// NOTE: We must use the nearest monitor because sometimes the system moves
// the window around into strange spots while performing snap and Win+D
// operations. Those operations won't work correctly if we use
// MONITOR_DEFAULTTOPRIMARY.
if (!EqualRect(&rc, &rcZero))
{
// For invalid window handles or when we were passed a non-zero suggestion rectangle, get the monitor from the rect.
// For invalid window handles or when we were passed a non-zero
// suggestion rectangle, get the monitor from the rect.
hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
}
else
@ -331,8 +411,9 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
hMonitor = MonitorFromWindow(_window.get(), MONITOR_DEFAULTTONEAREST);
}
// If for whatever reason there is no monitor, we're going to give back whatever we got since we can't figure anything out.
// We won't adjust the DPI either. That's OK. DPI doesn't make much sense with no display.
// If for whatever reason there is no monitor, we're going to give back
// whatever we got since we can't figure anything out. We won't adjust the
// DPI either. That's OK. DPI doesn't make much sense with no display.
if (nullptr == hMonitor)
{
return rc;
@ -344,9 +425,11 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
GetMonitorInfoW(hMonitor, &MonitorInfo);
// We have to make a correction to the work area. If we actually consume the entire work area (by maximizing the window)
// The window manager will render the borders off-screen.
// We need to pad the work rectangle with the border dimensions to represent the actual max outer edges of the window rect.
// We have to make a correction to the work area. If we actually consume the
// entire work area (by maximizing the window). The window manager will
// render the borders off-screen. We need to pad the work rectangle with the
// border dimensions to represent the actual max outer edges of the window
// rect.
WINDOWINFO wi = { 0 };
wi.cbSize = sizeof(WINDOWINFO);
GetWindowInfo(_window.get(), &wi);
@ -464,8 +547,8 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
const auto yPos = _isMaximized ? _maximizedMargins.cyTopHeight : dragY;
// Create brush for borders, titlebar color.
const auto backgroundBrush = _dragBar.Background();
const auto backgroundSolidBrush = backgroundBrush.as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
const auto backgroundBrush = _titlebar.Background();
const auto backgroundSolidBrush = backgroundBrush.as<Media::SolidColorBrush>();
const auto backgroundColor = backgroundSolidBrush.Color();
const auto color = RGB(backgroundColor.R, backgroundColor.G, backgroundColor.B);
_backgroundBrush = wil::unique_hbrush(CreateSolidBrush(color));
@ -475,12 +558,16 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
const auto cx = windowRect.right - windowRect.left;
const auto cy = windowRect.bottom - windowRect.top;
// Fill in the _entire_ titlebar area.
RECT dragBarRect = {};
dragBarRect.left = xPos;
dragBarRect.right = xPos + cx;
dragBarRect.top = yPos;
dragBarRect.bottom = yPos + cy;
// Fill in ONLY the titlebar area. If we paint the _entirety_ of the
// window rect here, the single pixel of the bottom border (set in
// _UpdateFrameMargins) will be drawn, and blend with whatever the
// border color is.
RECT dragBarRect = GetDragAreaRect();
const auto dragHeight = RECT_HEIGHT(&dragBarRect);
dragBarRect.left = 0;
dragBarRect.right = cx;
dragBarRect.top = 0;
dragBarRect.bottom = dragHeight + yPos;
::FillRect(hdc.get(), &dragBarRect, _backgroundBrush.get());
// Draw the top window border

View file

@ -36,9 +36,16 @@ public:
MARGINS GetFrameMargins() const noexcept;
void OnAppInitialized(winrt::TerminalApp::App app) override;
void Initialize() override;
void OnAppInitialized() override;
void SetContent(winrt::Windows::UI::Xaml::UIElement content) override;
void SetTitlebarContent(winrt::Windows::UI::Xaml::UIElement content);
private:
winrt::TerminalApp::TitlebarControl _titlebar{ nullptr };
winrt::Windows::UI::Xaml::UIElement _clientContent{ nullptr };
wil::unique_hbrush _backgroundBrush;
wil::unique_hrgn _dragBarRegion;

View file

@ -187,7 +187,7 @@ function Invoke-OpenConsoleTests()
}
$OpenConsolePath = "$env:OpenConsoleroot\bin\$OpenConsolePlatform\$Configuration\OpenConsole.exe"
$RunTePath = "$env:OpenConsoleRoot\tools\runte.cmd"
$TaefExePath = "$env:OpenConsoleRoot\packages\Taef.Redist.Wlk.10.30.180808002\build\binaries\$Platform\te.exe"
$TaefExePath = "$env:OpenConsoleRoot\packages\Taef.Redist.Wlk.10.38.190610001-uapadmin\build\Binaries\$Platform\te.exe"
$BinDir = "$env:OpenConsoleRoot\bin\$OpenConsolePlatform\$Configuration"
[xml]$TestConfig = Get-Content "$env:OpenConsoleRoot\tools\tests.xml"

View file

@ -104,7 +104,7 @@ shift
goto :ARGS_LOOP
:POST_ARGS_LOOP
set TAEF=%OPENCON%\packages\Taef.Redist.Wlk.10.30.180808002\build\binaries\%ARCH%\TE.exe
set TAEF=%OPENCON%\packages\Taef.Redist.Wlk.10.38.190610001-uapadmin\build\Binaries\%ARCH%\TE.exe
rem Set this envvar so setup won't repeat itself
set OpenConBuild=true