KeyNames = { [const.vkEsc ] = T(994618945577, "Escape"), [const.vkBackspace ] = T(363663173763, --[[key name]] "Backspace"), [const.vkTab ] = T(362312379813, --[[key name]] "Tab"), [const.vkEnter ] = T(434251720954, --[[key name]] "Enter"), [const.vkShift ] = T(528194924773, --[[key name]] "Shift"), [const.vkControl ] = T(526443613034, --[[key name]] "Ctrl"), [const.vkAlt ] = T(382578073377, --[[key name]] "Alt"), [const.vkCapital ] = T(295522905381, --[[key name]] "Caps Lock"), [const.vkSpace ] = T(918886773235, --[[key name]] "Space"), [const.vkPageup ] = T(408309138461, --[[key name]] "Pageup"), [const.vkPagedown ] = T(842877867225, --[[key name]] "Pagedown"), [const.vkEnd ] = T(431579043068, --[[key name]] "End"), [const.vkHome ] = T(758009688242, --[[key name]] "Home"), [const.vkLeft ] = T(986696793449, --[[key name]] "Left"), [const.vkUp ] = T(456582989896, --[[key name]] "Up"), [const.vkRight ] = T(154027640280, --[[key name]] "Right"), [const.vkDown ] = T(931890286355, --[[key name]] "Down"), [const.vkSnapshot ] = T(860978238624, --[[key name]] "PrtScr"), [const.vkInsert ] = T(133397615161, --[[key name]] "Insert"), [const.vkDelete ] = T(575155046483, --[[key name]] "Delete"), [const.vk0 ] = T(727885787643, --[[key name]] "0"), [const.vk1 ] = T(374798850608, --[[key name]] "1"), [const.vk2 ] = T(874244724515, --[[key name]] "2"), [const.vk3 ] = T(503064235248, --[[key name]] "3"), [const.vk4 ] = T(944609632600, --[[key name]] "4"), [const.vk5 ] = T(632712324097, --[[key name]] "5"), [const.vk6 ] = T(323389503557, --[[key name]] "6"), [const.vk7 ] = T(722986100874, --[[key name]] "7"), [const.vk8 ] = T(110554267033, --[[key name]] "8"), [const.vk9 ] = T(865411898395, --[[key name]] "9"), [const.vkA ] = T(149656302141, --[[key name]] "A"), [const.vkB ] = T(698574916535, --[[key name]] "B"), [const.vkC ] = T(741290411749, --[[key name]] "C"), [const.vkD ] = T(545051320623, --[[key name]] "D"), [const.vkE ] = T(753030316400, --[[key name]] "E"), [const.vkF ] = T(218798608273, --[[key name]] "F"), [const.vkG ] = T(891009741813, --[[key name]] "G"), [const.vkH ] = T(692140541849, --[[key name]] "H"), [const.vkI ] = T(174022551728, --[[key name]] "I"), [const.vkJ ] = T(539479830500, --[[key name]] "J"), [const.vkK ] = T(161860974128, --[[key name]] "K"), [const.vkL ] = T(249226123778, --[[key name]] "L"), [const.vkM ] = T(481171943908, --[[key name]] "M"), [const.vkN ] = T(839266622388, --[[key name]] "N"), [const.vkO ] = T(157030789856, --[[key name]] "O"), [const.vkP ] = T(516854979267, --[[key name]] "P"), [const.vkQ ] = T(777840477129, --[[key name]] "Q"), [const.vkR ] = T(334310658454, --[[key name]] "R"), [const.vkS ] = T(757474062216, --[[key name]] "S"), [const.vkT ] = T(631701410137, --[[key name]] "T"), [const.vkU ] = T(746408826482, --[[key name]] "U"), [const.vkV ] = T(821369968483, --[[key name]] "V"), [const.vkW ] = T(462254668873, --[[key name]] "W"), [const.vkX ] = T(777329821172, --[[key name]] "X"), [const.vkY ] = T(247827094995, --[[key name]] "Y"), [const.vkZ ] = T(828110723178, --[[key name]] "Z"), [const.vkNumpad0 ] = T(489779093554, --[[key name]] "Numpad 0"), [const.vkNumpad1 ] = T(456380228262, --[[key name]] "Numpad 1"), [const.vkNumpad2 ] = T(113337768441, --[[key name]] "Numpad 2"), [const.vkNumpad3 ] = T(740942281281, --[[key name]] "Numpad 3"), [const.vkNumpad4 ] = T(980927237943, --[[key name]] "Numpad 4"), [const.vkNumpad5 ] = T(588948567523, --[[key name]] "Numpad 5"), [const.vkNumpad6 ] = T(340606982373, --[[key name]] "Numpad 6"), [const.vkNumpad7 ] = T(772104171308, --[[key name]] "Numpad 7"), [const.vkNumpad8 ] = T(227858857321, --[[key name]] "Numpad 8"), [const.vkNumpad9 ] = T(153825312527, --[[key name]] "Numpad 9"), [const.vkMultiply ] = T(351609916758, --[[key name]] "Numpad *"), [const.vkAdd ] = T(405660426752, --[[key name]] "Numpad +"), [const.vkNumpadenter] = T(499808818233, --[[key name]] "Numpad Enter"), [const.vkSubtract ] = T(903488781508, --[[key name]] "Numpad -"), [const.vkDecimal ] = T(716491142574, --[[key name]] "Numpad ."), [const.vkDivide ] = T(491313029155, --[[key name]] "Numpad /"), [const.vkF1 ] = T(613301875525, --[[key name]] "F1"), [const.vkF2 ] = T(528903768897, --[[key name]] "F2"), [const.vkF3 ] = T(810815604850, --[[key name]] "F3"), [const.vkF4 ] = T(133047976173, --[[key name]] "F4"), [const.vkF5 ] = T(251314716947, --[[key name]] "F5"), [const.vkF6 ] = T(596085690833, --[[key name]] "F6"), [const.vkF7 ] = T(791055510938, --[[key name]] "F7"), [const.vkF8 ] = T(700725082489, --[[key name]] "F8"), [const.vkF9 ] = T(929007287373, --[[key name]] "F9"), [const.vkF10 ] = T(856045529332, --[[key name]] "F10"), [const.vkF11 ] = T(220520835553, --[[key name]] "F11"), [const.vkF12 ] = T(777345806029, --[[key name]] "F12"), [const.vkNumlock ] = T(472739269737, --[[key name]] "Num Lock"), [const.vkScroll ] = T(742990430859, --[[key name]] "Scroll Lock"), [const.vkPause ] = T(539846438970, --[[key name]] "Pause"), [const.vkLshift ] = T(584720376973, --[[key name]] "L Shift"), [const.vkRshift ] = T(875823520952, --[[key name]] "R Shift"), [const.vkLcontrol ] = T(818714172929, --[[key name]] "L Ctrl"), [const.vkRcontrol ] = T(965397112297, --[[key name]] "R Ctrl"), [const.vkLalt ] = T(790540664825, --[[key name]] "L Alt"), [const.vkRalt ] = T(797234617727, --[[key name]] "R Alt"), [const.vkSemicolon ] = T(189878265130, --[[key name]] ";"), [const.vkEquals ] = T(650293704285, --[[key name]] "="), [const.vkComma ] = T(425322120344, --[[key name]] ","), [const.vkMinus ] = T(931174084977, --[[key name]] "-"), [const.vkPlus ] = T(134544119265, --[[key name]] "+"), [const.vkDot ] = T(580472321420, --[[key name]] "."), [const.vkSlash ] = T(354341087783, --[[key name]] "/"), [const.vkTilde ] = T(861506842495, --[[key name]] "~"), [const.vkOpensq ] = T(989084215718, --[[key name]] "["), [const.vkBackslash ] = T(263567644090, --[[key name]] "\\"), [const.vkClosesq ] = T(137406678256, --[[key name]] "]"), [const.vkQuote ] = T(358440088708, --[[key name]] "'"), [const.vkLwin or false] = T(672291274770, "Lwin"), [const.vkRwin or false] = T(895098105879, "Rwin"), [const.vkApps or false] = T(358439604347, "Menu"), } KeyNames[false] = nil VKStrNames = { [const.vkEsc ] = "Escape", [const.vkBackspace ] = "Backspace", [const.vkTab ] = "Tab", [const.vkEnter ] = "Enter", [const.vkShift ] = "Shift", [const.vkControl ] = "Ctrl", [const.vkAlt ] = "Alt", [const.vkCapital ] = "Caps Lock", [const.vkSpace ] = "Space", [const.vkPageup ] = "Pageup", [const.vkPagedown ] = "Pagedown", [const.vkEnd ] = "End", [const.vkHome ] = "Home", [const.vkLeft ] = "Left", [const.vkUp ] = "Up", [const.vkRight ] = "Right", [const.vkDown ] = "Down", [const.vkSnapshot ] = "PrtScr", [const.vkInsert ] = "Insert", [const.vkDelete ] = "Delete", [const.vk0 ] = "0", [const.vk1 ] = "1", [const.vk2 ] = "2", [const.vk3 ] = "3", [const.vk4 ] = "4", [const.vk5 ] = "5", [const.vk6 ] = "6", [const.vk7 ] = "7", [const.vk8 ] = "8", [const.vk9 ] = "9", [const.vkA ] = "A", [const.vkB ] = "B", [const.vkC ] = "C", [const.vkD ] = "D", [const.vkE ] = "E", [const.vkF ] = "F", [const.vkG ] = "G", [const.vkH ] = "H", [const.vkI ] = "I", [const.vkJ ] = "J", [const.vkK ] = "K", [const.vkL ] = "L", [const.vkM ] = "M", [const.vkN ] = "N", [const.vkO ] = "O", [const.vkP ] = "P", [const.vkQ ] = "Q", [const.vkR ] = "R", [const.vkS ] = "S", [const.vkT ] = "T", [const.vkU ] = "U", [const.vkV ] = "V", [const.vkW ] = "W", [const.vkX ] = "X", [const.vkY ] = "Y", [const.vkZ ] = "Z", [const.vkNumpad0 ] = "Numpad 0", [const.vkNumpad1 ] = "Numpad 1", [const.vkNumpad2 ] = "Numpad 2", [const.vkNumpad3 ] = "Numpad 3", [const.vkNumpad4 ] = "Numpad 4", [const.vkNumpad5 ] = "Numpad 5", [const.vkNumpad6 ] = "Numpad 6", [const.vkNumpad7 ] = "Numpad 7", [const.vkNumpad8 ] = "Numpad 8", [const.vkNumpad9 ] = "Numpad 9", [const.vkMultiply ] = "Numpad *", [const.vkAdd ] = "Numpad +", [const.vkNumpadenter] = "Numpad Enter", [const.vkSubtract ] = "Numpad -", [const.vkDecimal ] = "Numpad .", [const.vkDivide ] = "Numpad /", [const.vkF1 ] = "F1", [const.vkF2 ] = "F2", [const.vkF3 ] = "F3", [const.vkF4 ] = "F4", [const.vkF5 ] = "F5", [const.vkF6 ] = "F6", [const.vkF7 ] = "F7", [const.vkF8 ] = "F8", [const.vkF9 ] = "F9", [const.vkF10 ] = "F10", [const.vkF11 ] = "F11", [const.vkF12 ] = "F12", [const.vkNumlock ] = "Num Lock", [const.vkScroll ] = "Scroll Lock", [const.vkPause ] = "Pause", [const.vkLshift ] = "L Shift", [const.vkRshift ] = "R Shift", [const.vkLcontrol ] = "L Ctrl", [const.vkRcontrol ] = "R Ctrl", [const.vkLalt ] = "L Alt", [const.vkRalt ] = "R Alt", [const.vkSemicolon ] = ";", [const.vkEquals ] = "=", [const.vkComma ] = ",", [const.vkMinus ] = "-", [const.vkPlus ] = "+", [const.vkDot ] = ".", [const.vkSlash ] = "/", [const.vkTilde ] = "~", [const.vkOpensq ] = "[", [const.vkBackslash ] = "\\", [const.vkClosesq ] = "]", [const.vkQuote ] = "'", [const.vkLwin or false] = "Lwin", [const.vkRwin or false] = "Rwin", [const.vkApps or false] = "Menu", } VKStrNames[false] = nil MouseVKStrNames = { [const.vkLbutton] = "MouseL", [const.vkRbutton] = "MouseR", [const.vkMbutton] = "MouseM", [const.vkXbutton1] = "MouseX1", [const.vkXbutton2] = "MouseX2", } if Platform.osx then KeyNames[131] = Untranslated(--[[key name]] "Cmd") -- unexported const.vkWin VKStrNames[131] = "Cmd" -- unexported const.vkWin end VKStrNamesInverse = {} for k,v in pairs(VKStrNames) do VKStrNamesInverse[v] = k end MouseVKStrNamesInverse = {} for k,v in pairs(MouseVKStrNames) do MouseVKStrNamesInverse[v] = k end validKeys = {} for k, v in pairs(KeyNames) do validKeys[k] = true end function KbdShortcut(virtual_key) if not VKStrNames[virtual_key] then return -- some keys are not present as const.vk*, e.g. RWIN and APPS end local s = "" if virtual_key == const.vkControl or terminal.IsKeyPressed(const.vkControl) or Platform.osx and terminal.IsKeyPressed(const.vkLwin) then s = s .. "Ctrl-" end if virtual_key == const.vkAlt or terminal.IsKeyPressed(const.vkAlt) then s = s .. "Alt-" end if virtual_key == const.vkShift or terminal.IsKeyPressed(const.vkShift) then s = s .. "Shift-" end if virtual_key == const.vkControl or virtual_key == const.vkAlt or virtual_key == const.vkShift then return s:sub(1, -2) -- remove trailing dash end return s .. VKStrNames[virtual_key] end function XInputShortcut(button, controller_id) local s = "" if button == "LeftTrigger" or XInput.IsCtrlButtonPressed(controller_id, "LeftTrigger") then s = s .. "LeftTrigger-" end if button == "RightTrigger" or XInput.IsCtrlButtonPressed(controller_id, "RightTrigger") then s = s .. "RightTrigger-" end if button == "LeftShoulder" or XInput.IsCtrlButtonPressed(controller_id, "LeftShoulder") then s = s .. "LeftShoulder-" end if button == "RightShoulder" or XInput.IsCtrlButtonPressed(controller_id, "RightShoulder") then s = s .. "RightShoulder-" end if button == "LeftTrigger" or button == "RightTrigger" or button == "LeftShoulder" or button == "RightShoulder" then return s:sub(1, -2) -- remove trailing dash end return s .. button end function MouseShortcut(button) if not button or button == "" then return end local s = "" if terminal.IsKeyPressed(const.vkControl) or Platform.osx and terminal.IsKeyPressed(const.vkLwin) then s = s .. "Ctrl-" end if terminal.IsKeyPressed(const.vkAlt) then s = s .. "Alt-" end if terminal.IsKeyPressed(const.vkShift) then s = s .. "Shift-" end return s .. "Mouse" .. button end if FirstLoad then g_WaitShortcutThread = false end function WaitShortcut() g_WaitShortcutThread = CurrentThread() local win = XWindow:new({ OnKbdKeyUp = function(self, virtual_key) local shortcut = KbdShortcut(virtual_key) if shortcut ~= "Ctrl" and shortcut ~= "Shift" then Wakeup(g_WaitShortcutThread, shortcut) end return "break" end, OnKbdKeyDown = function() return "break" end, OnKbdChar = function() return "break" end, OnKbdIMEStartComposition = function() return "break" end, OnKbdIMEEndComposition = function() return "break" end, OnMouseButtonUp = function(self, pt, button) local shortcut = MouseShortcut(button) Wakeup(g_WaitShortcutThread, shortcut) return "break" end, OnXButtonDown = function(self, button, controller_id) -- allow closing of the keybinding assignment window with a controller Wakeup(g_WaitShortcutThread, "Escape") return "break" end, HandleMouse = true, }, terminal.desktop) win:Open() win:SetModal() win:SetFocus() local success, shortcut = WaitWakeup() g_WaitShortcutThread = false win:Close() return shortcut end local function CancelKeybindingThread() if g_WaitShortcutThread then Wakeup(g_WaitShortcutThread, "Escape") end end -- cancel keybinding assignment when the controller gets disconnected OnMsg.OnXInputControllerDisconnected = CancelKeybindingThread -- cancel keybinding assignment when switching between inputs OnMsg.GamepadUIStyleChanged = CancelKeybindingThread function GetCameraVKCodeFromShortcut(shortcut) return shortcut and (VKStrNamesInverse[shortcut] or MouseVKStrNamesInverse[shortcut]) or -1 end