centralized_hotkeys.cpp
1 #include "pch.h" 2 #include "centralized_hotkeys.h" 3 4 #include <map> 5 #include <common/logger/logger.h> 6 #include <common/utils/winapi_error.h> 7 #include <common/SettingsAPI/settings_objects.h> 8 9 namespace CentralizedHotkeys 10 { 11 std::map<Shortcut, std::vector<Action>> actions; 12 std::map<Shortcut, int> ids; 13 HWND runnerWindow; 14 15 std::wstring ToWstring(const Shortcut& shortcut) 16 { 17 std::wstring res = L""; 18 if (shortcut.modifiersMask & MOD_SHIFT) 19 { 20 res += L"shift+"; 21 } 22 23 if (shortcut.modifiersMask & MOD_CONTROL) 24 { 25 res += L"ctrl+"; 26 } 27 28 if (shortcut.modifiersMask & MOD_WIN) 29 { 30 res += L"win+"; 31 } 32 33 if (shortcut.modifiersMask & MOD_ALT) 34 { 35 res += L"alt+"; 36 } 37 38 res += PowerToysSettings::HotkeyObject::key_from_code(shortcut.vkCode); 39 40 return res; 41 } 42 43 bool AddHotkeyAction(Shortcut shortcut, Action action) 44 { 45 if (!actions[shortcut].empty()) 46 { 47 // It will only work if previous one is rewritten 48 Logger::warn(L"{} shortcut is already registered", ToWstring(shortcut)); 49 } 50 51 actions[shortcut].push_back(action); 52 // Register hotkey if it is the first shortcut 53 if (actions[shortcut].size() == 1) 54 { 55 if (ids.find(shortcut) == ids.end()) 56 { 57 static int nextId = 0; 58 ids[shortcut] = nextId++; 59 } 60 61 if (!RegisterHotKey(runnerWindow, ids[shortcut], shortcut.modifiersMask, shortcut.vkCode)) 62 { 63 Logger::warn(L"Failed to add {} shortcut. {}", ToWstring(shortcut), get_last_error_or_default(GetLastError())); 64 return false; 65 } 66 67 Logger::trace(L"{} shortcut registered", ToWstring(shortcut)); 68 return true; 69 } 70 71 return true; 72 } 73 74 void UnregisterHotkeysForModule(std::wstring moduleName) 75 { 76 for (auto it = actions.begin(); it != actions.end(); it++) 77 { 78 auto val = std::find_if(it->second.begin(), it->second.end(), [moduleName](Action a) { return a.moduleName == moduleName; }); 79 if (val != it->second.end()) 80 { 81 it->second.erase(val); 82 83 if (it->second.empty()) 84 { 85 if (!UnregisterHotKey(runnerWindow, ids[it->first])) 86 { 87 Logger::warn(L"Failed to unregister {} shortcut. {}", ToWstring(it->first), get_last_error_or_default(GetLastError())); 88 } 89 else 90 { 91 Logger::trace(L"{} shortcut unregistered", ToWstring(it->first)); 92 } 93 } 94 } 95 } 96 } 97 98 void PopulateHotkey(Shortcut shortcut) 99 { 100 if (!actions.empty()) 101 { 102 try 103 { 104 actions[shortcut].begin()->action(shortcut.modifiersMask, shortcut.vkCode); 105 } 106 catch(std::exception& ex) 107 { 108 Logger::error("Failed to execute hotkey's action. {}", ex.what()); 109 } 110 catch(...) 111 { 112 Logger::error(L"Failed to execute hotkey's action"); 113 } 114 } 115 } 116 117 void RegisterWindow(HWND hwnd) 118 { 119 runnerWindow = hwnd; 120 } 121 }