Skip to content

Commit 12a4be7

Browse files
committed
Fix full screen gallery
1 parent 169fe4c commit 12a4be7

5 files changed

Lines changed: 200 additions & 109 deletions

File tree

‎Telegram/Controls/OverlayWindow.cs‎

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
using Telegram.Views.Host;
1414
using Windows.Devices.Input;
1515
using Windows.UI;
16-
using Windows.UI.Core.Preview;
1716
using Windows.UI.ViewManagement;
1817
using Windows.UI.Xaml;
1918
using Windows.UI.Xaml.Controls;
@@ -28,6 +27,7 @@ public abstract class OverlayWindow : ContentControl, INavigablePage
2827
private Popup _popupHost;
2928

3029
private bool _closing;
30+
private bool _watching;
3131

3232
private TaskCompletionSource<ContentDialogResult> _callback;
3333
private ContentDialogResult _result;
@@ -79,6 +79,34 @@ private void OnXamlRootChanged(XamlRoot sender, XamlRootChangedEventArgs args)
7979
UpdateViewBase();
8080
}
8181

82+
/// <summary>
83+
/// Subscribed from <see cref="ShowAsync"/> rather than from the popup's Opened, which the
84+
/// XAML core raises asynchronously: a Loaded handler runs synchronously inside the tick
85+
/// that opens the popup, and the gallery's enters full screen from there. Subscribing
86+
/// afterwards races the resize, and losing it leaves the overlay at its windowed size for
87+
/// as long as it stays open.
88+
/// </summary>
89+
private void WatchWindow(bool watch)
90+
{
91+
if (_watching == watch || XamlRoot == null)
92+
{
93+
return;
94+
}
95+
96+
_watching = watch;
97+
98+
if (watch)
99+
{
100+
XamlRoot.Changed += OnXamlRootChanged;
101+
Window.CloseRequested += OnCloseRequested;
102+
}
103+
else
104+
{
105+
XamlRoot.Changed -= OnXamlRootChanged;
106+
Window.CloseRequested -= OnCloseRequested;
107+
}
108+
}
109+
82110
protected virtual void MaskTitleAndStatusBar(WindowContext window)
83111
{
84112
if (window.Content is IPopupHost host)
@@ -146,12 +174,16 @@ public async Task<ContentDialogResult> ShowAsync()
146174

147175
_closing = false;
148176
_popupHost.XamlRoot = XamlRoot;
177+
178+
WatchWindow(true);
179+
UpdateViewBase();
180+
149181
_popupHost.IsOpen = true;
150182

151183
return await _callback.Task;
152184
}
153185

