diff --git a/.gitignore b/.gitignore
index 1318abc22c..b8a09a865e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,6 +56,7 @@ project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
+!src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
@@ -358,4 +359,4 @@ src/common/Telemetry/*.etl
/src/settings-ui/Settings.UI/Assets/Settings/search.index.json
# PowerToysInstaller Build Temp Files
-installer/*/*.wxs.bk
\ No newline at end of file
+installer/*/*.wxs.bk
diff --git a/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj b/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj
index a4c7c6c997..52588938e4 100644
--- a/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj
+++ b/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj
@@ -15,5 +15,6 @@
+
diff --git a/src/modules/awake/Awake.ModuleServices/AwakeService.cs b/src/modules/awake/Awake.ModuleServices/AwakeService.cs
index c71066f285..c1b5bcbd55 100644
--- a/src/modules/awake/Awake.ModuleServices/AwakeService.cs
+++ b/src/modules/awake/Awake.ModuleServices/AwakeService.cs
@@ -2,9 +2,9 @@
// 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.Diagnostics;
+using System.Text.Json;
using Common.UI;
-using ManagedCommon;
+using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.ModuleContracts;
namespace Awake.ModuleServices;
@@ -28,7 +28,13 @@ public sealed class AwakeService : ModuleServiceBase, IAwakeService
public Task SetIndefiniteAsync(CancellationToken cancellationToken = default)
{
- return InvokeCliAsync("-m indefinite");
+ return UpdateSettingsAsync(
+ settings =>
+ {
+ settings.Properties.Mode = AwakeMode.INDEFINITE;
+ settings.Properties.KeepDisplayOn = true;
+ },
+ cancellationToken);
}
public Task SetTimedAsync(int minutes, CancellationToken cancellationToken = default)
@@ -38,42 +44,49 @@ public sealed class AwakeService : ModuleServiceBase, IAwakeService
return Task.FromResult(OperationResult.Fail("Minutes must be greater than zero."));
}
- return InvokeCliAsync($"-m timed -t {minutes}");
+ return UpdateSettingsAsync(
+ settings =>
+ {
+ var totalMinutes = Math.Min(minutes, int.MaxValue);
+ settings.Properties.Mode = AwakeMode.TIMED;
+ settings.Properties.KeepDisplayOn = true;
+ settings.Properties.IntervalHours = (uint)(totalMinutes / 60);
+ settings.Properties.IntervalMinutes = (uint)(totalMinutes % 60);
+ },
+ cancellationToken);
}
public Task SetOffAsync(CancellationToken cancellationToken = default)
{
- return InvokeCliAsync("-m passive");
+ return UpdateSettingsAsync(
+ settings =>
+ {
+ settings.Properties.Mode = AwakeMode.PASSIVE;
+ },
+ cancellationToken);
}
- private static Task InvokeCliAsync(string arguments)
+ private static Task UpdateSettingsAsync(Action mutateSettings, CancellationToken cancellationToken)
{
try
{
- var basePath = PowerToysPathResolver.GetPowerToysInstallPath();
- if (string.IsNullOrWhiteSpace(basePath))
- {
- return Task.FromResult(OperationResult.Fail("PowerToys install path not found."));
- }
+ cancellationToken.ThrowIfCancellationRequested();
- var exePath = Path.Combine(basePath, "PowerToys.Awake.exe");
- if (!File.Exists(exePath))
- {
- return Task.FromResult(OperationResult.Fail("Unable to locate PowerToys.Awake.exe."));
- }
+ var settingsUtils = new SettingsUtils();
+ var settings = settingsUtils.GetSettingsOrDefault(AwakeSettings.ModuleName);
- var startInfo = new ProcessStartInfo(exePath, arguments)
- {
- UseShellExecute = false,
- CreateNoWindow = true,
- };
+ mutateSettings(settings);
- Process.Start(startInfo);
+ settingsUtils.SaveSettings(JsonSerializer.Serialize(settings, AwakeServiceJsonContext.Default.AwakeSettings), AwakeSettings.ModuleName);
return Task.FromResult(OperationResult.Ok());
}
+ catch (OperationCanceledException)
+ {
+ return Task.FromResult(OperationResult.Fail("Awake update was cancelled."));
+ }
catch (Exception ex)
{
- return Task.FromResult(OperationResult.Fail($"Failed to invoke Awake: {ex.Message}"));
+ return Task.FromResult(OperationResult.Fail($"Failed to update Awake settings: {ex.Message}"));
}
}
}
diff --git a/src/modules/awake/Awake.ModuleServices/AwakeServiceJsonContext.cs b/src/modules/awake/Awake.ModuleServices/AwakeServiceJsonContext.cs
new file mode 100644
index 0000000000..cfaeff5bed
--- /dev/null
+++ b/src/modules/awake/Awake.ModuleServices/AwakeServiceJsonContext.cs
@@ -0,0 +1,13 @@
+// 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.Text.Json.Serialization;
+using Microsoft.PowerToys.Settings.UI.Library;
+
+namespace Awake.ModuleServices;
+
+[JsonSerializable(typeof(AwakeSettings))]
+internal sealed partial class AwakeServiceJsonContext : JsonSerializerContext
+{
+}
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Modules/AwakeModuleCommandProvider.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Modules/AwakeModuleCommandProvider.cs
index 52026d0bdb..ba4e72fb4d 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Modules/AwakeModuleCommandProvider.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Modules/AwakeModuleCommandProvider.cs
@@ -8,6 +8,7 @@ using Common.UI;
using Microsoft.CommandPalette.Extensions.Toolkit;
using PowerToysExtension.Commands;
using PowerToysExtension.Helpers;
+using PowerToysExtension.Pages;
namespace PowerToysExtension.Modules;
@@ -15,25 +16,65 @@ internal sealed class AwakeModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable BuildCommands()
{
- var title = SettingsDeepLink.SettingsWindow.Awake.ModuleDisplayName();
- var icon = SettingsDeepLink.SettingsWindow.Awake.ModuleIcon();
+ var items = new List();
+ var icon = IconHelpers.FromRelativePath("Assets\\Awake.png");
- var more = new List
+ // Settings entry with quick actions in MoreCommands.
+ var settingsTitle = SettingsDeepLink.SettingsWindow.Awake.ModuleDisplayName();
+ items.Add(new ListItem(new OpenInSettingsCommand(SettingsDeepLink.SettingsWindow.Awake, settingsTitle))
{
- new CommandContextItem(new StartAwakeCommand("Awake: Keep awake indefinitely", () => AwakeService.Instance.SetIndefiniteAsync(), "Awake set to indefinite")),
- new CommandContextItem(new StartAwakeCommand("Awake: Keep awake for 30 minutes", () => AwakeService.Instance.SetTimedAsync(30), "Awake set for 30 minutes")),
- new CommandContextItem(new StartAwakeCommand("Awake: Keep awake for 2 hours", () => AwakeService.Instance.SetTimedAsync(120), "Awake set for 2 hours")),
- new CommandContextItem(new StopAwakeCommand()),
- };
-
- var item = new ListItem(new OpenInSettingsCommand(SettingsDeepLink.SettingsWindow.Awake, title))
- {
- Title = title,
+ Title = settingsTitle,
Subtitle = "Open Awake settings",
- Icon = icon,
- MoreCommands = more.ToArray(),
- };
+ Icon = SettingsDeepLink.SettingsWindow.Awake.ModuleIcon(),
+ MoreCommands =
+ [
+ new CommandContextItem(new StartAwakeCommand("Awake: Keep awake indefinitely", () => AwakeService.Instance.SetIndefiniteAsync(), "Awake set to indefinite")),
+ new CommandContextItem(new StartAwakeCommand("Awake: Keep awake for 30 minutes", () => AwakeService.Instance.SetTimedAsync(30), "Awake set for 30 minutes")),
+ new CommandContextItem(new StartAwakeCommand("Awake: Keep awake for 1 hour", () => AwakeService.Instance.SetTimedAsync(60), "Awake set for 1 hour")),
+ new CommandContextItem(new StartAwakeCommand("Awake: Keep awake for 2 hours", () => AwakeService.Instance.SetTimedAsync(120), "Awake set for 2 hours")),
+ new CommandContextItem(new StopAwakeCommand()),
+ new CommandContextItem(new AwakeProcessListPage()),
+ ],
+ });
- return [item];
+ // Direct commands surfaced in the PowerToys list page.
+ items.Add(new ListItem(new StartAwakeCommand("Awake: Keep awake indefinitely", () => AwakeService.Instance.SetIndefiniteAsync(), "Awake set to indefinite"))
+ {
+ Title = "Awake: Keep awake indefinitely",
+ Subtitle = "Run Awake in indefinite mode",
+ Icon = icon,
+ });
+ items.Add(new ListItem(new StartAwakeCommand("Awake: Keep awake for 30 minutes", () => AwakeService.Instance.SetTimedAsync(30), "Awake set for 30 minutes"))
+ {
+ Title = "Awake: Keep awake for 30 minutes",
+ Subtitle = "Run Awake timed for 30 minutes",
+ Icon = icon,
+ });
+ items.Add(new ListItem(new StartAwakeCommand("Awake: Keep awake for 1 hour", () => AwakeService.Instance.SetTimedAsync(60), "Awake set for 1 hour"))
+ {
+ Title = "Awake: Keep awake for 1 hour",
+ Subtitle = "Run Awake timed for 1 hour",
+ Icon = icon,
+ });
+ items.Add(new ListItem(new StartAwakeCommand("Awake: Keep awake for 2 hours", () => AwakeService.Instance.SetTimedAsync(120), "Awake set for 2 hours"))
+ {
+ Title = "Awake: Keep awake for 2 hours",
+ Subtitle = "Run Awake timed for 2 hours",
+ Icon = icon,
+ });
+ items.Add(new ListItem(new StopAwakeCommand())
+ {
+ Title = "Awake: Turn off",
+ Subtitle = "Switch Awake back to Off",
+ Icon = icon,
+ });
+ items.Add(new ListItem(new CommandItem(new AwakeProcessListPage()))
+ {
+ Title = "Bind Awake to another process",
+ Subtitle = "Stop automatically when the target process exits",
+ Icon = icon,
+ });
+
+ return items;
}
}
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Pages/PowerToysExtensionPage.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Pages/PowerToysExtensionPage.cs
index 12f9d92cde..4dad6534bf 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Pages/PowerToysExtensionPage.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Pages/PowerToysExtensionPage.cs
@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Awake.ModuleServices;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using PowerToysExtension.Commands;
@@ -40,26 +41,6 @@ internal sealed partial class PowerToysExtensionPage : ListPage
Title = "Open Workspaces editor",
Subtitle = "Launch the Workspaces editor",
},
- new ListItem(new StartAwakeCommand("Awake: Keep awake indefinitely", () => "-m indefinite", "Awake set to indefinite"))
- {
- Title = "Awake: Keep awake indefinitely",
- Subtitle = "Run Awake in indefinite mode",
- },
- new ListItem(new StartAwakeCommand("Awake: Keep awake for 30 minutes", () => "-m timed -t 30", "Awake set for 30 minutes"))
- {
- Title = "Awake: Keep awake for 30 minutes",
- Subtitle = "Run Awake timed for 30 minutes",
- },
- new ListItem(new StartAwakeCommand("Awake: Keep awake for 2 hours", () => "-m timed -t 120", "Awake set for 2 hours"))
- {
- Title = "Awake: Keep awake for 2 hours",
- Subtitle = "Run Awake timed for 2 hours",
- },
- new ListItem(new StopAwakeCommand())
- {
- Title = "Awake: Turn off",
- Subtitle = "Switch Awake back to Off",
- },
];
}
}
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Properties/launchSettings.json b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Properties/launchSettings.json
new file mode 100644
index 0000000000..c0037538b9
--- /dev/null
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "profiles": {
+ "Microsoft.CmdPal.Ext.PowerToys (Package)": {
+ "commandName": "MsixPackage",
+ "doNotLaunchApp": true,
+ "nativeDebugging": false
+ },
+ "Microsoft.CmdPal.Ext.PowerToys (Unpackaged)": {
+ "commandName": "Project"
+ }
+ }
+}