Skip to content

Commit d14747f

Browse files
AliremuDHowett
authored andcommitted
Dim the caption buttons for unfocused windows (#19668)
This PR closes #12632 by dimming the caption controls in the titlebar when unfocused. Leaves them intact when in high contrast mode. The color used is borrowed from PowerToys' unfocused color. ## Validation Steps Performed Tested by hovering and unhovering in focused and unfocused states, as well as in high contrast mode. States are consistent and applied correctly. I did notice that clicking on the titlebar wouldn't put it into focus unless I also moved my mouse though, but that is also present in the release branch. Closes #12632 (cherry picked from commit 8d94edd) Service-Card-Id: PVTI_lADOAF3p4s4AxadtzgkC_KQ Service-Version: 1.23
1 parent 1149f0a commit d14747f

File tree

9 files changed

+96
-15
lines changed

9 files changed

+96
-15
lines changed

.github/actions/spelling/expect/expect.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,7 @@ Mypair
11211121
Myval
11221122
NAMELENGTH
11231123
namestream
1124+
NCACTIVATE
11241125
NCCALCSIZE
11251126
NCCREATE
11261127
NCLBUTTONDOWN

src/cascadia/TerminalApp/MinMaxCloseControl.cpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ namespace winrt::TerminalApp::implementation
8989
CloseClick.raise(*this, e);
9090
}
9191

92+
bool MinMaxCloseControl::Focused() const
93+
{
94+
return _focused;
95+
}
96+
97+
void MinMaxCloseControl::Focused(bool focused)
98+
{
99+
_focused = focused;
100+
101+
ReleaseButtons();
102+
}
103+
92104
void MinMaxCloseControl::SetWindowVisualState(WindowVisualState visualState)
93105
{
94106
// Look up the heights we should use for the caption buttons from our
@@ -170,25 +182,25 @@ namespace winrt::TerminalApp::implementation
170182
// animate the fade in/out transition between colors.
171183
case CaptionButton::Minimize:
172184
VisualStateManager::GoToState(MinimizeButton(), L"PointerOver", true);
173-
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
174-
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
185+
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
186+
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
175187

176188
_displayToolTip->Run(MinimizeButton());
177189
closeToolTipForButton(MaximizeButton());
178190
closeToolTipForButton(CloseButton());
179191
break;
180192
case CaptionButton::Maximize:
181-
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
193+
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
182194
VisualStateManager::GoToState(MaximizeButton(), L"PointerOver", true);
183-
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
195+
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
184196

185197
closeToolTipForButton(MinimizeButton());
186198
_displayToolTip->Run(MaximizeButton());
187199
closeToolTipForButton(CloseButton());
188200
break;
189201
case CaptionButton::Close:
190-
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
191-
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
202+
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
203+
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
192204
VisualStateManager::GoToState(CloseButton(), L"PointerOver", true);
193205

194206
closeToolTipForButton(MinimizeButton());
@@ -211,17 +223,17 @@ namespace winrt::TerminalApp::implementation
211223
{
212224
case CaptionButton::Minimize:
213225
VisualStateManager::GoToState(MinimizeButton(), L"Pressed", true);
214-
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
215-
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
226+
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
227+
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
216228
break;
217229
case CaptionButton::Maximize:
218-
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
230+
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
219231
VisualStateManager::GoToState(MaximizeButton(), L"Pressed", true);
220-
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
232+
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
221233
break;
222234
case CaptionButton::Close:
223-
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
224-
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
235+
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
236+
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
225237
VisualStateManager::GoToState(CloseButton(), L"Pressed", true);
226238
break;
227239
}
@@ -234,14 +246,21 @@ namespace winrt::TerminalApp::implementation
234246
void MinMaxCloseControl::ReleaseButtons()
235247
{
236248
_displayToolTip->Run(nullptr);
237-
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
238-
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
239-
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
249+
VisualStateManager::GoToState(MinimizeButton(), _normalState(), true);
250+
VisualStateManager::GoToState(MaximizeButton(), _normalState(), true);
251+
VisualStateManager::GoToState(CloseButton(), _normalState(), true);
240252

241253
closeToolTipForButton(MinimizeButton());
242254
closeToolTipForButton(MaximizeButton());
243255
closeToolTipForButton(CloseButton());
244256

245257
_lastPressedButton = std::nullopt;
246258
}
259+
260+
const winrt::param::hstring& MinMaxCloseControl::_normalState() const
261+
{
262+
static const winrt::param::hstring normal = L"Normal";
263+
static const winrt::param::hstring unfocused = L"Unfocused";
264+
return (_focused ? normal : unfocused);
265+
}
247266
}

