do not give module command if module is not enabled

This commit is contained in:
vanzue
2025-12-12 12:25:17 +08:00
parent 538358b47b
commit a75eb482bf
19 changed files with 495 additions and 202 deletions

View File

@@ -0,0 +1,108 @@
// 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.Collections.Generic;
using System.IO;
using System.Text.Json;
using static Common.UI.SettingsDeepLink;
namespace PowerToysExtension.Helpers;
/// <summary>
/// Reads PowerToys module enablement flags from the global settings.json.
/// </summary>
internal static class ModuleEnablementService
{
internal static string SettingsFilePath { get; } = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft",
"PowerToys",
"settings.json");
internal static bool IsModuleEnabled(SettingsWindow module)
{
var key = GetEnabledKey(module);
return string.IsNullOrEmpty(key) || IsKeyEnabled(key);
}
internal static bool IsKeyEnabled(string enabledKey)
{
if (string.IsNullOrWhiteSpace(enabledKey))
{
return true;
}
try
{
var enabled = ReadEnabledFlags();
return enabled is null || !enabled.TryGetValue(enabledKey, out var value) || value;
}
catch
{
return true;
}
}
private static Dictionary<string, bool>? ReadEnabledFlags()
{
if (!File.Exists(SettingsFilePath))
{
return null;
}
var json = File.ReadAllText(SettingsFilePath).Trim('\0');
using var doc = JsonDocument.Parse(json);
if (!doc.RootElement.TryGetProperty("enabled", out var enabledRoot) ||
enabledRoot.ValueKind != JsonValueKind.Object)
{
return null;
}
var result = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
foreach (var prop in enabledRoot.EnumerateObject())
{
if (prop.Value.ValueKind is JsonValueKind.True or JsonValueKind.False)
{
result[prop.Name] = prop.Value.GetBoolean();
}
}
return result;
}
private static string? GetEnabledKey(SettingsWindow module) => module switch
{
SettingsWindow.Awake => "Awake",
SettingsWindow.AdvancedPaste => "AdvancedPaste",
SettingsWindow.AlwaysOnTop => "AlwaysOnTop",
SettingsWindow.ColorPicker => "ColorPicker",
SettingsWindow.CropAndLock => "CropAndLock",
SettingsWindow.EnvironmentVariables => "EnvironmentVariables",
SettingsWindow.FancyZones => "FancyZones",
SettingsWindow.FileExplorer => "File Explorer Preview",
SettingsWindow.FileLocksmith => "FileLocksmith",
SettingsWindow.Hosts => "Hosts",
SettingsWindow.ImageResizer => "Image Resizer",
SettingsWindow.KBM => "Keyboard Manager",
SettingsWindow.LightSwitch => "LightSwitch",
SettingsWindow.MeasureTool => "Measure Tool",
SettingsWindow.MouseWithoutBorders => "MouseWithoutBorders",
SettingsWindow.NewPlus => "NewPlus",
SettingsWindow.Peek => "Peek",
SettingsWindow.PowerAccent => "QuickAccent",
SettingsWindow.PowerLauncher => "PowerToys Run",
SettingsWindow.Run => "PowerToys Run",
SettingsWindow.PowerRename => "PowerRename",
SettingsWindow.PowerOCR => "TextExtractor",
SettingsWindow.RegistryPreview => "RegistryPreview",
SettingsWindow.ShortcutGuide => "Shortcut Guide",
SettingsWindow.Workspaces => "Workspaces",
SettingsWindow.ZoomIt => "ZoomIt",
SettingsWindow.CmdNotFound => "CmdNotFound",
SettingsWindow.CmdPal => "CmdPal",
_ => null,
};
}

View File

