awful.key: Turn into an object.
This commit is contained in:
parent
3b5db8a9be
commit
21ae9c1edb
|
@ -2,7 +2,8 @@
|
|||
--- Create easily new key objects ignoring certain modifiers.
|
||||
--
|
||||
-- @author Julien Danjou <julien@danjou.info>
|
||||
-- @copyright 2009 Julien Danjou
|
||||
-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
|
||||
-- @copyright 2018 Emmanuel Lepage Vallee
|
||||
-- @inputmodule awful.key
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
@ -14,10 +15,148 @@ local gmath = require("gears.math")
|
|||
local gtable = require("gears.table")
|
||||
local gdebug = require("gears.debug")
|
||||
|
||||
--- The keyboard key used to trigger this keybinding.
|
||||
--
|
||||
-- It can be the key symbol, such as `space`, the character, such as ` ` or the
|
||||
-- keycode such as `#65`.
|
||||
--
|
||||
-- @property key
|
||||
-- @param string
|
||||
|
||||
--- The table of modifier keys.
|
||||
--
|
||||
-- A modifier, such as `Control` are a predetermined set of keys that can be
|
||||
-- used to implement keybindings. Note that this list is fix and cannot be
|
||||
-- extended using random key names, code or characters.
|
||||
--
|
||||
-- Common modifiers are:
|
||||
--
|
||||
-- <table class='widget_list' border=1>
|
||||
-- <tr style='font-weight: bold;'>
|
||||
-- <th align='center'>Name</th>
|
||||
-- <th align='center'>Description</th>
|
||||
-- </tr>
|
||||
-- <tr><td>Mod1</td><td>Usually called Alt on PCs and Option on Macs</td></tr>
|
||||
-- <tr><td>Mod4</td><td>Also called Super, Windows and Command ⌘</td></tr>
|
||||
-- <tr><td>Mod5</td><td>Also called AltGr or ISO Level 3</td></tr>
|
||||
-- <tr><td>Shift</td><td>Both left and right shift keys</td></tr>
|
||||
-- <tr><td>Control</td><td>Also called CTRL on some keyboards</td></tr>
|
||||
-- </table>
|
||||
--
|
||||
-- Please note that Awesome ignores the status of "Lock" and "Mod2" (Num Lock).
|
||||
--
|
||||
-- @property modifiers
|
||||
-- @tparam table modifiers
|
||||
|
||||
--- The key description.
|
||||
--
|
||||
-- This is used, for example, by the `awful.hotkey_popup`.
|
||||
--
|
||||
-- @property description
|
||||
-- @param string
|
||||
|
||||
--- The key name.
|
||||
--
|
||||
-- This can be useful when searching for keybindings by keywords.
|
||||
--
|
||||
-- @property name
|
||||
-- @param string
|
||||
|
||||
--- The key group.
|
||||
--
|
||||
-- This is used, for example, by the `awful.hotkey_popup`.
|
||||
--
|
||||
-- @property group
|
||||
-- @param string
|
||||
|
||||
--- The callback when this key is pressed.
|
||||
--
|
||||
-- @property on_press
|
||||
-- @param function
|
||||
|
||||
--- The callback when this key is released.
|
||||
--
|
||||
-- @property on_release
|
||||
-- @param function
|
||||
|
||||
local key = { mt = {}, hotkeys = {} }
|
||||
|
||||
local reverse_map = setmetatable({}, {__mode="k"})
|
||||
|
||||
function key:set_key(k)
|
||||
for _, v in ipairs(self) do
|
||||
v.key = k
|
||||
end
|
||||
end
|
||||
|
||||
function key:get_key()
|
||||
return self[1].key
|
||||
end
|
||||
|
||||
function key:set_modifiers(mod)
|
||||
local subsets = gmath.subsets(key.ignore_modifiers)
|
||||
for k, set in ipairs(subsets) do
|
||||
self[k].modifiers = gtable.join(mod, set)
|
||||
end
|
||||
end
|
||||
|
||||
for _, prop in ipairs { "description", "group", "on_press", "on_release", "name" } do
|
||||
key["get_"..prop] = function(self)
|
||||
return reverse_map[self][prop]
|
||||
end
|
||||
key["set_"..prop] = function(self, value)
|
||||
reverse_map[self][prop] = value
|
||||
end
|
||||
end
|
||||
|
||||
--- Execute this keybinding.
|
||||
--
|
||||
-- @method :trigger
|
||||
|
||||
function key:trigger()
|
||||
local data = reverse_map[self]
|
||||
if data.on_press then
|
||||
data.on_press()
|
||||
end
|
||||
|
||||
if data.on_release then
|
||||
data.on_release()
|
||||
end
|
||||
end
|
||||
|
||||
local function index_handler(self, k)
|
||||
if key["get_"..k] then
|
||||
return key["get_"..k](self)
|
||||
end
|
||||
|
||||
if type(key[k]) == "function" then
|
||||
return key[k](self)
|
||||
end
|
||||
|
||||
local data = reverse_map[self]
|
||||
assert(data)
|
||||
|
||||
return data[k]
|
||||
end
|
||||
|
||||
local function newindex_handler(self, k, value)
|
||||
if key["set_"..k] then
|
||||
return key["set_"..k](self, value)
|
||||
end
|
||||
|
||||
local data = reverse_map[self]
|
||||
assert(data)
|
||||
|
||||
data[k] = value
|
||||
end
|
||||
|
||||
local obj_mt = {
|
||||
__index = index_handler,
|
||||
__newindex = newindex_handler
|
||||
}
|
||||
|
||||
--- 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
|
||||
-- when pressing keys.
|
||||
-- @name awful.key.ignore_modifiers
|
||||
|
@ -46,30 +185,37 @@ function key.execute(mod, k)
|
|||
require("awful.keyboard").emulate_key_combination(mod, k)
|
||||
end
|
||||
|
||||
--- Create a new key to use as binding.
|
||||
-- This function is useful to create several keys from one, because it will use
|
||||
-- the ignore_modifier variable to create several keys with and without the
|
||||
-- ignored modifiers activated.
|
||||
-- For example if you want to ignore CapsLock in your keybinding (which is
|
||||
-- ignored by default by this function), creating a key binding with this
|
||||
-- function will return 2 key objects: one with CapsLock on, and another one
|
||||
-- with CapsLock off.
|
||||
--- Create a new key binding.
|
||||
--
|
||||
-- @tparam table mod A list of modifier keys. Valid modifiers are: Any, Mod1,
|
||||
-- Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control.
|
||||
-- @tparam string _key The key to trigger an event.
|
||||
-- @constructorfct2 awful.key
|
||||
-- @tparam table args
|
||||
-- @tparam function args.key The key to trigger an event. It can be the character
|
||||
-- itself of `#+keycode` (**mandatory**).
|
||||
-- @tparam function args.modifiers A list of modifier keys. Valid modifiers are:
|
||||
-- `Any`, `Mod1`, Mod2`, `Mod3`, `Mod4`, `Mod5`, `Shift`, `Lock` and `Control`.
|
||||
-- This argument is (**mandatory**).
|
||||
-- @tparam function args.on_press Callback for when the key is pressed.
|
||||
-- @tparam function args.on_release Callback for when the key is released.
|
||||
|
||||
--- Create a new key binding (alternate constructor).
|
||||
--
|
||||
-- @tparam table mod A list of modifier keys. Valid modifiers are: `Any`,
|
||||
-- `Mod1`, `Mod2`, `Mod3`, `Mod4`, `Mod5`, `Shift`, `Lock` and `Control`.
|
||||
-- @tparam string _key The key to trigger an event. It can be the character
|
||||
-- itself of `#+keycode`.
|
||||
-- @tparam function press Callback for when the key is pressed.
|
||||
-- @tparam[opt] function release Callback for when the key is released.
|
||||
-- @tparam table data User data for key,
|
||||
-- @tparam[opt] table data User data for key,
|
||||
-- for example {description="select next tag", group="tag"}.
|
||||
-- @treturn table A table with one or several key objects.
|
||||
-- @constructorfct awful.key
|
||||
|
||||
function key.new(mod, _key, press, release, data)
|
||||
local function new_common(mod, _key, press, release, data)
|
||||
if type(release)=='table' then
|
||||
data=release
|
||||
release=nil
|
||||
end
|
||||
|
||||
local ret = {}
|
||||
local subsets = gmath.subsets(key.ignore_modifiers)
|
||||
for _, set in ipairs(subsets) do
|
||||
|
@ -87,12 +233,36 @@ function key.new(mod, _key, press, release, data)
|
|||
data = data and gtable.clone(data) or {}
|
||||
data.mod = mod
|
||||
data.key = _key
|
||||
data.press = press
|
||||
data.release = release
|
||||
data.on_press = press
|
||||
data.on_release = release
|
||||
data._is_capi_key = false
|
||||
table.insert(key.hotkeys, data)
|
||||
data.execute = function(_) key.execute(mod, _key) end
|
||||
|
||||
return ret
|
||||
-- Store the private data
|
||||
reverse_map[ret] = data
|
||||
|
||||
--WARNING this object needs to expose only ordered keys for legacy reasons.
|
||||
-- All other properties needs to be fully handled by the meta table and never
|
||||
-- be stored directly in the object.
|
||||
|
||||
return setmetatable(ret, obj_mt)
|
||||
end
|
||||
|
||||
function key.new(args, _key, press, release, data)
|
||||
-- Assume this is the new constructor.
|
||||
if not _key then
|
||||
assert(not (press or release or data), "Calling awful.key() requires a key name")
|
||||
return new_common(
|
||||
args.modifiers,
|
||||
args.key,
|
||||
args.on_press,
|
||||
args.on_release,
|
||||
args
|
||||
)
|
||||
else
|
||||
return new_common(args, _key, press, release, data)
|
||||
end
|
||||
end
|
||||
|
||||
--- Compare a key object with modifiers and key.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
_G.key = setmetatable({
|
||||
set_index_miss_handler = function() end,
|
||||
set_newindex_miss_handler = function() end
|
||||
}, {
|
||||
__call = function() return {} end
|
||||
})
|
||||
|
||||
local function assert_markup_format(markup)
|
||||
if #markup == 0 then
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue