Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/expect/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,7 @@ namestream
nano
natvis
nbsp
NCACTIVATE
NCCALCSIZE
NCCREATE
NCLBUTTONDOWN
Expand Down
12 changes: 12 additions & 0 deletions src/cascadia/TerminalApp/MinMaxCloseControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ namespace winrt::TerminalApp::implementation
MaximizeToolTip().Text(RS_(L"WindowRestoreDownButtonToolTip"));
break;

case WindowVisualState::WindowVisualStateUnfocused:
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateUnfocused", false);
VisualStateManager::GoToState(MinimizeButton(), L"WindowStateUnfocused", false);
VisualStateManager::GoToState(CloseButton(), L"WindowStateUnfocused", false);
break;

case WindowVisualState::WindowVisualStateFocused:
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateFocused", false);
VisualStateManager::GoToState(MinimizeButton(), L"WindowStateFocused", false);
VisualStateManager::GoToState(CloseButton(), L"WindowStateFocused", false);
break;

case WindowVisualState::WindowVisualStateNormal:
case WindowVisualState::WindowVisualStateIconified:
default:
Expand Down
16 changes: 16 additions & 0 deletions src/cascadia/TerminalApp/MinMaxCloseControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
ResourceKey="SystemControlBackgroundBaseMediumLowBrush" />
<StaticResource x:Key="CaptionButtonStroke"
ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CaptionButtonStrokeWindowUnfocused"
ResourceKey="SystemControlForegroundBaseLowBrush" />
<StaticResource x:Key="CaptionButtonStrokeColor"
ResourceKey="SystemBaseHighColor" />
<StaticResource x:Key="CaptionButtonStrokePointerOver"
Expand Down Expand Up @@ -55,6 +57,8 @@
ResourceKey="SystemControlBackgroundBaseMediumLowBrush" />
<StaticResource x:Key="CaptionButtonStroke"
ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CaptionButtonStrokeWindowUnfocused"
ResourceKey="SystemControlForegroundBaseLowBrush" />
<StaticResource x:Key="CaptionButtonStrokeColor"
ResourceKey="SystemBaseHighColor" />
<StaticResource x:Key="CaptionButtonStrokePointerOver"
Expand Down Expand Up @@ -88,6 +92,8 @@
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="CaptionButtonStroke"
Color="{ThemeResource SystemColorButtonTextColor}" />
<StaticResource x:Key="CaptionButtonStrokeWindowUnfocused"
ResourceKey="SystemControlForegroundBaseLowBrush" />
<StaticResource x:Key="CaptionButtonStrokeColor"
ResourceKey="SystemColorButtonTextColor" />
<SolidColorBrush x:Key="CaptionButtonStrokePointerOver"
Expand Down Expand Up @@ -197,6 +203,16 @@
<VisualState x:Name="Disabled" />
</VisualStateGroup>

<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="WindowStateFocused" />

<VisualState x:Name="WindowStateUnfocused">
<VisualState.Setters>
<Setter Target="Path.Stroke" Value="{ThemeResource CaptionButtonStrokeWindowUnfocused}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>

<VisualStateGroup x:Name="MinMaxStates">
<VisualState x:Name="WindowStateNormal" />

Expand Down
13 changes: 13 additions & 0 deletions src/cascadia/TerminalApp/TitlebarControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ namespace winrt::TerminalApp::implementation
}
}

void TitlebarControl::Focused(bool focused)
{
_focused = focused;
const auto state = focused ? winrt::TerminalApp::WindowVisualState::WindowVisualStateFocused :
winrt::TerminalApp::WindowVisualState::WindowVisualStateUnfocused;
MinMaxCloseControl().SetWindowVisualState(state);
}

bool TitlebarControl::Focused() const
{
return _focused;
}