@@ -0,0 +1,72 @@
// 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.IO;
using System.Threading;
using ManagedCommon;
namespace PowerToysExtension.Helpers;
/// <summary>
/// Watches the global PowerToys settings.json and notifies listeners when it changes.
/// </summary>
internal static class SettingsChangeNotifier
{
private static readonly object Sync = new();
private static FileSystemWatcher? _watcher;
private static Timer? _debounceTimer;
internal static event Action? SettingsChanged;
static SettingsChangeNotifier()
{
TryStartWatcher();
}
private static void TryStartWatcher()
{
try
{
var filePath = ModuleEnablementService.SettingsFilePath;
var directory = Path.GetDirectoryName(filePath);
var fileName = Path.GetFileName(filePath);
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(fileName))
{
return;
}
_watcher = new FileSystemWatcher(directory)
{
Filter = fileName,
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Size,
IncludeSubdirectories = false,
EnableRaisingEvents = true,
};
_watcher.Changed += (_, _) => ScheduleRaise();
_watcher.Created += (_, _) => ScheduleRaise();
_watcher.Deleted += (_, _) => ScheduleRaise();
_watcher.Renamed += (_, _) => ScheduleRaise();
}
catch (Exception ex)
{
Logger.LogError($"SettingsChangeNotifier failed to start: {ex.Message}");
}
}
private static void ScheduleRaise()
{
lock (Sync)
{
_debounceTimer?.Dispose();
_debounceTimer = new Timer(
_ => SettingsChanged?.Invoke(),
null,
200,
Timeout.Infinite);
}
}
}

View File

