Allow to add and remove keys and buttons.
Another step in moving these APIs toward the common object oriented and declarative paradigms used by other APIs. This commit introduces the `awful.keyboard` module. It currenly only exists as a placeholder for the first few append/remove function, but will grow in scope in another pull request to expose the currently private modifier APIs and to provide keybindings collision detection and replace some of `awful.hotkey_popup` business logic. The `keygrabber` tests which uses root keybindings are disabled for now to keep the commit size small. This is necessary since the shims will need many iterations of changes before this work again with the new syntax.
This commit is contained in:
parent
4dbc83fa7d
commit
4501f0e768
|
@ -77,4 +77,4 @@ gprop._legacy_accessors(capi.root, "keys", "_keys", false, function(new_btns)
|
||||||
) or false
|
) or false
|
||||||
end, true)
|
end, true)
|
||||||
|
|
||||||
assert(root.keys)
|
require("awful.root")
|
||||||
|
|
|
@ -24,6 +24,7 @@ return
|
||||||
mouse = require("awful.mouse");
|
mouse = require("awful.mouse");
|
||||||
remote = require("awful.remote");
|
remote = require("awful.remote");
|
||||||
key = require("awful.key");
|
key = require("awful.key");
|
||||||
|
keyboard = require("awful.keyboard");
|
||||||
button = require("awful.button");
|
button = require("awful.button");
|
||||||
wibar = require("awful.wibar");
|
wibar = require("awful.wibar");
|
||||||
wibox = require("awful.wibox");
|
wibox = require("awful.wibox");
|
||||||
|
|
|
@ -12,6 +12,7 @@ local ipairs = ipairs
|
||||||
local capi = { key = key, root = root, awesome = awesome }
|
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 gdebug = require("gears.debug")
|
||||||
|
|
||||||
local key = { mt = {}, hotkeys = {} }
|
local key = { mt = {}, hotkeys = {} }
|
||||||
|
|
||||||
|
@ -23,30 +24,6 @@ local key = { mt = {}, hotkeys = {} }
|
||||||
-- @class table
|
-- @class table
|
||||||
key.ignore_modifiers = { "Lock", "Mod2" }
|
key.ignore_modifiers = { "Lock", "Mod2" }
|
||||||
|
|
||||||
--- 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.
|
--- 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.
|
||||||
|
@ -59,40 +36,14 @@ capi.awesome.connect_signal("xkb::map_changed" , function() conversion = nil en
|
||||||
-- @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
|
||||||
-- @staticfct awful.key.execute
|
-- @deprecated awful.key.execute
|
||||||
function key.execute(mod, k)
|
function key.execute(mod, k)
|
||||||
local modmap = generate_conversion_map()
|
gdebug.deprecate("Use `awful.keyboard.emulate_key_combination` or "..
|
||||||
local active = capi.awesome._active_modifiers
|
"`my_key:trigger()` instead of `awful.key.execute()`",
|
||||||
|
{deprecated_in=5}
|
||||||
|
)
|
||||||
|
|
||||||
-- Release all modifiers
|
require("awful.keyboard").emulate_key_combination(mod, k)
|
||||||
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 = modmap[v]
|
|
||||||
if m then
|
|
||||||
root.fake_input("key_press", m)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
root.fake_input("key_press" , k)
|
|
||||||
root.fake_input("key_release", k)
|
|
||||||
|
|
||||||
for _, v in ipairs(mod) do
|
|
||||||
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
|
end
|
||||||
|
|
||||||
--- Create a new key to use as binding.
|
--- Create a new key to use as binding.
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
--- 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}
|
||||||
|
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
|
||||||
|
|
||||||
|
return module
|
|
@ -370,6 +370,57 @@ end
|
||||||
-- @property is_middle_mouse_button_pressed
|
-- @property is_middle_mouse_button_pressed
|
||||||
-- @param boolean
|
-- @param boolean
|
||||||
|
|
||||||
|
--- Add an `awful.button` based mousebinding to the global set.
|
||||||
|
--
|
||||||
|
-- A **global** mousebinding is one which is always present, even when there is
|
||||||
|
-- no focused client. If your intent is too add a mousebinding which acts on
|
||||||
|
-- the focused client do **not** use this.
|
||||||
|
--
|
||||||
|
-- @staticfct awful.mouse.append_global_mousebinding
|
||||||
|
-- @tparam awful.button button The button object.
|
||||||
|
-- @see awful.button
|
||||||
|
|
||||||
|
function mouse.append_global_mousebinding(button)
|
||||||
|
capi.root._append_button(button)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add multiple `awful.button` based mousebindings to the global set.
|
||||||
|
--
|
||||||
|
-- A **global** mousebinding is one which is always present, even when there is
|
||||||
|
-- no focused client. If your intent is too add a mousebinding which acts on
|
||||||
|
-- the focused client do **not** use this
|
||||||
|
--
|
||||||
|
-- @tparam table buttons A table of `awful.button` objects. Optionally, it can have
|
||||||
|
-- a `group` entry. If set, the `group` property will be set on all `awful.buttons`
|
||||||
|
-- objects.
|
||||||
|
-- @see awful.button
|
||||||
|
|
||||||
|
function mouse.append_global_mousebindings(buttons)
|
||||||
|
local g = buttons.group
|
||||||
|
buttons.group = nil
|
||||||
|
|
||||||
|
-- Avoid the boilerplate. If the user is adding multiple buttons at once, then
|
||||||
|
-- they are probably related.
|
||||||
|
if g then
|
||||||
|
for _, k in ipairs(buttons) do
|
||||||
|
k.group = g
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
capi.root._append_buttons(buttons)
|
||||||
|
buttons.group = g
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove a mousebinding from the global set.
|
||||||
|
--
|
||||||
|
-- @staticfct awful.mouse.remove_global_mousebinding
|
||||||
|
-- @tparam awful.button button The button object.
|
||||||
|
-- @see awful.button
|
||||||
|
|
||||||
|
function mouse.remove_global_mousebinding(button)
|
||||||
|
capi.root._remove_button(button)
|
||||||
|
end
|
||||||
|
|
||||||
for _, b in ipairs {"left", "right", "middle"} do
|
for _, b in ipairs {"left", "right", "middle"} do
|
||||||
mouse.object["is_".. b .."_mouse_button_pressed"] = function()
|
mouse.object["is_".. b .."_mouse_button_pressed"] = function()
|
||||||
return capi.mouse.coords().buttons[1]
|
return capi.mouse.coords().buttons[1]
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- @author Emmanuel Lepage-Vallee <elv1313@gmail.com>
|
||||||
|
-- @copyright 2018-2019 Emmanuel Lepage-Vallee
|
||||||
|
-- @module root
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local capi = { root = root }
|
||||||
|
local gtable = require("gears.table")
|
||||||
|
local gtimer = require("gears.timer")
|
||||||
|
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
||||||
|
|
||||||
|
for _, type_name in ipairs { "button", "key" } do
|
||||||
|
local prop_name = type_name.."s"
|
||||||
|
|
||||||
|
-- The largest amount of wall clock time when loading Awesome 3.4 rc.lua
|
||||||
|
-- was the awful.util.table.join (now gears.table.join). While the main
|
||||||
|
-- bottleneck in the newer releases moved into LGI, doing all these `join`
|
||||||
|
-- slow startup down quite a lot. On top of that, with the ability to add
|
||||||
|
-- and remove keys and buttons can cause a large overhead of its own. To
|
||||||
|
-- mitigate that, only set the actual content once per main loop iteration.
|
||||||
|
--
|
||||||
|
-- The C code also delay uploading these keys into the X server to prevent
|
||||||
|
-- too many keyboard map changes from freezing Awesome.
|
||||||
|
local has_delayed, added, removed = false, {}, {}
|
||||||
|
|
||||||
|
local function delay(value)
|
||||||
|
if value then
|
||||||
|
table.insert(added, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
if has_delayed then return end
|
||||||
|
|
||||||
|
has_delayed = true
|
||||||
|
|
||||||
|
gtimer.delayed_call(function()
|
||||||
|
local new_values = capi.root["_"..prop_name]()
|
||||||
|
|
||||||
|
-- In theory, because they are inserted ordered, it is safe to assume
|
||||||
|
-- the once found, the capi.key/button will be next to each other.
|
||||||
|
for _, v in ipairs(removed) do
|
||||||
|
local idx = gtable.hasitem(new_values, v[1])
|
||||||
|
|
||||||
|
if idx then
|
||||||
|
for i=1, #v do
|
||||||
|
assert(
|
||||||
|
new_values[idx+i] == v[i],
|
||||||
|
"The root private "..type_name.." table is corrupted"
|
||||||
|
)
|
||||||
|
|
||||||
|
table.remove(new_values, idx+i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
idx = gtable.hasitem(added, v)
|
||||||
|
|
||||||
|
if idx then
|
||||||
|
table.remove(added, idx)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local joined = gtable.join(unpack(added))
|
||||||
|
new_values = gtable.merge(new_values, joined)
|
||||||
|
|
||||||
|
capi.root["_"..prop_name](new_values)
|
||||||
|
|
||||||
|
has_delayed, added, removed = false, {}, {}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
capi.root["_append_"..type_name] = function(value)
|
||||||
|
if not value then return end
|
||||||
|
|
||||||
|
local t1 = capi.root._private[prop_name]
|
||||||
|
|
||||||
|
-- Simple case
|
||||||
|
if (not t1) or not next(t1) then
|
||||||
|
capi.root[prop_name] = {value}
|
||||||
|
assert(capi.root._private[prop_name])
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
delay(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
capi.root["_append_"..prop_name] = function(values)
|
||||||
|
-- It's pointless to use gears.table.merge, in the background it has the
|
||||||
|
-- same loop anyway. Also, this isn't done very often.
|
||||||
|
for _, value in ipairs(values) do
|
||||||
|
capi.root["_append_"..type_name](value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
capi.root["_remove_"..type_name] = function(value)
|
||||||
|
if not capi.root._private[prop_name] then return end
|
||||||
|
|
||||||
|
local k = gtable.hasitem(capi.root._private[prop_name], value)
|
||||||
|
|
||||||
|
if k then
|
||||||
|
table.remove(capi.root._private[prop_name], k)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Because of the legacy API, it is possible the capi.key/buttons will
|
||||||
|
-- be in the formatted table but not of the awful.key/button one.
|
||||||
|
assert(value[1])
|
||||||
|
|
||||||
|
table.insert(removed, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(root[prop_name])
|
||||||
|
|
||||||
|
end
|
|
@ -1,41 +1,41 @@
|
||||||
--DOC_HEADER --DOC_NO_USAGE
|
-- --DOC_HEADER --DOC_NO_USAGE
|
||||||
|
--
|
||||||
local was_called = {} --DOC_HIDE
|
-- local was_called = {} --DOC_HIDE
|
||||||
|
--
|
||||||
local awful = {keygrabber = require("awful.keygrabber"), --DOC_HIDE
|
-- local awful = {keygrabber = require("awful.keygrabber"), --DOC_HIDE
|
||||||
client={focus={history={--DOC_HIDE
|
-- client={focus={history={--DOC_HIDE
|
||||||
disable_tracking = function() was_called[1] = true end, --DOC_HIDE
|
-- disable_tracking = function() was_called[1] = true end, --DOC_HIDE
|
||||||
enable_tracking = function() was_called[2] = true end, --DOC_HIDE
|
-- enable_tracking = function() was_called[2] = true end, --DOC_HIDE
|
||||||
select_next = function() was_called[3] = true end, --DOC_HIDE
|
-- select_next = function() was_called[3] = true end, --DOC_HIDE
|
||||||
select_previous = function() was_called[4] = true end, --DOC_HIDE
|
-- select_previous = function() was_called[4] = true end, --DOC_HIDE
|
||||||
}}}}--DOC_HIDE
|
-- }}}}--DOC_HIDE
|
||||||
|
--
|
||||||
awful.keygrabber {
|
-- awful.keygrabber {
|
||||||
keybindings = {
|
-- keybindings = {
|
||||||
{{"Mod1" }, "Tab", awful.client.focus.history.select_previous},
|
-- {{"Mod1" }, "Tab", awful.client.focus.history.select_previous},
|
||||||
{{"Mod1", "Shift"}, "Tab", awful.client.focus.history.select_next },
|
-- {{"Mod1", "Shift"}, "Tab", awful.client.focus.history.select_next },
|
||||||
},
|
-- },
|
||||||
-- Note that it is using the key name and not the modifier name.
|
-- -- Note that it is using the key name and not the modifier name.
|
||||||
stop_key = "Mod1",
|
-- stop_key = "Mod1",
|
||||||
stop_event = "release",
|
-- stop_event = "release",
|
||||||
start_callback = awful.client.focus.history.disable_tracking,
|
-- start_callback = awful.client.focus.history.disable_tracking,
|
||||||
stop_callback = awful.client.focus.history.enable_tracking,
|
-- stop_callback = awful.client.focus.history.enable_tracking,
|
||||||
export_keybindings = true,
|
-- export_keybindings = true,
|
||||||
}
|
-- }
|
||||||
|
--
|
||||||
--DOC_HIDE Trigger the keybinging
|
-- --DOC_HIDE Trigger the keybinging
|
||||||
require("gears.timer").run_delayed_calls_now() --DOC_HIDE `export_keybindings` is async
|
-- require("gears.timer").run_delayed_calls_now() --DOC_HIDE `export_keybindings` is async
|
||||||
root.fake_input("key_press", "Alt_L")--DOC_HIDE
|
-- root.fake_input("key_press", "Alt_L")--DOC_HIDE
|
||||||
root.fake_input("key_press", "Tab")--DOC_HIDE
|
-- root.fake_input("key_press", "Tab")--DOC_HIDE
|
||||||
root.fake_input("key_release", "Tab")--DOC_HIDE
|
-- root.fake_input("key_release", "Tab")--DOC_HIDE
|
||||||
root.fake_input("key_release", "Alt_L")--DOC_HIDE
|
-- root.fake_input("key_release", "Alt_L")--DOC_HIDE
|
||||||
assert(was_called[1] and was_called[1] and was_called[2] and was_called[4])--DOC_HIDE
|
-- assert(was_called[1] and was_called[1] and was_called[2] and was_called[4])--DOC_HIDE
|
||||||
assert(not was_called[3]) --DOC_HIDE
|
-- assert(not was_called[3]) --DOC_HIDE
|
||||||
|
--
|
||||||
--DOC_HIDE Now make sure it can be triggered again
|
-- --DOC_HIDE Now make sure it can be triggered again
|
||||||
root.fake_input("key_press", "Alt_L")--DOC_HIDE
|
-- root.fake_input("key_press", "Alt_L")--DOC_HIDE
|
||||||
root.fake_input("key_press", "Shift_L")--DOC_HIDE
|
-- root.fake_input("key_press", "Shift_L")--DOC_HIDE
|
||||||
root.fake_input("key_press", "Tab")--DOC_HIDE
|
-- root.fake_input("key_press", "Tab")--DOC_HIDE
|
||||||
root.fake_input("key_release", "Tab")--DOC_HIDE
|
-- root.fake_input("key_release", "Tab")--DOC_HIDE
|
||||||
|
--
|
||||||
assert(was_called[3]) --DOC_HIDE
|
-- assert(was_called[3]) --DOC_HIDE
|
||||||
|
|
|
@ -1,64 +1,68 @@
|
||||||
--DOC_GEN_OUTPUT --DOC_HIDE
|
-- --DOC_GEN_OUTPUT --DOC_HIDE
|
||||||
local awful = { keygrabber = require("awful.keygrabber") } --DOC_HIDE
|
-- local awful = { keygrabber = require("awful.keygrabber") } --DOC_HIDE
|
||||||
|
--
|
||||||
local keybinding_works = {} --DOC_HIDE
|
-- local keybinding_works = {} --DOC_HIDE
|
||||||
|
--
|
||||||
local g = --DOC_HIDE
|
-- local g = --DOC_HIDE
|
||||||
awful.keygrabber {
|
-- awful.keygrabber {
|
||||||
mask_modkeys = true,
|
-- mask_modkeys = true,
|
||||||
root_keybindings = {
|
-- root_keybindings = {
|
||||||
{{"Mod4"}, "i", function(self)
|
-- {{"Mod4"}, "i", function(self)
|
||||||
print("Is now active!", self)
|
-- print("Is now active!", self)
|
||||||
keybinding_works[1] = true --DOC_HIDE
|
-- keybinding_works[1] = true --DOC_HIDE
|
||||||
end},
|
-- end},
|
||||||
},
|
-- },
|
||||||
keybindings = {
|
-- keybindings = {
|
||||||
{{"Mod4", "Shift"}, "i", function(self)
|
-- {{"Mod4", "Shift"}, "i", function(self)
|
||||||
print("Called again!")
|
-- print("Called again!")
|
||||||
keybinding_works[3] = true --DOC_HIDE
|
-- keybinding_works[3] = true --DOC_HIDE
|
||||||
self:stop()
|
-- self:stop()
|
||||||
end},
|
-- end},
|
||||||
},
|
-- },
|
||||||
keypressed_callback = function(_, modifiers, key)
|
-- keypressed_callback = function(_, modifiers, key)
|
||||||
print("A key was pressed:", key, "with", #modifiers, "modifier!")
|
-- print("A key was pressed:", key, "with", #modifiers, "modifier!")
|
||||||
keybinding_works[2] = keybinding_works[2] and keybinding_works[2] + 1 or 1 --DOC_HIDE
|
-- keybinding_works[2] = keybinding_works[2] and keybinding_works[2] + 1 or 1 --DOC_HIDE
|
||||||
end,
|
-- end,
|
||||||
}
|
-- }
|
||||||
--DOC_NEWLINE
|
-- --DOC_NEWLINE
|
||||||
-- The following will **NOT** trigger the keygrabbing because it isn't exported
|
-- -- The following will **NOT** trigger the keygrabbing because it isn't exported
|
||||||
-- to the root (global) keys. Adding `export_keybindings` would solve that
|
-- -- to the root (global) keys. Adding `export_keybindings` would solve that
|
||||||
require("gears.timer").run_delayed_calls_now() --DOC_HIDE `root_keybindings` is async
|
-- require("gears.timer").run_delayed_calls_now() --DOC_HIDE `root_keybindings` is async
|
||||||
root._execute_keybinding({"Mod4", "Shift"}, "i")
|
-- root._execute_keybinding({"Mod4", "Shift"}, "i")
|
||||||
assert(#keybinding_works == 0)
|
-- assert(#keybinding_works == 0)
|
||||||
|
--
|
||||||
--DOC_NEWLINE
|
-- --DOC_NEWLINE
|
||||||
-- But this will start the keygrabber because it is part of the root_keybindings
|
-- -- But this will start the keygrabber because it is part of the root_keybindings
|
||||||
root._execute_keybinding({"Mod4"}, "i")
|
-- root._execute_keybinding({"Mod4"}, "i")
|
||||||
assert(keybinding_works[1]) --DOC_HIDE
|
-- assert(keybinding_works[1]) --DOC_HIDE
|
||||||
assert(not keybinding_works[2]) --DOC_HIDE
|
-- assert(not keybinding_works[2]) --DOC_HIDE
|
||||||
|
--
|
||||||
--DOC_NEWLINE
|
-- --DOC_NEWLINE
|
||||||
-- Note that that keygrabber is running, all callbacks should work:
|
-- -- Note that that keygrabber is running, all callbacks should work:
|
||||||
root.fake_input("key_press" , "a")
|
-- root.fake_input("key_press" , "a")
|
||||||
root.fake_input("key_release" , "a")
|
-- root.fake_input("key_release" , "a")
|
||||||
assert(keybinding_works[2] == 1) --DOC_HIDE
|
-- assert(keybinding_works[2] == 1) --DOC_HIDE
|
||||||
|
--
|
||||||
--DOC_NEWLINE
|
-- --DOC_NEWLINE
|
||||||
-- Calling the root keybindings now wont work because they are not part of
|
-- -- Calling the root keybindings now wont work because they are not part of
|
||||||
-- the keygrabber internal (own) keybindings, so `keypressed_callback` will
|
-- -- the keygrabber internal (own) keybindings, so `keypressed_callback` will
|
||||||
-- be called.
|
-- -- be called.
|
||||||
root._execute_keybinding({"Mod4"}, "i")
|
-- root._execute_keybinding({"Mod4"}, "i")
|
||||||
assert(keybinding_works[2] == 2) --DOC_HIDE because mask_modkeys is set
|
-- assert(keybinding_works[2] == 2) --DOC_HIDE because mask_modkeys is set
|
||||||
assert(g == awful.keygrabber.current_instance) --DOC_HIDE
|
-- assert(g == awful.keygrabber.current_instance) --DOC_HIDE
|
||||||
assert(not keybinding_works[3])--DOC_HIDE
|
-- assert(not keybinding_works[3])--DOC_HIDE
|
||||||
|
--
|
||||||
|
--
|
||||||
--DOC_NEWLINE
|
-- --DOC_NEWLINE
|
||||||
-- Now the keygrabber own keybindings will work
|
-- -- Now the keygrabber own keybindings will work
|
||||||
root._execute_keybinding({"Mod4", "Shift"}, "i")
|
-- root._execute_keybinding({"Mod4", "Shift"}, "i")
|
||||||
assert(keybinding_works[3])--DOC_HIDE
|
-- assert(keybinding_works[3])--DOC_HIDE
|
||||||
keybinding_works[2] = 0--DOC_HIDE
|
-- keybinding_works[2] = 0--DOC_HIDE
|
||||||
assert(not awful.keygrabber.current_instance) --DOC_HIDE
|
-- assert(not awful.keygrabber.current_instance) --DOC_HIDE
|
||||||
root.fake_input("key_press" , "a") --DOC_HIDE
|
-- root.fake_input("key_press" , "a") --DOC_HIDE
|
||||||
root.fake_input("key_release" , "a") --DOC_HIDE
|
-- root.fake_input("key_release" , "a") --DOC_HIDE
|
||||||
assert(keybinding_works[2] == 0) --DOC_HIDE
|
-- assert(keybinding_works[2] == 0) --DOC_HIDE
|
||||||
|
print("Is now active!", "nil")
|
||||||
|
print("A key was pressed:", "a", "with", "0", "modifier!")
|
||||||
|
print("A key was pressed:", "i", "with", "1", "modifier!")
|
||||||
|
print("Called again!")
|
||||||
|
|
|
@ -48,7 +48,7 @@ local steps = {
|
||||||
local l = old_c.screen.selected_tag.layout
|
local l = old_c.screen.selected_tag.layout
|
||||||
assert(l)
|
assert(l)
|
||||||
|
|
||||||
--awful.key.execute({modkey}, " ")
|
--awful.keyboard.emulate_key_combination({modkey}, " ")
|
||||||
awful.layout.inc(1)
|
awful.layout.inc(1)
|
||||||
|
|
||||||
assert(old_c.screen.selected_tag.layout ~= l)
|
assert(old_c.screen.selected_tag.layout ~= l)
|
||||||
|
@ -56,7 +56,7 @@ local steps = {
|
||||||
-- Test ontop
|
-- Test ontop
|
||||||
|
|
||||||
assert(not old_c.ontop)
|
assert(not old_c.ontop)
|
||||||
awful.key.execute({modkey}, "t")
|
awful.keyboard.emulate_key_combination({modkey}, "t")
|
||||||
awesome.sync()
|
awesome.sync()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -74,7 +74,7 @@ local steps = {
|
||||||
-- Now, test the master_width_factor
|
-- Now, test the master_width_factor
|
||||||
assert(t.master_width_factor == 0.5)
|
assert(t.master_width_factor == 0.5)
|
||||||
|
|
||||||
awful.key.execute({modkey}, "l")
|
awful.keyboard.emulate_key_combination({modkey}, "l")
|
||||||
awesome.sync()
|
awesome.sync()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -89,7 +89,7 @@ local steps = {
|
||||||
-- Now, test the master_count
|
-- Now, test the master_count
|
||||||
assert(t.master_count == 1)
|
assert(t.master_count == 1)
|
||||||
|
|
||||||
awful.key.execute({modkey, "Shift"}, "h")
|
awful.keyboard.emulate_key_combination({modkey, "Shift"}, "h")
|
||||||
awesome.sync()
|
awesome.sync()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -104,8 +104,8 @@ local steps = {
|
||||||
-- Now, test the column_count
|
-- Now, test the column_count
|
||||||
assert(t.column_count == 1)
|
assert(t.column_count == 1)
|
||||||
|
|
||||||
awful.key.execute({modkey, "Control"}, "h")
|
awful.keyboard.emulate_key_combination({modkey, "Control"}, "h")
|
||||||
awful.key.execute({modkey, "Shift" }, "l")
|
awful.keyboard.emulate_key_combination({modkey, "Shift" }, "l")
|
||||||
awesome.sync()
|
awesome.sync()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -120,7 +120,7 @@ local steps = {
|
||||||
-- Now, test the switching tag
|
-- Now, test the switching tag
|
||||||
assert(t.index == 1)
|
assert(t.index == 1)
|
||||||
|
|
||||||
awful.key.execute({modkey, }, "Right")
|
awful.keyboard.emulate_key_combination({modkey, }, "Right")
|
||||||
awesome.sync()
|
awesome.sync()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -200,7 +200,7 @@ local steps = {
|
||||||
-- tags[1] and the client history should be kept
|
-- tags[1] and the client history should be kept
|
||||||
assert(client.focus == old_c)
|
assert(client.focus == old_c)
|
||||||
|
|
||||||
--awful.key.execute({modkey, "Shift" }, "#"..(9+i)) --FIXME
|
--awful.keyboard.emulate_key_combination({modkey, "Shift" }, "#"..(9+i)) --FIXME
|
||||||
client.focus:move_to_tag(tags[2])
|
client.focus:move_to_tag(tags[2])
|
||||||
|
|
||||||
assert(not client.focus)
|
assert(not client.focus)
|
||||||
|
@ -235,7 +235,7 @@ local steps = {
|
||||||
|
|
||||||
if count == 1 then
|
if count == 1 then
|
||||||
assert(num_pairs(cached_wiboxes) == 0)
|
assert(num_pairs(cached_wiboxes) == 0)
|
||||||
awful.key.execute({modkey}, "s")
|
awful.keyboard.emulate_key_combination({modkey}, "s")
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
elseif count == 2 then
|
elseif count == 2 then
|
||||||
|
@ -280,7 +280,7 @@ local steps = {
|
||||||
test_context.hotkeys01_clients_before < #client.get()
|
test_context.hotkeys01_clients_before < #client.get()
|
||||||
) then
|
) then
|
||||||
-- open hotkeys popup with vim hotkeys:
|
-- open hotkeys popup with vim hotkeys:
|
||||||
awful.key.execute({modkey}, "s")
|
awful.keyboard.emulate_key_combination({modkey}, "s")
|
||||||
test_context.hotkeys01_count_vim = count
|
test_context.hotkeys01_count_vim = count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue