Closed jandob closed 5 years ago
Is there any possibility to have widgets in an awful.tooltip?
Nope, sorry.
If not, can someone provide any pointers on how to place a widget outside the wibar?
-- Preparation
local tooltip_widget = whatever
local w = wibox{ width = 42, height = 42, widget = tooltip_widget }
-- Making visible
awful.placement.left(w, { parent = mouse, offset = { x=1, y=0 }})
w.visible = true
-- Hiding
w.visible = false
And if you want to implement your own tooltip on something:
local widget = whatever
local tooltip_widget = whatever
local w = wibox{ width = 42, height = 42, widget = tooltip_widget }
widget:connect_signal("mouse::enter", function()
awful.placement.left(w, { parent = mouse, offset = { x=1, y=0 }})
w.visible = true
end)
widget:connect_signal("mouse::leave", function()
w.visible = false
end)
If you wonder "how do I pick good values for width and height?", then you found out why awful.tooltip
cannot display arbitrary widgets (yet). A text can be queried for its size (more or less...), but arbitrary widgets cannot.
(Memo to myself: awful.tooltip
could provide a function set_widget(widget, width, height)
, I think....)
Thanks for your quick response, i have got it working now!
In case you are curious, here is my current implementation:
volWidget:connect_signal("mouse::enter", function(other, geo)
pulseaudio.get_devices(function (deviceList)
local wibox_height = 0
local slider_height = 20
local slider_width = 100
local sliders = wibox.widget {
forced_width = slider_width,
layout = wibox.layout.flex.vertical
}
for _, device in ipairs(deviceList) do
local slider = wibox.widget(slider_properties)
slider.value = device.volume
slider.pulseaudio_device = device
slider:connect_signal("widget::redraw_needed", function ()
-- called when the slider value changes
if not slider.pulseaudio_device then return end
pulseaudio.set_volume(slider.pulseaudio_device, slider.value)
end)
sliders:add(slider)
wibox_height = wibox_height + slider_height
end
local w = wibox {
width = slider_width,
height = wibox_height,
ontop = true,
widget = sliders,
}
w:connect_signal("mouse::leave", function()
-- TODO how to destroy the wibox? (so it gets garbage collected)
w.visible = false
end)
awful.placement.next_to(w, {
preferred_positions = {"top", "right", "left", "bottom"},
geometry = geo,
honor_workarea = true,
})
awful.placement.no_offscreen(w)
w.visible = true
end)
end)
One Question remains:
Since i am dynamically building the slider widgets, how can i delete them in the mouse::leave
callback? (see TODO in the code)
And another small remark:
I couldn't find documentation on the arguments in the mouse::enter
callback, i copied that from the awful.tooltip
implementation. Shouldn't this be in the documentation for wibox.widget.base
?
slider:connect_signal("widget::redraw_needed", function () -- called when the slider value changes
I would propose property::value
instead (not that it makes much of a difference, but still...)
One Question remains: Since i am dynamically building the slider widgets, how can i delete them in the mouse::leave callback? > (see TODO in the code)
In Lua, everything is garbage collected when it is no longer references. When you do w.visible = true
, the C code adds a reference to prevent the wibox from getting garbage collected. w.visible = false
drops that reference. I think that nothing in your code keeps a (reachable) reference to the wibox after mouse::leave
, so it should be garbage-collectable.
To test this, you could use awesome-client 'collectgarbage("collect") return drawin.instances()'
in a shell. The value that you get here should stay the same over time (unless e.g. awful.tooltip
starts creating new wiboxes; so it should stay the same when you triggered your popup).
I couldn't find documentation on the arguments in the mouse::enter callback, i copied that from the awful.tooltip implementation. Shouldn't this be in the documentation for wibox.widget.base?
Hm, I guess. @Elv13 ? However, you can find it on the individual widgets: https://awesomewm.org/doc/api/classes/wibox.widget.checkbox.html#mouse::enter
i copied that from the awful.tooltip implementation.
Please, don't ask why awful.tooltip
does something different than the docs above say. I'm not happy with the reason....
I finished a first working version of the pulseaudio widget and leave it here as a reference for anyone trying to implement a richer tooltip: https://github.com/jandob/pulseaudio
I tested the garbage collection, and indeed setting wibox.visible to false is sufficient for garbage collection.
Also i am using the property::value
signal now (couldn't find it in the documentation either :) )
Also i am using the property::value signal now (couldn't find it in the documentation either :) )
Hm... It's implicit. Each property called foo
has an implicit signal property::foo
that should be emitted when it changes.
Ok, maybe this could be mentioned somewhere. Is this true for all classes? I think the documentation could be more consistent here, some examples from different classes:
drawable
: the property change signals are documented in the "Signals" section, no documentation of the properties themselveclient
: documented for each individual property; four properties additionaly in the "Signals" sectionwibox
: documented for each individual property; no signals sectionwibox.widget.slider
not documented; same for the other wibox.widget.*
classesAfter 7 (!!!) years of procrastination, the popup widget is now upstreamed and will be part of Awesome v4.3. It can be used in the same way as the tooltip, but with widgets.
I am currently trying to make a volume control widget for pulse audio. On mouse over it would be nice to show volume control sliders for all sinks, sources and clients.
Is there any possibility to have widgets in an
awful.tooltip
? If not, can someone provide any pointers on how to place a widget outside the wibar?