mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 20:27:36 +02:00
[OOBE] Out of box experience window (#9973)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<Application x:Class="PowerToys.Settings.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
StartupUri="MainWindow.xaml">
|
||||
Startup="Application_Startup">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
namespace PowerToys.Settings
|
||||
{
|
||||
@@ -11,5 +14,60 @@ namespace PowerToys.Settings
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
private MainWindow settingsWindow;
|
||||
|
||||
public bool ShowOobe { get; set; }
|
||||
|
||||
public void OpenSettingsWindow(Type type)
|
||||
{
|
||||
if (settingsWindow == null)
|
||||
{
|
||||
settingsWindow = new MainWindow();
|
||||
}
|
||||
|
||||
settingsWindow.Show();
|
||||
settingsWindow.NavigateToSection(type);
|
||||
}
|
||||
|
||||
private void InitHiddenSettingsWindow()
|
||||
{
|
||||
settingsWindow = new MainWindow();
|
||||
|
||||
// To avoid visual flickering, show the window with a size of 0,0
|
||||
// and don't show it in the taskbar
|
||||
var originalHight = settingsWindow.Height;
|
||||
var originalWidth = settingsWindow.Width;
|
||||
settingsWindow.Height = 0;
|
||||
settingsWindow.Width = 0;
|
||||
settingsWindow.ShowInTaskbar = false;
|
||||
|
||||
settingsWindow.Show();
|
||||
settingsWindow.Hide();
|
||||
|
||||
settingsWindow.Height = originalHight;
|
||||
settingsWindow.Width = originalWidth;
|
||||
settingsWindow.ShowInTaskbar = true;
|
||||
}
|
||||
|
||||
private void Application_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
if (!ShowOobe)
|
||||
{
|
||||
settingsWindow = new MainWindow();
|
||||
settingsWindow.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
|
||||
|
||||
// Create the Settings window so that it's fully initialized and
|
||||
// it will be ready to receive the notification if the user opens
|
||||
// the Settings from the tray icon.
|
||||
InitHiddenSettingsWindow();
|
||||
|
||||
OobeWindow oobeWindow = new OobeWindow();
|
||||
oobeWindow.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:Controls="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls"
|
||||
xmlns:xaml="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"
|
||||
mc:Ignorable="d"
|
||||
Title="PowerToys Settings" MinWidth="480" Height="800" Width="1100" Closing="MainWindow_Closing">
|
||||
Title="PowerToys Settings" MinWidth="480" Height="800" Width="1100" Closing="MainWindow_Closing" Loaded="MainWindow_Loaded" Activated="MainWindow_Activated">
|
||||
<Grid>
|
||||
<xaml:WindowsXamlHost InitialTypeName="Microsoft.PowerToys.Settings.UI.Views.ShellPage" ChildChanged="WindowsXamlHost_ChildChanged" />
|
||||
</Grid>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
@@ -16,6 +16,8 @@ namespace PowerToys.Settings
|
||||
// Interaction logic for MainWindow.xaml.
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private static Window inst;
|
||||
|
||||
private bool isOpen = true;
|
||||
|
||||
public MainWindow()
|
||||
@@ -29,6 +31,23 @@ namespace PowerToys.Settings
|
||||
PowerToysTelemetry.Log.WriteEvent(new SettingsBootEvent() { BootTimeMs = bootTime.ElapsedMilliseconds });
|
||||
}
|
||||
|
||||
public static void CloseHiddenWindow()
|
||||
{
|
||||
if (inst != null && inst.Visibility == Visibility.Hidden)
|
||||
{
|
||||
inst.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void NavigateToSection(Type type)
|
||||
{
|
||||
if (inst != null)
|
||||
{
|
||||
Activate();
|
||||
ShellPage.Navigate(type);
|
||||
}
|
||||
}
|
||||
|
||||
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
|
||||
{
|
||||
// If sender is null, it could lead to a NullReferenceException. This might occur on restarting as admin (check https://github.com/microsoft/PowerToys/issues/7393 for details)
|
||||
@@ -63,6 +82,13 @@ namespace PowerToys.Settings
|
||||
Program.GetTwoWayIPCManager().Send(msg);
|
||||
});
|
||||
|
||||
// open oobe
|
||||
ShellPage.SetOpenOobeCallback(() =>
|
||||
{
|
||||
var oobe = new OobeWindow();
|
||||
oobe.Show();
|
||||
});
|
||||
|
||||
// receive IPC Message
|
||||
Program.IPCMessageReceivedCallback = (string msg) =>
|
||||
{
|
||||
@@ -97,7 +123,15 @@ namespace PowerToys.Settings
|
||||
|
||||
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
isOpen = false;
|
||||
if (OobeWindow.IsOpened)
|
||||
{
|
||||
e.Cancel = true;
|
||||
((Window)sender).Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
isOpen = false;
|
||||
}
|
||||
|
||||
// XAML Islands: If the window is closed while minimized, exit the process. Required to avoid process not terminating issue - https://github.com/microsoft/PowerToys/issues/4430
|
||||
if (WindowState == WindowState.Minimized)
|
||||
@@ -106,5 +140,18 @@ namespace PowerToys.Settings
|
||||
System.Threading.Tasks.Task.Run(() => { Environment.Exit(0); });
|
||||
}
|
||||
}
|
||||
|
||||
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
inst = (Window)sender;
|
||||
}
|
||||
|
||||
private void MainWindow_Activated(object sender, EventArgs e)
|
||||
{
|
||||
if (((Window)sender).Visibility == Visibility.Hidden)
|
||||
{
|
||||
((Window)sender).Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
src/settings-ui/PowerToys.Settings/OobeWindow.xaml
Normal file
19
src/settings-ui/PowerToys.Settings/OobeWindow.xaml
Normal file
@@ -0,0 +1,19 @@
|
||||
<Window x:Class="PowerToys.Settings.OobeWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:PowerToys.Settings"
|
||||
xmlns:Controls="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls"
|
||||
xmlns:xaml="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"
|
||||
mc:Ignorable="d"
|
||||
Title="Welcome to PowerToys"
|
||||
MinWidth="480" Height="700" Width="1100"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Loaded="Window_Loaded"
|
||||
Closed="Window_Closed">
|
||||
<Grid>
|
||||
<xaml:WindowsXamlHost InitialTypeName="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeShellPage" ChildChanged="WindowsXamlHost_ChildChanged" />
|
||||
</Grid>
|
||||
</Window>
|
||||
88
src/settings-ui/PowerToys.Settings/OobeWindow.xaml.cs
Normal file
88
src/settings-ui/PowerToys.Settings/OobeWindow.xaml.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using interop;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Views;
|
||||
using Microsoft.Toolkit.Wpf.UI.XamlHost;
|
||||
|
||||
namespace PowerToys.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for OobeWindow.xaml
|
||||
/// </summary>
|
||||
public partial class OobeWindow : Window
|
||||
{
|
||||
private static Window inst;
|
||||
private OobeShellPage shellPage;
|
||||
|
||||
public static bool IsOpened
|
||||
{
|
||||
get
|
||||
{
|
||||
return inst != null;
|
||||
}
|
||||
}
|
||||
|
||||
public OobeWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Window_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (shellPage != null)
|
||||
{
|
||||
shellPage.OnClosing();
|
||||
}
|
||||
|
||||
inst = null;
|
||||
MainWindow.CloseHiddenWindow();
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (inst != null)
|
||||
{
|
||||
inst.Close();
|
||||
}
|
||||
|
||||
inst = this;
|
||||
}
|
||||
|
||||
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (sender == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WindowsXamlHost windowsXamlHost = sender as WindowsXamlHost;
|
||||
shellPage = windowsXamlHost.GetUwpInternalObject() as OobeShellPage;
|
||||
|
||||
OobeShellPage.SetRunSharedEventCallback(() =>
|
||||
{
|
||||
return Constants.PowerLauncherSharedEvent();
|
||||
});
|
||||
|
||||
OobeShellPage.SetColorPickerSharedEventCallback(() =>
|
||||
{
|
||||
return Constants.ShowColorPickerSharedEvent();
|
||||
});
|
||||
|
||||
OobeShellPage.SetShortcutGuideSharedEventCallback(() =>
|
||||
{
|
||||
NativeMethods.AllowSetForegroundWindow(PowerToys.Settings.Program.PowerToysPID);
|
||||
return Constants.ShowShortcutGuideSharedEvent();
|
||||
});
|
||||
|
||||
OobeShellPage.SetOpenMainWindowCallback((Type type) =>
|
||||
{
|
||||
((App)Application.Current).OpenSettingsWindow(type);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,12 @@ namespace PowerToys.Settings
|
||||
Theme, // used in the old settings
|
||||
ElevatedStatus,
|
||||
IsUserAdmin,
|
||||
ShowOobeWindow,
|
||||
}
|
||||
|
||||
// Quantity of arguments
|
||||
private const int ArgumentsQty = 6;
|
||||
private const int RequiredArgumentsQty = 6;
|
||||
private const int RequiredAndOptionalArgumentsQty = 7;
|
||||
|
||||
// Create an instance of the IPC wrapper.
|
||||
private static TwoWayPipeMessageIPCManaged ipcmanager;
|
||||
@@ -43,7 +45,7 @@ namespace PowerToys.Settings
|
||||
App app = new App();
|
||||
app.InitializeComponent();
|
||||
|
||||
if (args != null && args.Length >= ArgumentsQty)
|
||||
if (args != null && args.Length >= RequiredArgumentsQty)
|
||||
{
|
||||
_ = int.TryParse(args[(int)Arguments.PTPid], out int powerToysPID);
|
||||
PowerToysPID = powerToysPID;
|
||||
@@ -51,6 +53,12 @@ namespace PowerToys.Settings
|
||||
IsElevated = args[(int)Arguments.ElevatedStatus] == "true";
|
||||
IsUserAnAdmin = args[(int)Arguments.IsUserAdmin] == "true";
|
||||
|
||||
if (args.Length == RequiredAndOptionalArgumentsQty)
|
||||
{
|
||||
// open oobe window
|
||||
app.ShowOobe = args[(int)Arguments.ShowOobeWindow] == "true";
|
||||
}
|
||||
|
||||
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
||||
{
|
||||
Environment.Exit(0);
|
||||
|
||||
Reference in New Issue
Block a user