@@ -14,17 +14,21 @@ internal sealed class AdvancedPasteModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsDeepLink.SettingsWindow.AdvancedPaste.ModuleDisplayName();
var icon = SettingsDeepLink.SettingsWindow.AdvancedPaste.ModuleIcon();
var module = SettingsDeepLink.SettingsWindow.AdvancedPaste;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new OpenAdvancedPasteCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Open Advanced Paste",
Subtitle = "Launch the Advanced Paste UI",
Icon = icon,
};
yield return new ListItem(new OpenAdvancedPasteCommand())
{
Title = "Open Advanced Paste",
Subtitle = "Launch the Advanced Paste UI",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsDeepLink.SettingsWindow.AdvancedPaste, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Advanced Paste settings",

View File

@@ -17,15 +17,29 @@ internal sealed class AwakeModuleCommandProvider : ModuleCommandProvider
public override IEnumerable<ListItem> BuildCommands()
{
var items = new List<ListItem>();
var module = SettingsDeepLink.SettingsWindow.Awake;
var settingsTitle = module.ModuleDisplayName();
var icon = PowerToysResourcesHelper.IconFromSettingsIcon("Awake.png");
var moduleIcon = module.ModuleIcon();
if (!ModuleEnablementService.IsModuleEnabled(module))
{
items.Add(new ListItem(new OpenInSettingsCommand(module, settingsTitle))
{
Title = settingsTitle,
Subtitle = "Open Awake settings",
Icon = moduleIcon,
});
return items;
}
// Settings entry with quick actions in MoreCommands.
var settingsTitle = SettingsDeepLink.SettingsWindow.Awake.ModuleDisplayName();
items.Add(new ListItem(new OpenInSettingsCommand(SettingsDeepLink.SettingsWindow.Awake, settingsTitle))
items.Add(new ListItem(new OpenInSettingsCommand(module, settingsTitle))
{
Title = settingsTitle,
Subtitle = "Open Awake settings",
Icon = SettingsDeepLink.SettingsWindow.Awake.ModuleIcon(),
Icon = moduleIcon,
MoreCommands =
[
new CommandContextItem(new StartAwakeCommand("Awake: Keep awake indefinitely", () => AwakeService.Instance.SetIndefiniteAsync(), "Awake set to indefinite")),

View File

@@ -15,41 +15,54 @@ internal sealed class ColorPickerModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsDeepLink.SettingsWindow.ColorPicker.ModuleDisplayName();
var icon = SettingsDeepLink.SettingsWindow.ColorPicker.ModuleIcon();
var module = SettingsDeepLink.SettingsWindow.ColorPicker;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
var commands = new List<ListItem>();
// Quick actions under MoreCommands.
var more = new List<CommandContextItem>
if (ModuleEnablementService.IsModuleEnabled(module))
{
new CommandContextItem(new OpenColorPickerCommand()),
new CommandContextItem(new CopyColorCommand()),
new CommandContextItem(new ColorPickerSavedColorsPage()),
};
// Quick actions under MoreCommands.
var more = new List<CommandContextItem>
{
new CommandContextItem(new OpenColorPickerCommand()),
new CommandContextItem(new CopyColorCommand()),
new CommandContextItem(new ColorPickerSavedColorsPage()),
};
commands.Add(new ListItem(new OpenInSettingsCommand(SettingsDeepLink.SettingsWindow.ColorPicker, title))
{
Title = title,
Subtitle = "Open Color Picker settings",
Icon = icon,
MoreCommands = more.ToArray(),
});
commands.Add(new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Color Picker settings",
Icon = icon,
MoreCommands = more.ToArray(),
});
// Direct entries in the module list.
commands.Add(new ListItem(new OpenColorPickerCommand())
{
Title = "Open Color Picker",
Subtitle = "Start a color pick session",
Icon = icon,
});
// Direct entries in the module list.
commands.Add(new ListItem(new OpenColorPickerCommand())
{
Title = "Open Color Picker",
Subtitle = "Start a color pick session",
Icon = icon,
});
commands.Add(new ListItem(new CommandItem(new ColorPickerSavedColorsPage()))
commands.Add(new ListItem(new CommandItem(new ColorPickerSavedColorsPage()))
{
Title = "Saved colors",
Subtitle = "Browse and copy saved colors",
Icon = icon,
});
}
else
{
Title = "Saved colors",
Subtitle = "Browse and copy saved colors",
Icon = icon,
});
commands.Add(new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Color Picker settings",
Icon = icon,
});
}
return commands;
}

View File

@@ -14,24 +14,28 @@ internal sealed class CropAndLockModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.CropAndLock.ModuleDisplayName();
var icon = SettingsWindow.CropAndLock.ModuleIcon();
var module = SettingsWindow.CropAndLock;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new CropAndLockReparentCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Crop and Lock (Reparent)",
Subtitle = "Create a cropped reparented window",
Icon = icon,
};
yield return new ListItem(new CropAndLockReparentCommand())
{
Title = "Crop and Lock (Reparent)",
Subtitle = "Create a cropped reparented window",
Icon = icon,
};
yield return new ListItem(new CropAndLockThumbnailCommand())
{
Title = "Crop and Lock (Thumbnail)",
Subtitle = "Create a cropped thumbnail window",
Icon = icon,
};
yield return new ListItem(new CropAndLockThumbnailCommand())
{
Title = "Crop and Lock (Thumbnail)",
Subtitle = "Create a cropped thumbnail window",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.CropAndLock, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Crop and Lock settings",

View File

@@ -14,24 +14,28 @@ internal sealed class EnvironmentVariablesModuleCommandProvider : ModuleCommandP
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.EnvironmentVariables.ModuleDisplayName();
var icon = SettingsWindow.EnvironmentVariables.ModuleIcon();
var module = SettingsWindow.EnvironmentVariables;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new OpenEnvironmentVariablesCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Open Environment Variables",
Subtitle = "Launch Environment Variables editor",
Icon = icon,
};
yield return new ListItem(new OpenEnvironmentVariablesCommand())
{
Title = "Open Environment Variables",
Subtitle = "Launch Environment Variables editor",
Icon = icon,
};
yield return new ListItem(new OpenEnvironmentVariablesAdminCommand())
{
Title = "Open Environment Variables (Admin)",
Subtitle = "Launch Environment Variables editor as admin",
Icon = icon,
};
yield return new ListItem(new OpenEnvironmentVariablesAdminCommand())
{
Title = "Open Environment Variables (Admin)",
Subtitle = "Launch Environment Variables editor as admin",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.EnvironmentVariables, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Environment Variables settings",

View File

@@ -14,17 +14,21 @@ internal sealed class FancyZonesModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.FancyZones.ModuleDisplayName();
var icon = SettingsWindow.FancyZones.ModuleIcon();
var module = SettingsWindow.FancyZones;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new OpenFancyZonesEditorCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Open FancyZones Editor",
Subtitle = "Launch layout editor",
Icon = icon,
};
yield return new ListItem(new OpenFancyZonesEditorCommand())
{
Title = "Open FancyZones Editor",
Subtitle = "Launch layout editor",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.FancyZones, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open FancyZones settings",

View File

@@ -14,24 +14,28 @@ internal sealed class HostsModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.Hosts.ModuleDisplayName();
var icon = SettingsWindow.Hosts.ModuleIcon();
var module = SettingsWindow.Hosts;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new OpenHostsEditorCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Open Hosts File Editor",
Subtitle = "Launch Hosts File Editor",
Icon = icon,
};
yield return new ListItem(new OpenHostsEditorCommand())
{
Title = "Open Hosts File Editor",
Subtitle = "Launch Hosts File Editor",
Icon = icon,
};
yield return new ListItem(new OpenHostsEditorAdminCommand())
{
Title = "Open Hosts File Editor (Admin)",
Subtitle = "Launch Hosts File Editor as admin",
Icon = icon,
};
yield return new ListItem(new OpenHostsEditorAdminCommand())
{
Title = "Open Hosts File Editor (Admin)",
Subtitle = "Launch Hosts File Editor as admin",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.Hosts, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Hosts File Editor settings",

View File

@@ -14,24 +14,28 @@ internal sealed class LightSwitchModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.LightSwitch.ModuleDisplayName();
var icon = SettingsWindow.LightSwitch.ModuleIcon();
var module = SettingsWindow.LightSwitch;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
var items = new List<ListItem>
var items = new List<ListItem>();
if (ModuleEnablementService.IsModuleEnabled(module))
{
new ListItem(new ToggleLightSwitchCommand())
items.Add(new ListItem(new ToggleLightSwitchCommand())
{
Title = "Toggle Light Switch",
Subtitle = "Toggle system/apps theme immediately",
Icon = icon,
},
new ListItem(new OpenInSettingsCommand(SettingsWindow.LightSwitch, title))
{
Title = title,
Subtitle = "Open Light Switch settings",
Icon = icon,
},
};
});
}
items.Add(new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Light Switch settings",
Icon = icon,
});
return items;
}

