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
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
The third sentence on https://awesomewm.org/doc/api/classes/wibox.container.scroll.html is:
Please note that mouse events do not propagate to widgets inside of the scroll container.
So, this is "working as intended".