Skip to content

Commit 7e7759a

Browse files
committed
Pause stickers/gifs when popups are opened
1 parent 3ca6e95 commit 7e7759a

File tree

4 files changed

+216
-65
lines changed

4 files changed

+216
-65
lines changed

Telegram/Common/VisualUtilities.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ namespace Telegram.Common
2323
{
2424
public partial class VisualUtilities
2525
{
26+
public static bool IsInPopupTree(UIElement element)
27+
{
28+
return null != element.GetParent<ContentDialog>();
29+
}
30+
2631
public static SpriteVisual DropShadow(UIElement element, float radius = 20, float opacity = 0.25f, UIElement target = null)
2732
{
2833
var compositor = BootStrapper.Current.Compositor;

Telegram/Controls/AnimatedImage.cs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ private AnimatedImagePresentation GetPresentation()
443443
return null;
444444
}
445445

446-
return new AnimatedImagePresentation(Source, width, height, scale, LimitFps, LoopCount, AutoPlay, IsCachingEnabled, resize);
446+
return new AnimatedImagePresentation(Source, width, height, scale, LimitFps, LoopCount, AutoPlay, IsCachingEnabled, resize, VisualUtilities.IsInPopupTree(this));
447447
}
448448

449449
return null;
@@ -500,14 +500,15 @@ private void Load()
500500
{
501501
if (_presenter != null)
502502
{
503-
_presenter.Unload(this, _state == PlayingState.Playing);
503+
_presenter.Unload(this, _state == PlayingState.Playing || _presenter.Presentation.AutoPlay);
504504
_presenter.LoopCompleted -= OnLoopCompleted;
505505
_presenter.PositionChanged -= OnPositionChanged;
506506
_presenter.Paused -= OnPaused;
507507
_presenter = null;
508508
}
509509

510510
_delayedPlay |= _state == PlayingState.Playing;
511+
_delayedPlay |= presentation?.AutoPlay ?? false;
511512
_state = PlayingState.None;
512513
_clean = true;
513514

@@ -1029,6 +1030,7 @@ private void UnloadImpl(bool playing)
10291030
if (_loaded <= 0 && _tracker == 0)
10301031
{
10311032
_loader.Activated -= OnActivated;
1033+
_loader.PopupActivated -= OnActivated;
10321034
_loader.Remove(_presentation);
10331035

10341036
var task = Volatile.Read(ref _task);
@@ -1194,6 +1196,7 @@ private void ReadyImpl(AnimatedImageTask task)
11941196
else if (_tracker == 0)
11951197
{
11961198
_loader.Activated -= OnActivated;
1199+
_loader.PopupActivated -= OnActivated;
11971200
_loader.Remove(_presentation);
11981201

11991202
// Ticking should be always false here
@@ -1248,6 +1251,7 @@ private void CreateResources()
12481251
{
12491252
_activated = true;
12501253
_loader.Activated += OnActivated;
1254+
_loader.PopupActivated += OnActivated;
12511255
}
12521256

12531257
RegisterRendering();
@@ -1261,19 +1265,42 @@ private void InvokePaused()
12611265
_pausedLock.Release();
12621266
}
12631267

1268+
private void OnActivated(object sender, PopupActivatedEventArgs args)
1269+
{
1270+
if (_presentation.IsPopup)
1271+
{
1272+
OnActivated(WindowContext.Current.ActivationMode != CoreWindowActivationMode.Deactivated);
1273+
}
1274+
else
1275+
{
1276+
OnActivated(WindowContext.Current.ActivationMode != CoreWindowActivationMode.Deactivated && !args.IsActive);
1277+
}
1278+
}
1279+
12641280
private void OnActivated(object sender, WindowActivatedEventArgs args)
1281+
{
1282+
if (_presentation.IsPopup)
1283+
{
1284+
OnActivated(args.WindowActivationState != CoreWindowActivationState.Deactivated);
1285+
}
1286+
else
1287+
{
1288+
OnActivated(args.WindowActivationState != CoreWindowActivationState.Deactivated && !WindowContext.Current.IsPopupOpened);
1289+
}
1290+
}
1291+
1292+
private void OnActivated(bool activated)
12651293
{
12661294
if (_disposed)
12671295
{
12681296
//UnregisterEvents();
12691297

12701298
_loader.Activated -= OnActivated;
1299+
_loader.PopupActivated -= OnActivated;
12711300
return;
12721301
}
12731302

1274-
var activated = args.WindowActivationState != CoreWindowActivationState.Deactivated;
12751303
var subscribe = Activated(activated);
1276-
12771304
if (subscribe)
12781305
{
12791306
RegisterRendering();
@@ -1423,6 +1450,7 @@ private void Dispose()
14231450
Interlocked.Exchange(ref _backgroundNext, null);
14241451

14251452
_loader.Activated -= OnActivated;
1453+
_loader.PopupActivated -= OnActivated;
14261454
_loader.Remove(_presentation);
14271455
}
14281456

@@ -1735,7 +1763,7 @@ public virtual void Seek(string marker)
17351763
}
17361764
}
17371765

1738-
public record AnimatedImagePresentation(AnimatedImageSource Source, int PixelWidth, int PixelHeight, double RasterizationScale, bool LimitFps, int LoopCount, bool AutoPlay, bool IsCachingEnabled, AnimatedImageResizeMode ResizeMode);
1766+
public record AnimatedImagePresentation(AnimatedImageSource Source, int PixelWidth, int PixelHeight, double RasterizationScale, bool LimitFps, int LoopCount, bool AutoPlay, bool IsCachingEnabled, AnimatedImageResizeMode ResizeMode, bool IsPopup);
17391767

17401768
public partial class AnimatedImageLoader
17411769
{
@@ -1786,6 +1814,12 @@ public event EventHandler<WindowActivatedEventArgs> Activated
17861814
remove => _window.Activated -= value;
17871815
}
17881816

1817+
public event EventHandler<PopupActivatedEventArgs> PopupActivated
1818+
{
1819+
add => _window.PopupActivated += value;
1820+
remove => _window.PopupActivated -= value;
1821+
}
1822+
17891823
private void OnRendering(object sender, object e)
17901824
{
17911825
for (int i = 0; i < _rendering.Count; i++)

Telegram/Controls/ContentPopup.cs

Lines changed: 130 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public ContentPopup()
7474
}
7575
}
7676

77+
Closing += OnClosing;
78+
7779
Connected += OnLoaded;
7880
Disconnected += OnUnloaded;
7981

@@ -84,6 +86,14 @@ public ContentPopup()
8486
this.RegisterPropertyChangedCallback(CloseButtonTextProperty, OnButtonTextChanged, ref _closeTextToken);
8587
}
8688

