keygrabber: Do not try to guess the modifiers name
There is no an API to query the correct value Fixes #2515
This commit is contained in:
parent
b466db955f
commit
0d80b3f0e9
|
@ -9,15 +9,12 @@
|
|||
-- Grab environment we need
|
||||
local setmetatable = setmetatable
|
||||
local ipairs = ipairs
|
||||
local capi = { key = key, root = root }
|
||||
local capi = { key = key, root = root, awesome = awesome }
|
||||
local gmath = require("gears.math")
|
||||
local gtable = require("gears.table")
|
||||
|
||||
|
||||
|
||||
local key = { mt = {}, hotkeys = {} }
|
||||
|
||||
|
||||
--- Modifiers to ignore.
|
||||
-- By default this is initialized as { "Lock", "Mod2" }
|
||||
-- so the Caps Lock or Num Lock modifier are not taking into account by awesome
|
||||
|
@ -27,23 +24,53 @@ local key = { mt = {}, hotkeys = {} }
|
|||
key.ignore_modifiers = { "Lock", "Mod2" }
|
||||
|
||||
--- Convert the modifiers into pc105 key names
|
||||
local conversion = {
|
||||
mod4 = "Super_L",
|
||||
control = "Control_L",
|
||||
shift = "Shift_L",
|
||||
mod1 = "Alt_L",
|
||||
}
|
||||
local conversion = nil
|
||||
|
||||
local function generate_conversion_map()
|
||||
if conversion then return conversion end
|
||||
|
||||
local mods = capi.awesome._modifiers
|
||||
assert(mods)
|
||||
|
||||
conversion = {}
|
||||
|
||||
for mod, keysyms in pairs(mods) do
|
||||
for _, keysym in ipairs(keysyms) do
|
||||
assert(keysym.keysym)
|
||||
conversion[mod] = conversion[mod] or keysym.keysym
|
||||
conversion[keysym.keysym] = mod
|
||||
end
|
||||
end
|
||||
|
||||
return conversion
|
||||
end
|
||||
|
||||
capi.awesome.connect_signal("xkb::map_changed" , function() conversion = nil end)
|
||||
|
||||
--- Execute a key combination.
|
||||
-- If an awesome keybinding is assigned to the combination, it should be
|
||||
-- executed.
|
||||
--
|
||||
-- To limit the chances of accidentally leaving a modifier key locked when
|
||||
-- calling this function from a keybinding, make sure is attached to the
|
||||
-- release event and not the press event.
|
||||
--
|
||||
-- @see root.fake_input
|
||||
-- @tparam table mod A modified table. Valid modifiers are: Any, Mod1,
|
||||
-- Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control.
|
||||
-- @tparam string k The key
|
||||
function key.execute(mod, k)
|
||||
local modmap = generate_conversion_map()
|
||||
local active = capi.awesome._active_modifiers
|
||||
|
||||
-- Release all modifiers
|
||||
for _, m in ipairs(active) do
|
||||
assert(modmap[m])
|
||||
root.fake_input("key_release", modmap[m])
|
||||
end
|
||||
|
||||
for _, v in ipairs(mod) do
|
||||
local m = conversion[v:lower()]
|
||||
local m = modmap[v]
|
||||
if m then
|
||||
root.fake_input("key_press", m)
|
||||
end
|
||||
|
@ -53,11 +80,18 @@ function key.execute(mod, k)
|
|||
root.fake_input("key_release", k)
|
||||
|
||||
for _, v in ipairs(mod) do
|
||||
local m = conversion[v:lower()]
|
||||
local m = modmap[v]
|
||||
if m then
|
||||
root.fake_input("key_release", m)
|
||||
end
|
||||
end
|
||||
|
||||
-- Restore the previous modifiers all modifiers. Please note that yes,
|
||||
-- there is a race condition if the user was fast enough to release the
|
||||
-- key during this operation.
|
||||
for _, m in ipairs(active) do
|
||||
root.fake_input("key_press", modmap[m])
|
||||
end
|
||||
end
|
||||
|
||||
--- Create a new key to use as binding.
|
||||
|
|
|
@ -72,7 +72,7 @@ local gtable = require("gears.table")
|
|||
local gobject = require("gears.object")
|
||||
local gtimer = require("gears.timer")
|
||||
local glib = require("lgi").GLib
|
||||
local capi = { keygrabber = keygrabber, root = root }
|
||||
local capi = { keygrabber = keygrabber, root = root, awesome = awesome }
|
||||
|
||||
local keygrab = {}
|
||||
|
||||
|
@ -85,17 +85,7 @@ local keygrabber = {
|
|||
}
|
||||
|
||||
-- Instead of checking for every modifiers, check the key directly.
|
||||
--FIXME This is slightly broken but still good enough for `mask_modkeys`
|
||||
local conversion = {
|
||||
Super_L = "Mod4",
|
||||
Control_L = "Control",
|
||||
Shift_L = "Shift",
|
||||
Alt_L = "Mod1",
|
||||
Super_R = "Mod4",
|
||||
Control_R = "Control",
|
||||
Shift_R = "Shift",
|
||||
Alt_R = "Mod1",
|
||||
}
|
||||
local conversion = nil
|
||||
|
||||
--BEGIN one day create a proper API to add and remove keybindings at runtime.
|
||||
-- Doing it this way is horrible.
|
||||
|
@ -103,6 +93,27 @@ local conversion = {
|
|||
-- This list of keybindings to add in the next event loop cycle.
|
||||
local delay_list = {}
|
||||
|
||||
-- Read the modifiers name and map their keysyms to the modkeys
|
||||
local function generate_conversion_map()
|
||||
if conversion then return conversion end
|
||||
|
||||
local mods = capi.awesome._modifiers
|
||||
assert(mods)
|
||||
|
||||
conversion = {}
|
||||
|
||||
for mod, keysyms in pairs(mods) do
|
||||
for _, keysym in ipairs(keysyms) do
|
||||
assert(keysym.keysym)
|
||||
conversion[keysym.keysym] = mod
|
||||
end
|
||||
end
|
||||
|
||||
return conversion
|
||||
end
|
||||
|
||||
capi.awesome.connect_signal("xkb::map_changed" , function() conversion = nil end)
|
||||
|
||||
local function add_root_keybindings(self, list)
|
||||
assert(
|
||||
list, "`add_root_keybindings` needs to be called with a list of keybindings"
|
||||
|
@ -168,9 +179,11 @@ local function grabber(mod, key, event)
|
|||
end
|
||||
|
||||
local function runner(self, modifiers, key, event)
|
||||
local converted = generate_conversion_map()[key]
|
||||
|
||||
-- Stop the keygrabber with the `stop_key`
|
||||
if key == self.stop_key
|
||||
and event == self.stop_event and self.stop_key then
|
||||
if (key == self.stop_key or (converted and converted == self.stop_key))
|
||||
and event == self.stop_event and self.stop_key then
|
||||
self:stop(key, modifiers)
|
||||
return false
|
||||
end
|
||||
|
@ -191,7 +204,7 @@ local function runner(self, modifiers, key, event)
|
|||
end
|
||||
end
|
||||
|
||||
local is_modifier = conversion[key] ~= nil
|
||||
local is_modifier = converted ~= nil
|
||||
|
||||
-- Reset the inactivity timer on each events.
|
||||
if self._private.timer and self._private.timer.started then
|
||||
|
|
Loading…
Reference in New Issue