Merge pull request #2893 from Elv13/xmas_2k18_2_merge_p1

API standardization merge part 1
This commit is contained in:
Emmanuel Lepage Vallée 2019-10-05 22:53:42 -04:00 committed by GitHub
commit 019a36535f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 514 additions and 100 deletions

View File

@ -26,7 +26,6 @@ read_globals = {
"key",
"keygrabber",
"mousegrabber",
"root",
"selection",
"tag",
"window",
@ -43,6 +42,7 @@ read_globals = {
globals = {
"screen",
"mouse",
"root",
"client"
}

View File

@ -54,7 +54,7 @@ local allowed_deps = {
-- Turn "foo.bar.baz" into "foo.bar". Returns nil if there is nothing more to
-- remove.
local function get_supermodule(module)
return string.match(module, "(.+)%.%a+")
return string.match(module, "(.+)%.[a-z_]+")
end
-- Check if "module" (or one of its parents) is allowed to depend on

View File

@ -40,9 +40,13 @@
-- @property visible
-- @param boolean
--- Set/get a widget's buttons.
-- @param _buttons The table of buttons that should bind to the widget.
-- @method buttons
--- The widget buttons.
--
-- The table contains a list of `awful.button` objects.
--
-- @property buttons
-- @param table
-- @see awful.button
--- Emit a signal and ensure all parent widgets in the hierarchies also
-- forward the signal. This is useful to track signals when there is a dynamic

View File

@ -118,10 +118,8 @@ file = {
'../spawn.c',
'../xkb.c',
'../common/luaobject.c',
'../objects/button.c',
'../objects/client.c',
'../objects/drawable.c',
'../objects/key.c',
'../objects/screen.c',
'../objects/tag.c',
'../objects/window.c',
@ -135,6 +133,7 @@ file = {
-- documentation
'../lib/awful/autofocus.lua',
'../lib/awful/dbus.lua',
'../lib/awful/_compat.lua',
'../lib/awful/init.lua',
'../lib/awful/remote.lua',
'../lib/awful/screen/dpi.lua',
@ -155,6 +154,11 @@ file = {
'../lib/naughty/list/init.lua',
'../lib/naughty/widget/_default.lua',
-- Ignore components that provide no value to users and have confusing
-- names
'../objects/button.c',
'../objects/key.c',
-- Deprecated classes for one years or more don't deserve entries
-- in the index
'../lib/awful/widget/graph.lua',

80
lib/awful/_compat.lua Normal file
View File

@ -0,0 +1,80 @@
-- This file contains all global backward compatibility workarounds for the
-- Core API changes.
local gtimer = require("gears.timer")
local util = require("awful.util")
local spawn = require("awful.spawn")
local gdebug = require("gears.debug")
local gprop = require("gears.object.properties")
local capi = {root = root}
function timer(...) -- luacheck: ignore
gdebug.deprecate("gears.timer", {deprecated_in=4})
return gtimer(...)
end
util.spawn = function(...)
gdebug.deprecate("awful.spawn", {deprecated_in=4})
return spawn.spawn(...)
end
util.spawn_with_shell = function(...)
gdebug.deprecate("awful.spawn.with_shell", {deprecated_in=4})
return spawn.with_shell(...)
end
util.pread = function()
gdebug.deprecate("Use io.popen() directly or look at awful.spawn.easy_async() "
.. "for an asynchronous alternative", {deprecated_in=4})
return ""
end
-- Allow properties to be set on the root object. This helps to migrate some
-- capi function to an higher level Lua implementation.
do
local root_props, root_object = {}, {}
capi.root.set_newindex_miss_handler(function(_,key,value)
if root_object["set_"..key] then
root_object["set_"..key](value)
elseif not root_object["get_"..key] then
root_props[key] = value
else
-- If there is a getter, but no setter, then the property is read-only
error("Cannot set '" .. tostring(key) .. " because it is read-only")
end
end)
capi.root.set_index_miss_handler(function(_,key)
if root_object["get_"..key] then
return root_object["get_"..key]()
else
return root_props[key]
end
end)
root._private = {}
root.object = root_object
assert(root.object == root_object)
end
-- root.bottons() used to be a capi function. However this proved confusing
-- as rc.lua used `awful.button` and `root.buttons()` used capi.button. There
-- was a little documented hack to "flatten" awful.button into a pair of
-- capi.button. A consequence of this, beside being ugly, was that it was
-- de-facto read-only due the confusion related the difference between the
-- capi and "high level" format difference.
gprop._legacy_accessors(capi.root, "buttons", "_buttons", false, function(new_btns)
return new_btns[1] and (
type(new_btns[1]) == "button" or new_btns[1]._is_capi_button
) or false
end, true)
gprop._legacy_accessors(capi.root, "keys", "_keys", false, function(new_btns)
return new_btns[1] and (
type(new_btns[1]) == "key" or new_btns[1]._is_capi_button
) or false
end, true)
assert(root.keys)

View File

@ -35,7 +35,6 @@ local ignore_modifiers = { "Lock", "Mod2" }
-- will return 2 button objects: one with CapsLock on, and the other one with
-- CapsLock off.
--
-- @see button
-- @treturn table A table with one or several button objects.
function button.new(mod, _button, press, release)
local ret = {}

View File

@ -1344,6 +1344,18 @@ function client.object.is_transient_for(self, c2)
return nil
end
object.properties._legacy_accessors(client, "buttons", "_buttons", true, function(new_btns)
return new_btns[1] and (
type(new_btns[1]) == "button" or new_btns[1]._is_capi_button
) or false
end, true)
object.properties._legacy_accessors(client, "keys", "_keys", true, function(new_btns)
return new_btns[1] and (
type(new_btns[1]) == "key" or new_btns[1]._is_capi_key
) or false
end, true)
--- Set the client shape.
-- @property shape
-- @tparam gears.shape A gears.shape compatible function.

View File

@ -6,34 +6,7 @@
-- @module awful
---------------------------------------------------------------------------
-- TODO: This is a hack for backwards-compatibility with 3.5, remove!
local util = require("awful.util")
local gtimer = require("gears.timer")
local gdebug = require("gears.debug")
function timer(...) -- luacheck: ignore
gdebug.deprecate("gears.timer", {deprecated_in=4})
return gtimer(...)
end
--TODO: This is a hack for backwards-compatibility with 3.5, remove!
-- Set awful.util.spawn* and awful.util.pread.
local spawn = require("awful.spawn")
util.spawn = function(...)
gdebug.deprecate("awful.spawn", {deprecated_in=4})
return spawn.spawn(...)
end
util.spawn_with_shell = function(...)
gdebug.deprecate("awful.spawn.with_shell", {deprecated_in=4})
return spawn.with_shell(...)
end
util.pread = function()
gdebug.deprecate("Use awful.spawn.easy_async() "
.. "for an asynchronous alternative", {deprecated_in=4})
return ""
end
require("awful._compat")
return
{
@ -60,7 +33,7 @@ return
titlebar = require("awful.titlebar");
rules = require("awful.rules");
popup = require("awful.popup");
spawn = spawn;
spawn = require("awful.spawn");
}
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -103,7 +103,7 @@ end
-- 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.
-- @see key.key
--
-- @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.
@ -113,6 +113,7 @@ end
-- 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)
if type(release)=='table' then
data=release

View File

@ -421,6 +421,8 @@ function awfulwibar.new(args)
w:connect_signal("property::visible", function() reattach(w) end)
assert(w.buttons)
return w
end

View File

@ -21,9 +21,14 @@ local common = {}
-- @param object
-- @treturn table
function common.create_buttons(buttons, object)
local is_formatted = buttons and buttons[1] and (
type(buttons[1]) == "button" or buttons[1]._is_capi_button) or false
if buttons then
local btns = {}
for _, b in ipairs(buttons) do
for _, src in ipairs(buttons) do
--TODO v6 Remove this legacy overhead
for _, b in ipairs(is_formatted and {src} or src) do
-- Create a proxy button object: it will receive the real
-- press and release events, and will propagate them to the
-- button object the user provided, but with the object as
@ -33,6 +38,7 @@ function common.create_buttons(buttons, object)
btn:connect_signal("release", function () b:emit_signal("release", object) end)
btns[#btns + 1] = btn
end
end
return btns
end

View File

@ -1,5 +1,6 @@
---------------------------------------------------------------------------
--- Layoutbox widget.
--- Display the current client layout (`awful.layout`) icon or name
--
--
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2009 Julien Danjou
@ -13,6 +14,8 @@ local tooltip = require("awful.tooltip")
local beautiful = require("beautiful")
local wibox = require("wibox")
local surface = require("gears.surface")
-- local gdebug = require("gears.debug")
local gtable = require("gears.table")
local function get_screen(s)
return s and capi.screen[s]
@ -42,10 +45,25 @@ end
--- Create a layoutbox widget. It draws a picture with the current layout
-- symbol of the current tag.
-- @param screen The screen number that the layout will be represented for.
-- @return An imagebox widget configured as a layoutbox.
-- @constructorfct awful.widget.layoutbox
function layoutbox.new(screen)
-- @tparam table args The arguments.
-- @tparam screen args.screen The screen number that the layout will be represented for.
-- @tparam table args.buttons The `awful.button`s for this layoutbox.
-- @return The layoutbox.
function layoutbox.new(args)
args = args or {}
local screen = nil
if type(args) == "number" or type(args) == "screen" or args.fake_remove then
screen, args = args, {}
--TODO uncomment
-- gdebug.deprecate(
-- "Use awful.widget.layoutbox{screen=s} instead of awful.widget.layoutbox(screen)",
-- {deprecated_in=5}
-- )
end
assert(type(args) == "table")
screen = get_screen(screen or 1)
-- Do we already have the update callbacks registered?
@ -80,6 +98,9 @@ function layoutbox.new(screen)
w._layoutbox_tooltip = tooltip {objects = {w}, delay_show = 1}
-- Apply the buttons, visible, forced_width and so on
gtable.crush(w, args)
update(w, screen)
boxes[screen] = w
end
@ -91,6 +112,10 @@ function layoutbox.mt:__call(...)
return layoutbox.new(...)
end
--@DOC_widget_COMMON@
--@DOC_object_COMMON@
return setmetatable(layoutbox, layoutbox.mt)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -7,7 +7,10 @@
-- @submodule gears.object
---------------------------------------------------------------------------
local gtable = require("gears.table")
-- local gdebug = require("gears.debug")
local object = {}
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
--- Add the missing properties handler to a CAPI object such as client/tag/screen.
@ -84,6 +87,126 @@ function object.capi_index_fallback(class, args)
class.set_newindex_miss_handler(setter)
end
-- (private api)
-- Many legacy Awesome APIs such as `client:tags()`, `root.buttons()`,
-- `client:keys()`, `drawin:geometry()`, etc used functions for both the getter
-- and setter. This contrast with just about everything else that came after
-- it and is an artifact of an earlier time before we had "good" Lua object
-- support.
--
-- Because both consistency and backward compatibility are important, this
-- table wrapper allows to support both the legacy method based accessors
-- and key/value based accessors.
--
-- TO BE USED FOR DEPRECATION ONLY.
local function copy_object(obj, to_set, name, capi_name, is_object, join_if, set_empty)
local ret = gtable.clone(to_set, false)
-- .buttons used to be a function taking the result of `gears.table.join`.
-- For compatibility, support this, but from now on, it's a property.
return setmetatable(ret, {
__call = function(_, self, new_objs)
--TODO uncomment
-- gdebug.deprecate("`"..name.."` is no longer a function, it is a property. "..
-- "Remove the `gears.table.join` and use a brace enclosed table",
-- {deprecated_in=5}
-- )
new_objs, self = is_object and new_objs or self, is_object and self or obj
-- Setter
if new_objs and #new_objs > 0 then
if (not set_empty) and not next(new_objs) then return end
local is_formatted = join_if(new_objs)
-- Because modules may rely on :buttons taking a list of
-- `capi.buttons`/`capi.key` and now the user passes a list of
-- `awful.button`/`awful.key` convert this.
local result = is_formatted and
new_objs or gtable.join(unpack(new_objs))
if capi_name and is_object then
return self[capi_name](self, result)
elseif capi_name then
return self[capi_name](result)
else
self._private[name.."_formatted"] = result
return self._private[name.."_formatted"]
end
end
-- Getter
if capi_name and is_object then
return self[capi_name](self)
elseif capi_name then
return self[capi_name]()
else
return self._private[name.."_formatted"] or {}
end
end
})
end
function object._legacy_accessors(obj, name, capi_name, is_object, join_if, set_empty)
-- Some objects have a special "object" property to add more properties, but
-- not all.
local magic_obj = obj.object and obj.object or obj
magic_obj["get_"..name] = function(self)
self = is_object and self or obj
self._private[name] = self._private[name] or copy_object(
obj, {}, name, capi_name, is_object, join_if, set_empty
)
assert(self._private[name])
return self._private[name]
end
magic_obj["set_"..name] = function(self, objs)
if (not set_empty) and not next(objs) then return end
if not is_object then
objs, self = self, obj
end
assert(objs)
-- When called from a declarative property list, "buttons" will be set
-- using the result of gears.table.join, detect this
local is_formatted = join_if(objs)
-- if is_formatted then
--TODO uncomment
-- gdebug.deprecate("Remove the `gears.table.join` and replace it with braces",
-- {deprecated_in=5}
-- )
-- end
--TODO v6 Use the original directly and drop this legacy copy
local result = is_formatted and objs
or gtable.join(unpack(objs))
if is_object and capi_name then
self[capi_name](self, result)
elseif capi_name then
obj[capi_name](result)
else
self._private[name.."_formatted"] = result
end
self._private[name] = copy_object(
obj, objs, name, capi_name, is_object, join_if, set_empty
)
end
end
return setmetatable( object, {__call = function(_,...) object.capi_index_fallback(...) end})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -19,6 +19,7 @@ local beautiful = require("beautiful")
local base = require("wibox.widget.base")
local cairo = require("lgi").cairo
--- This provides widget box windows. Every wibox can also be used as if it were
-- a drawin. All drawin functions and properties are also available on wiboxes!
-- wibox
@ -63,6 +64,10 @@ function wibox:find_widgets(x, y)
return self._drawable:find_widgets(x, y)
end
function wibox:_buttons(btns)
return self.drawin:_buttons(btns)
end
--- Create a widget that reflects the current state of this wibox.
-- @treturn widget A new widget.
-- @method to_widget
@ -207,12 +212,18 @@ function wibox:get_children_by_id(name)
return {}
end
for _, k in pairs{ "buttons", "struts", "geometry", "get_xproperty", "set_xproperty" } do
for _, k in pairs{ "struts", "geometry", "get_xproperty", "set_xproperty" } do
wibox[k] = function(self, ...)
return self.drawin[k](self.drawin, ...)
end
end
object.properties._legacy_accessors(wibox.object, "buttons", "_buttons", true, function(new_btns)
return new_btns[1] and (
type(new_btns[1]) == "button" or new_btns[1]._is_capi_button
) or false
end, true)
local function setup_signals(_wibox)
local obj
local function clone_signal(name)
@ -264,6 +275,7 @@ local function new(args)
return ret
end
w._private = {}
ret.drawin = w
ret._drawable = wibox.drawable(w.drawable, { wibox = ret },
"wibox drawable (" .. object.modulename(3) .. ")")
@ -365,6 +377,8 @@ object.properties(capi.drawin, {
auto_emit = true,
})
capi.drawin.object = wibox.object
return setmetatable(wibox, wibox.mt)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -7,6 +7,7 @@
local object = require("gears.object")
local cache = require("gears.cache")
local matrix = require("gears.matrix")
local gdebug = require("gears.debug")
local protected_call = require("gears.protected_call")
local gtable = require("gears.table")
local setmetatable = setmetatable
@ -21,15 +22,11 @@ local base = {}
-- Functions available on all widgets.
base.widget = {}
--- Set/get a widget's buttons.
-- @tab _buttons The table of buttons that is bound to the widget.
-- @method buttons
function base.widget:buttons(_buttons)
if _buttons then
self._private.widget_buttons = _buttons
end
return self._private.widget_buttons
end
object.properties._legacy_accessors(base.widget, "buttons", nil, true, function(new_btns)
return new_btns[1] and (
type(new_btns[1]) == "button" or new_btns[1]._is_capi_button
) or false
end, true)
--- Set a widget's visibility.
-- @tparam boolean b Whether the widget is visible.
@ -367,7 +364,7 @@ function base.handle_button(event, widget, x, y, button, modifiers, geometry)
-- Find all matching button objects.
local matches = {}
for _, v in pairs(widget._private.widget_buttons) do
for _, v in pairs(widget._private.buttons_formatted or {}) do
local match = true
-- Is it the right button?
if v.button ~= 0 and v.button ~= button then match = false end
@ -609,17 +606,22 @@ end
--
-- @param wdg The value.
-- @param[opt=nil] ... Arguments passed to the contructor (if any).
-- @treturn The new widget.
-- @constructorfct wibox.widget.base.make_widget_from_value
-- @treturn widget|nil The new widget or `nil` in case of failure.
function base.make_widget_from_value(wdg, ...)
if not wdg then return nil end
local is_function, t = is_callable(wdg)
if is_function then
wdg = wdg(...)
elseif t == "table" and not wdg.is_widget then
wdg = base.make_widget_declarative(wdg)
elseif t == "table" then
wdg = wdg.is_widget and wdg or base.make_widget_declarative(wdg)
else
assert(wdg.is_widget, "The argument is not a function, table, or widget.")
gdebug.print_warning(
"The argument is not a function, table, or widget."
)
return nil
end
return wdg
@ -656,9 +658,6 @@ function base.make_widget(proxy, widget_name, args)
-- Create a table used to store the widgets internal data.
rawset(ret, "_private", {})
-- No buttons yet.
ret._private.widget_buttons = {}
-- Widget is visible.
ret._private.visible = true
@ -713,6 +712,20 @@ function base.make_widget(proxy, widget_name, args)
mt.__tostring = function()
return string.format("%s (%s)", ret.widget_name, orig_string)
end
-- Even when properties are disabled, buttons is required for backward
-- compatibility.
--TODO v6 Remove this
if not args.enable_properties then
mt.__index = function(_, key)
if key == "buttons" then
return base.widget.get_buttons(ret)
end
return rawget(ret, key)
end
end
return setmetatable(ret, mt)
end

6
luaa.c
View File

@ -80,9 +80,10 @@ extern const struct luaL_Reg awesome_dbus_lib[];
#endif
extern const struct luaL_Reg awesome_keygrabber_lib[];
extern const struct luaL_Reg awesome_mousegrabber_lib[];
extern const struct luaL_Reg awesome_root_lib[];
extern const struct luaL_Reg awesome_mouse_methods[];
extern const struct luaL_Reg awesome_mouse_meta[];
extern const struct luaL_Reg awesome_root_methods[];
extern const struct luaL_Reg awesome_root_meta[];
/** A call into the Lua code aborted with an error.
*
@ -995,8 +996,7 @@ luaA_init(xdgHandle* xdg, string_array_t *searchpath)
setup_awesome_signals(L);
/* Export root lib */
luaA_registerlib(L, "root", awesome_root_lib);
lua_pop(L, 1); /* luaA_registerlib() leaves the table on stack */
luaA_openlib(L, "root", awesome_root_methods, awesome_root_meta);
#ifdef WITH_DBUS
/* Export D-Bus lib */

View File

@ -949,9 +949,9 @@
/** Get or set mouse buttons bindings for a client.
*
* @param buttons_table An array of mouse button bindings objects, or nothing.
* @return A table with all buttons.
* @method buttons
* @property buttons
* @param table
* @see awful.button
*/
/** Get the number of instances.
@ -3677,9 +3677,9 @@ luaA_client_set_shape_input(lua_State *L, client_t *c)
/** Get or set keys bindings for a client.
*
* @param keys_table An array of key bindings objects, or nothing.
* @return A table with all keys.
* @method keys
* @property keys
* @param table
* @see awful.key
*/
static int
luaA_client_keys(lua_State *L)
@ -3813,7 +3813,7 @@ client_class_setup(lua_State *L)
{
LUA_OBJECT_META(client)
LUA_CLASS_META
{ "keys", luaA_client_keys },
{ "_keys", luaA_client_keys },
{ "isvisible", luaA_client_isvisible },
{ "geometry", luaA_client_geometry },
{ "apply_size_hints", luaA_client_apply_size_hints },

View File

@ -515,7 +515,7 @@ window_class_setup(lua_State *L)
static const struct luaL_Reg window_meta[] =
{
{ "struts", luaA_window_struts },
{ "buttons", luaA_window_buttons },
{ "_buttons", luaA_window_buttons },
{ "set_xproperty", luaA_window_set_xproperty },
{ "get_xproperty", luaA_window_get_xproperty },
{ NULL, NULL }

107
root.c
View File

@ -31,6 +31,7 @@
#include "common/xcursor.h"
#include "common/xutil.h"
#include "objects/button.h"
#include "common/luaclass.h"
#include "xwindow.h"
#include "math.h"
@ -39,6 +40,10 @@
#include <xcb/xcb_aux.h>
#include <cairo-xcb.h>
static int miss_index_handler = LUA_REFNIL;
static int miss_newindex_handler = LUA_REFNIL;
static int miss_call_handler = LUA_REFNIL;
static void
root_set_wallpaper_pixmap(xcb_connection_t *c, xcb_pixmap_t p)
{
@ -330,11 +335,12 @@ luaA_root_fake_input(lua_State *L)
}
/** Get or set global key bindings.
* These bindings will be available when you press keys on the root window.
* These bindings will be available when you press keys on the root window
* (the wallpaper).
*
* @tparam table|nil keys_array An array of key binding objects, or nothing.
* @return The array of key bindings objects of this client.
* @staticfct keys
* @property keys
* @param table
* @see awful.key
*/
static int
luaA_root_keys(lua_State *L)
@ -369,13 +375,22 @@ luaA_root_keys(lua_State *L)
return 1;
}
/** Get or set global mouse bindings.
* This binding will be available when you click on the root window.
/**
* Store the list of mouse buttons to be applied on the wallpaper (also
* known as root window).
*
* @param button_table An array of mouse button bindings objects, or nothing.
* @return The array of mouse button bindings objects.
* @staticfct buttons
* @property buttons
* @tparam[opt={}] table buttons The list of buttons.
* @see awful.button
*
* @usage
* root.buttons = {
* awful.button({ }, 3, function () mymainmenu:toggle() end),
* awful.button({ }, 4, awful.tag.viewnext),
* awful.button({ }, 5, awful.tag.viewprev),
* }
*/
static int
luaA_root_buttons(lua_State *L)
{
@ -525,10 +540,65 @@ luaA_root_tags(lua_State *L)
return 1;
}
const struct luaL_Reg awesome_root_lib[] =
/**
* Add a custom call handler.
*/
static int
luaA_root_set_call_handler(lua_State *L)
{
{ "buttons", luaA_root_buttons },
{ "keys", luaA_root_keys },
return luaA_registerfct(L, 1, &miss_call_handler);
}
/**
* Add a custom property handler (getter).
*/
static int
luaA_root_set_index_miss_handler(lua_State *L)
{
return luaA_registerfct(L, 1, &miss_index_handler);
}
/**
* Add a custom property handler (setter).
*/
static int
luaA_root_set_newindex_miss_handler(lua_State *L)
{
return luaA_registerfct(L, 1, &miss_newindex_handler);
}
/** Root library.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
*/
static int
luaA_root_index(lua_State *L)
{
if (miss_index_handler != LUA_REFNIL)
return luaA_call_handler(L, miss_index_handler);
return luaA_default_index(L);
}
/** Newindex for root.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
*/
static int
luaA_root_newindex(lua_State *L)
{
/* Call the lua root property handler */
if (miss_newindex_handler != LUA_REFNIL)
return luaA_call_handler(L, miss_newindex_handler);
return luaA_default_newindex(L);
}
const struct luaL_Reg awesome_root_methods[] =
{
{ "_buttons", luaA_root_buttons },
{ "_keys", luaA_root_keys },
{ "cursor", luaA_root_cursor },
{ "fake_input", luaA_root_fake_input },
{ "drawins", luaA_root_drawins },
@ -536,8 +606,17 @@ const struct luaL_Reg awesome_root_lib[] =
{ "size", luaA_root_size },
{ "size_mm", luaA_root_size_mm },
{ "tags", luaA_root_tags },
{ "__index", luaA_default_index },
{ "__newindex", luaA_default_newindex },
{ "__index", luaA_root_index },
{ "__newindex", luaA_root_newindex },
{ "set_index_miss_handler", luaA_root_set_index_miss_handler},
{ "set_call_handler", luaA_root_set_call_handler},
{ "set_newindex_miss_handler", luaA_root_set_newindex_miss_handler},
{ NULL, NULL }
};
const struct luaL_Reg awesome_root_meta[] =
{
{ NULL, NULL }
};

View File

@ -33,6 +33,8 @@ return function(_, _)
-- backend.
local bg = require("wibox.container.background")
bg._use_fallback_algorithm()
require("awful._compat")
end
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -1,5 +1,6 @@
return function() return {
data = {},
_is_capi_button = true,
connect_signal = function() end
} end

View File

@ -37,7 +37,7 @@ local function new_drawin(_, args)
ret.data.drawable.refresh = function() end
ret.data._struts = { top = 0, right = 0, left = 0, bottom = 0 }
for _, k in pairs{ "buttons", "get_xproperty", "set_xproperty" } do
for _, k in pairs{ "_buttons", "get_xproperty", "set_xproperty" } do
ret[k] = function() end
end

View File

@ -1,6 +1,6 @@
local gobject = require("gears.object")
local gtable = require("gears.table")
return setmetatable({}, {__call = function(_, args)
return setmetatable({_is_capi_key = true}, {__call = function(_, args)
return gtable.crush(gobject(), args)
end})

View File

@ -32,7 +32,7 @@ function root.cursor() end
local keys = {}
function root.keys(k)
function root._keys(k)
keys = k or keys
return keys
end
@ -128,6 +128,9 @@ function root.fake_input(event_type, detail, x, y)
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.
@ -174,6 +177,31 @@ function root._write_string(string, c)
end
end
return root
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

View File

@ -4,7 +4,10 @@ local mouse = mouse
local class = tag
local obj = class({})
local handler = require("gears.object.properties")
local abutton = require("awful.button")
local gtable = require("gears.table")
local wibox = require("wibox")
local runner = require("_runner")
awesome.connect_signal("debug::index::miss", error)
awesome.connect_signal("debug::newindex::miss", error)
@ -68,6 +71,51 @@ assert(w2:get_children_by_id("main_textbox")[1])
assert(w2.main_background.main_textbox)
assert(w2.main_background == w2:get_children_by_id("main_background")[1])
require("_runner").run_steps({ function() return true end })
-- You can't retry this, so if the assert above were false, assume it never
-- reaches this.
local steps = { function() return true end }
-- Try each combinations of current and legacy style accessors.
table.insert(steps, function()local b1, b2 = button({}, 1, function() end), button({}, 2, function() end)
root.buttons = {b1}
assert(#root.buttons == 1 )
assert(#root.buttons() == 1 )
assert(root.buttons[1] == b1)
root.buttons{b2}
assert(#root.buttons == 1 )
assert(#root.buttons() == 1 )
assert(root.buttons()[1] == b2)
local ab1, ab2 = abutton({}, 1, function() end), abutton({}, 2, function() end)
root.buttons = {ab1}
assert(#root.buttons == 1)
assert(#root.buttons() == 4)
for i=1, 4 do
assert(root.buttons()[i] == ab1[i])
end
root.buttons(gtable.join(ab2))
assert(#root.buttons == 1)
assert(#root.buttons() == 4)
for i=1, 4 do
assert(root.buttons()[i] == ab2[i])
end
root.buttons{ab1}
assert(#root.buttons == 1)
assert(#root.buttons() == 4)
for i=1, 4 do
assert(root.buttons()[i] == ab1[i])
end
return true
end)
runner.run_steps(steps)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80