mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 19:27:56 +01:00
OK, screen ruler
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#include <codecvt>
|
||||
#include <common/utils/logger_helper.h>
|
||||
#include "ThemeHelper.h"
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
@@ -98,12 +100,18 @@ private:
|
||||
HANDLE m_force_light_event_handle;
|
||||
HANDLE m_force_dark_event_handle;
|
||||
HANDLE m_manual_override_event_handle;
|
||||
HANDLE m_toggle_event_handle{ nullptr };
|
||||
std::thread m_toggle_thread;
|
||||
std::atomic<bool> m_toggle_thread_running{ false };
|
||||
|
||||
static const constexpr int NUM_DEFAULT_HOTKEYS = 4;
|
||||
|
||||
Hotkey m_toggle_theme_hotkey = { .win = true, .ctrl = true, .shift = true, .alt = false, .key = 'D' };
|
||||
|
||||
void init_settings();
|
||||
void ToggleTheme();
|
||||
void StartToggleListener();
|
||||
void StopToggleListener();
|
||||
|
||||
public:
|
||||
LightSwitchInterface()
|
||||
@@ -113,6 +121,7 @@ public:
|
||||
m_force_light_event_handle = CreateDefaultEvent(L"POWERTOYS_LIGHTSWITCH_FORCE_LIGHT");
|
||||
m_force_dark_event_handle = CreateDefaultEvent(L"POWERTOYS_LIGHTSWITCH_FORCE_DARK");
|
||||
m_manual_override_event_handle = CreateEventW(nullptr, TRUE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
m_toggle_event_handle = CreateDefaultEvent(L"Local\\PowerToys-LightSwitch-ToggleEvent-d8dc2f29-8c94-4ca1-8c5f-3e2b1e3c4f5a");
|
||||
|
||||
init_settings();
|
||||
};
|
||||
@@ -437,6 +446,8 @@ public:
|
||||
Logger::info(L"Light Switch process launched successfully (PID: {}).", pi.dwProcessId);
|
||||
m_process = pi.hProcess;
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
StartToggleListener();
|
||||
}
|
||||
|
||||
// Disable the powertoy
|
||||
@@ -462,6 +473,8 @@ public:
|
||||
CloseHandle(m_process);
|
||||
m_process = nullptr;
|
||||
}
|
||||
|
||||
StopToggleListener();
|
||||
}
|
||||
|
||||
// Returns if the powertoys is enabled
|
||||
@@ -523,31 +536,8 @@ public:
|
||||
}
|
||||
else if (hotkeyId == 0)
|
||||
{
|
||||
// get current will return true if in light mode; otherwise false
|
||||
Logger::info(L"[Light Switch] Hotkey triggered: Toggle Theme");
|
||||
if (g_settings.m_changeSystem)
|
||||
{
|
||||
SetSystemTheme(!GetCurrentSystemTheme());
|
||||
}
|
||||
if (g_settings.m_changeApps)
|
||||
{
|
||||
SetAppsTheme(!GetCurrentAppsTheme());
|
||||
}
|
||||
|
||||
if (!m_manual_override_event_handle)
|
||||
{
|
||||
m_manual_override_event_handle = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
if (!m_manual_override_event_handle)
|
||||
{
|
||||
m_manual_override_event_handle = CreateEventW(nullptr, TRUE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
}
|
||||
}
|
||||
|
||||
if (m_manual_override_event_handle)
|
||||
{
|
||||
SetEvent(m_manual_override_event_handle);
|
||||
Logger::debug(L"[Light Switch] Manual override event set");
|
||||
}
|
||||
ToggleTheme();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -560,6 +550,77 @@ public:
|
||||
{
|
||||
return WaitForSingleObject(m_process, 0) == WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
void ToggleTheme()
|
||||
{
|
||||
if (g_settings.m_changeSystem)
|
||||
{
|
||||
SetSystemTheme(!GetCurrentSystemTheme());
|
||||
}
|
||||
if (g_settings.m_changeApps)
|
||||
{
|
||||
SetAppsTheme(!GetCurrentAppsTheme());
|
||||
}
|
||||
|
||||
if (!m_manual_override_event_handle)
|
||||
{
|
||||
m_manual_override_event_handle = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
if (!m_manual_override_event_handle)
|
||||
{
|
||||
m_manual_override_event_handle = CreateEventW(nullptr, TRUE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
}
|
||||
}
|
||||
|
||||
if (m_manual_override_event_handle)
|
||||
{
|
||||
SetEvent(m_manual_override_event_handle);
|
||||
Logger::debug(L"[Light Switch] Manual override event set");
|
||||
}
|
||||
}
|
||||
|
||||
void StartToggleListener()
|
||||
{
|
||||
if (m_toggle_thread_running || !m_toggle_event_handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_toggle_thread_running = true;
|
||||
m_toggle_thread = std::thread([this]() {
|
||||
while (m_toggle_thread_running)
|
||||
{
|
||||
const DWORD wait_result = WaitForSingleObject(m_toggle_event_handle, 500);
|
||||
if (!m_toggle_thread_running)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (wait_result == WAIT_OBJECT_0)
|
||||
{
|
||||
ToggleTheme();
|
||||
ResetEvent(m_toggle_event_handle);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void StopToggleListener()
|
||||
{
|
||||
if (!m_toggle_thread_running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_toggle_thread_running = false;
|
||||
if (m_toggle_event_handle)
|
||||
{
|
||||
SetEvent(m_toggle_event_handle);
|
||||
}
|
||||
if (m_toggle_thread.joinable())
|
||||
{
|
||||
m_toggle_thread.join();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::wstring utf8_to_wstring(const std::string& str)
|
||||
@@ -639,4 +700,4 @@ void LightSwitchInterface::init_settings()
|
||||
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
|
||||
{
|
||||
return new LightSwitchInterface();
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,35 @@
|
||||
// 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.Threading;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToysExtension.Helpers;
|
||||
|
||||
namespace PowerToysExtension.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Toggles Light Switch via the shared event.
|
||||
/// </summary>
|
||||
internal sealed partial class ToggleLightSwitchCommand : InvokableCommand
|
||||
{
|
||||
public ToggleLightSwitchCommand()
|
||||
{
|
||||
Name = "Toggle Light Switch";
|
||||
}
|
||||
|
||||
public override CommandResult Invoke()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var evt = new EventWaitHandle(false, EventResetMode.AutoReset, PowerToysEventNames.LightSwitchToggle);
|
||||
evt.Set();
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return CommandResult.ShowToast($"Failed to toggle Light Switch: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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.Threading;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToysExtension.Helpers;
|
||||
|
||||
namespace PowerToysExtension.Commands;
|
||||
|
||||
internal sealed partial class ToggleScreenRulerCommand : InvokableCommand
|
||||
{
|
||||
public ToggleScreenRulerCommand()
|
||||
{
|
||||
Name = "Toggle Screen Ruler";
|
||||
}
|
||||
|
||||
public override CommandResult Invoke()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var evt = new EventWaitHandle(false, EventResetMode.AutoReset, PowerToysEventNames.MeasureToolTrigger);
|
||||
evt.Set();
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return CommandResult.ShowToast($"Failed to toggle Screen Ruler: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,10 @@ internal static class ModuleCommandCatalog
|
||||
new AwakeModuleCommandProvider(),
|
||||
new AdvancedPasteModuleCommandProvider(),
|
||||
new WorkspacesModuleCommandProvider(),
|
||||
new LightSwitchModuleCommandProvider(),
|
||||
new PowerToysRunModuleCommandProvider(),
|
||||
new ScreenRulerModuleCommandProvider(),
|
||||
new ColorPickerModuleCommandProvider(),
|
||||
new DefaultSettingsModuleCommandProvider(),
|
||||
];
|
||||
|
||||
public static IListItem[] FilteredItems(string query)
|
||||
|
||||
@@ -25,6 +25,7 @@ internal static class PowerToysEventNames
|
||||
internal const string PowerToysRunInvoke = "Local\\PowerToysRunInvokeEvent-30f26ad7-d36d-4c0e-ab02-68bb5ff3c4ab";
|
||||
internal const string RegistryPreviewTrigger = "Local\\RegistryPreviewEvent-4C559468-F75A-4E7F-BC4F-9C9688316687";
|
||||
internal const string ShortcutGuideTrigger = "Local\\ShortcutGuide-TriggerEvent-d4275ad3-2531-4d19-9252-c0becbd9b496";
|
||||
internal const string LightSwitchToggle = "Local\\PowerToys-LightSwitch-ToggleEvent-d8dc2f29-8c94-4ca1-8c5f-3e2b1e3c4f5a";
|
||||
internal const string WorkspacesLaunchEditor = "Local\\Workspaces-LaunchEditorEvent-a55ff427-cf62-4994-a2cd-9f72139296bf";
|
||||
internal const string WorkspacesHotkey = "Local\\PowerToys-Workspaces-HotkeyEvent-2625C3C8-BAC9-4DB3-BCD6-3B4391A26FD0";
|
||||
internal const string CropAndLockThumbnail = "Local\\PowerToysCropAndLockThumbnailEvent-1637be50-da72-46b2-9220-b32b206b2434";
|
||||
|
||||
@@ -38,6 +38,7 @@ internal static class PowerToysResourcesHelper
|
||||
SettingsWindow.FileLocksmith => "Assets\\FileLocksmith.png",
|
||||
SettingsWindow.NewPlus => "Assets\\NewPlus.png",
|
||||
SettingsWindow.Peek => "Assets\\Peek.png",
|
||||
SettingsWindow.LightSwitch => "Assets\\LightSwitch.png",
|
||||
SettingsWindow.AlwaysOnTop => "Assets\\AlwaysOnTop.png",
|
||||
SettingsWindow.CmdNotFound => "Assets\\CommandNotFound.png",
|
||||
SettingsWindow.MouseWithoutBorders => "Assets\\MouseWithoutBorders.png",
|
||||
@@ -79,6 +80,7 @@ internal static class PowerToysResourcesHelper
|
||||
SettingsWindow.FileLocksmith => "File Locksmith",
|
||||
SettingsWindow.NewPlus => "New+",
|
||||
SettingsWindow.Peek => "Peek",
|
||||
SettingsWindow.LightSwitch => "Light Switch",
|
||||
SettingsWindow.AlwaysOnTop => "Always On Top",
|
||||
SettingsWindow.CmdNotFound => "Command Not Found",
|
||||
SettingsWindow.MouseWithoutBorders => "Mouse Without Borders",
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// 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.Linq;
|
||||
using Common.UI;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToysExtension.Commands;
|
||||
using PowerToysExtension.Helpers;
|
||||
|
||||
namespace PowerToysExtension.Modules;
|
||||
|
||||
/// <summary>
|
||||
/// Provides open-settings commands for modules without specialized commands.
|
||||
/// </summary>
|
||||
internal sealed class DefaultSettingsModuleCommandProvider : ModuleCommandProvider
|
||||
{
|
||||
private static readonly SettingsDeepLink.SettingsWindow[] _excluded =
|
||||
[
|
||||
SettingsDeepLink.SettingsWindow.Dashboard,
|
||||
SettingsDeepLink.SettingsWindow.Workspaces,
|
||||
SettingsDeepLink.SettingsWindow.Awake,
|
||||
SettingsDeepLink.SettingsWindow.ColorPicker,
|
||||
];
|
||||
|
||||
public override IEnumerable<ListItem> BuildCommands()
|
||||
{
|
||||
foreach (var module in Enum.GetValues<SettingsDeepLink.SettingsWindow>())
|
||||
{
|
||||
if (_excluded.Contains(module))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var title = module.ModuleDisplayName();
|
||||
yield return new ListItem(new OpenInSettingsCommand(module, title))
|
||||
{
|
||||
Title = title,
|
||||
Subtitle = "Open module settings",
|
||||
Icon = module.ModuleIcon(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// 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.Collections.Generic;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToysExtension.Commands;
|
||||
using PowerToysExtension.Helpers;
|
||||
using static Common.UI.SettingsDeepLink;
|
||||
|
||||
namespace PowerToysExtension.Modules;
|
||||
|
||||
internal sealed class LightSwitchModuleCommandProvider : ModuleCommandProvider
|
||||
{
|
||||
public override IEnumerable<ListItem> BuildCommands()
|
||||
{
|
||||
var title = SettingsWindow.LightSwitch.ModuleDisplayName();
|
||||
var icon = SettingsWindow.LightSwitch.ModuleIcon();
|
||||
|
||||
var items = new List<ListItem>
|
||||
{
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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.Collections.Generic;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToysExtension.Commands;
|
||||
using PowerToysExtension.Helpers;
|
||||
using static Common.UI.SettingsDeepLink;
|
||||
|
||||
namespace PowerToysExtension.Modules;
|
||||
|
||||
internal sealed class PowerToysRunModuleCommandProvider : ModuleCommandProvider
|
||||
{
|
||||
public override IEnumerable<ListItem> BuildCommands()
|
||||
{
|
||||
var title = SettingsWindow.PowerLauncher.ModuleDisplayName();
|
||||
var icon = SettingsWindow.PowerLauncher.ModuleIcon();
|
||||
|
||||
yield return new ListItem(new OpenInSettingsCommand(SettingsWindow.PowerLauncher, title))
|
||||
{
|
||||
Title = title,
|
||||
Subtitle = "Open PowerToys Run settings",
|
||||
Icon = icon,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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.Collections.Generic;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToysExtension.Commands;
|
||||
using PowerToysExtension.Helpers;
|
||||
using static Common.UI.SettingsDeepLink;
|
||||
|
||||
namespace PowerToysExtension.Modules;
|
||||
|
||||
internal sealed class ScreenRulerModuleCommandProvider : ModuleCommandProvider
|
||||
{
|
||||
public override IEnumerable<ListItem> BuildCommands()
|
||||
{
|
||||
var title = SettingsWindow.MeasureTool.ModuleDisplayName();
|
||||
var icon = SettingsWindow.MeasureTool.ModuleIcon();
|
||||
|
||||
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))
|
||||
{
|
||||
Title = title,
|
||||
Subtitle = "Open Screen Ruler settings",
|
||||
Icon = icon,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user