Skip to content

Commit

Permalink
feat: CloseRequested event on Skia
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Mar 10, 2022
1 parent 30484be commit 9f25358
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ private void RemoveHandler_Click(object sender, RoutedEventArgs args)
private async void CloseRequestedTests_CloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
{
var deferral = e.GetDeferral();
var dialog = new MessageDialog("Are you sure you want to exit?", "Exit");
var confirmCommand = new UICommand("Yes");
var cancelCommand = new UICommand("No");
dialog.Commands.Add(confirmCommand);
dialog.Commands.Add(cancelCommand);
if (await dialog.ShowAsync() == cancelCommand)
var dialog = new ContentDialog();
dialog.Title = "Exit";
dialog.Content = "Are you sure you want to exit?";
dialog.PrimaryButtonText = "Yes";
dialog.SecondaryButtonText = "No";
if (await dialog.ShowAsync() != ContentDialogResult.Primary)
{
//cancel close by handling the event
e.Handled = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#nullable enable

using Gtk;
using Uno.UI.Core.Preview;

namespace Uno.Extensions.UI.Core.Preview;

public class SystemNavigationManagerPreviewExtension : ISystemNavigationManagerPreviewExtension
{
private readonly Window _window;

public SystemNavigationManagerPreviewExtension(Gtk.Window window)
{
_window = window;
}

public void RequestNativeAppClose() => _window.Close();
}
68 changes: 44 additions & 24 deletions src/Uno.UI.Runtime.Skia.Gtk/GtkHost.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
using System;
using System.IO;
using Windows.System;
using Gtk;
using Uno.ApplicationModel.DataTransfer;
using Uno.Extensions;
using Uno.Extensions.Storage.Pickers;
using Uno.Extensions.System;
using Uno.Extensions.UI.Core.Preview;
using Uno.Foundation.Extensibility;
using Uno.Foundation.Logging;
using Uno.Helpers.Theming;
using Uno.UI.Runtime.Skia.GTK.Extensions.Helpers.Theming;
using Windows.UI.Xaml;
using WUX = Windows.UI.Xaml;
using Uno.UI.Xaml.Controls.Extensions;
using Uno.UI.Runtime.Skia.GTK.Extensions.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls;
using Gtk;
using Uno.UI.Core.Preview;
using Uno.UI.Runtime.Skia.GTK.Extensions.ApplicationModel.DataTransfer;
using Uno.UI.Runtime.Skia.GTK.Extensions.Helpers;
using Uno.Extensions.System;
using Uno.UI.Runtime.Skia.GTK.Extensions.Helpers.Theming;
using Uno.UI.Runtime.Skia.GTK.Extensions.System;
using Uno.UI.Runtime.Skia.GTK.Extensions.UI.Xaml.Controls;
using Uno.UI.Runtime.Skia.GTK.System.Profile;
using Uno.UI.Runtime.Skia.GTK.UI.Core;
using Uno.Extensions.Storage.Pickers;
using Windows.Storage.Pickers;
using Windows.UI.ViewManagement;
using Uno.UI.Xaml.Controls.Extensions;
using Windows.Foundation;
using Uno.ApplicationModel.DataTransfer;
using Uno.UI.Runtime.Skia.GTK.Extensions.ApplicationModel.DataTransfer;
using Uno.Foundation.Logging;
using Windows.Storage.Pickers;
using Windows.System.Profile.Internal;
using Uno.UI.Runtime.Skia.GTK.System.Profile;
using Uno.UI.Runtime.Skia.Helpers;
using Uno.UI.Runtime.Skia.Helpers.Dpi;
using Windows.UI.Core.Preview;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using UnoApplication = Windows.UI.Xaml.Application;
using WUX = Windows.UI.Xaml;

namespace Uno.UI.Runtime.Skia
{
Expand Down Expand Up @@ -70,6 +71,7 @@ public void Run()
ApiExtensibility.Register(typeof(IClipboardExtension), o => new ClipboardExtensions(o));
ApiExtensibility.Register<FileSavePicker>(typeof(IFileSavePickerExtension), o => new FileSavePickerExtension(o));
ApiExtensibility.Register(typeof(IAnalyticsInfoExtension), o => new AnalyticsInfoExtension());
ApiExtensibility.Register(typeof(ISystemNavigationManagerPreviewExtension), o => new SystemNavigationManagerPreviewExtension(_window));

_isDispatcherThread = true;
_window = new Gtk.Window("Uno Host");
Expand All @@ -91,10 +93,7 @@ public void Run()
Cursors.Reload();
};

_window.DeleteEvent += delegate
{
Gtk.Application.Quit();
};
_window.DeleteEvent += WindowClosing;

void Dispatch(System.Action d)
{
Expand Down Expand Up @@ -166,6 +165,27 @@ void CreateApp(ApplicationInitializationCallbackParams _)
Gtk.Application.Run();
}

private void WindowClosing(object sender, DeleteEventArgs args)
{
var manager = SystemNavigationManagerPreview.GetForCurrentView();
if (!manager.HasConfirmedClose)
{
if (!manager.RequestAppClose())
{
// App closing was prevented, handle event
args.RetVal = true;
return;
}
}

// Closing should continue, perform suspension.
UnoApplication.Current.RaiseSuspending();

// All prerequisites passed, can safely close.
args.RetVal = false;
Gtk.Main.Quit();
}

private void OnWindowStateChanged(object o, WindowStateEventArgs args)
{
var winUIApplication = WUX.Application.Current;
Expand Down Expand Up @@ -193,13 +213,13 @@ private void OnWindowStateChanged(object o, WindowStateEventArgs args)
{
if (isVisible)
{
winUIApplication?.OnLeavingBackground();
winUIApplication?.RaiseLeavingBackground(null);
winUIWindow?.OnVisibilityChanged(true);
}
else
{
winUIWindow?.OnVisibilityChanged(false);
winUIApplication?.OnEnteredBackground();
winUIApplication?.RaiseEnteredBackground(null);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;
using Uno.UI.Core.Preview;

namespace Uno.Extensions.UI.Core.Preview
{
public class SystemNavigationManagerPreviewExtension : ISystemNavigationManagerPreviewExtension
{
public void RequestNativeAppClose() => Application.Current.MainWindow.Close();
}
}
27 changes: 25 additions & 2 deletions src/Uno.UI.Runtime.Skia.Wpf/WpfHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
using WpfCanvas = System.Windows.Controls.Canvas;
using WpfControl = System.Windows.Controls.Control;
using WpfFrameworkPropertyMetadata = System.Windows.FrameworkPropertyMetadata;
using UnoApplication = Windows.UI.Xaml.Application;
using Windows.UI.ViewManagement;
using Uno.UI.Xaml;
using Uno.UI.Runtime.Skia.Wpf;
Expand All @@ -39,6 +40,9 @@
using Windows.System.Profile.Internal;
using Uno.Extensions.System.Profile;
using Windows.Storage.Pickers;
using Uno.UI.Core.Preview;
using Uno.Extensions.UI.Core.Preview;
using Windows.UI.Core.Preview;

namespace Uno.UI.Skia.Platform
{
Expand Down Expand Up @@ -76,6 +80,7 @@ static WpfHost()
ApiExtensibility.Register(typeof(ILauncherExtension), o => new LauncherExtension(o));
ApiExtensibility.Register(typeof(IClipboardExtension), o => new ClipboardExtensions(o));
ApiExtensibility.Register(typeof(IAnalyticsInfoExtension), o => new AnalyticsInfoExtension());
ApiExtensibility.Register(typeof(ISystemNavigationManagerPreviewExtension), o => new SystemNavigationManagerPreviewExtension());
}

public static WpfHost Current => _current;
Expand Down Expand Up @@ -119,6 +124,7 @@ void CreateApp(WinUI.ApplicationInitializationCallbackParams _)
WpfApplication.Current.Activated += Current_Activated;
WpfApplication.Current.Deactivated += Current_Deactivated;
WpfApplication.Current.MainWindow.StateChanged += MainWindow_StateChanged;
WpfApplication.Current.MainWindow.Closing += MainWindow_Closing;

Windows.Foundation.Size preferredWindowSize = ApplicationView.PreferredLaunchViewSize;
if (preferredWindowSize != Windows.Foundation.Size.Empty)
Expand All @@ -131,6 +137,23 @@ void CreateApp(WinUI.ApplicationInitializationCallbackParams _)
Loaded += WpfHost_Loaded;
}

private void MainWindow_Closing(object sender, CancelEventArgs e)
{
var manager = SystemNavigationManagerPreview.GetForCurrentView();
if (!manager.HasConfirmedClose)
{
if (!manager.RequestAppClose())
{
e.Cancel = true;
return;
}
}

// Closing should continue, perform suspension.
// TODO: Support async suspension
UnoApplication.Current.RaiseSuspending();
}

public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Expand All @@ -152,13 +175,13 @@ private void Current_Deactivated(object? sender, EventArgs e)
winUIWindow?.OnActivated(Windows.UI.Core.CoreWindowActivationState.Deactivated);

var application = WinUI.Application.Current;
application?.OnEnteredBackground();
application?.RaiseEnteredBackground(null);
}

private void Current_Activated(object? sender, EventArgs e)
{
var application = WinUI.Application.Current;
application?.OnLeavingBackground();
application?.RaiseLeavingBackground(null);

var winUIWindow = WinUI.Window.Current;
winUIWindow?.OnActivated(Windows.UI.Core.CoreWindowActivationState.CodeActivated);
Expand Down
15 changes: 6 additions & 9 deletions src/Uno.UI/Controls/Window.macOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -643,23 +643,20 @@ public override bool WindowShouldClose(NSObject sender)
var manager = SystemNavigationManagerPreview.GetForCurrentView();
if (!manager.HasConfirmedClose)
{
manager.OnCloseRequested();
if (!manager.HasConfirmedClose)
{
// Close was either deferred or canceled synchronously.
if (!manager.RequestAppClose())
{
return false;
}
}
}

// closing should continue, perform suspension

// Closing should continue, perform suspension.
if (!Application.Current.Suspended)
{
Application.Current.OnSuspending();
Application.Current.RaiseSuspending();
return Application.Current.Suspended;
}

// all prerequisites passed, can safely close
// All prerequisites passed, can safely close.
return true;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Uno.UI/UI/Xaml/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ internal void RaiseSuspending()
CoreApplication.RaiseSuspending(suspendingEventArgs);
var completedSynchronously = suspendingOperation.DeferralManager.EventRaiseCompleted();

#if !__IOS__ && !__ANDROID__ && !__MACOS__
#if !__IOS__ && !__ANDROID__
// Asynchronous suspension is not supported on all targets, warn the user
if (!completedSynchronously && this.Log().IsEnabled(LogLevel.Warning))
{
Expand All @@ -331,7 +331,7 @@ internal void RaiseSuspending()
#endif
}

#if !__IOS__ && !__ANDROID__ && !__MACOS__
#if !__IOS__ && !__ANDROID__
/// <summary>
/// On platforms which don't support asynchronous suspension we indicate that with immediate
/// deadline and warning in logs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
#pragma warning disable 114 // new keyword hiding
namespace Windows.UI.Core.Preview
{
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented]
#endif
public partial class SystemNavigationCloseRequestedPreviewEventArgs
{
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__")]
public bool Handled
{
Expand All @@ -23,7 +23,7 @@ public bool Handled
#endif
// Forced skipping of method Windows.UI.Core.Preview.SystemNavigationCloseRequestedPreviewEventArgs.Handled.get
// Forced skipping of method Windows.UI.Core.Preview.SystemNavigationCloseRequestedPreviewEventArgs.Handled.set
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__")]
public global::Windows.Foundation.Deferral GetDeferral()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
#pragma warning disable 114 // new keyword hiding
namespace Windows.UI.Core.Preview
{
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented]
#endif
public partial class SystemNavigationManagerPreview
{
// Forced skipping of method Windows.UI.Core.Preview.SystemNavigationManagerPreview.CloseRequested.add
// Forced skipping of method Windows.UI.Core.Preview.SystemNavigationManagerPreview.CloseRequested.remove
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__")]
public static global::Windows.UI.Core.Preview.SystemNavigationManagerPreview GetForCurrentView()
{
throw new global::System.NotImplementedException("The member SystemNavigationManagerPreview SystemNavigationManagerPreview.GetForCurrentView() is not implemented in Uno.");
}
#endif
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__")]
public event global::System.EventHandler<global::Windows.UI.Core.Preview.SystemNavigationCloseRequestedPreviewEventArgs> CloseRequested
{
Expand Down
8 changes: 7 additions & 1 deletion src/Uno.UWP/Helpers/DeferralManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public DeferralManager(Func<DeferralCompletedHandler, T> deferralFactory)

internal event EventHandler? Completed;

internal bool CompletedSynchronously { get; set; }

public T GetDeferral()
{
_deferralsCount++;
Expand Down Expand Up @@ -57,7 +59,11 @@ void OnDeferralCompleted()
/// the Completed event.
/// </summary>
/// <returns>A value indicating whether the deferral completed synchronously.</returns>
internal bool EventRaiseCompleted() => DeferralCompleted();
internal bool EventRaiseCompleted()
{
CompletedSynchronously = DeferralCompleted();
return CompletedSynchronously;
}

internal Task WhenAllCompletedAsync() => _allDeferralsCompletedCompletionSource.Task;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Uno.UI.Core.Preview;

public interface ISystemNavigationManagerPreviewExtension
{
void RequestNativeAppClose();
}
Loading

0 comments on commit 9f25358

Please sign in to comment.