2021-03-02 20:56:37 +03:00
// Copyright (c) Microsoft Corporation
2020-04-07 14:19:33 -07:00
// 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 ;
2021-10-25 20:23:36 +02:00
using System.ComponentModel ;
using System.Drawing ;
2020-04-07 14:19:33 -07:00
using System.Windows ;
2021-10-25 20:23:36 +02:00
using System.Windows.Interop ;
2020-08-17 10:00:56 -07:00
using Microsoft.PowerLauncher.Telemetry ;
2020-10-26 11:09:18 -07:00
using Microsoft.PowerToys.Settings.UI.Library.Utilities ;
2020-04-07 14:19:33 -07:00
using Microsoft.PowerToys.Settings.UI.Views ;
2020-08-17 10:00:56 -07:00
using Microsoft.PowerToys.Telemetry ;
2020-04-07 10:19:14 -07:00
using Microsoft.Toolkit.Wpf.UI.XamlHost ;
2021-10-25 20:23:36 +02:00
using PowerToys.Settings.Helpers ;
2021-03-05 13:51:34 +03:00
using Windows.ApplicationModel.Resources ;
2020-09-04 11:56:52 +03:00
using Windows.Data.Json ;
2020-04-07 14:19:33 -07:00
2021-02-11 19:29:56 +03:00
namespace PowerToys.Settings
2020-04-07 14:19:33 -07:00
{
// Interaction logic for MainWindow.xaml.
public partial class MainWindow : Window
{
2021-03-02 20:56:37 +03:00
private static Window inst ;
2020-06-22 15:38:55 -07:00
private bool isOpen = true ;
2020-04-07 14:19:33 -07:00
public MainWindow ( )
2020-08-17 10:00:56 -07:00
{
var bootTime = new System . Diagnostics . Stopwatch ( ) ;
bootTime . Start ( ) ;
this . InitializeComponent ( ) ;
2021-03-04 17:58:01 +01:00
2021-11-02 11:16:03 +01:00
Utils . FitToScreen ( this ) ;
2021-03-05 13:51:34 +03:00
ResourceLoader loader = ResourceLoader . GetForViewIndependentUse ( ) ;
Title = loader . GetString ( "SettingsWindow_Title" ) ;
2020-08-17 10:00:56 -07:00
bootTime . Stop ( ) ;
2020-05-15 09:08:39 -07:00
PowerToysTelemetry . Log . WriteEvent ( new SettingsBootEvent ( ) { BootTimeMs = bootTime . ElapsedMilliseconds } ) ;
2020-04-07 14:19:33 -07:00
}
2021-03-02 20:56:37 +03:00
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 ) ;
}
}
2021-10-25 20:23:36 +02:00
protected override void OnSourceInitialized ( EventArgs e )
{
base . OnSourceInitialized ( e ) ;
var handle = new WindowInteropHelper ( this ) . Handle ;
NativeMethods . GetWindowPlacement ( handle , out var startupPlacement ) ;
var placement = Utils . DeserializePlacementOrDefault ( handle ) ;
NativeMethods . SetWindowPlacement ( handle , ref placement ) ;
var windowRect = new Rectangle ( ( int ) Left , ( int ) Top , ( int ) Width , ( int ) Height ) ;
var screenRect = new Rectangle ( ( int ) SystemParameters . VirtualScreenLeft , ( int ) SystemParameters . VirtualScreenTop , ( int ) SystemParameters . VirtualScreenWidth , ( int ) SystemParameters . VirtualScreenHeight ) ;
var intersection = Rectangle . Intersect ( windowRect , screenRect ) ;
2021-11-02 11:16:03 +01:00
// Restore default position if 5% of width or height of the window is offscreen
if ( intersection . Width < ( Width * 0.95 ) | | intersection . Height < ( Height * 0.95 ) )
2021-10-25 20:23:36 +02:00
{
NativeMethods . SetWindowPlacement ( handle , ref startupPlacement ) ;
}
}
protected override void OnClosing ( CancelEventArgs e )
{
base . OnClosing ( e ) ;
var handle = new WindowInteropHelper ( this ) . Handle ;
Utils . SerializePlacement ( handle ) ;
}
2020-04-07 14:19:33 -07:00
private void WindowsXamlHost_ChildChanged ( object sender , EventArgs e )
{
2020-10-20 12:50:04 -07:00
// 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)
if ( sender = = null )
{
return ;
}
2020-04-07 14:19:33 -07:00
// Hook up x:Bind source.
WindowsXamlHost windowsXamlHost = sender as WindowsXamlHost ;
ShellPage shellPage = windowsXamlHost . GetUwpInternalObject ( ) as ShellPage ;
2020-03-24 19:55:02 -07:00
if ( shellPage ! = null )
{
2020-03-30 02:02:25 -07:00
// send IPC Message
2020-10-29 14:24:16 -07:00
ShellPage . SetDefaultSndMessageCallback ( msg = >
2020-03-24 19:55:02 -07:00
{
2020-05-15 09:08:39 -07:00
// IPC Manager is null when launching runner directly
2020-05-05 11:44:54 -07:00
Program . GetTwoWayIPCManager ( ) ? . Send ( msg ) ;
2020-03-24 19:55:02 -07:00
} ) ;
2020-05-05 10:02:31 -07:00
// send IPC Message
2020-10-29 14:24:16 -07:00
ShellPage . SetRestartAdminSndMessageCallback ( msg = >
2020-05-05 10:02:31 -07:00
{
2021-04-07 02:54:15 -07:00
Program . GetTwoWayIPCManager ( ) ? . Send ( msg ) ;
2021-03-03 14:03:37 +03:00
isOpen = false ;
2020-05-05 10:02:31 -07:00
System . Windows . Application . Current . Shutdown ( ) ; // close application
} ) ;
2020-06-23 15:53:02 +03:00
// send IPC Message
2020-10-29 14:24:16 -07:00
ShellPage . SetCheckForUpdatesMessageCallback ( msg = >
2020-06-23 15:53:02 +03:00
{
2021-04-07 02:54:15 -07:00
Program . GetTwoWayIPCManager ( ) ? . Send ( msg ) ;
2020-06-23 15:53:02 +03:00
} ) ;
2021-03-02 20:56:37 +03:00
// open oobe
ShellPage . SetOpenOobeCallback ( ( ) = >
{
var oobe = new OobeWindow ( ) ;
oobe . Show ( ) ;
} ) ;
2020-09-04 11:56:52 +03:00
// receive IPC Message
Program . IPCMessageReceivedCallback = ( string msg ) = >
{
if ( ShellPage . ShellHandler . IPCResponseHandleList ! = null )
{
2020-10-26 11:09:18 -07:00
var success = JsonObject . TryParse ( msg , out JsonObject json ) ;
if ( success )
2020-09-04 11:56:52 +03:00
{
foreach ( Action < JsonObject > handle in ShellPage . ShellHandler . IPCResponseHandleList )
{
handle ( json ) ;
}
}
2020-10-26 11:09:18 -07:00
else
2020-09-04 11:56:52 +03:00
{
2020-10-26 11:09:18 -07:00
Logger . LogError ( "Failed to parse JSON from IPC message." ) ;
2020-09-04 11:56:52 +03:00
}
}
} ;
2020-10-29 14:24:16 -07:00
ShellPage . SetElevationStatus ( Program . IsElevated ) ;
ShellPage . SetIsUserAnAdmin ( Program . IsUserAnAdmin ) ;
2020-05-05 10:02:31 -07:00
shellPage . Refresh ( ) ;
2020-04-07 14:19:33 -07:00
}
2020-06-22 15:38:55 -07:00
2020-10-30 14:41:09 -04:00
// XAML Islands: If the window is open, explicitly force it to be shown to solve the blank dialog issue https://github.com/microsoft/PowerToys/issues/3384
2020-08-17 10:00:56 -07:00
if ( isOpen )
2020-06-22 15:38:55 -07:00
{
2021-03-03 14:03:37 +03:00
try
{
Show ( ) ;
}
catch ( InvalidOperationException )
{
}
2020-06-22 15:38:55 -07:00
}
2020-08-17 10:00:56 -07:00
}
private void MainWindow_Closing ( object sender , System . ComponentModel . CancelEventArgs e )
{
2021-03-02 20:56:37 +03:00
if ( OobeWindow . IsOpened )
{
e . Cancel = true ;
( ( Window ) sender ) . Hide ( ) ;
}
else
{
isOpen = false ;
}
2020-09-16 09:47:43 -07:00
// 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 )
{
// Run Environment.Exit on a separate task to avoid performance impact
System . Threading . Tasks . Task . Run ( ( ) = > { Environment . Exit ( 0 ) ; } ) ;
}
2020-08-17 10:00:56 -07:00
}
2021-03-02 20:56:37 +03:00
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 ;
}
}
2020-04-07 14:19:33 -07:00
}
2020-04-10 15:22:07 -07:00
}