View File

@@ -14,45 +14,61 @@ internal sealed class MouseUtilsModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.MouseUtils.ModuleDisplayName();
var icon = SettingsWindow.MouseUtils.ModuleIcon();
var module = SettingsWindow.MouseUtils;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new ToggleFindMyMouseCommand())
if (ModuleEnablementService.IsKeyEnabled("FindMyMouse"))
{
Title = "Trigger Find My Mouse",
Subtitle = "Focus the mouse pointer",
Icon = icon,
};
yield return new ListItem(new ToggleFindMyMouseCommand())
{
Title = "Trigger Find My Mouse",
Subtitle = "Focus the mouse pointer",
Icon = icon,
};
}
yield return new ListItem(new ToggleMouseHighlighterCommand())
if (ModuleEnablementService.IsKeyEnabled("MouseHighlighter"))
{
Title = "Toggle Mouse Highlighter",
Subtitle = "Highlight mouse clicks",
Icon = icon,
};
yield return new ListItem(new ToggleMouseHighlighterCommand())
{
Title = "Toggle Mouse Highlighter",
Subtitle = "Highlight mouse clicks",
Icon = icon,
};
}
yield return new ListItem(new ToggleMouseCrosshairsCommand())
if (ModuleEnablementService.IsKeyEnabled("MousePointerCrosshairs"))
{
Title = "Toggle Mouse Crosshairs",
Subtitle = "Enable or disable pointer crosshairs",
Icon = icon,
};
yield return new ListItem(new ToggleMouseCrosshairsCommand())
{
Title = "Toggle Mouse Crosshairs",
Subtitle = "Enable or disable pointer crosshairs",
Icon = icon,
};
}
yield return new ListItem(new ToggleCursorWrapCommand())
if (ModuleEnablementService.IsKeyEnabled("CursorWrap"))
{
Title = "Toggle Cursor Wrap",
Subtitle = "Wrap the cursor across monitor edges",
Icon = icon,
};
yield return new ListItem(new ToggleCursorWrapCommand())
{
Title = "Toggle Cursor Wrap",
Subtitle = "Wrap the cursor across monitor edges",
Icon = icon,
};
}
yield return new ListItem(new ShowMouseJumpPreviewCommand())
if (ModuleEnablementService.IsKeyEnabled("MouseJump"))
{
Title = "Show Mouse Jump Preview",
Subtitle = "Jump the pointer to a target",
Icon = icon,
};
yield return new ListItem(new ShowMouseJumpPreviewCommand())
{
Title = "Show Mouse Jump Preview",
Subtitle = "Jump the pointer to a target",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.MouseUtils, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Mouse Utilities settings",

View File

@@ -14,17 +14,21 @@ internal sealed class RegistryPreviewModuleCommandProvider : ModuleCommandProvid
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.RegistryPreview.ModuleDisplayName();
var icon = SettingsWindow.RegistryPreview.ModuleIcon();
var module = SettingsWindow.RegistryPreview;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new OpenRegistryPreviewCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Open Registry Preview",
Subtitle = "Launch Registry Preview",
Icon = icon,
};
yield return new ListItem(new OpenRegistryPreviewCommand())
{
Title = "Open Registry Preview",
Subtitle = "Launch Registry Preview",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.RegistryPreview, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Registry Preview settings",

View File

@@ -14,17 +14,21 @@ internal sealed class ScreenRulerModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.MeasureTool.ModuleDisplayName();
var icon = SettingsWindow.MeasureTool.ModuleIcon();
var module = SettingsWindow.MeasureTool;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new ToggleScreenRulerCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Toggle Screen Ruler",
Subtitle = "Start or close Screen Ruler",
Icon = icon,
};
yield return new ListItem(new ToggleScreenRulerCommand())
{
Title = "Toggle Screen Ruler",
Subtitle = "Start or close Screen Ruler",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.MeasureTool, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Screen Ruler settings",

View File

@@ -14,17 +14,21 @@ internal sealed class ShortcutGuideModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.ShortcutGuide.ModuleDisplayName();
var icon = SettingsWindow.ShortcutGuide.ModuleIcon();
var module = SettingsWindow.ShortcutGuide;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new ToggleShortcutGuideCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Toggle Shortcut Guide",
Subtitle = "Show or hide Shortcut Guide",
Icon = icon,
};
yield return new ListItem(new ToggleShortcutGuideCommand())
{
Title = "Toggle Shortcut Guide",
Subtitle = "Show or hide Shortcut Guide",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.ShortcutGuide, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Shortcut Guide settings",

View File

@@ -14,17 +14,21 @@ internal sealed class TextExtractorModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.PowerOCR.ModuleDisplayName();
var icon = SettingsWindow.PowerOCR.ModuleIcon();
var module = SettingsWindow.PowerOCR;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
yield return new ListItem(new ToggleTextExtractorCommand())
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "Toggle Text Extractor",
Subtitle = "Start or close Text Extractor",
Icon = icon,
};
yield return new ListItem(new ToggleTextExtractorCommand())
{
Title = "Toggle Text Extractor",
Subtitle = "Start or close Text Extractor",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.PowerOCR, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Text Extractor settings",

View File

@@ -21,15 +21,29 @@ internal sealed class WorkspacesModuleCommandProvider : ModuleCommandProvider
public override IEnumerable<ListItem> BuildCommands()
{
var items = new List<ListItem>();
var module = SettingsDeepLink.SettingsWindow.Workspaces;
var title = module.ModuleDisplayName();
var icon = PowerToysResourcesHelper.IconFromSettingsIcon("Workspaces.png");
var moduleIcon = module.ModuleIcon();
if (!ModuleEnablementService.IsModuleEnabled(module))
{
items.Add(new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Workspaces settings",
Icon = moduleIcon,
});
return items;
}
// Settings entry plus common actions.
var title = SettingsDeepLink.SettingsWindow.Workspaces.ModuleDisplayName();
items.Add(new ListItem(new OpenInSettingsCommand(SettingsDeepLink.SettingsWindow.Workspaces, title))
items.Add(new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open Workspaces settings",
Icon = SettingsDeepLink.SettingsWindow.Workspaces.ModuleIcon(),
Icon = moduleIcon,
MoreCommands =
[
new CommandContextItem(new WorkspacesListPage()),

View File

@@ -14,48 +14,52 @@ internal sealed class ZoomItModuleCommandProvider : ModuleCommandProvider
{
public override IEnumerable<ListItem> BuildCommands()
{
var title = SettingsWindow.ZoomIt.ModuleDisplayName();
var icon = SettingsWindow.ZoomIt.ModuleIcon();
var module = SettingsWindow.ZoomIt;
var title = module.ModuleDisplayName();
var icon = module.ModuleIcon();
// Action commands via ZoomIt IPC
yield return new ListItem(new ZoomItActionCommand("zoom", "ZoomIt: Zoom"))
if (ModuleEnablementService.IsModuleEnabled(module))
{
Title = "ZoomIt: Zoom",
Subtitle = "Enter zoom mode",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("draw", "ZoomIt: Draw"))
{
Title = "ZoomIt: Draw",
Subtitle = "Enter drawing mode",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("break", "ZoomIt: Break"))
{
Title = "ZoomIt: Break",
Subtitle = "Enter break timer",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("liveZoom", "ZoomIt: Live Zoom"))
{
Title = "ZoomIt: Live Zoom",
Subtitle = "Toggle live zoom",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("snip", "ZoomIt: Snip"))
{
Title = "ZoomIt: Snip",
Subtitle = "Enter snip mode",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("record", "ZoomIt: Record"))
{
Title = "ZoomIt: Record",
Subtitle = "Start recording",
Icon = icon,
};
// Action commands via ZoomIt IPC
yield return new ListItem(new ZoomItActionCommand("zoom", "ZoomIt: Zoom"))
{
Title = "ZoomIt: Zoom",
Subtitle = "Enter zoom mode",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("draw", "ZoomIt: Draw"))
{
Title = "ZoomIt: Draw",
Subtitle = "Enter drawing mode",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("break", "ZoomIt: Break"))
{
Title = "ZoomIt: Break",
Subtitle = "Enter break timer",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("liveZoom", "ZoomIt: Live Zoom"))
{
Title = "ZoomIt: Live Zoom",
Subtitle = "Toggle live zoom",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("snip", "ZoomIt: Snip"))
{
Title = "ZoomIt: Snip",
Subtitle = "Enter snip mode",
Icon = icon,
};
yield return new ListItem(new ZoomItActionCommand("record", "ZoomIt: Record"))
{
Title = "ZoomIt: Record",
Subtitle = "Start recording",
Icon = icon,
};
}
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.ZoomIt, title))
yield return new ListItem(new OpenInSettingsCommand(module, title))
{
Title = title,
Subtitle = "Open ZoomIt settings",

View File

@@ -17,6 +17,7 @@ internal sealed partial class PowerToysListPage : DynamicListPage
Icon = PowerToysResourcesHelper.IconFromSettingsIcon("PowerToys.png");
Name = Title = "PowerToys";
Id = "com.microsoft.cmdpal.powertoys";
SettingsChangeNotifier.SettingsChanged += OnSettingsChanged;
_empty = new CommandItem()
{
Icon = PowerToysResourcesHelper.IconFromSettingsIcon("PowerToys.png"),
@@ -26,6 +27,11 @@ internal sealed partial class PowerToysListPage : DynamicListPage
EmptyContent = _empty;
}
private void OnSettingsChanged()
{
RaiseItemsChanged(0);
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
_empty.Subtitle = newSearch;

View File

@@ -19,6 +19,7 @@ internal sealed partial class WorkspacesListPage : DynamicListPage
Icon = PowerToysResourcesHelper.IconFromSettingsIcon("Workspaces.png");
Name = Title = "Workspaces";
Id = "com.microsoft.cmdpal.powertoys.workspaces";
SettingsChangeNotifier.SettingsChanged += OnSettingsChanged;
_emptyMessage = new CommandItem()
{
Icon = PowerToysResourcesHelper.IconFromSettingsIcon("Workspaces.png"),
@@ -28,6 +29,11 @@ internal sealed partial class WorkspacesListPage : DynamicListPage
EmptyContent = _emptyMessage;
}
private void OnSettingsChanged()
{
RaiseItemsChanged(0);
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
_emptyMessage.Subtitle = newSearch;