src/cascadia/TerminalApp/MinMaxCloseControl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ namespace winrt::TerminalApp::implementation
2121
void PressButton(CaptionButton button);
2222
void ReleaseButtons();
2323

24+
bool Focused() const;
25+
void Focused(bool focused);
26+
2427
void _MinimizeClick(const winrt::Windows::Foundation::IInspectable& sender,
2528
const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
2629
void _MaximizeClick(const winrt::Windows::Foundation::IInspectable& sender,
@@ -32,8 +35,12 @@ namespace winrt::TerminalApp::implementation
3235
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> MaximizeClick;
3336
til::typed_event<TerminalApp::MinMaxCloseControl, winrt::Windows::UI::Xaml::RoutedEventArgs> CloseClick;
3437

38+
bool _focused{ false };
3539
std::shared_ptr<ThrottledFunc<winrt::Windows::UI::Xaml::Controls::Button>> _displayToolTip{ nullptr };
3640
std::optional<CaptionButton> _lastPressedButton{ std::nullopt };
41+
42+
private:
43+
const winrt::param::hstring& _normalState() const;
3744
};
3845
}
3946

src/cascadia/TerminalApp/MinMaxCloseControl.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace TerminalApp
1414
void HoverButton(CaptionButton button);
1515
void PressButton(CaptionButton button);
1616
void ReleaseButtons();
17+
Boolean Focused { get; set; };
1718

1819
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MinimizeClick;
1920
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MaximizeClick;

src/cascadia/TerminalApp/MinMaxCloseControl.xaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
ResourceKey="SystemControlForegroundBaseHighBrush" />
3333
<StaticResource x:Key="CaptionButtonForegroundPressed"
3434
ResourceKey="SystemControlForegroundBaseHighBrush" />
35+
<StaticResource x:Key="CaptionButtonForegroundUnfocusedColor"
36+
ResourceKey="TextFillColorDisabled" />
37+
<SolidColorBrush x:Key="CaptionButtonForegroundUnfocused"
38+
Color="{ThemeResource CaptionButtonForegroundUnfocusedColor}" />
3539
<SolidColorBrush x:Key="CaptionButtonBackground"
3640
Color="Transparent" />
3741
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
@@ -66,6 +70,10 @@
6670
ResourceKey="SystemControlForegroundBaseHighBrush" />
6771
<StaticResource x:Key="CaptionButtonForegroundPressed"
6872
ResourceKey="SystemControlForegroundBaseHighBrush" />
73+
<StaticResource x:Key="CaptionButtonForegroundUnfocusedColor"
74+
ResourceKey="TextFillColorDisabled" />
75+
<SolidColorBrush x:Key="CaptionButtonForegroundUnfocused"
76+
Color="{ThemeResource CaptionButtonForegroundUnfocusedColor}" />
6977
<SolidColorBrush x:Key="CaptionButtonBackground"
7078
Color="Transparent" />
7179
<Color x:Key="CaptionButtonBackgroundColor">Transparent</Color>
@@ -103,6 +111,10 @@
103111
Color="{ThemeResource SystemColorHighlightTextColor}" />
104112
<SolidColorBrush x:Key="CaptionButtonForegroundPressed"
105113
Color="{ThemeResource SystemColorHighlightTextColor}" />
114+
<SolidColorBrush x:Key="CaptionButtonForegroundUnfocused"
115+
Color="{ThemeResource SystemColorButtonTextColor}" />
116+
<StaticResource x:Key="CaptionButtonForegroundUnfocusedColor"
117+
ResourceKey="SystemColorButtonTextColor" />
106118
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver"
107119
Color="{ThemeResource SystemColorHighlightColor}" />
108120
<SolidColorBrush x:Key="CloseButtonForegroundPointerOver"
@@ -189,6 +201,20 @@
189201
Duration="0:0:0.1" />
190202
</Storyboard>
191203
</VisualTransition>
204+
205+
<VisualTransition From="PointerOver"
206+
To="Unfocused">
207+
<Storyboard>
208+
<ColorAnimation Storyboard.TargetName="ButtonBaseElement"
209+
Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)"
210+
To="{ThemeResource CaptionButtonBackgroundColor}"
211+
Duration="0:0:0.15" />
212+
<ColorAnimation Storyboard.TargetName="ButtonIcon"
213+
Storyboard.TargetProperty="(UIElement.Foreground).(SolidColorBrush.Color)"
214+
To="{ThemeResource CaptionButtonForegroundUnfocusedColor}"
215+
Duration="0:0:0.1" />
216+
</Storyboard>
217+
</VisualTransition>
192218
</VisualStateGroup.Transitions>
193219