154-
private void OnCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
186+
private void OnCloseRequested(object sender, WindowCloseRequestedEventArgs e)
155187
{
156188
var args = new BackRequestedRoutedEventArgs();
157189
OnBackRequested(args);
@@ -204,19 +236,13 @@ public void PopupClosed()
204236
private void PopupHost_Opened(object sender, object e)
205237
{
206238
MaskTitleAndStatusBar(Window);
207-
208-
_popupHost.XamlRoot.Changed += OnXamlRootChanged;
209-
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += OnCloseRequested;
210239
}
211240

212241
private void PopupHost_Closed(object sender, object e)
213242
{
214243
UnmaskTitleAndStatusBar(Window);
215244

216245
//_callback.TrySetResult(_result);
217-
218-
_popupHost.XamlRoot.Changed -= OnXamlRootChanged;
219-
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested -= OnCloseRequested;
220246
}
221247

222248
public void OnBackRequested(BackRequestedRoutedEventArgs e)
@@ -287,6 +313,11 @@ public void Hide(ContentDialogResult result)
287313
_result = result;
288314
_popupHost.IsOpen = false;
289315

316+
// Paired with ShowAsync, not with the popup's Closed: that one arrives late enough for
317+
// a re-show to have already opened the popup again, and it would unsubscribe the live
318+
// instance.
319+
WatchWindow(false);
320+
290321
if (_instances.TryGetValue(XamlRoot, out OverlayWindow window))
291322
{
292323
if (window == this)

‎Telegram/Controls/WindowContent.cs‎

Lines changed: 5 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -5,86 +5,15 @@
55
// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt)
66
//
77

8-
using System;
9-
using System.Threading.Tasks;
108
using Telegram.Common;
119
using Telegram.Navigation;
1210
using Telegram.Views.Host;
13-
using Windows.Foundation;
1411
using Windows.UI;
15-
using Windows.UI.Core.Preview;
1612
using Windows.UI.ViewManagement;
1713
using Windows.UI.Xaml;
1814

1915
namespace Telegram.Controls
2016
{
21-
/// <summary>
22-
/// Raised by <see cref="WindowContent.OnWindowCloseRequested"/>. Wraps the UWP args rather
23-
/// than exposing them, so a root only ever sees Handled and a deferral - the two things
24-
/// every caller actually used, and the two an island host can supply by other means.
25-
/// </summary>
26-
public class WindowCloseRequestedEventArgs : EventArgs
27-
{
28-
private readonly SystemNavigationCloseRequestedPreviewEventArgs _args;
29-
private TaskCompletionSource<bool> _deferral;
30-
private bool _handled;
31-
32-
internal WindowCloseRequestedEventArgs(SystemNavigationCloseRequestedPreviewEventArgs args)
33-
{
34-
_args = args;
35-
}
36-
37-
/// <summary>
38-
/// Raised by the app rather than by the system - the window's own close button. Handled is
39-
/// then just a bool, and the deferral has to be honoured by whoever raised it.
40-
/// </summary>
41-
internal WindowCloseRequestedEventArgs()
42-
{
43-
}
44-
45-
public bool Handled
46-
{
47-
get => _args?.Handled ?? _handled;
48-
set
49-
{
50-
if (_args != null)
51-
{
52-
_args.Handled = value;
53-
}
54-
else
55-
{
56-
_handled = value;
57-
}
58-
}
59-
}
60-
61-
public Deferral GetDeferral()
62-
{
63-
if (_args != null)
64-
{
65-
return _args.GetDeferral();
66-
}
67-
68-
// Allocated only when a handler actually asks to defer, which is the uncommon case.
69-
_deferral ??= new TaskCompletionSource<bool>();
70-
return new Deferral(CompleteDeferral);
71-
}
72-
73-
private void CompleteDeferral()
74-
{
75-
_deferral.TrySetResult(true);
76-
}
77-
78-
/// <summary>
79-
/// Completes once every handler that took a deferral has released it. Only meaningful for
80-
/// an app-raised request: the system waits on its own.
81-
/// </summary>
82-
internal Task WaitAsync()
83-
{
84-
return _deferral?.Task ?? Task.CompletedTask;
85-
}
86-
}
87-
8817
/// <summary>
8918
/// Base for anything assigned to <see cref="WindowContext.Content"/> - the root of a window,
9019
/// though not a window itself. Was WindowEx, declared at the bottom of VoipWindow.xaml.cs.
@@ -137,7 +66,7 @@ protected virtual void OnPopupClosed()
13766

13867
/// <summary>
13968
/// Wired once, here, rather than in each root: what raises these is the part that differs
140-
/// between a CoreWindow and an island host, and this is the only place that should know.
69+
/// between a CoreWindow and an island host, and no root should have to know.
14170
///
14271
/// OnLoaded rather than the constructor or the raw Loaded event: roots used to subscribe
14372
/// from their constructors and never unsubscribe, keeping themselves reachable from the
@@ -153,10 +82,9 @@ protected override void OnLoaded()
15382
{
15483
window.Activated += OnWindowActivatedCore;
15584
window.VisibilityChanged += OnWindowVisibilityChangedCore;
85+
window.CloseRequested += OnCloseRequestedCore;
15686
}
15787

158-
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += OnCloseRequestedCore;
159-
16088
var view = ApplicationView.GetForCurrentView();
16189
view.Consolidated += OnConsolidatedCore;
16290
view.VisibleBoundsChanged += OnVisibleBoundsChangedCore;
@@ -168,10 +96,9 @@ protected override void OnUnloaded()
16896
{
16997
window.Activated -= OnWindowActivatedCore;
17098
window.VisibilityChanged -= OnWindowVisibilityChangedCore;
99+
window.CloseRequested -= OnCloseRequestedCore;
171100
}
172101

173-
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested -= OnCloseRequestedCore;
174-
175102
var view = ApplicationView.GetForCurrentView();
176103
view.Consolidated -= OnConsolidatedCore;
177104
view.VisibleBoundsChanged -= OnVisibleBoundsChangedCore;
@@ -187,9 +114,9 @@ private void OnWindowVisibilityChangedCore(object sender, WindowVisibilityEventA
187114
OnWindowVisibilityChanged(args.IsVisible);
188115
}
189116

190-
private void OnCloseRequestedCore(object sender, SystemNavigationCloseRequestedPreviewEventArgs args)
117+
private void OnCloseRequestedCore(object sender, WindowCloseRequestedEventArgs args)
191118
{
192-
OnWindowCloseRequested(new WindowCloseRequestedEventArgs(args));
119+
OnWindowCloseRequested(args);
193120
}
194121

195122
// Neither carries a payload worth forwarding: the one caller of Consolidated ignored its
@@ -218,24 +145,6 @@ protected virtual void OnWindowCloseRequested(WindowCloseRequestedEventArgs args
218145
{
219146
}
220147

221-
/// <summary>
222-
/// The window's own close button, routed into the same override the system's close request
223-
/// uses: a root has one place to intercept a close, whatever asked for it. Returns false
224-
/// when the root refused.
225-
///
226-
/// Awaited, because the answer can be a question: the web app window takes a deferral and
227-
/// asks the user whether to discard the bot's changes.
228-
/// </summary>
229-
internal async Task<bool> RequestCloseAsync()
230-
{
231-
var args = new WindowCloseRequestedEventArgs();
232-
OnWindowCloseRequested(args);
233-
234-
await args.WaitAsync();
235-
236-
return !args.Handled;
237-
}
238-
239148
protected virtual void OnWindowConsolidated()
240149
{
241150
}

‎Telegram/Navigation/WindowContext.Uwp.cs‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using Windows.UI;
2323
using Windows.UI.Composition;
2424
using Windows.UI.Core;
25+
using Windows.UI.Core.Preview;
2526
using Windows.UI.ViewManagement;
2627
using Windows.UI.WindowManagement;
2728
using Windows.UI.Xaml;
@@ -152,6 +153,25 @@ private void OnVisibleBoundsChanged(ApplicationView sender, object args)
152153
VisibleBoundsChanged?.Invoke(this, args);
153154
}
154155

156+
partial void AttachCloseRequested()
157+
{
158+
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += OnCloseRequested;
159+
}
160+
161+
partial void DetachCloseRequested()
162+
{
163+
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested -= OnCloseRequested;
164+
}
165+
166+
/// <summary>
167+
/// The system's own request. Raised and returned rather than awaited: the system honours
168+
/// the deferrals its args hand out, so there is nothing here to wait for.
169+
/// </summary>
170+
private void OnCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs args)
171+
{
172+
RaiseCloseRequested(new WindowCloseRequestedEventArgs(args));
173+
}
174+
155175
public void Close()
156176
{
157177
_ = ConsolidateAsync();

‎Telegram/Navigation/WindowContext.Win32.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ private async void CloseRequestedAsync()
147147
return;
148148
}
149149

150-
if (Content is WindowContent root && !await root.RequestCloseAsync())
150+
if (!await RequestCloseAsync())
151151
{
152152
return;
153153
}

0 commit comments

Comments
 (0)