awesome/tests/examples/shims/root.lua

220 lines
5.2 KiB
Lua
Raw Normal View History

local root = {_tags={}}
local gtable = require("gears.table")
2021-06-07 10:42:47 +02:00
local cairo = require( "lgi" ).cairo
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)
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
end
function root.cursor() end
-- GLOBAL KEYBINDINGS --
local keys = {}
function root._keys(k)
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)
for _, v in ipairs(keys) do
if key == v.key and match_modifiers(v.modifiers, get_mods()) then
v:emit_signal(event)
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,
}
function root.fake_input(event_type, detail, x, y)
assert(fake_input_handlers[event_type], "Unknown event_type")
fake_input_handlers[event_type](detail, x, y)
end
function root._buttons()
return {}
end
-- 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
root.fake_input("key_press", real_key)
break
end
end
end
root.fake_input("key_press" , key)
root.fake_input("key_release", key)
for _, mod in ipairs(modifiers) do
for real_key, mod_name in pairs(conversion) do
if mod == mod_name then
root.fake_input("key_release", real_key)
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)
root.fake_input("key_press" , char)
root.fake_input("key_release", char)
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
function root.set_newindex_miss_handler(h)
rawset(root, "_ni_handler", h)
end
function root.set_index_miss_handler(h)
rawset(root, "_i_handler", h)
end
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,
})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80