-
Notifications
You must be signed in to change notification settings - Fork 590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make the wibox get_children_by_id reliable #2181
Comments
So... basically, |
does that also implies what we need to add some recursive check to ensure what id is unique? or if id is the same list of widgets should be returned? |
The problem right now is that if you create widgets with As @psychon sugested solution demonstrate, the easy way to do this is So both solutions have big drawbacks and it's why it wasn't implemented yet. In theory, the lookup happens more often than building new trees, so it should be prioritized in term of performance (slower tree building for faster lookups instead of the other way around). This is why I think the solution should involve being able to track changes to the subtrees. That also make the solution more complicated. Maybe moving that to the |
and does having ids worth it? i think using variable or table to store references when it's needed is quite viable solution. especially if infrastructure for ids could not only encomplicate the code but also cause some performance affect |
Honestly, I don't know. I made it this way so people coming from JavaScript don't have to learn anything new and make the wibox "DOM-like". This issue was reported twice and I never seen the alternate One way or another, it uses IDs, so something has to be done. As said by the previous commit, maybe it's a good idea to extend the hierarchy itself to manage that list instead of inventing a new system just for IDs. |
Sigh. I'd say "premature optimisation", but no one would listen to me anyway... So, how about amortised O(1) performance? You have a first commit that does the "ugly" O(N) lookup. If you want, you can measure the performance (relative to e.g. redrawing a wibox, or something). At this point I'd likely conclude "fast enough" and be done, but since you want this to be faster: Next, you add a cache to I'm not quite sure what you want to do in P.S.: Why does Edit: Actually, you want to wire up |
Before this commit, it was added by `wibox.widget.base` if `:setup()` is used. However it doesn't work for the `awful.popup` because of the extra indirection. This commit stops the monkey-patching and make sure the function always exists. This doesn't prevent it from not working and in the long run this should still be moved into the hierarchy. However for now it makes the situation a lot more consistent and is a quick band-aid without too much controversy. Mitigate awesomeWM#2181
This commit does two things: It gets rid of the reference to the layoutbox that the default config created and it changes the widget dependency cache to not keep widgets alive unnecessarily. Signed-off-by: Uli Schlachter <psychon@znc.in>
Before this commit, it was added by `wibox.widget.base` if `:setup()` is used. However it doesn't work for the `awful.popup` because of the extra indirection. This commit stops the monkey-patching and make sure the function always exists. This doesn't prevent it from not working and in the long run this should still be moved into the hierarchy. However for now it makes the situation a lot more consistent and is a quick band-aid without too much controversy. Mitigate awesomeWM#2181
Since this is listed as a release-blocker and progress on it was... well, slow, here is an untested implementation of diff --git a/lib/wibox/drawable.lua b/lib/wibox/drawable.lua
index cf9a129e..786bc0d0 100644
--- a/lib/wibox/drawable.lua
+++ b/lib/wibox/drawable.lua
@@ -27,6 +27,16 @@ local visible_drawables = {}
local systray_widget
+local function _do_get_children_by_id(self, id)
+ local result = {}
+ for _, w in pairs(self:get_children()) do
+ if w.id == id then
+ table.insert(result, w)
+ end
+ end
+ return result
+end
+
-- Get the widget context. This should always return the same table (if
-- possible), so that our draw and fit caches can work efficiently.
local function get_widget_context(self)
@@ -104,6 +114,9 @@ local function do_redraw(self)
x = 0, y = 0, width = width, height = height
})
end
+
+ -- Kill the cache
+ self._get_children_by_id = require("gears.cache")(_do_get_children_by_id)
end
-- Clip to the dirty area
@@ -309,6 +322,10 @@ function drawable:_inform_visible(visible)
end
end
+function drawable:get_children_by_id(id)
+ return self._get_children_by_id(self, id)
+end
+
local function emit_difference(name, list, skip)
local function in_table(table, val)
for _, v in pairs(table) do
@@ -383,6 +400,8 @@ function drawable.new(d, widget_context_skeleton, drawable_name)
end
end
+ ret._get_children_by_id = function() return {} end
+
-- Only redraw a drawable once, even when we get told to do so multiple times.
ret._redraw_pending = false
ret._do_redraw = function() |
And just because, here is the beginning of a hierarchy-based approach: diff --git a/lib/wibox/hierarchy.lua b/lib/wibox/hierarchy.lua
index e0da295c..e1d1b2e2 100644
--- a/lib/wibox/hierarchy.lua
+++ b/lib/wibox/hierarchy.lua
@@ -48,6 +48,7 @@ local function hierarchy_new(redraw_callback, layout_callback, callback_arg)
},
_parent = nil,
_children = {},
+ _children_by_id = {},
_widget_counts = {},
}
@@ -190,6 +191,24 @@ function hierarchy_update(self, context, widget, width, height, region, matrix_t
x = new_x, y = new_y, width = new_width, height = new_height
})
end
+
+ -- Update children by id
+ self._children_by_id = {}
+ local function merge(children_by_id)
+ for id, other_list in pairs(children_by_id) do
+ local own_list = self._children_by_id[id] or {}
+ self._children_by_id[id] = own_list
+ for _, w in ipairs(other_list) do
+ table.insert(own_list, w)
+ end
+ end
+ end
+ if self._widget.id then
+ merge({ [self._widget.id] = { self } })
+ end
+ for _, h in ipairs(self._children) do
+ merge(h._children_by_id)
+ end
end
--- Create a new widget hierarchy that has no parent.
@@ -282,6 +301,13 @@ function hierarchy:get_children()
return self._children
end
+--- TODO
+-- @arg todo
+-- @return todo
+function hierarchy:get_children_recursively_by_id(id)
+ return self._children_by_id[id] or {}
+end
+
--- Count how often this widget is visible inside this hierarchy. This function
-- only works with widgets registered via `count_widget`.
-- @param widget The widget that should be counted |
Before this commit, it was added by `wibox.widget.base` if `:setup()` is used. However it doesn't work for the `awful.popup` because of the extra indirection. This commit stops the monkey-patching and make sure the function always exists. This doesn't prevent it from not working and in the long run this should still be moved into the hierarchy. However for now it makes the situation a lot more consistent and is a quick band-aid without too much controversy. Mitigate awesomeWM#2181
Before this commit, it was added by `wibox.widget.base` if `:setup()` is used. However it doesn't work for the `awful.popup` because of the extra indirection. This commit stops the monkey-patching and make sure the function always exists. This doesn't prevent it from not working and in the long run this should still be moved into the hierarchy. However for now it makes the situation a lot more consistent and is a quick band-aid without too much controversy. Mitigate awesomeWM#2181
Before this commit, it was added by `wibox.widget.base` if `:setup()` is used. However it doesn't work for the `awful.popup` because of the extra indirection. This commit stops the monkey-patching and make sure the function always exists. This doesn't prevent it from not working and in the long run this should still be moved into the hierarchy. However for now it makes the situation a lot more consistent and is a quick band-aid without too much controversy. Mitigate #2181
can this be closed now or after you'll move it to hierarchy? |
It has to be ported to the hierarchy before we can really unify the wibox constructors (as we both discussed and agreed upon elsewhere). Example: works: local l = wibox.widget {
{
id = "foobar",
text = "foobar",
widget = wibox.widget.textbox,
},
layout = wibox.layout.fixed.horizontal
} broken: local l = wibox.layout.fixed.horizontal {
wibox.widget.textbox {
id = "foobar",
text = "foobar",
}
} Of course, in this example, there is a whole bunch of issue. First of all, the fixed need to support |
…meWM#2513) Before this commit, it was added by `wibox.widget.base` if `:setup()` is used. However it doesn't work for the `awful.popup` because of the extra indirection. This commit stops the monkey-patching and make sure the function always exists. This doesn't prevent it from not working and in the long run this should still be moved into the hierarchy. However for now it makes the situation a lot more consistent and is a quick band-aid without too much controversy. Mitigate awesomeWM#2181
…meWM#2513) Before this commit, it was added by `wibox.widget.base` if `:setup()` is used. However it doesn't work for the `awful.popup` because of the extra indirection. This commit stops the monkey-patching and make sure the function always exists. This doesn't prevent it from not working and in the long run this should still be moved into the hierarchy. However for now it makes the situation a lot more consistent and is a quick band-aid without too much controversy. Mitigate awesomeWM#2181
Output of
awesome --version
:4.0 to git-master.
Right now it doesn't cross the
wibox.widget {}
sections that can be pasted from the documentation inside of a wibox:setup{}
section. So copy-pasted documentation examples end up confusingly "working" visually, but are not reachable. This was reported on reddit and is indeed a prime example of confusing anti-features.Opening this issue so it is not forgotten.
The text was updated successfully, but these errors were encountered: