Files
2dust_v2rayN/v2rayN/v2rayN.Desktop/Manager/HotkeyManager.cs
T
Miheichev Aleksandr Sergeevich 58d2641559 chore: remove NoWarn and fix .NET 10 build warnings across platforms (#9301)
* deps: bump ZXing.Net.Bindings.SkiaSharp from 0.16.14 to 0.16.22

Patch update to the latest stable release on the 0.16.x line. No breaking changes, no public API changes - purely internal fixes.

Verified by a full Release build of v2rayN.sln on .NET 10; no new warnings or errors are introduced.

* chore: remove NoWarn and fix .NET 10 build warnings

Removes the repository-level NoWarn suppression from Directory.Build.props and addresses the warnings that surface on top of the .NET 10 migration in #9179, keeping Debug, Release, and cross-platform publishes warning-free without suppressing warnings globally.

Changes:

- Removes <NoWarn>CA1031;CS1591;NU1507;CA1416;IDE0058;IDE0053;IDE0200</NoWarn> from Directory.Build.props.

- Annotates Windows-only APIs with [SupportedOSPlatform] and [SupportedOSPlatformGuard] so CA1416 accepts that the Windows surface is gated behind Utils.IsWindows() / Utils.IsNonWindows().

- Splits Utils.SetUnixFileMode into a cross-platform wrapper and a private [UnsupportedOSPlatform("windows")] implementation so File.SetUnixFileMode never reaches the analyzer on Windows builds.

- Adds a parameterless constructor to MessageBoxDialog so Avalonia's runtime XAML loader (AVLN3001) can instantiate the dialog.

- Moves the WPF high-DPI configuration from app.manifest to <ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode> in v2rayN.csproj, fixing WFO0003.

- Adds global using System.Runtime.Versioning; to ServiceLib and v2rayN.Desktop so the platform attributes are usable project-wide.

* test: make cycle dependency tests locale-independent

Accept the localized Russian cycle dependency diagnostic in CoreConfigContextBuilderTests so the assertions pass when tests run under a Russian UI culture.

* fix: tighten Unix platform handling

Adds Linux and macOS platform guards so the analyzer can narrow calls through Utils.IsLinux() and Utils.IsMacOS().

Marks the Linux/macOS autostart and system proxy helpers with explicit platform attributes.

Updates Utils.GetSystemHosts() to read /etc/hosts on Linux and macOS while keeping the existing Windows hosts and hosts.ics merge behavior.
2026-05-14 19:25:07 +08:00

95 lines
2.3 KiB
C#

using Avalonia.Win32.Input;
using GlobalHotKeys;
namespace v2rayN.Desktop.Manager;
public sealed class HotkeyManager
{
private static readonly Lazy<HotkeyManager> _instance = new(() => new());
public static HotkeyManager Instance = _instance.Value;
private readonly Dictionary<int, EGlobalHotkey> _hotkeyTriggerDic = new();
[SupportedOSPlatform("windows")]
private GlobalHotKeys.HotKeyManager? _hotKeyManager;
private Config? _config;
private event Action<EGlobalHotkey>? _updateFunc;
public bool IsPause { get; set; } = false;
[SupportedOSPlatform("windows")]
public void Init(Config config, Action<EGlobalHotkey> updateFunc)
{
_config = config;
_updateFunc = updateFunc;
Register();
}
public void Dispose()
{
if (!Utils.IsWindows())
{
return;
}
_hotKeyManager?.Dispose();
}
[SupportedOSPlatform("windows")]
private void Register()
{
if (_config.GlobalHotkeys.Any(t => t.KeyCode > 0) == false)
{
return;
}
_hotKeyManager ??= new GlobalHotKeys.HotKeyManager();
_hotkeyTriggerDic.Clear();
foreach (var item in _config.GlobalHotkeys)
{
if (item.KeyCode is null or 0)
{
continue;
}
var vKey = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
var modifiers = Modifiers.None;
if (item.Control)
{
modifiers |= Modifiers.Control;
}
if (item.Shift)
{
modifiers |= Modifiers.Shift;
}
if (item.Alt)
{
modifiers |= Modifiers.Alt;
}
var result = _hotKeyManager?.Register((VirtualKeyCode)vKey, modifiers);
if (result?.IsSuccessful == true)
{
_hotkeyTriggerDic.Add(result.Id, item.EGlobalHotkey);
}
}
_hotKeyManager?.HotKeyPressed
.ObserveOn(AvaloniaScheduler.Instance)
.Subscribe(OnNext);
}
private void OnNext(HotKey key)
{
if (_updateFunc == null || IsPause)
{
return;
}
if (_hotkeyTriggerDic.TryGetValue(key.Id, out var value))
{
_updateFunc?.Invoke(value);
}
}
}