194220
<VisualState x:Name="Normal">
@@ -198,6 +224,13 @@
198224
</VisualState.Setters>
199225
</VisualState>
200226

227+
<VisualState x:Name="Unfocused">
228+
<VisualState.Setters>
229+
<Setter Target="ButtonBaseElement.Background" Value="{ThemeResource CaptionButtonBackground}" />
230+
<Setter Target="ButtonIcon.Foreground" Value="{ThemeResource CaptionButtonForegroundUnfocused}" />
231+
</VisualState.Setters>
232+
</VisualState>
233+
201234
<VisualState x:Name="PointerOver">
202235
<VisualState.Setters>
203236
<Setter Target="ButtonBaseElement.Background" Value="{ThemeResource CaptionButtonBackgroundPointerOver}" />

src/cascadia/TerminalApp/TitlebarControl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ namespace winrt::TerminalApp::implementation
5454
return static_cast<float>(minMaxCloseWidth) / 3.0f;
5555
}
5656

57+
bool TitlebarControl::Focused()
58+
{
59+
return MinMaxCloseControl().Focused();
60+
}
61+
62+
void TitlebarControl::Focused(bool focused)
63+
{
64+
MinMaxCloseControl().Focused(focused);
65+
}
66+
5767
IInspectable TitlebarControl::Content()
5868
{
5969
return ContentRoot().Content();

src/cascadia/TerminalApp/TitlebarControl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ namespace winrt::TerminalApp::implementation
1717
void ReleaseButtons();
1818
float CaptionButtonWidth();
1919

20+
bool Focused();
21+
void Focused(bool focused);
22+
2023
IInspectable Content();
2124
void Content(IInspectable content);
2225

src/cascadia/TerminalApp/TitlebarControl.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace TerminalApp
2929
void ClickButton(CaptionButton button);
3030
void ReleaseButtons();
3131
Single CaptionButtonWidth { get; };
32+
Boolean Focused { get; set; };
3233

3334
IInspectable Content;
3435
Windows.UI.Xaml.Controls.Border DragBar { get; };

src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,12 @@ void NonClientIslandWindow::_UpdateFrameMargins() const noexcept
958958
{
959959
switch (message)
960960
{
961+
case WM_NCACTIVATE:
962+
{
963+
const bool activated = LOWORD(wParam) != 0;
964+
_titlebar.Focused(activated);
965+
break;
966+
}
961967
case WM_SETCURSOR:
962968
return _OnSetCursor(wParam, lParam);
963969
case WM_DISPLAYCHANGE:

0 commit comments

Comments
 (0)