awesomeWM / awesome

awesome window manager
https://awesomewm.org/
GNU General Public License v2.0
6.39k stars 597 forks source link

:get_children_by_id on awful.titlebar throws an error #3800

Open yessiest opened 1 year ago

yessiest commented 1 year ago

Output of awesome --version:

awesome v4.3-1589-gb6263bf20 (Too long)
 • Compiled against Lua 5.4.4 (running with 0.9.2)
 • API level: 4
 • D-Bus support: yes
 • xcb-errors support: no
 • execinfo support: yes
 • xcb-randr version: 1.6
 • LGI version: /usr/share/lua/5.4/lgi/version.lua
 • Transparency enabled: yes
 • Custom search paths: no

How to reproduce the issue:

Create an awful.titlebar object and call :get_children_by_id("<some valid widget id>") on it

Actual result: A nil value error

error: /usr/share/awesome/lib/awful/titlebar.lua:754: attempt to index a nil value (field '_drawable')

Expected result:

A table of widgets with matching ids (the default behavior of :get_children_by_id)

paulhersch commented 1 year ago

from the source it seems like awful.titlebar doesn't use : for get_children_by_id but instead .. For reference: lib/awful/titlebar.lua:807

Aire-One commented 1 year ago

Hello @yessiest, do you have a code example of what you are actually doing?

@paulhersch, note that the line you are pointing to is a basic function assignation to a member of the returned table. It does not define how the user should invoke the function. The colon operator in Lua is a kind of Syntactic Sugar. foo:bar(1) is strictly equivalent to foo.bar(foo, 1). See https://www.lua.org/pil/16.html

sclu1034 commented 1 year ago

I don't see why a code example would be needed in this case.

The local get_children_by_id attempts to index a value self._drawable, which doesn't exist. self is the drawable (ret = drawable() in the constructor).

So the first step to try would be

-    if self._drawable._widget
-      and self._drawable._widget._private
-      and self._drawable._widget._private.by_id then
-          return self._drawable.widget._private.by_id[name]
+    local widget = self:get_widget()
+
+    if widget
+      and widget._private
+      and widget._private.by_id then
+          return widget._private.by_id[name]
    end

Though, a better approach than relying on accessing _private would probably be to remove the custom get_children_by_id and to rely on the fact that base.widget.setup sets up its own version of that method.

TIAcode commented 4 months ago

Any solutions for this one? I can't seem to get it working, trying to access a textbox widget in a titlebar to set the markup but errors at get_children_by_id. Change suggested by @sclu1034 broke awesome.