void TitlebarControl::Maximize_Click(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::RoutedEventArgs const& /*e*/)
{
_OnMaximizeOrRestore(HTMAXBUTTON);
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/TitlebarControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace winrt::TerminalApp::implementation
{
TitlebarControl(uint64_t handle);

bool Focused() const;
void Focused(bool focused);

IInspectable Content();
void Content(IInspectable content);

Expand All @@ -29,6 +32,7 @@ namespace winrt::TerminalApp::implementation
void DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e);

private:
bool _focused;
void _OnMaximizeOrRestore(byte flag);
HWND _window{ nullptr }; // non-owning handle; should not be freed in the dtor.
};
Expand Down
6 changes: 5 additions & 1 deletion src/cascadia/TerminalApp/TitlebarControl.idl
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ namespace TerminalApp
{
WindowVisualStateNormal = 0,
WindowVisualStateMaximized,
WindowVisualStateIconified
WindowVisualStateIconified,
WindowVisualStateFocused,
Comment on lines +10 to +11

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still pretty worried about including these in the list of window states. I think they need to be a separate enum. Here's why:

The window is always aware of its current visual state, right...

What happens if you maximize it, then un-focus it, and then focus it again?

The visual state, according to the window, is no longer "maximized." It's "focused." It totally forgot that it was maximized!

We need to track the focus state separately from whether the window is normal, maximized or iconified.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I thought I had fixed that🤔, nvm, doing it asap

WindowVisualStateUnfocused
};

[default_interface] runtimeclass TitlebarControl : Windows.UI.Xaml.Controls.Grid
{
TitlebarControl(UInt64 parentWindowHandle);
void SetWindowVisualState(WindowVisualState visualState);

Boolean Focused { get; set; };

IInspectable Content;
Windows.UI.Xaml.Controls.Border DragBar { get; };
}
Expand Down
28 changes: 28 additions & 0 deletions src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,32 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
return 0;
}

// Method Description:
// - Responds to the WM_NCACTIVATE message by changing the focus state of
// the window.
[[nodiscard]] LRESULT NonClientIslandWindow::_OnFocusChanged(const WPARAM wParam, const LPARAM lParam) noexcept
{
const auto windowStyle = GetWindowStyle(_window.get());
const auto isIconified = WI_IsFlagSet(windowStyle, WS_ICONIC);

if (isIconified)
{
return DefWindowProc(_window.get(), WM_NCACTIVATE, wParam, lParam);
}

if (_titlebar)
{
_isFocused = wParam;
try
{
_titlebar.Focused(_isFocused);
}
CATCH_LOG();
}

return TRUE;
}

// Method Description:
// - Hit test the frame for resizing and moving.
// Arguments:
Expand Down Expand Up @@ -708,6 +734,8 @@ void NonClientIslandWindow::_UpdateFrameMargins() const noexcept
return 0;
case WM_NCCALCSIZE:
return _OnNcCalcSize(wParam, lParam);
case WM_NCACTIVATE:
return _OnFocusChanged(wParam, lParam);
case WM_NCHITTEST:
return _OnNcHitTest({ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) });
case WM_PAINT:
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/WindowsTerminal/NonClientIslandWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class NonClientIslandWindow : public IslandWindow
winrt::Windows::UI::Xaml::ElementTheme _theme;

bool _isMaximized;
bool _isFocused;

[[nodiscard]] static LRESULT __stdcall _StaticInputSinkWndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept;
[[nodiscard]] LRESULT _InputSinkMessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept;
Expand All @@ -73,6 +74,7 @@ class NonClientIslandWindow : public IslandWindow

[[nodiscard]] LRESULT _OnNcCreate(WPARAM wParam, LPARAM lParam) noexcept override;
[[nodiscard]] LRESULT _OnNcCalcSize(const WPARAM wParam, const LPARAM lParam) noexcept;
[[nodiscard]] LRESULT _OnFocusChanged(const WPARAM wParam, const LPARAM lParam) noexcept;
[[nodiscard]] LRESULT _OnNcHitTest(POINT ptMouse) const noexcept;
[[nodiscard]] LRESULT _OnPaint() noexcept;
[[nodiscard]] LRESULT _OnSetCursor(WPARAM wParam, LPARAM lParam) const noexcept;
Expand Down