Skip to content

Commit 5dfcc73

Browse files
committed
Match the system caption buttons more closely
1 parent b5b46e6 commit 5dfcc73

8 files changed

Lines changed: 515 additions & 176 deletions

File tree

‎Telegram/App.xaml‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
<ResourceDictionary>
1414
<ResourceDictionary.ThemeDictionaries>
1515
<ResourceDictionary x:Key="Default">
16-
<SolidColorBrush x:Key="TitleBarButtonBackgroundPointerOver">#19FFFFFF</SolidColorBrush>
17-
<SolidColorBrush x:Key="TitleBarButtonBackgroundPressed">#33FFFFFF</SolidColorBrush>
18-
1916
<StaticResource x:Key="SettingsItemBorderBrush"
2017
ResourceKey="CardStrokeColorDefaultBrush" />
2118
<StaticResource x:Key="SettingsItemBorderBrushPointerOver"
@@ -58,9 +55,6 @@
5855
</LinearGradientBrush>
5956
</ResourceDictionary>
6057
<ResourceDictionary x:Key="Light">
61-
<SolidColorBrush x:Key="TitleBarButtonBackgroundPointerOver">#19000000</SolidColorBrush>
62-
<SolidColorBrush x:Key="TitleBarButtonBackgroundPressed">#33000000</SolidColorBrush>
63-
6458
<StaticResource x:Key="SettingsItemBorderBrush"
6559
ResourceKey="CardStrokeColorDefaultBrush" />
6660
<StaticResource x:Key="SettingsItemBorderBrushPointerOver"

‎Telegram/Host/IslandWindow.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ public static IslandWindow Create(string title, int x, int y, int width, int hei
132132
window._islandHwnd = window._native.GetWindowHandle();
133133
window._source.Content = content;
134134

135+
// A window can open behind another, and the first WM_ACTIVATE would then never come.
136+
if (content is WindowPresenter presenter)
137+
{
138+
presenter.IsActive = Win32.GetActiveWindow() == window._hwnd;
139+
}
140+
135141
// XAML creates the thread's CoreWindow with the first island and parents it there.
136142
// Destroying that window would destroy it, and it cannot be recreated - so it is moved
137143
// to a window of ours that never closes.

‎Telegram/Navigation/WindowContext.Uwp.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,12 @@ private void OnClosed(object sender, CoreWindowEventArgs e)
237237
private void OnActivated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
238238
{
239239
var isActive = e.WindowActivationState != CoreWindowActivationState.Deactivated;
240+
241+
if (_content != null)
242+
{
243+
_content.IsActive = isActive;
244+
}
245+
240246
Activated?.Invoke(this, new WindowActivatedEventArgs(isActive));
241247

242248
lock (_activeLock)

‎Telegram/Navigation/WindowContext.Win32.cs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ bool IIslandOwner.CloseRequested()
116116
/// </summary>
117117
void IIslandOwner.ActivationChanged(bool active)
118118
{
119+
if (_content != null)
120+
{
121+
_content.IsActive = active;
122+
}
123+
119124
Activated?.Invoke(this, new WindowActivatedEventArgs(active));
120125

121126
lock (_activeLock)

‎Telegram/Navigation/WindowContext.cs‎

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,7 @@ public bool IsMaximized
160160
{
161161
_isMaximized = value;
162162

163-
if (MaximizeButton != null)
164-
{
165-
VisualStateManager.GoToState(MaximizeButton, value ? "Maximized" : "Restored", false);
166-
}
163+
ApplyMaximizeGlyph();
167164
}
168165
}
169166
}
@@ -212,6 +209,11 @@ public void SetCaptionButtonState(CaptionButtons button, bool pressed)
212209
GoToCaptionButtonState(CloseButton, CaptionButtons.Close);
213210
}
214211

212+
/// <summary>
213+
/// The window's own caption buttons dim while it is not the active one, the way the shell's
214+
/// do. Pushed in by the host: neither the buttons nor the presenter can see activation, and
215+
/// on Win32 the pointer is over the drag bar rather than over them.
216+
/// </summary>
215217
private void GoToCaptionButtonState(Button button, CaptionButtons which)
216218
{
217219
if (button == null)
@@ -220,10 +222,41 @@ private void GoToCaptionButtonState(Button button, CaptionButtons which)
220222
}
221223

222224
var state = _hotButton != which
223-
? "Normal"
225+
? _isActive ? "Normal" : "Unfocused"
224226
: _hotPressed ? "Pressed" : "PointerOver";
225227

226-
VisualStateManager.GoToState(button, state, false);
228+
// Transitions, so leaving a button fades the way the system's do rather than snapping.
229+
VisualStateManager.GoToState(button, state, true);
230+
}
231+
232+
private bool _isActive = true;
233+
/// <summary>
234+
/// Whether the window is the active one. The system dims its caption glyphs when it is not,
235+
/// and nothing about a button's own pointer state says so - the host has to tell us.
236+
/// </summary>
237+
public bool IsActive
238+
{
239+
get => _isActive;
240+
set
241+
{
242+
if (_isActive != value)
243+
{
244+
_isActive = value;
245+
246+
GoToCaptionButtonState(MinimizeButton, CaptionButtons.Minimize);
247+
GoToCaptionButtonState(MaximizeButton, CaptionButtons.Maximize);
248+
GoToCaptionButtonState(CloseButton, CaptionButtons.Close);
249+
}
250+
}
251+
}
252+
253+
private void ApplyMaximizeGlyph()
254+
{
255+
if (MaximizeButton != null)
256+
{
257+
VisualStateManager.GoToState(MaximizeButton,
258+
_isMaximized ? "WindowStateMaximized" : "WindowStateNormal", false);
259+
}
227260
}
228261

229262
protected override void OnApplyTemplate()
@@ -253,10 +286,7 @@ protected override void OnApplyTemplate()
253286
}
254287

255288
// The window can already be maximized by the time the template arrives.
256-
if (MaximizeButton != null && _isMaximized)
257-
{
258-
VisualStateManager.GoToState(MaximizeButton, "Maximized", false);
259-
}
289+
ApplyMaximizeGlyph();
260290

261291
ApplyCaptionButtons();
262292

0 commit comments

Comments
 (0)