awesome/lib/awful/keyboard.lua

210 lines
6.1 KiB
Lua
Raw Normal View History

---------------------------------------------------------------------------
--- Utilities related to the keyboard and keybindings.
--
-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
-- @copyright 2018-2019 Emmanuel Lepage Vallee
-- @inputmodule awful.keyboard
---------------------------------------------------------------------------
local capi = {root = root, awesome = awesome, client = client}
local module = {}
--- Convert the modifiers into pc105 key names
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 modifiers A modified table. Valid modifiers are: `Any`, `Mod1`,
-- `Mod2`, `Mod3`, `Mod4`, `Mod5`, `Shift`, `Lock` and `Control`.
-- @tparam string key The key.
-- @staticfct awful.keyboard.emulate_key_combination
function module.emulate_key_combination(modifiers, key)
local modmap = generate_conversion_map()
local active = capi.awesome._active_modifiers
-- Release all modifiers
for _, m in ipairs(active) do
assert(modmap[m])
capi.root.fake_input("key_release", modmap[m])
end
for _, v in ipairs(modifiers) do
local m = modmap[v]
if m then
capi.root.fake_input("key_press", m)
end
end
capi.root.fake_input("key_press" , key)
capi.root.fake_input("key_release", key)
for _, v in ipairs(modifiers) do
local m = modmap[v]
if m then
capi.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
capi.root.fake_input("key_press", modmap[m])
end
end
--- Add an `awful.key` based keybinding to the global set.
--
-- A **global** keybinding is one which is always present, even when there is
-- no focused client. If your intent is too add a keybinding which acts on
-- the focused client do **not** use this.
--
-- @staticfct awful.keyboard.append_global_keybinding
-- @tparam awful.key key The key object.
-- @see awful.key
-- @see awful.keyboard.append_global_keybindings
-- @see awful.keyboard.remove_global_keybinding
function module.append_global_keybinding(key)
capi.root._append_key(key)
end
--- Add multiple `awful.key` based keybindings to the global set.
--
-- A **global** keybinding is one which is always present, even when there is
-- no focused client. If your intent is too add a keybinding which acts on
-- the focused client do **not** use this
--
-- @tparam table keys A table of `awful.key` objects. Optionally, it can have
-- a `group` entry. If set, the `group` property will be set on all `awful.keys`
-- objects.
-- @see awful.key
-- @see awful.keyboard.append_global_keybinding
-- @see awful.keyboard.remove_global_keybinding
function module.append_global_keybindings(keys)
local g = keys.group
keys.group = nil
-- Avoid the boilerplate. If the user is adding multiple keys at once, then
-- they are probably related.
if g then
for _, k in ipairs(keys) do
k.group = g
end
end
capi.root._append_keys(keys)
keys.group = g
end
--- Remove a keybinding from the global set.
--
-- @staticfct awful.keyboard.remove_global_keybinding
-- @tparam awful.key key The key object.
-- @see awful.key
-- @see awful.keyboard.append_global_keybinding
function module.remove_global_keybinding(key)
capi.root._remove_key(key)
end
local default_keys = {}
--- Add an `awful.key` to the default client keys.
--
-- @staticfct awful.keyboard.append_client_keybinding
-- @tparam awful.key key The key.
-- @emits client_keybinding::added
-- @emitstparam client_keybinding::added awful.key key The key.
-- @see awful.key
-- @see awful.keyboard.append_client_keybindings
function module.append_client_keybinding(key)
table.insert(default_keys, key)
for _, c in ipairs(capi.client.get(nil, false)) do
c:append_keybinding(key)
end
capi.client.emit_signal("client_keybinding::added", key)
end
--- Add a `awful.key`s to the default client keys.
--
-- @staticfct awful.keyboard.append_client_keybindings
-- @tparam table keys A table containing `awful.key` objects.
-- @emits client_keybinding::added
-- @emitstparam client_keybinding::added awful.key key The key.
-- @see awful.key
-- @see awful.keyboard.append_client_keybinding
function module.append_client_keybindings(keys)
for _, key in ipairs(keys) do
module.append_client_keybinding(key)
end
end
--- Remove a key from the default client keys.
--
-- @staticfct awful.keyboard.remove_client_keybinding
-- @tparam awful.key key The key.
-- @treturn boolean True if the key was removed and false if it wasn't found.
-- @see awful.keyboard.append_client_keybinding
function module.remove_client_keybinding(key)
for k, v in ipairs(default_keys) do
if key == v then
table.remove(default_keys, k)
for _, c in ipairs(capi.client.get(nil, false)) do
c:remove_keybinding(key)
end
return true
end
end
return false
end
capi.client.connect_signal("scanning", function()
capi.client.emit_signal("request::default_keybindings", "context")
end)
-- Private function to be used by `ruled.client`.
function module._get_client_keybindings()
return default_keys
end
return module