89+
private ContentDialogResult _closingResult;
90+
private TaskCompletionSource<ContentDialogResult> _closingTask;
91+
92+
private void OnClosing(ContentDialog sender, ContentDialogClosingEventArgs args)
93+
{
94+
_closingResult = args.Result;
95+
}
96+
8797
private void OnCloseButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
8898
{
8999
// For some weird reason, there's no ContentDialogResult.Close, so we hack it around.
@@ -190,18 +200,18 @@ private void OnLoaded(object sender, RoutedEventArgs e)
190200
this.RegisterPropertyChangedCallback(SecondaryButtonTextProperty, OnButtonTextChanged, ref _secondaryTextToken);
191201
this.RegisterPropertyChangedCallback(CloseButtonTextProperty, OnButtonTextChanged, ref _closeTextToken);
192202

193-
try
194-
{
195-
if (XamlRoot.Content is IPopupHost host)
196-
{
197-
host.PopupOpened();
198-
}
199-
}
200-
catch
201-
{
202-
// XamlRoot.Content seems to throw a NullReferenceException
203-
// whenever corresponding window has been already closed.
204-
}
203+
//try
204+
//{
205+
// if (XamlRoot.Content is IPopupHost host)
206+
// {
207+
// host.PopupOpened();
208+
// }
209+
//}
210+
//catch
211+
//{
212+
// // XamlRoot.Content seems to throw a NullReferenceException
213+
// // whenever corresponding window has been already closed.
214+
//}
205215

206216
var canvas = VisualTreeHelper.GetParent(this) as Canvas;
207217
if (canvas != null)
@@ -249,18 +259,18 @@ private void OnUnloaded(object sender, RoutedEventArgs e)
249259
this.UnregisterPropertyChangedCallback(SecondaryButtonTextProperty, ref _secondaryTextToken);
250260
this.UnregisterPropertyChangedCallback(CloseButtonTextProperty, ref _closeTextToken);
251261

252-
try
253-
{
254-
if (XamlRoot.Content is IPopupHost host)
255-
{
256-
host.PopupClosed();
257-
}
258-
}
259-
catch
260-
{
261-
// XamlRoot.Content seems to throw a NullReferenceException
262-
// whenever corresponding window has been already closed.
263-
}
262+
//try
263+
//{
264+
// if (XamlRoot.Content is IPopupHost host)
265+
// {
266+
// host.PopupClosed();
267+
// }
268+
//}
269+
//catch
270+
//{
271+
// // XamlRoot.Content seems to throw a NullReferenceException
272+
// // whenever corresponding window has been already closed.
273+
//}
264274
}
265275

266276
private void OnProcessKeyboardAccelerators(UIElement sender, ProcessKeyboardAcceleratorEventArgs args)
@@ -329,6 +339,7 @@ protected override void OnApplyTemplate()
329339

330340
if (LayoutRoot != null)
331341
{
342+
LayoutRoot.RegisterPropertyChangedCallback(IsHitTestVisibleProperty, OnIsHitTestVisibleChanged);
332343
LayoutRoot.ProcessKeyboardAccelerators += OnProcessKeyboardAccelerators;
333344
ElementCompositionPreview.SetIsTranslationEnabled(LayoutRoot, true);
334345
}
@@ -340,6 +351,79 @@ protected override void OnApplyTemplate()
340351
CalculateButtonsVisualState();
341352
}
342353

354+
private void OnIsHitTestVisibleChanged(DependencyObject sender, DependencyProperty dp)
355+
{
356+
if (!LayoutRoot.IsHitTestVisible)
357+
{
358+
VisualUtilities.QueueCallbackForCompositionRendered(Test);
359+
}
360+
}
361+
362+
private void Test()
363+
{
364+
_closingTask?.TrySetResult(_closingResult);
365+
}
366+
367+
[ThreadStatic]
368+
private static TaskCompletionSource<ContentDialogResult> _currentDialogShowRequest;
369+
370+
/// <summary>
371+
/// Begins an asynchronous operation showing a dialog.
372+
/// If another dialog is already shown using
373+
/// ShowQueuedAsync or ShowIfPossibleAsync method - it will wait
374+
/// for that previous dialog to be dismissed before showing the new one.
375+
/// </summary>
376+
/// <param name="dialog">The dialog.</param>
377+
/// <returns></returns>
378+
/// <exception cref="InvalidOperationException">This method can only be invoked from UI thread.</exception>
379+
public async Task<ContentDialogResult> ShowQueuedAsync(XamlRoot xamlRoot)
380+
{
381+
while (_currentDialogShowRequest != null)
382+
{
383+
await _currentDialogShowRequest.Task;
384+
}
385+
386+
Logger.Info(GetType().Name);
387+
388+
XamlRoot = xamlRoot;
389+
OnCreate();
390+
391+
_closingTask = new TaskCompletionSource<ContentDialogResult>();
392+
_currentDialogShowRequest = _closingTask;
393+
_ = ShowAsync();
394+
395+
try
396+
{
397+
if (XamlRoot.Content is IPopupHost host)
398+
{
399+
host.PopupOpened();
400+
}
401+
}
402+
catch
403+
{
404+
// XamlRoot.Content seems to throw a NullReferenceException
405+
// whenever corresponding window has been already closed.
406+
}
407+
408+
var result = await _closingTask.Task;
409+
_currentDialogShowRequest = null;
410+
411+
try
412+
{
413+
if (XamlRoot.Content is IPopupHost host)
414+
{
415+
host.PopupClosed();
416+
}
417+
}
418+
catch
419+
{
420+
// XamlRoot.Content seems to throw a NullReferenceException
421+
// whenever corresponding window has been already closed.
422+
}
423+
424+
return result;
425+
}
426+
343427
private void OnButtonTextChanged(DependencyObject sender, DependencyProperty dp)
344428
{
345429
if (dp == PrimaryButtonTextProperty)
@@ -584,19 +668,6 @@ public ContentDialogResult CloseButtonResult
584668

585669
#endregion
586670

587-
#region SecondaryBackground
588-
589-
public Brush SecondaryBackground
590-
{
591-
get { return (Brush)GetValue(SecondaryBackgroundProperty); }
592-
set { SetValue(SecondaryBackgroundProperty, value); }
593-
}
594-
595-
public static readonly DependencyProperty SecondaryBackgroundProperty =
596-
DependencyProperty.Register("SecondaryBackground", typeof(Brush), typeof(ContentPopup), new PropertyMetadata(null));
597-
598-
#endregion
599-
600671
#region ContentMaxWidth
601672

602673
public double ContentMaxWidth
@@ -782,33 +853,33 @@ private static void OnBlockedClosing(ContentDialog sender, ContentDialogClosingE
782853
args.Cancel = sender.Tag != null;
783854
}
784855

785-
[ThreadStatic]
786-
private static TaskCompletionSource<ContentDialog> _currentDialogShowRequest;
856+
//[ThreadStatic]
857+
//private static TaskCompletionSource<ContentDialog> _currentDialogShowRequest;
787858

788-
public async Task<ContentDialogResult> ShowQueuedAsync(XamlRoot xamlRoot)
789-
{
790-
while (_currentDialogShowRequest != null)
791-
{
792-
await _currentDialogShowRequest.Task;
793-
}
859+
//public async Task<ContentDialogResult> ShowQueuedAsync(XamlRoot xamlRoot)
860+
//{
861+
// while (_currentDialogShowRequest != null)
862+
// {
863+
// await _currentDialogShowRequest.Task;
864+
// }
794865

795-
var dialog = this;
796-
Logger.Info(dialog.GetType().Name);
866+
// var dialog = this;
867+
// Logger.Info(dialog.GetType().Name);
797868

798-
if (dialog is ContentPopup popup)
799-
{
800-
popup.OnCreate();
801-
}
869+
// if (dialog is ContentPopup popup)
870+
// {
871+
// popup.OnCreate();
872+
// }
802873

803-
dialog.XamlRoot = xamlRoot;
874+
// dialog.XamlRoot = xamlRoot;
804875

805-
var request = _currentDialogShowRequest = new TaskCompletionSource<ContentDialog>();
806-
var result = await dialog.ShowAsync();
807-
_currentDialogShowRequest = null;
808-
request.SetResult(dialog);
876+
// var request = _currentDialogShowRequest = new TaskCompletionSource<ContentDialog>();
877+
// var result = await dialog.ShowAsync();
878+
// _currentDialogShowRequest = null;
879+
// request.SetResult(dialog);
809880

810-
Logger.Info(dialog.GetType().Name + ", closed");
811-
return result;
812-
}
881+
// Logger.Info(dialog.GetType().Name + ", closed");
882+
// return result;
883+
//}
813884
}
814885
}

0 commit comments

Comments
 (0)