2016-03-19 09:57:37 +01:00
|
|
|
local root = {_tags={}}
|
|
|
|
|
2018-07-24 23:13:36 +02:00
|
|
|
local gtable = require("gears.table")
|
2021-06-07 10:42:47 +02:00
|
|
|
local cairo = require( "lgi" ).cairo
|
|
|
|
|
2018-07-24 23:13:36 +02:00
|
|
|
|
2016-03-19 09:57:37 +01:00
|
|
|
function root:tags()
|
|
|
|
return root._tags
|
|
|
|
end
|
|
|
|
|
2019-07-18 06:23:53 +02:00
|
|
|
function root.size()
|
|
|
|
local geo = {x1 = math.huge, y1 = math.huge, x2 = 0, y2 = 0}
|
|
|
|
|
|
|
|
for s in screen do
|
|
|
|
geo.x1 = math.min( geo.x1, s.geometry.x )
|
|
|
|
geo.y1 = math.min( geo.y1, s.geometry.y )
|
|
|
|
geo.x2 = math.max( geo.x2, s.geometry.x+s.geometry.width )
|
|
|
|
geo.y2 = math.max( geo.y2, s.geometry.y+s.geometry.height )
|
|
|
|
end
|
|
|
|
|
|
|
|
return math.max(0, geo.x2-geo.x1), math.max(0, geo.y2 - geo.y1)
|
2018-07-24 23:13:36 +02:00
|
|
|
end
|
|
|
|
|
2019-07-18 06:23:53 +02:00
|
|
|
function root.size_mm()
|
|
|
|
local w, h = root.size()
|
|
|
|
return (w/96)*25.4, (h/96)*25.4
|
2018-07-24 23:13:36 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function root.cursor() end
|
|
|
|
|
|
|
|
-- GLOBAL KEYBINDINGS --
|
|
|
|
|
|
|
|
local keys = {}
|
|
|
|
|
2018-12-27 04:51:58 +01:00
|
|
|
function root._keys(k)
|
2018-07-24 23:13:36 +02:00
|
|
|
keys = k or keys
|
|
|
|
return keys
|
|
|
|
end
|
|
|
|
|
|
|
|
-- FAKE INPUTS --
|
|
|
|
|
|
|
|
-- Turn keysym into modkey names
|
|
|
|
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",
|
|
|
|
}
|
|
|
|
|
|
|
|
-- The currently pressed modkeys.
|
|
|
|
local mods = {}
|
|
|
|
local function get_mods()
|
|
|
|
local ret = {}
|
|
|
|
|
|
|
|
for mod in pairs(mods) do
|
|
|
|
table.insert(ret, mod)
|
|
|
|
end
|
|
|
|
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
|
|
|
local function add_modkey(key)
|
|
|
|
if not conversion[key] then return end
|
|
|
|
mods[conversion[key]] = true
|
|
|
|
end
|
|
|
|
|
|
|
|
local function remove_modkey(key)
|
|
|
|
if not conversion[key] then return end
|
|
|
|
mods[conversion[key]] = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
local function match_modifiers(mods1, mods2)
|
|
|
|
if #mods1 ~= #mods2 then return false end
|
|
|
|
|
|
|
|
for _, mod1 in ipairs(mods1) do
|
|
|
|
if not gtable.hasitem(mods2, mod1) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
local function execute_keybinding(key, event)
|
2019-10-20 01:08:46 +02:00
|
|
|
for _, v in ipairs(keys) do
|
|
|
|
if key == v.key and match_modifiers(v.modifiers, get_mods()) then
|
|
|
|
v:emit_signal(event)
|
2018-07-24 23:13:36 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local fake_input_handlers = {
|
|
|
|
key_press = function(key)
|
|
|
|
add_modkey(key)
|
|
|
|
if keygrabber._current_grabber then
|
|
|
|
keygrabber._current_grabber(get_mods(), key, "press")
|
|
|
|
else
|
|
|
|
execute_keybinding(key, "press")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
key_release = function(key)
|
|
|
|
remove_modkey(key)
|
|
|
|
if keygrabber._current_grabber then
|
|
|
|
keygrabber._current_grabber(get_mods(), key, "release")
|
|
|
|
else
|
|
|
|
execute_keybinding(key, "release")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
button_press = function() --[[TODO]] end,
|
|
|
|
button_release = function() --[[TODO]] end,
|
|
|
|
motion_notify = function() --[[TODO]] end,
|
|
|
|
}
|
|
|
|
|
2018-08-06 00:45:01 +02:00
|
|
|
function root.fake_input(event_type, detail, x, y)
|
2018-07-24 23:13:36 +02:00
|
|
|
assert(fake_input_handlers[event_type], "Unknown event_type")
|
|
|
|
|
|
|
|
fake_input_handlers[event_type](detail, x, y)
|
|
|
|
end
|
|
|
|
|
2018-12-26 23:38:05 +01:00
|
|
|
function root._buttons()
|
|
|
|
return {}
|
|
|
|
end
|
2018-07-29 16:10:11 +02:00
|
|
|
|
|
|
|
-- Send an artificial set of key events to trigger a key combination.
|
|
|
|
-- It only works in the shims and should not be used with UTF-8 chars.
|
|
|
|
function root._execute_keybinding(modifiers, key)
|
|
|
|
for _, mod in ipairs(modifiers) do
|
|
|
|
for real_key, mod_name in pairs(conversion) do
|
|
|
|
if mod == mod_name then
|
2018-08-06 00:45:01 +02:00
|
|
|
root.fake_input("key_press", real_key)
|
2018-07-29 16:10:11 +02:00
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-08-06 00:45:01 +02:00
|
|
|
root.fake_input("key_press" , key)
|
|
|
|
root.fake_input("key_release", key)
|
2018-07-29 16:10:11 +02:00
|
|
|
|
|
|
|
for _, mod in ipairs(modifiers) do
|
|
|
|
for real_key, mod_name in pairs(conversion) do
|
|
|
|
if mod == mod_name then
|
2018-08-06 00:45:01 +02:00
|
|
|
root.fake_input("key_release", real_key)
|
2018-07-29 16:10:11 +02:00
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Send artificial key events to write a string.
|
|
|
|
-- It only works in the shims and should not be used with UTF-8 strings.
|
|
|
|
function root._write_string(string, c)
|
|
|
|
local old_c = client.focus
|
|
|
|
|
|
|
|
if c then
|
|
|
|
client.focus = c
|
|
|
|
end
|
|
|
|
|
|
|
|
for i=1, #string do
|
|
|
|
local char = string:sub(i,i)
|
2018-08-06 00:45:01 +02:00
|
|
|
root.fake_input("key_press" , char)
|
|
|
|
root.fake_input("key_release", char)
|
2018-07-29 16:10:11 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if c then
|
|
|
|
client.focus = old_c
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-06-07 10:42:47 +02:00
|
|
|
function root._wallpaper(pattern)
|
|
|
|
if not pattern then return root._wallpaper_surface end
|
|
|
|
|
|
|
|
-- Make a copy because `:finish()` is called by `root.wallpaper` to avoid
|
|
|
|
-- a memory leak in the "real" backend.
|
|
|
|
local target = cairo.ImageSurface(cairo.Format.RGB32, root.size())
|
|
|
|
local cr = cairo.Context(target)
|
|
|
|
|
|
|
|
cr:set_source(pattern)
|
|
|
|
cr:rectangle(0, 0, root.size())
|
|
|
|
cr:fill()
|
|
|
|
|
|
|
|
root._wallpaper_pattern = cairo.Pattern.create_for_surface(target)
|
|
|
|
root._wallpaper_surface = target
|
|
|
|
|
|
|
|
return target
|
|
|
|
end
|
|
|
|
|
2018-12-26 21:50:21 +01:00
|
|
|
|
|
|
|
function root.set_newindex_miss_handler(h)
|
2018-12-26 21:52:34 +01:00
|
|
|
rawset(root, "_ni_handler", h)
|
2018-12-26 21:50:21 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function root.set_index_miss_handler(h)
|
2018-12-26 21:52:34 +01:00
|
|
|
rawset(root, "_i_handler", h)
|
2018-12-26 21:50:21 +01:00
|
|
|
end
|
|
|
|
|
2018-12-26 21:52:34 +01:00
|
|
|
return setmetatable(root, {
|
|
|
|
__index = function(self, key)
|
|
|
|
if key == "screen" then
|
|
|
|
return screen[1]
|
|
|
|
end
|
|
|
|
local h = rawget(root,"_i_handler")
|
|
|
|
if h then
|
|
|
|
return h(self, key)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
__newindex = function(...)
|
|
|
|
local h = rawget(root,"_ni_handler")
|
|
|
|
if h then
|
|
|
|
h(...)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
})
|
2016-03-19 09:57:37 +01:00
|
|
|
|
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|