I am constructing widgets dynamically from from the output of iw dev interface scan I then add them to a scroll box held in a wibox. The problem I find is that the mouse::enter and mouse::leave signals I connect the widgets to do not catch the mouse signals when inside the wibox.container.scroll. All the rest of the code works as intended and the signals are caught as intended if I omit the wibox.container.scroll wrapper.
The widget template to be added to the scroll container:
function wifitbox.new(ssid, screen, interface)
tbox = wibox.widget{
{
{
wibox.widget.textbox(ssid[2] .. " " .. ssid[3]),
{
wibox.widget.textbox(ssid[4]),
halign = "right",
widget = wibox.container.place
},
layout = wibox.layout.ratio.horizontal
},
margins = beautiful.xresources.apply_dpi(10, screen),
widget = wibox.container.margin
},
id = "tbox",
bg = beautiful.wifi_tbox_bg or "#928374",
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 5)
end,
widget = wibox.container.background
}
awful.spawn.easy_async('bash -c "sudo iw dev ' .. interface .. ' station dump | awk \'FNR == 1 {print($2)}\'"', function(stdout)
if(gears.string.split(stdout, "\n")[1] == ssid[1]) then
tbox.bg = "#b16286"
end
end)
tbox:connect_signal("mouse::enter", function()
tbox.bg_cache = tbox.bg
tbox.bg = "#689d6a"
end)
tbox:connect_signal("mouse::leave", function()
tbox.bg = tbox.bg_cache
end)
return tbox
end
The two :signal_connect() statements are the ones in questions.
The widgets are added to the scroll container a follows:
awful.spawn.with_line_callback(cmd, {
stdout = function(line)
local ssid = gears.string.split(line, "\t")
wifitbox_table:get_children_by_id("tbox_list")[1]:add(wifitbox(ssid, screen, interface))
end,
output_done = function()
self:set_widget(wifitbox_table)
end
})
The widget the containing the scroll container is as follows:
local wifitbox_table = wibox.widget{
scrollbtn,
{
id = "scroll_box",
speed = 100,
extra_space = beautiful.xresources.apply_dpi(5, screen),
layout = wibox.container.scroll.vertical,
step_function = wibox.container.scroll.step_functions.linear_increase,
{
id= "tbox_list",
spacing = beautiful.xresources.apply_dpi(5, screen),
layout = wibox.layout.fixed.vertical()
}
},
spacing = beautiful.xresources.apply_dpi(5, screen),
layout = wibox.layout.fixed.vertical,
}
As I mentioned before if i remove the "scroll_box" widget around the "tbox_list" widget the signals connect without issue. But then obviously I don't get scrolling.
And finally all of it put together:
local awful = require('awful')
local wibox = require('wibox')
local gears = require('gears')
local beautiful = require('beautiful')
local wifimodal = { mt = {} }
local wifitbox = { mt = {} }
local setmetatable = setmetatable
function wifitbox.new(ssid, screen, interface)
tbox = wibox.widget{
{
{
wibox.widget.textbox(ssid[2] .. " " .. ssid[3]),
{
wibox.widget.textbox(ssid[4]),
halign = "right",
widget = wibox.container.place
},
layout = wibox.layout.ratio.horizontal
},
margins = beautiful.xresources.apply_dpi(10, screen),
widget = wibox.container.margin
},
id = "tbox",
bg = beautiful.wifi_tbox_bg or "#928374",
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 5)
end,
widget = wibox.container.background,
}
awful.spawn.easy_async('bash -c "sudo iw dev ' .. interface .. ' station dump | awk \'FNR == 1 {print($2)}\'"', function(stdout)
if(gears.string.split(stdout, "\n")[1] == ssid[1]) then
tbox.bg = "#b16286"
end
end)
tbox:connect_signal("mouse::enter", function()
tbox.bg_cache = tbox.bg
tbox.bg = "#689d6a"
end)
tbox:connect_signal("mouse::leave", function()
tbox.bg = tbox.bg_cache
end)
return tbox
end
function wifitbox.mt.__call(_, ...)
return wifitbox.new(...)
end
setmetatable(wifitbox, wifitbox.mt)
function wifimodal.new(screen, interface, curSSID)
self = wibox {
screen = screen,
width = screen.geometry.width / 5,
type = 'modal',
height = screen.workarea.height/2,
x = screen.geometry.width - screen.geometry.width/5,
y = beautiful.xresources.apply_dpi(beautiful.wibar_height or 25, screen),
ontop = true,
visible = true,
bg = beautiful.bg_normal,
fg = "black",
opacity = 0.8,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 5)
end
}
self:connect_signal('mouse::leave', function()
self.visible = false
self = nil
end)
local scrollbtn = wibox.widget{
{
{
widget = wibox.widget.imagebox,
resize = true,
image = gears.filesystem.get_configuration_dir() .. "widgets/wifi/arrow_up.png",
forced_height = beautiful.xresources.apply_dpi(25, screen),
},
widget = wibox.container.place,
valign = "center",
},
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 5)
end,
widget = wibox.container.background,
bg = beautiful.wifi_scroll_btn_bg or "#d79921",
}
scrollbtn:connect_signal("mouse::enter", function()
scrollbtn:emit_signal_recursive("scroll::continue")
scrollbtn.bg = beautiful.wifi_scroll_btn_bg_hover or "#458588"
end)
scrollbtn:connect_signal("mouse::leave", function()
scrollbtn:emit_signal_recursive("scroll::pause")
scrollbtn.bg = beautiful.wifi_scroll_btn_bg or "#d79921"
end)
local scan_awk = gears.filesystem.get_configuration_dir() .. "widgets/wifi/scan.awk"
local cmd = 'bash -c "sudo iw ' .. interface .. ' scan | awk -f ' .. scan_awk .. '"'
local wifitbox_table = wibox.widget{
scrollbtn,
{
id = "scroll_box",
speed = 100,
extra_space = beautiful.xresources.apply_dpi(5, screen),
layout = wibox.container.scroll.vertical,
step_function = wibox.container.scroll.step_functions.linear_increase,
{
id= "tbox_list",
spacing = beautiful.xresources.apply_dpi(5, screen),
layout = wibox.layout.fixed.vertical()
}
},
spacing = beautiful.xresources.apply_dpi(5, screen),
layout = wibox.layout.fixed.vertical,
}
local scrollbox = wifitbox_table:get_children_by_id("scroll_box")[1]
scrollbox:pause()
wifitbox_table:connect_signal("scroll::continue", function()
scrollbox:continue()
end)
wifitbox_table:connect_signal("scroll::pause", function()
scrollbox:pause()
end)
awful.spawn.with_line_callback(cmd, {
stdout = function(line)
local ssid = gears.string.split(line, "\t")
wifitbox_table:get_children_by_id("tbox_list")[1]:add(wifitbox(ssid, screen, interface))
end,
output_done = function()
self:set_widget(wifitbox_table)
end
})
return self
end
function wifimodal.mt.__call(_, ...)
return wifimodal.new(...)
end
return setmetatable(wifimodal, wifimodal.mt)
Here is a screen shot for some context:
Also, if you don't have the answer but notice something else you can critic feel free. Thank you
