Commit Graph

35 Commits

Author SHA1 Message Date
Uli Schlachter ef110361dc Reduce code duplication with luaA_*_call_handler (#2321)
The functions luaA_class_call_handler() and luaA_mouse_call_handler()
are basically identical. Fix this code duplication by moving this to
luaA_call_handler() in lualib.h.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2018-07-25 18:31:02 -04:00
Uli Schlachter 9566defa93 C: Add a .data table to all C objects
This table is "just a normal Lua table". Lua code can use it in whatever
way it wants to store things related to a given C object.

An object (userdata) already references a "plain Lua table" via
lua_setuservalue() / lua_setfenv(). This is used to keep a reference to
signal functions that are connected to an object. The signal code only
uses lightuserdata keys in this table. This commit adds an entry with
key "data" to this table which just references another table. This is
the table that is made available as .data.

Via this .data property, Lua code can add own properties to C objects
without having to use, for example, weak tables. The weak tables have
the downside that they produce a leak if the value references the key.
The new .data property does not have any such problem (no weak
references are involved).

This new data property is not documented, because I'd have to touch lots
of files and I'm lazy.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-09-30 11:07:55 +02:00
Uli Schlachter 489aa4dc24 Improve behaviour of GC'd objects
Before this commit: When we are GC'ing an object, we clear its metatable, since
otherwise crashes could occur in various places. This means that if someone
tries to use such an object, they get an unhelpful error message like "attempt
to index userdata object" and they don't understand what the problem is. Also,
this means that foo.valid does not actually work after GC.

This commit changes this behaviour. Instead of setting an empty metatable, we
now create a metatable with an __index and __newindex method. These metamethods
produce better error messages that they sat the underlying object was already
garbage collected. Better yet, the __index metamethod makes foo.valid be false
instead of causing an error, so that the existing machinery for detecting
invalid objects continues to work.

This commit also adds a functional test that verifies this behaviour.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-09-24 14:37:07 +02:00
Uli Schlachter 6f1df7a3ad Fix disconnecting not connected signals (#950)
When a function is disconnected from a signal ("disconnect_signal") that is not
actually connected to the function, two things happened:

1. The attempt to remove the function from the signal array didn't do anything
2. Unreferencing the function noticed that the function wasn't referenced

The second step printed a big, fat scary warning.

Actually, this has the possibility of causing errors. For example, in the
following code, awesome would wrongly unreference the function at the
disconnect_signal() call and might later still try to call it when the
"refresh" signal is emitted:

do
    local function f() end
    awesome.connect_signal("refresh", f)
    awesome.disconnect_signal("debug::error", f)
end

Fix this by making signal_disconnect() return a boolean value indicating if it
actually did something. All callers are fixed to use this value and only update
the reference counts if something was actually disconnected.

Fixes: https://github.com/awesomeWM/awesome/issues/814
Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-06-09 00:03:08 +02:00
Uli Schlachter 231436d9e3 C: Remove unneeded calls to signal_add()
Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-06-04 17:57:08 +02:00
Uli Schlachter a964396771 Deprecate signal_add() on C-API objects
This commit makes the code automatically add signals when they are first used.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-06-04 17:51:45 +02:00
Uli Schlachter a5a106f97f Make it possible for Lua to emulate arbitrary properties
This makes it possible to add something similar to a __index / __newindex
metamethod to all our C objects. Based on this, Lua can then easily implement
arbitrary properties on our capi objects.
2015-09-27 17:43:41 +02:00
Uli Schlachter 1408e8b952 Unset object's metatable in __gc
Run the following code:

  do
      local d
      local f = function() d.visible = true end
      if _VERSION >= "Lua 5.2" then
          setmetatable({}, { __gc = f })
      else
          getmetatable(newproxy(true)).__gc = f
      end
      d = drawin({})
  end
  collectgarbage("collect")

Awesome will segfault.

The reason for this is that after the above code ran, all variables in it are
unreferenced and will be garbage-collected at the next sweep phase. Lua runs
garbage collectors in the inverse order that their corresponding objects were
"marked" which means for the above code that the drawin's garbage collector will
run before function f runs. So the code will access the drawin after its
destructor already ran. Obviously, awesome's C code does not expect nor
correctly deal with this situation and was dereferencing a NULL pointer.

To fix this, this commit "unsets" the metatable of a userdata object when it is
being garbage collected. Since the type of a userdata is inferred via its
metatable, the object will no longer be accepted by luaA_toudata().

For the above code this will result in an unhelpful error message saying that
something tried to index a userdata, but userdata cannot be indexed. At least we
no longer crash and the traceback of the error will hopefully point at some __gc
metamethod which should be enough of a hint to figure out the problem.

Thanks-to: http://blog.reverberate.org/2014/06/beware-of-lua-finalizers-in-c-modules.html
Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-06-20 12:33:17 +02:00
Uli Schlachter f5610fa920 objects: Add .valid property (Fixes #110)
This property is especially useful for client objects which are unusable after
unmanage. "Unusuable" here means that pretty much everything you do with the
client object results in a lua error.

Syntax is c.valid.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-02-15 12:16:03 +01:00
Uli Schlachter 8eed5e7bcf client: Include c.name in the result of tostring(c)
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-12-06 18:16:05 +01:00
Uli Schlachter d2b1e92f9e Clean up header includes
Every .c file has to include the corresponding .h file first to make sure the
headers are self-contained. Additionally, this moves some unneeded includes
around.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-03-30 20:07:48 +02:00
Uli Schlachter 2b1febeabe Make objects properly inherit signals from classes
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-03-07 14:42:03 +01:00
Arvydas Sidorenko f41590e19c Wrapped luaL_register
Signed-off-by: Arvydas Sidorenko <asido4@gmail.com>
Signed-off-by: Julien Danjou <julien@danjou.info>
2012-06-12 13:32:40 +02:00
Arvydas Sidorenko f2942a994d luaL_typerror -> luaA_typerror
Lua 5.2 removed luaL_typerror leaving to write our own version
if need it.

Signed-off-by: Arvydas Sidorenko <asido4@gmail.com>
2012-06-12 10:56:19 +02:00
Arvydas Sidorenko d61cdb86c9 Renamed luaL_reg to luaL_Reg
The original struct name is luaL_Reg, but Lua v5.1 had a
`typedef luaL_reg luaL_Reg`, which in v5.2 was removed
and as a result breaking the build in Awesome which uses luaL_reg
version exclusively.

Signed-off-by: Arvydas Sidorenko <asido4@gmail.com>
2012-06-12 10:52:10 +02:00
Gregor Best c2ea920ca0 remove encoding=utf-8 from modelines
This option is no longer valid in modelines, so it has been removed from
all modelines using the following shellscript:

    #!/bin/ksh

    git ls-tree -r HEAD | cut -f2 | while read f; do
        egrep -e '^(//|--) vim: .*encoding=' $f >/dev/null || continue
        sed -E -e '/^(\/\/|--) vim:/s/:encoding=utf-8//' $f > /tmp/foo
        mv /tmp/foo $f
    done

Signed-off-by: Gregor Best <gbe@ring0.de>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2011-09-11 17:34:09 +02:00
Uli Schlachter 8701295e6c Track the number of objects
With this patch, we track the number of objects that are alive for any class.
This information can be accessed via class.instances()

For example:

  print("wiboxes", wibox.instances())
  print("widgets", widget.instances())

Signed-off-by: Uli Schlachter <psychon@znc.in>
2010-09-17 17:39:41 +02:00
Uli Schlachter eae3e5b9c4 luaclass properties: Use C strings
This modifies the lua class code to use C strings instead of the tokens
generated via gperf.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2010-09-01 15:41:41 +02:00
Uli Schlachter ab4c151ed8 Add signals before using them
This commit makes it an error if an unknown signal is connected, disconnected or
emitted. All signals have to be added before they can be used.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2010-08-25 23:00:36 +02:00
Uli Schlachter 948f960b7e Also rename the signal_* C function
Signed-off-by: Uli Schlachter <psychon@znc.in>
2010-08-25 20:48:42 +02:00
Julien Danjou 6d332f07a0 lua{class,object}: rename signals functions
I knew this was wrong at the beginning, f*ck.

Signed-off-by: Julien Danjou <julien@danjou.info>
2010-08-25 20:28:20 +02:00
Julien Danjou f523b37e1d lua{class,object}: {add,remove}_signal() take lua_CFunction as arg
Signed-off-by: Julien Danjou <julien@danjou.info>
2010-08-25 20:14:55 +02:00
Julien Danjou f7746a198c luaclass: take care of inheritance garbage collection
Signed-off-by: Julien Danjou <julien@danjou.info>
2010-05-28 13:27:49 +02:00
Julien Danjou fccc451f89 luaclass: add inheritance support
Signed-off-by: Julien Danjou <julien@danjou.info>
2010-05-28 13:27:04 +02:00
Julien Danjou d8c0f516ba luaclass: implement object checking
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-10-27 12:16:30 +01:00
Julien Danjou 4d0a025f51 luaclass: add handling of {new,}index of missing properties (FS#584)
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-08-21 15:30:48 +02:00
Julien Danjou f111d0cab1 luaclass: use signal_object_emit
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-08-21 15:30:48 +02:00
Julien Danjou dc61d258f0 luaclass: optimize type handling
We use lua_class_t pointer as key in the registry to store metatable we
will compare.
lauxlib uses a string, which sucks, because it forces to do a
pushliteral() each time you want to get a metatable from the registry,
which is slower.

Signed-off-by: Julien Danjou <julien@danjou.info>
2009-08-21 15:30:47 +02:00
Julien Danjou 6cfaafbab3 luaclass: remove useless property name
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-08-20 16:46:33 +02:00
Julien Danjou 45702de158 luaclass: add support for new()
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-08-17 17:45:17 +02:00
Julien Danjou 1300b16c1e luaclass: add generic {new,}index meta methods
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-08-17 17:45:14 +02:00
Julien Danjou 537506a0c1 luaclass: add property array handling in classes
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-08-17 17:45:10 +02:00
Julien Danjou 284338532b luaobject: add type recognition
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-07-29 15:48:19 +02:00
Julien Danjou 706d545076 luaclass: register class in an array
That should permit class identification.

Signed-off-by: Julien Danjou <julien@danjou.info>
2009-07-29 15:48:19 +02:00
Julien Danjou 4003ef726f luaclass: import class system
Signed-off-by: Julien Danjou <julien@danjou.info>
2009-07-29 15:48:18 +02:00