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
|
-- Grab environment we need
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
local ipairs = ipairs
|
local ipairs = ipairs
|
||||||
local capi = { key = key, root = root }
|
local capi = { key = key, root = root, awesome = awesome }
|
||||||
local gmath = require("gears.math")
|
local gmath = require("gears.math")
|
||||||
local gtable = require("gears.table")
|
local gtable = require("gears.table")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local key = { mt = {}, hotkeys = {} }
|
local key = { mt = {}, hotkeys = {} }
|
||||||
|
|
||||||
|
|
||||||
--- Modifiers to ignore.
|
--- Modifiers to ignore.
|
||||||
-- By default this is initialized as { "Lock", "Mod2" }
|
-- By default this is initialized as { "Lock", "Mod2" }
|
||||||
-- so the Caps Lock or Num Lock modifier are not taking into account by awesome
|
-- 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" }
|
key.ignore_modifiers = { "Lock", "Mod2" }
|
||||||
|
|
||||||
--- Convert the modifiers into pc105 key names
|
--- Convert the modifiers into pc105 key names
|
||||||
local conversion = {
|
local conversion = nil
|
||||||
mod4 = "Super_L",
|
|
||||||
control = "Control_L",
|
local function generate_conversion_map()
|
||||||
shift = "Shift_L",
|
if conversion then return conversion end
|
||||||
mod1 = "Alt_L",
|
|
||||||
}
|
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.
|
--- Execute a key combination.
|
||||||
-- If an awesome keybinding is assigned to the combination, it should be
|
-- If an awesome keybinding is assigned to the combination, it should be
|
||||||
-- executed.
|
-- 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
|
-- @see root.fake_input
|
||||||
-- @tparam table mod A modified table. Valid modifiers are: Any, Mod1,
|
-- @tparam table mod A modified table. Valid modifiers are: Any, Mod1,
|
||||||
-- Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control.
|
-- Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control.
|
||||||
-- @tparam string k The key
|
-- @tparam string k The key
|
||||||
function key.execute(mod, k)
|
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
|
for _, v in ipairs(mod) do
|
||||||
local m = conversion[v:lower()]
|
local m = modmap[v]
|
||||||
if m then
|
if m then
|
||||||
root.fake_input("key_press", m)
|
root.fake_input("key_press", m)
|
||||||
end
|
end
|
||||||
|
@ -53,11 +80,18 @@ function key.execute(mod, k)
|
||||||
root.fake_input("key_release", k)
|
root.fake_input("key_release", k)
|
||||||
|
|
||||||
for _, v in ipairs(mod) do
|
for _, v in ipairs(mod) do
|
||||||
local m = conversion[v:lower()]
|
local m = modmap[v]
|
||||||
if m then
|
if m then
|
||||||
root.fake_input("key_release", m)
|
root.fake_input("key_release", m)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
--- Create a new key to use as binding.
|
--- Create a new key to use as binding.
|
||||||
|
|
|
@ -72,7 +72,7 @@ local gtable = require("gears.table")
|
||||||
local gobject = require("gears.object")
|
local gobject = require("gears.object")
|
||||||
local gtimer = require("gears.timer")
|
local gtimer = require("gears.timer")
|
||||||
local glib = require("lgi").GLib
|
local glib = require("lgi").GLib
|
||||||
local capi = { keygrabber = keygrabber, root = root }
|
local capi = { keygrabber = keygrabber, root = root, awesome = awesome }
|
||||||
|
|
||||||
local keygrab = {}
|
local keygrab = {}
|
||||||
|
|
||||||
|
@ -85,17 +85,7 @@ local keygrabber = {
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Instead of checking for every modifiers, check the key directly.
|
-- Instead of checking for every modifiers, check the key directly.
|
||||||
--FIXME This is slightly broken but still good enough for `mask_modkeys`
|
local conversion = nil
|
||||||
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",
|
|
||||||
}
|
|
||||||
|
|
||||||
--BEGIN one day create a proper API to add and remove keybindings at runtime.
|
--BEGIN one day create a proper API to add and remove keybindings at runtime.
|
||||||
-- Doing it this way is horrible.
|
-- Doing it this way is horrible.
|
||||||
|
@ -103,6 +93,27 @@ local conversion = {
|
||||||
-- This list of keybindings to add in the next event loop cycle.
|
-- This list of keybindings to add in the next event loop cycle.
|
||||||
local delay_list = {}
|
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)
|
local function add_root_keybindings(self, list)
|
||||||
assert(
|
assert(
|
||||||
list, "`add_root_keybindings` needs to be called with a list of keybindings"
|
list, "`add_root_keybindings` needs to be called with a list of keybindings"
|
||||||
|
@ -168,8 +179,10 @@ local function grabber(mod, key, event)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function runner(self, modifiers, key, event)
|
local function runner(self, modifiers, key, event)
|
||||||
|
local converted = generate_conversion_map()[key]
|
||||||
|
|
||||||
-- Stop the keygrabber with the `stop_key`
|
-- Stop the keygrabber with the `stop_key`
|
||||||
if key == self.stop_key
|
if (key == self.stop_key or (converted and converted == self.stop_key))
|
||||||
and event == self.stop_event and self.stop_key then
|
and event == self.stop_event and self.stop_key then
|
||||||
self:stop(key, modifiers)
|
self:stop(key, modifiers)
|
||||||
return false
|
return false
|
||||||
|
@ -191,7 +204,7 @@ local function runner(self, modifiers, key, event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local is_modifier = conversion[key] ~= nil
|
local is_modifier = converted ~= nil
|
||||||
|
|
||||||
-- Reset the inactivity timer on each events.
|
-- Reset the inactivity timer on each events.
|
||||||
if self._private.timer and self._private.timer.started then
|
if self._private.timer and self._private.timer.started then
|
||||||
|
|
Loading…
Reference in New Issue