diff --git a/src/Calculator/App.xaml.cs b/src/Calculator/App.xaml.cs
index 84d75e10..9ecfaa03 100644
--- a/src/Calculator/App.xaml.cs
+++ b/src/Calculator/App.xaml.cs
@@ -6,26 +6,22 @@
// Declaration of the App class.
//
-using CalculatorApp.ViewModel.Common;
-using CalculatorApp.ViewModel.Common.Automation;
-
using System;
-using System.Collections.Generic;
using System.Diagnostics;
-using System.Threading;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
-using Windows.ApplicationModel.Core;
using Windows.Foundation;
using Windows.Storage;
-using Windows.UI.Core;
using Windows.UI.StartScreen;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
+using CalculatorApp.ViewModel.Common;
+using CalculatorApp.ViewModel.Common.Automation;
+
namespace CalculatorApp
{
namespace ApplicationResourceKeys
@@ -49,17 +45,12 @@ namespace CalculatorApp
public App()
{
InitializeComponent();
-
- m_preLaunched = false;
-
- RegisterDependencyProperties();
+ NarratorNotifier.RegisterDependencyProperties();
// TODO: MSFT 14645325: Set this directly from XAML.
// Currently this is bugged so the property is only respected from code-behind.
HighContrastAdjustment = ApplicationHighContrastAdjustment.None;
-
Suspending += OnSuspending;
-
#if DEBUG
DebugSettings.IsBindingTracingEnabled = true;
DebugSettings.BindingFailed += (sender, args) =>
@@ -81,18 +72,12 @@ namespace CalculatorApp
/// Details about the launch request and process.
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
- if (args.PrelaunchActivated)
- {
- // If the app got pre-launch activated, then save that state in a flag
- m_preLaunched = true;
- }
-
NavCategoryStates.SetCurrentUser(args.User.NonRoamableId);
// It takes time to check GraphingMode at the 1st time. So, do it in a background thread
Task.Run(() => NavCategoryStates.IsViewModeEnabled(ViewMode.Graphing));
- OnAppLaunch(args, args.Arguments);
+ OnAppLaunch(args, args.Arguments, args.PrelaunchActivated);
}
protected override void OnActivated(IActivatedEventArgs args)
@@ -101,63 +86,21 @@ namespace CalculatorApp
{
// We currently don't pass the uri as an argument,
// and handle any protocol launch as a normal app launch.
- OnAppLaunch(args, null);
+ OnAppLaunch(args, null, false);
}
}
- internal void RemoveWindow(WindowFrameService frameService)
- {
- // Shell does not allow killing the main window.
- if (m_mainViewId != frameService.GetViewId())
- {
- _ = HandleViewReleaseAndRemoveWindowFromMap(frameService);
- }
- }
-
- internal void RemoveSecondaryWindow(WindowFrameService frameService)
- {
- // Shell does not allow killing the main window.
- if (m_mainViewId != frameService.GetViewId())
- {
- RemoveWindowFromMap(frameService.GetViewId());
- }
- }
-
- private static Frame CreateFrame()
- {
- var frame = new Frame
- {
- FlowDirection = LocalizationService.GetInstance().GetFlowDirection()
- };
- return frame;
- }
-
- private static void SetMinWindowSizeAndThemeAndActivate(Frame rootFrame, Size minWindowSize)
- {
- // SetPreferredMinSize should always be called before Window.Activate
- ApplicationView appView = ApplicationView.GetForCurrentView();
- appView.SetPreferredMinSize(minWindowSize);
-
- // Place the frame in the current Window
- Window.Current.Content = rootFrame;
- CalculatorApp.Utils.ThemeHelper.InitializeAppTheme();
- Window.Current.Activate();
- }
-
- private void OnAppLaunch(IActivatedEventArgs args, string argument)
+ private void OnAppLaunch(IActivatedEventArgs args, string argument, bool isPreLaunch)
{
// Uncomment the following lines to display frame-rate and per-frame CPU usage info.
- //#if _DEBUG
+ //#if DEBUG
// if (IsDebuggerPresent())
// {
- // DebugSettings->EnableFrameRateCounter = true;
+ // DebugSettings.EnableFrameRateCounter = true;
// }
//#endif
- args.SplashScreen.Dismissed += DismissedEventHandler;
-
- var rootFrame = (Window.Current.Content as Frame);
- WeakReference weak = new WeakReference(this);
+ args.SplashScreen.Dismissed += async (_, __) => await SetupJumpListAsync();
float minWindowWidth = (float)((double)Resources[ApplicationResourceKeys.Globals.AppMinWindowWidth]);
float minWindowHeight = (float)((double)Resources[ApplicationResourceKeys.Globals.AppMinWindowHeight]);
@@ -179,190 +122,37 @@ namespace CalculatorApp
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
+ var rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
- if (!Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons")) // PC Family
+ rootFrame = new Frame
{
- // Disable the system view activation policy during the first launch of the app
- // only for PC family devices and not for phone family devices
- try
- {
- ApplicationViewSwitcher.DisableSystemViewActivationPolicy();
- }
- catch (Exception)
- {
- // Log that DisableSystemViewActionPolicy didn't work
- }
- }
-
- // Create a Frame to act as the navigation context
- rootFrame = App.CreateFrame();
-
- // When the navigation stack isn't restored navigate to the first page,
- // configuring the new page by passing required information as a navigation
- // parameter
- if (!rootFrame.Navigate(typeof(MainPage), argument))
- {
- // We couldn't navigate to the main page, kill the app so we have a good
- // stack to debug
- throw new SystemException();
- }
-
- SetMinWindowSizeAndThemeAndActivate(rootFrame, minWindowSize);
- m_mainViewId = ApplicationView.GetForCurrentView().Id;
- AddWindowToMap(WindowFrameService.CreateNewWindowFrameService(rootFrame, false, weak));
+ FlowDirection = LocalizationService.GetInstance().GetFlowDirection()
+ };
}
- else
+
+ if (isPreLaunch)
{
- // For first launch, LaunchStart is logged in constructor, this is for subsequent launches.
-
- // !Phone check is required because even in continuum mode user interaction mode is Mouse not Touch
- if ((UIViewSettings.GetForCurrentView().UserInteractionMode == UserInteractionMode.Mouse)
- && (!Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons")))
- {
- // If the pre-launch hasn't happened then allow for the new window/view creation
- if (!m_preLaunched)
- {
- var newCoreAppView = CoreApplication.CreateNewView();
- _ = newCoreAppView.Dispatcher.RunAsync(
- CoreDispatcherPriority.Normal, async () =>
- {
- if (weak.Target is App that)
- {
- var newRootFrame = App.CreateFrame();
-
- SetMinWindowSizeAndThemeAndActivate(newRootFrame, minWindowSize);
-
- if (!newRootFrame.Navigate(typeof(MainPage), argument))
- {
- // We couldn't navigate to the main page, kill the app so we have a good
- // stack to debug
- throw new SystemException();
- }
-
- var frameService = WindowFrameService.CreateNewWindowFrameService(newRootFrame, true, weak);
- that.AddWindowToMap(frameService);
-
- var dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
-
- // CSHARP_MIGRATION_ANNOTATION:
- // class SafeFrameWindowCreation is being interpreted into a IDisposable class
- // in order to enhance its RAII capability that was written in C++/CX
- using (var safeFrameServiceCreation = new SafeFrameWindowCreation(frameService, that))
- {
- int newWindowId = ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread());
-
- ActivationViewSwitcher activationViewSwitcher = null;
- var activateEventArgs = (args as IViewSwitcherProvider);
- if (activateEventArgs != null)
- {
- activationViewSwitcher = activateEventArgs.ViewSwitcher;
- }
-
- if (activationViewSwitcher != null)
- {
- _ = activationViewSwitcher.ShowAsStandaloneAsync(newWindowId, ViewSizePreference.Default);
- safeFrameServiceCreation.SetOperationSuccess(true);
- }
- else
- {
- var activatedEventArgs = (args as IApplicationViewActivatedEventArgs);
- if ((activatedEventArgs != null) && (activatedEventArgs.CurrentlyShownApplicationViewId != 0))
- {
- // CSHARP_MIGRATION_ANNOTATION:
- // here we don't use ContinueWith() to interpret origin code because we would like to
- // pursue the design of class SafeFrameWindowCreate whichi was using RAII to ensure
- // some states get handled properly when its instance is being destructed.
- //
- // To achieve that, SafeFrameWindowCreate has been reinterpreted using IDisposable
- // pattern, which forces we use below way to keep async works being controlled within
- // a same code block.
- var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
- frameService.GetViewId(),
- ViewSizePreference.Default,
- activatedEventArgs.CurrentlyShownApplicationViewId,
- ViewSizePreference.Default);
- // SafeFrameServiceCreation is used to automatically remove the frame
- // from the list of frames if something goes bad.
- safeFrameServiceCreation.SetOperationSuccess(viewShown);
- }
- }
- }
- }
- });
- }
- else
- {
- ActivationViewSwitcher activationViewSwitcher = null;
- var activateEventArgs = (args as IViewSwitcherProvider);
- if (activateEventArgs != null)
- {
- activationViewSwitcher = activateEventArgs.ViewSwitcher;
- }
-
- if (activationViewSwitcher != null)
- {
- _ = activationViewSwitcher.ShowAsStandaloneAsync(
- ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread()), ViewSizePreference.Default);
- }
- else
- {
- TraceLogger.GetInstance().LogError(ViewMode.None, "App.OnAppLaunch", "Null_ActivationViewSwitcher");
- }
- }
- // Set the preLaunched flag to false
- m_preLaunched = false;
- }
- else // for touch devices
- {
- if (rootFrame.Content == null)
- {
- // When the navigation stack isn't restored navigate to the first page,
- // configuring the new page by passing required information as a navigation
- // parameter
- if (!rootFrame.Navigate(typeof(MainPage), argument))
- {
- // We couldn't navigate to the main page,
- // kill the app so we have a good stack to debug
- throw new SystemException();
- }
- }
- if (ApplicationView.GetForCurrentView().ViewMode != ApplicationViewMode.CompactOverlay)
- {
- if (!Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
- {
- // for tablet mode: since system view activation policy is disabled so do ShowAsStandaloneAsync if activationViewSwitcher exists in
- // activationArgs
- ActivationViewSwitcher activationViewSwitcher = null;
- var activateEventArgs = (args as IViewSwitcherProvider);
- if (activateEventArgs != null)
- {
- activationViewSwitcher = activateEventArgs.ViewSwitcher;
- }
- if (activationViewSwitcher != null)
- {
- var viewId = (args as IApplicationViewActivatedEventArgs).CurrentlyShownApplicationViewId;
- if (viewId != 0)
- {
- _ = activationViewSwitcher.ShowAsStandaloneAsync(viewId);
- }
- }
- }
- // Ensure the current window is active
- Window.Current.Activate();
- }
- }
+ return;
}
- }
- private void DismissedEventHandler(SplashScreen sender, object e)
- {
- _ = SetupJumpList();
- }
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ if (rootFrame.Content == null && !rootFrame.Navigate(typeof(MainPage), argument))
+ {
+ // We couldn't navigate to the main page, kill the app so we have a good
+ // stack to debug
+ throw new SystemException("6d430286-eb5d-4f8d-95d2-3d1059552968");
+ }
- private void RegisterDependencyProperties()
- {
- NarratorNotifier.RegisterDependencyProperties();
+ // SetPreferredMinSize should always be called before Window.Activate
+ appView.SetPreferredMinSize(minWindowSize);
+
+ // Place the frame in the current Window
+ Window.Current.Content = rootFrame;
+ Utils.ThemeHelper.InitializeAppTheme();
+ Window.Current.Activate();
}
private void OnSuspending(object sender, SuspendingEventArgs args)
@@ -370,43 +160,7 @@ namespace CalculatorApp
TraceLogger.GetInstance().LogButtonUsage();
}
- private sealed class SafeFrameWindowCreation : IDisposable
- {
- public SafeFrameWindowCreation(WindowFrameService frameService, App parent)
- {
- m_frameService = frameService;
- m_frameOpenedInWindow = false;
- m_parent = parent;
- }
-
- public void SetOperationSuccess(bool success)
- {
- m_frameOpenedInWindow = success;
- }
-
- public void Dispose()
- {
- if (!m_frameOpenedInWindow)
- {
- // Close the window as the navigation to the window didn't succeed
- // and this is not visible to the user.
- m_parent.RemoveWindowFromMap(m_frameService.GetViewId());
- }
-
- GC.SuppressFinalize(this);
- }
-
- ~SafeFrameWindowCreation()
- {
- Dispose();
- }
-
- private readonly WindowFrameService m_frameService;
- private bool m_frameOpenedInWindow;
- private readonly App m_parent;
- };
-
- private async Task SetupJumpList()
+ private async Task SetupJumpListAsync()
{
try
{
@@ -434,79 +188,11 @@ namespace CalculatorApp
}
catch
{
+#if DEBUG
+ throw;
+#endif
}
}
-
- private async Task HandleViewReleaseAndRemoveWindowFromMap(WindowFrameService frameService)
- {
- WeakReference weak = new WeakReference(this);
-
- // Unregister the event handler of the Main Page
- var frame = (Window.Current.Content as Frame);
- var mainPage = (frame.Content as MainPage);
-
- mainPage.UnregisterEventHandlers();
-
- await frameService.HandleViewRelease();
- await Task.Run(() =>
- {
- var that = weak.Target as App;
- that.RemoveWindowFromMap(frameService.GetViewId());
- }).ConfigureAwait(false /* task_continuation_context::use_arbitrary() */);
- }
-
- private void AddWindowToMap(WindowFrameService frameService)
- {
- m_windowsMapLock.EnterWriteLock();
- try
- {
- m_secondaryWindows[frameService.GetViewId()] = frameService;
- TraceLogger.GetInstance().UpdateWindowCount(Convert.ToUInt64(m_secondaryWindows.Count));
- }
- finally
- {
- m_windowsMapLock.ExitWriteLock();
- }
- }
-
- private WindowFrameService GetWindowFromMap(int viewId)
- {
- m_windowsMapLock.EnterReadLock();
- try
- {
- if (m_secondaryWindows.TryGetValue(viewId, out var windowMapEntry))
- {
- return windowMapEntry;
- }
- else
- {
- return null;
- }
- }
- finally
- {
- m_windowsMapLock.ExitReadLock();
- }
- }
-
- private void RemoveWindowFromMap(int viewId)
- {
- m_windowsMapLock.EnterWriteLock();
- try
- {
- bool removed = m_secondaryWindows.Remove(viewId);
- Debug.Assert(removed != false, "Window does not exist in the list");
- }
- finally
- {
- m_windowsMapLock.ExitWriteLock();
- }
- }
-
- private readonly ReaderWriterLockSlim m_windowsMapLock = new ReaderWriterLockSlim();
- private readonly Dictionary m_secondaryWindows = new Dictionary();
- private int m_mainViewId;
- private bool m_preLaunched;
}
}
diff --git a/src/Calculator/Calculator.csproj b/src/Calculator/Calculator.csproj
index e9f71be3..b92f52fd 100644
--- a/src/Calculator/Calculator.csproj
+++ b/src/Calculator/Calculator.csproj
@@ -250,7 +250,6 @@
UnitConverter.xaml
-
diff --git a/src/Calculator/Package.Release.appxmanifest b/src/Calculator/Package.Release.appxmanifest
index c71a8cbe..57f7e108 100644
--- a/src/Calculator/Package.Release.appxmanifest
+++ b/src/Calculator/Package.Release.appxmanifest
@@ -1,5 +1,12 @@
-
+
@@ -14,7 +21,11 @@
-
+
diff --git a/src/Calculator/Package.appxmanifest b/src/Calculator/Package.appxmanifest
index 515c8ee9..901b0453 100644
--- a/src/Calculator/Package.appxmanifest
+++ b/src/Calculator/Package.appxmanifest
@@ -1,5 +1,12 @@
-
+
@@ -14,7 +21,11 @@
-
+
diff --git a/src/Calculator/WindowFrameService.cs b/src/Calculator/WindowFrameService.cs
deleted file mode 100644
index 55f5c7d8..00000000
--- a/src/Calculator/WindowFrameService.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using CalculatorApp.Common;
-using CalculatorApp.ViewModel.Common;
-
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Diagnostics;
-using System.Threading.Tasks;
-
-using Windows.ApplicationModel.Core;
-using Windows.UI.Core;
-using Windows.UI.ViewManagement;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-
-namespace CalculatorApp
-{
- public sealed class WindowFrameService
- {
- public Page GetCurrentPage()
- {
- return (m_frame.Content as Page);
- }
-
- public void SetNewFrame(Windows.UI.Xaml.Controls.Frame frame)
- {
- Debug.Assert(frame.BackStackDepth == 0);
- m_frame = frame;
- }
-
- // createdByUs means any window that we create.
- // !createdByUs means the main window
- internal static WindowFrameService CreateNewWindowFrameService(Frame viewFrame, bool createdByUs, WeakReference parent)
- {
- Debug.Assert(CoreWindow.GetForCurrentThread() != null);
- var frameService = new WindowFrameService(viewFrame, parent);
- frameService.InitializeFrameService(createdByUs);
- return frameService;
- }
-
- public CoreDispatcher GetCoreDispatcher()
- {
- return m_coreDispatcher;
- }
-
- public int GetViewId()
- {
- return m_viewId;
- }
-
- public void RegisterOnWindowClosingHandler(Action onWindowClosingHandler)
- {
- m_onWindowClosingHandlers.Add(onWindowClosingHandler);
- }
-
- public Task HandleViewRelease()
- {
- TaskCompletionSource