using System; using CommunityToolkit.Mvvm.DependencyInjection; using Flow.Launcher.Avalonia.ViewModel; using Flow.Launcher.Infrastructure.Hotkey; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; namespace Flow.Launcher.Avalonia.Helper; /// /// Hotkey mapper for Avalonia - registers and manages global hotkeys. /// internal static class HotKeyMapper { private static readonly string ClassName = nameof(HotKeyMapper); private static Settings? _settings; private static MainViewModel? _mainViewModel; private static int _toggleHotkeyId = -1; /// /// Initialize the hotkey system and register configured hotkeys. /// internal static void Initialize() { _mainViewModel = Ioc.Default.GetRequiredService(); _settings = Ioc.Default.GetService(); if (_settings == null) { Log.Warn(ClassName, "Settings not available, using default hotkey"); return; } // Initialize the global hotkey system GlobalHotkey.Initialize(); // Register the main toggle hotkey SetToggleHotkey(_settings.Hotkey); Log.Info(ClassName, $"HotKeyMapper initialized with hotkey: {_settings.Hotkey}"); } /// /// Set or update the toggle hotkey. /// internal static void SetToggleHotkey(string hotkeyString) { RemoveToggleHotkey(); if (string.IsNullOrWhiteSpace(hotkeyString)) { Log.Warn(ClassName, "Empty hotkey string"); return; } var (mods, key) = GlobalHotkey.ParseHotkeyString(hotkeyString); if (key == 0) { Log.Error(ClassName, $"Failed to parse hotkey: {hotkeyString}"); return; } _toggleHotkeyId = GlobalHotkey.Register(mods, key, OnToggleHotkey); if (_toggleHotkeyId < 0) { Log.Error(ClassName, $"Failed to register hotkey: {hotkeyString}"); } else { Log.Info(ClassName, $"Registered toggle hotkey: {hotkeyString}"); } } /// /// Remove the current toggle hotkey. /// internal static void RemoveToggleHotkey() { if (_toggleHotkeyId >= 0) { GlobalHotkey.Unregister(_toggleHotkeyId); _toggleHotkeyId = -1; } } private static void OnToggleHotkey() { Log.Info(ClassName, "Toggle hotkey triggered"); _mainViewModel?.ToggleFlowLauncher(); } /// /// Checks if a hotkey is available for registration. /// internal static bool CheckAvailability(HotkeyModel hotkey) { var hotkeyString = hotkey.ToString(); var (mods, key) = GlobalHotkey.ParseHotkeyString(hotkeyString); if (key == 0) return false; // Try to register and immediately unregister int id = GlobalHotkey.Register(mods, key, () => { }); if (id >= 0) { GlobalHotkey.Unregister(id); return true; } return false; } /// /// Cleanup and unregister all hotkeys. /// internal static void Shutdown() { GlobalHotkey.Shutdown(); Log.Info(ClassName, "HotKeyMapper shutdown"); } }