diff --git a/src/modules/espresso/Espresso/Core/APIHelper.cs b/src/modules/espresso/Espresso/Core/APIHelper.cs index e0f23315c4..ac7b67e064 100644 --- a/src/modules/espresso/Espresso/Core/APIHelper.cs +++ b/src/modules/espresso/Espresso/Core/APIHelper.cs @@ -2,13 +2,13 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Win32; -using NLog; using System; using System.Drawing; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.Win32; +using NLog; namespace Espresso.Shell.Core { @@ -18,7 +18,7 @@ namespace Espresso.Shell.Core ES_AWAYMODE_REQUIRED = 0x00000040, ES_CONTINUOUS = 0x80000000, ES_DISPLAY_REQUIRED = 0x00000002, - ES_SYSTEM_REQUIRED = 0x00000001 + ES_SYSTEM_REQUIRED = 0x00000001, } /// @@ -27,16 +27,15 @@ namespace Espresso.Shell.Core /// public class APIHelper { - private const string BUILD_REGISTRY_LOCATION = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; + private const string BuildRegistryLocation = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; - private static CancellationTokenSource TokenSource; - private static CancellationToken ThreadToken; - - private static readonly Logger log; + private static readonly Logger _log; + private static CancellationTokenSource _tokenSource; + private static CancellationToken _threadToken; // More details about the API used: https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); + private static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); // More details about the API used: https://docs.microsoft.com/windows/win32/api/shellapi/nf-shellapi-extracticonexw [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] @@ -44,8 +43,8 @@ namespace Espresso.Shell.Core static APIHelper() { - log = LogManager.GetCurrentClassLogger(); - TokenSource = new CancellationTokenSource(); + _log = LogManager.GetCurrentClassLogger(); + _tokenSource = new CancellationTokenSource(); } /// @@ -60,23 +59,14 @@ namespace Espresso.Shell.Core try { var stateResult = SetThreadExecutionState(state); - bool stateSettingSucceeded = (stateResult != 0); - - if (stateSettingSucceeded) - { - return true; - } - else - { - return false; - } + return stateResult != 0; } catch { return false; } } - + /// /// Attempts to reset the current machine state to one where Espresso doesn't try to keep it awake. /// This does not interfere with the state that can be potentially set by other applications. @@ -84,7 +74,7 @@ namespace Espresso.Shell.Core /// Status of the attempt. True is successful, false if not. public static bool SetNormalKeepAwake() { - TokenSource.Cancel(); + _tokenSource.Cancel(); return SetAwakeState(EXECUTION_STATE.ES_CONTINUOUS); } @@ -95,33 +85,9 @@ namespace Espresso.Shell.Core /// Status of the attempt. True if successful, false if not. public static bool SetIndefiniteKeepAwake(bool keepDisplayOn = true) { - TokenSource = new CancellationTokenSource(); - ThreadToken = TokenSource.Token; - - //Put thread for indefinite loop. - } - - public static void SetTimedKeepAwake(long seconds, Action callback, Action failureCallback, bool keepDisplayOn = true) - { - TokenSource = new CancellationTokenSource(); - ThreadToken = TokenSource.Token; - - Task.Run(() => RunTimedLoop(seconds, keepDisplayOn), ThreadToken) - .ContinueWith((result) => callback(result.Result), TaskContinuationOptions.OnlyOnRanToCompletion) - .ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion); ; - - } - - private static void RunIndefiniteLoop(bool keepDisplayOn = true) - { - bool success = false; - - // In case cancellation was already requested. - ThreadToken.ThrowIfCancellationRequested(); - if (keepDisplayOn) { - SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS); + return SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS); } else { @@ -129,13 +95,22 @@ namespace Espresso.Shell.Core } } + public static void SetTimedKeepAwake(long seconds, Action callback, Action failureCallback, bool keepDisplayOn = true) + { + _tokenSource = new CancellationTokenSource(); + _threadToken = _tokenSource.Token; + + Task.Run(() => RunTimedLoop(seconds, keepDisplayOn), _threadToken) + .ContinueWith((result) => callback(result.Result), TaskContinuationOptions.OnlyOnRanToCompletion) + .ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion); + } + private static bool RunTimedLoop(long seconds, bool keepDisplayOn = true) { bool success = false; // In case cancellation was already requested. - ThreadToken.ThrowIfCancellationRequested(); - + _threadToken.ThrowIfCancellationRequested(); try { if (keepDisplayOn) @@ -143,20 +118,21 @@ namespace Espresso.Shell.Core success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS); if (success) { - log.Info("Timed keep-awake with display on."); + _log.Info("Timed keep-awake with display on."); var startTime = DateTime.UtcNow; while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(seconds)) { - if (ThreadToken.IsCancellationRequested) + if (_threadToken.IsCancellationRequested) { - ThreadToken.ThrowIfCancellationRequested(); + _threadToken.ThrowIfCancellationRequested(); } } + return success; } else { - log.Info("Could not set up timed keep-awake with display on."); + _log.Info("Could not set up timed keep-awake with display on."); return success; } } @@ -165,20 +141,21 @@ namespace Espresso.Shell.Core success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS); if (success) { - log.Info("Timed keep-awake with display off."); + _log.Info("Timed keep-awake with display off."); var startTime = DateTime.UtcNow; while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(seconds)) { - if (ThreadToken.IsCancellationRequested) + if (_threadToken.IsCancellationRequested) { - ThreadToken.ThrowIfCancellationRequested(); + _threadToken.ThrowIfCancellationRequested(); } } + return success; } else { - log.Info("Could not set up timed keep-awake with display off."); + _log.Info("Could not set up timed keep-awake with display off."); return success; } } @@ -186,7 +163,7 @@ namespace Espresso.Shell.Core catch (OperationCanceledException ex) { // Task was clearly cancelled. - log.Info($"Background thread termination. Message: {ex.Message}"); + _log.Info($"Background thread termination. Message: {ex.Message}"); return success; } } @@ -196,7 +173,7 @@ namespace Espresso.Shell.Core try { #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BUILD_REGISTRY_LOCATION); + RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BuildRegistryLocation); #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. if (registryKey != null) @@ -206,18 +183,17 @@ namespace Espresso.Shell.Core } else { - log.Debug("Registry key acquisition for OS failed."); + _log.Debug("Registry key acquisition for OS failed."); return string.Empty; } } catch (Exception ex) { - log.Debug($"Could not get registry key for the build number. Error: {ex.Message}"); + _log.Debug($"Could not get registry key for the build number. Error: {ex.Message}"); return string.Empty; } } - public static Icon? Extract(string file, int number, bool largeIcon) { ExtractIconEx(file, number, out IntPtr large, out IntPtr small, 1); @@ -229,8 +205,6 @@ namespace Espresso.Shell.Core { return null; } - } - } } diff --git a/src/modules/espresso/Espresso/Core/TrayHelper.cs b/src/modules/espresso/Espresso/Core/TrayHelper.cs index 0afb5ac8e2..fe41509b68 100644 --- a/src/modules/espresso/Espresso/Core/TrayHelper.cs +++ b/src/modules/espresso/Espresso/Core/TrayHelper.cs @@ -2,11 +2,11 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.PowerToys.Settings.UI.Library; using System; using System.Drawing; using System.Text.Json; using System.Windows.Forms; +using Microsoft.PowerToys.Settings.UI.Library; #pragma warning disable CS8602 // Dereference of a possibly null reference. #pragma warning disable CS8603 // Possible null reference return. @@ -15,10 +15,12 @@ namespace Espresso.Shell.Core { internal static class TrayHelper { - static NotifyIcon? trayIcon; + private static NotifyIcon? trayIcon; + private static NotifyIcon TrayIcon { get => trayIcon; set => trayIcon = value; } - static SettingsUtils? moduleSettings; + private static SettingsUtils? moduleSettings; + private static SettingsUtils ModuleSettings { get => moduleSettings; set => moduleSettings = value; } static TrayHelper() @@ -29,7 +31,8 @@ namespace Espresso.Shell.Core public static void InitializeTray(string text, Icon icon, ContextMenuStrip? contextMenu = null) { - System.Threading.Tasks.Task.Factory.StartNew((tray) => + System.Threading.Tasks.Task.Factory.StartNew( + (tray) => { ((NotifyIcon?)tray).Text = text; ((NotifyIcon?)tray).Icon = icon; @@ -42,31 +45,51 @@ namespace Espresso.Shell.Core internal static void SetTray(string text, EspressoSettings settings) { - SetTray(text, settings.Properties.KeepDisplayOn.Value, settings.Properties.Mode, - () => { - // Set indefinite keep awake. - var currentSettings = ModuleSettings.GetSettings(text); - currentSettings.Properties.Mode = EspressoMode.INDEFINITE; + SetTray( + text, + settings.Properties.KeepDisplayOn.Value, + settings.Properties.Mode, + IndefiniteKeepAwakeCallback(text), + TimedKeepAwakeCallback(text), + KeepDisplayOnCallback(text)); + } - ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text); - }, - (hours, minutes) => { - // Set timed keep awake. - var currentSettings = ModuleSettings.GetSettings(text); - currentSettings.Properties.Mode = EspressoMode.TIMED; - currentSettings.Properties.Hours.Value = hours; - currentSettings.Properties.Minutes.Value = minutes; + private static Action KeepDisplayOnCallback(string text) + { + return () => + { + // Just changing the display mode. + var currentSettings = ModuleSettings.GetSettings(text); + currentSettings.Properties.KeepDisplayOn.Value = !currentSettings.Properties.KeepDisplayOn.Value; - ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text); - }, - () => - { - // Just changing the display mode. - var currentSettings = ModuleSettings.GetSettings(text); - currentSettings.Properties.KeepDisplayOn.Value = !currentSettings.Properties.KeepDisplayOn.Value; + ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text); + }; + } - ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text); - }); + private static Action TimedKeepAwakeCallback(string text) + { + return (hours, minutes) => + { + // Set timed keep awake. + var currentSettings = ModuleSettings.GetSettings(text); + currentSettings.Properties.Mode = EspressoMode.TIMED; + currentSettings.Properties.Hours.Value = hours; + currentSettings.Properties.Minutes.Value = minutes; + + ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text); + }; + } + + private static Action IndefiniteKeepAwakeCallback(string text) + { + return () => + { + // Set indefinite keep awake. + var currentSettings = ModuleSettings.GetSettings(text); + currentSettings.Properties.Mode = EspressoMode.INDEFINITE; + + ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text); + }; } internal static void SetTray(string text, bool keepDisplayOn, EspressoMode mode, Action indefiniteKeepAwakeCallback, Action timedKeepAwakeCallback, Action keepDisplayOnCallback) @@ -76,13 +99,13 @@ namespace Espresso.Shell.Core // Main toolstrip. var operationContextMenu = new ToolStripMenuItem { - Text = "Mode" + Text = "Mode", }; // Indefinite keep-awake menu item. var indefiniteMenuItem = new ToolStripMenuItem { - Text = "Indefinite" + Text = "Indefinite", }; if (mode == EspressoMode.INDEFINITE) @@ -93,6 +116,7 @@ namespace Espresso.Shell.Core { indefiniteMenuItem.Checked = false; } + indefiniteMenuItem.Click += (e, s) => { // User opted to set the mode to indefinite, so we need to write new settings. @@ -101,7 +125,7 @@ namespace Espresso.Shell.Core var displayOnMenuItem = new ToolStripMenuItem { - Text = "Keep display on" + Text = "Keep display on", }; if (keepDisplayOn) { @@ -111,6 +135,7 @@ namespace Espresso.Shell.Core { displayOnMenuItem.Checked = false; } + displayOnMenuItem.Click += (e, s) => { // User opted to set the display mode directly. @@ -120,12 +145,12 @@ namespace Espresso.Shell.Core // Timed keep-awake menu item var timedMenuItem = new ToolStripMenuItem { - Text = "Timed" + Text = "Timed", }; var halfHourMenuItem = new ToolStripMenuItem { - Text = "30 minutes" + Text = "30 minutes", }; halfHourMenuItem.Click += (e, s) => { @@ -135,7 +160,7 @@ namespace Espresso.Shell.Core var oneHourMenuItem = new ToolStripMenuItem { - Text = "1 hour" + Text = "1 hour", }; oneHourMenuItem.Click += (e, s) => { @@ -145,7 +170,7 @@ namespace Espresso.Shell.Core var twoHoursMenuItem = new ToolStripMenuItem { - Text = "2 hours" + Text = "2 hours", }; twoHoursMenuItem.Click += (e, s) => { diff --git a/src/modules/espresso/Espresso/Espresso.csproj b/src/modules/espresso/Espresso/Espresso.csproj index 3669444ea8..2564272338 100644 --- a/src/modules/espresso/Espresso/Espresso.csproj +++ b/src/modules/espresso/Espresso/Espresso.csproj @@ -1,5 +1,5 @@  - + Exe netcoreapp3.1 @@ -12,12 +12,7 @@ true PowerToys.Espresso - Espresso.ico - Den Delimarsky - Den Delimarsky - Espresso - https://espresso.den.dev - Espresso.png + $(Version).0 @@ -66,5 +61,19 @@ PreserveNewest - + + + GlobalSuppressions.cs + + + StyleCop.json + + + + + 1.1.118 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + diff --git a/src/modules/espresso/Espresso/Program.cs b/src/modules/espresso/Espresso/Program.cs index 9db711c9be..025d163d88 100644 --- a/src/modules/espresso/Espresso/Program.cs +++ b/src/modules/espresso/Espresso/Program.cs @@ -2,10 +2,6 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Espresso.Shell.Core; -using ManagedCommon; -using Microsoft.PowerToys.Settings.UI.Library; -using NLog; using System; using System.CommandLine; using System.CommandLine.Invocation; @@ -16,40 +12,44 @@ using System.Reactive.Concurrency; using System.Reactive.Linq; using System.Reflection; using System.Threading; +using Espresso.Shell.Core; +using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Library; +using NLog; #pragma warning disable CS8602 // Dereference of a possibly null reference. #pragma warning disable CS8603 // Possible null reference return. namespace Espresso.Shell { - class Program + internal class Program { - private static Mutex? mutex = null; - private const string appName = "Espresso"; - private static FileSystemWatcher? watcher = null; - private static SettingsUtils? settingsUtils = null; + private static Mutex? _mutex = null; + private const string AppName = "Espresso"; + private static FileSystemWatcher? _watcher = null; + private static SettingsUtils? _settingsUtils = null; - public static Mutex Mutex { get => mutex; set => mutex = value; } + public static Mutex LockMutex { get => _mutex; set => _mutex = value; } - private static Logger? log; + private static Logger? _log; - static int Main(string[] args) + private static int Main(string[] args) { bool instantiated; - Mutex = new Mutex(true, appName, out instantiated); + LockMutex = new Mutex(true, AppName, out instantiated); if (!instantiated) { - ForceExit(appName + " is already running! Exiting the application.", 1); + ForceExit(AppName + " is already running! Exiting the application.", 1); } - log = LogManager.GetCurrentClassLogger(); - settingsUtils = new SettingsUtils(); + _log = LogManager.GetCurrentClassLogger(); + _settingsUtils = new SettingsUtils(); - log.Info("Launching Espresso..."); - log.Info(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion); - log.Debug($"OS: {Environment.OSVersion}"); - log.Debug($"OS Build: {APIHelper.GetOperatingSystemBuild()}"); + _log.Info("Launching Espresso..."); + _log.Info(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion); + _log.Debug($"OS: {Environment.OSVersion}"); + _log.Debug($"OS Build: {APIHelper.GetOperatingSystemBuild()}"); var configOption = new Option( aliases: new[] { "--use-pt-config", "-c" }, @@ -108,10 +108,10 @@ namespace Espresso.Shell configOption, displayOption, timeOption, - pidOption + pidOption, }; - rootCommand.Description = appName; + rootCommand.Description = AppName; rootCommand.Handler = CommandHandler.Create(HandleCommandLineArguments); @@ -120,21 +120,21 @@ namespace Espresso.Shell private static void ForceExit(string message, int exitCode) { - log.Debug(message); - log.Info(message); + _log.Debug(message); + _log.Info(message); Console.ReadKey(); Environment.Exit(exitCode); } private static void HandleCommandLineArguments(bool usePtConfig, bool displayOn, long timeLimit, int pid) { - log.Info($"The value for --use-pt-config is: {usePtConfig}"); - log.Info($"The value for --display-on is: {displayOn}"); - log.Info($"The value for --time-limit is: {timeLimit}"); - log.Info($"The value for --pid is: {pid}"); + _log.Info($"The value for --use-pt-config is: {usePtConfig}"); + _log.Info($"The value for --display-on is: {displayOn}"); + _log.Info($"The value for --time-limit is: {timeLimit}"); + _log.Info($"The value for --pid is: {pid}"); #pragma warning disable CS8604 // Possible null reference argument. - TrayHelper.InitializeTray(appName, APIHelper.Extract("shell32.dll", 32, true)); + TrayHelper.InitializeTray(AppName, APIHelper.Extract("shell32.dll", 32, true)); #pragma warning restore CS8604 // Possible null reference argument. if (usePtConfig) @@ -143,21 +143,20 @@ namespace Espresso.Shell // and instead watch for changes in the file. try { - var settingsPath = settingsUtils.GetSettingsFilePath(appName); - log.Info($"Reading configuration file: {settingsPath}"); + var settingsPath = _settingsUtils.GetSettingsFilePath(AppName); + _log.Info($"Reading configuration file: {settingsPath}"); - watcher = new FileSystemWatcher + _watcher = new FileSystemWatcher { Path = Path.GetDirectoryName(settingsPath), EnableRaisingEvents = true, NotifyFilter = NotifyFilters.LastWrite, - Filter = Path.GetFileName(settingsPath) + Filter = Path.GetFileName(settingsPath), }; Observable.FromEventPattern( - h => watcher.Changed += h, - h => watcher.Changed -= h - ) + h => _watcher.Changed += h, + h => _watcher.Changed -= h) .SubscribeOn(TaskPoolScheduler.Default) .Select(e => e.EventArgs) .Throttle(TimeSpan.FromMilliseconds(25)) @@ -170,8 +169,8 @@ namespace Espresso.Shell catch (Exception ex) { var errorString = $"There was a problem with the configuration file. Make sure it exists.\n{ex.Message}"; - log.Info(errorString); - log.Debug(errorString); + _log.Info(errorString); + _log.Debug(errorString); } } else @@ -204,20 +203,20 @@ namespace Espresso.Shell bool success = APIHelper.SetIndefiniteKeepAwake(displayOn); if (success) { - log.Info($"Currently in indefinite keep awake. Display always on: {displayOn}"); + _log.Info($"Currently in indefinite keep awake. Display always on: {displayOn}"); } else { var errorMessage = "Could not set up the state to be indefinite keep awake."; - log.Info(errorMessage); - log.Debug(errorMessage); + _log.Info(errorMessage); + _log.Debug(errorMessage); } } private static void HandleEspressoConfigChange(FileSystemEventArgs fileEvent) { - log.Info("Detected a settings file change. Updating configuration..."); - log.Info("Resetting keep-awake to normal state due to settings change."); + _log.Info("Detected a settings file change. Updating configuration..."); + _log.Info("Resetting keep-awake to normal state due to settings change."); ResetNormalPowerState(); ProcessSettings(); } @@ -226,7 +225,7 @@ namespace Espresso.Shell { try { - EspressoSettings settings = settingsUtils.GetSettings(appName); + EspressoSettings settings = _settingsUtils.GetSettings(AppName); if (settings != null) { @@ -238,6 +237,7 @@ namespace Espresso.Shell SetupIndefiniteKeepAwake(settings.Properties.KeepDisplayOn.Value); break; } + case EspressoMode.TIMED: { // Timed keep-awake. @@ -246,35 +246,36 @@ namespace Espresso.Shell break; } + default: { var errorMessage = "Unknown mode of operation. Check config file."; - log.Info(errorMessage); - log.Debug(errorMessage); + _log.Info(errorMessage); + _log.Debug(errorMessage); break; } } - TrayHelper.SetTray(appName, settings); + TrayHelper.SetTray(AppName, settings); } else { var errorMessage = "Settings are null."; - log.Info(errorMessage); - log.Debug(errorMessage); + _log.Info(errorMessage); + _log.Debug(errorMessage); } } catch (Exception ex) { var errorMessage = $"There was a problem reading the configuration file. Error: {ex.Message}"; - log.Info(errorMessage); - log.Debug(errorMessage); + _log.Info(errorMessage); + _log.Debug(errorMessage); } } private static void SetupTimedKeepAwake(long time, bool displayOn) { - log.Info($"Timed keep-awake. Expected runtime: {time} seconds with display on setting set to {displayOn}."); + _log.Info($"Timed keep-awake. Expected runtime: {time} seconds with display on setting set to {displayOn}."); APIHelper.SetTimedKeepAwake(time, LogTimedKeepAwakeCompletion, LogUnexpectedOrCancelledKeepAwakeCompletion, displayOn); } @@ -282,13 +283,13 @@ namespace Espresso.Shell private static void LogUnexpectedOrCancelledKeepAwakeCompletion() { var errorMessage = "The keep-awake thread was terminated early."; - log.Info(errorMessage); - log.Debug(errorMessage); + _log.Info(errorMessage); + _log.Debug(errorMessage); } private static void LogTimedKeepAwakeCompletion(bool result) { - log.Info($"Completed timed keep-awake successfully: {result}"); + _log.Info($"Completed timed keep-awake successfully: {result}"); } private static void ResetNormalPowerState() @@ -296,13 +297,13 @@ namespace Espresso.Shell bool success = APIHelper.SetNormalKeepAwake(); if (success) { - log.Info("Returned to normal keep-awake state."); + _log.Info("Returned to normal keep-awake state."); } else { var errorMessage = "Could not return to normal keep-awake state."; - log.Info(errorMessage); - log.Debug(errorMessage); + _log.Info(errorMessage); + _log.Debug(errorMessage); } } } diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj index 20f1a6e98c..d2745a3fbe 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj @@ -123,6 +123,9 @@ + + OobeEspresso.xaml + OobeColorPicker.xaml @@ -300,6 +303,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Enums/PowerToysModulesEnum.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Enums/PowerToysModulesEnum.cs index 83ca42c99f..3a5c7aa1b5 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Enums/PowerToysModulesEnum.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Enums/PowerToysModulesEnum.cs @@ -8,6 +8,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Enums { Overview = 0, ColorPicker, + Espresso, FancyZones, FileExplorer, ImageResizer, diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeEspresso.xaml b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeEspresso.xaml new file mode 100644 index 0000000000..c6581b629b --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeEspresso.xaml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeEspresso.xaml.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeEspresso.xaml.cs new file mode 100644 index 0000000000..6bfe060378 --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeEspresso.xaml.cs @@ -0,0 +1,48 @@ +// 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.Threading; +using Microsoft.PowerToys.Settings.UI.OOBE.Enums; +using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel; +using Microsoft.PowerToys.Settings.UI.Views; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Navigation; + +namespace Microsoft.PowerToys.Settings.UI.OOBE.Views +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class OobeEspresso : Page + { + public OobePowerToysModule ViewModel { get; set; } + + public OobeEspresso() + { + this.InitializeComponent(); + ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModulesEnum.Espresso]); + DataContext = ViewModel; + } + + private void SettingsLaunchButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + if (OobeShellPage.OpenMainWindowCallback != null) + { + OobeShellPage.OpenMainWindowCallback(typeof(EspressoPage)); + } + + ViewModel.LogOpeningSettingsEvent(); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + ViewModel.LogOpeningModuleEvent(); + } + + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + ViewModel.LogClosingModuleEvent(); + } + } +} diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeShellPage.xaml.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeShellPage.xaml.cs index f9eb0df929..afe9f34c48 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeShellPage.xaml.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/OOBE/Views/OobeShellPage.xaml.cs @@ -88,6 +88,18 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views Description = loader.GetString("Oobe_ColorPicker_Description"), Link = "https://aka.ms/PowerToysOverview_ColorPicker", }); + Modules.Insert((int)PowerToysModulesEnum.Espresso, new OobePowerToysModule() + { + ModuleName = loader.GetString("Oobe_Espresso"), + Tag = "Espresso", + IsNew = false, + Icon = "\uEC32", + Image = "ms-appx:///Assets/Modules/Espresso.png", + FluentIcon = "ms-appx:///Assets/FluentIcons/FluentIconsEspresso.png", + PreviewImageSource = "ms-appx:///Assets/Modules/OOBE/FancyZones.gif", + Description = loader.GetString("Oobe_Espresso_Description"), + Link = "https://aka.ms/PowerToysOverview_Espresso", + }); Modules.Insert((int)PowerToysModulesEnum.FancyZones, new OobePowerToysModule() { ModuleName = loader.GetString("Oobe_FancyZones"), @@ -211,6 +223,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views { case "Overview": NavigationFrame.Navigate(typeof(OobeOverview)); break; case "ColorPicker": NavigationFrame.Navigate(typeof(OobeColorPicker)); break; + case "Espresso": NavigationFrame.Navigate(typeof(OobeEspresso)); break; case "FancyZones": NavigationFrame.Navigate(typeof(OobeFancyZones)); break; case "Run": NavigationFrame.Navigate(typeof(OobeRun)); break; case "ImageResizer": NavigationFrame.Navigate(typeof(OobeImageResizer)); break; diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw index 25d1e7f0f6..828ea9ac82 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw @@ -909,6 +909,10 @@ https://aka.ms/PowerToysOverview_ColorPicker URL. Do not loc + + https://aka.ms/PowerToysOverview_Espresso + URL. Do not loc + https://aka.ms/PowerToysOverview_FancyZones URL. Do not loc @@ -1208,4 +1212,17 @@ From there, simply click on a Markdown file or SVG icon in the File Explorer and https://espresso.den.dev URL. Do not loc + + Espresso + Module name, do not loc + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + + Open PowerToys Settings and {turn on Espresso} + + + You can always change modes quickly by clicking the {Espresso icon in the system tray} + \ No newline at end of file