/
githubmirror
/
PowerToys
Обзор
Документация
Войти
/
githubmirror
/
PowerToys
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/modules/powerdisplay/PowerDisplay/Helpers/HotkeyService.cs
158 строк
5 KB
moooyo
[PD] Re-enable PowerDisplay (#46489)
10 апр 2026, 10:14
Не верифицирован
10 апр 2026, 10:14
0089de3
Код
Авторство
О чём код?
// 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.Runtime.InteropServices; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; namespace PowerDisplay.Helpers { /// <summary> /// Service for handling hotkey registration in-process. /// Uses RegisterHotKey Win32 API instead of Runner's centralized mechanism /// to avoid IPC timing issues (CmdPal pattern). /// </summary> internal sealed partial class HotkeyService : IDisposable { private const int HotkeyId = 9001; private readonly SettingsUtils _settingsUtils; private readonly Action _hotkeyAction; private nint _hwnd; private bool _isRegistered; private bool _disposed; public HotkeyService(SettingsUtils settingsUtils, Action hotkeyAction) { _settingsUtils = settingsUtils; _hotkeyAction = hotkeyAction; } /// <summary> /// Initialize the hotkey service with a window handle. /// Must be called after window is created and WndProcService is attached. /// </summary> public void Initialize(nint hwnd) { _hwnd = hwnd; ReloadSettings(); } /// <summary> /// Handle WM_HOTKEY messages. Called by WndProcService. /// </summary> /// <returns>True if the message was handled.</returns> public bool HandleMessage(uint uMsg, nuint wParam) { if (uMsg == WmHotkey && (int)wParam == HotkeyId) { try { _hotkeyAction?.Invoke(); } catch (Exception ex) { Logger.LogError($"[HotkeyService] Hotkey action failed: {ex.Message}"); } return true; } return false; } /// <summary> /// Reload settings and re-register hotkey. /// Call this when settings change. /// </summary> public void ReloadSettings() { UnregisterHotkey(); var settings = _settingsUtils.GetSettingsOrDefault<PowerDisplaySettings>(PowerDisplaySettings.ModuleName); var hotkey = settings?.Properties?.ActivationShortcut; if (hotkey == null || !hotkey.IsValid()) { return; } RegisterHotkey(hotkey); } private void RegisterHotkey(HotkeySettings hotkey) { if (_hwnd == 0) { Logger.LogWarning("[HotkeyService] Cannot register hotkey: window handle not set"); return; } // Build modifiers using bit flags uint modifiers = ModNoRepeat | (hotkey.Win ? ModWin : 0) | (hotkey.Ctrl ? ModControl : 0) | (hotkey.Alt ? ModAlt : 0) | (hotkey.Shift ? ModShift : 0); if (RegisterHotKeyNative(_hwnd, HotkeyId, modifiers, (uint)hotkey.Code)) { _isRegistered = true; } else { Logger.LogError($"[HotkeyService] Failed to register hotkey: {hotkey}, error={Marshal.GetLastWin32Error()}"); } } private void UnregisterHotkey() { if (!_isRegistered || _hwnd == 0) { return; } bool success = UnregisterHotKeyNative(_hwnd, HotkeyId); if (!success) { var error = Marshal.GetLastWin32Error(); Logger.LogWarning($"[HotkeyService] Failed to unregister hotkey, error={error}"); } _isRegistered = false; } public void Dispose() { if (_disposed) { return; } UnregisterHotkey(); _disposed = true; } // P/Invoke constants private const uint WmHotkey = 0x0312; // HOT_KEY_MODIFIERS flags private const uint ModAlt = 0x0001; private const uint ModControl = 0x0002; private const uint ModShift = 0x0004; private const uint ModWin = 0x0008; private const uint ModNoRepeat = 0x4000; [LibraryImport("user32.dll", EntryPoint = "RegisterHotKey", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static partial bool RegisterHotKeyNative(nint hWnd, int id, uint fsModifiers, uint vk); [LibraryImport("user32.dll", EntryPoint = "UnregisterHotKey", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static partial bool UnregisterHotKeyNative(nint hWnd, int id); } }