Итак, вам нужна сложная версия, которая обрезает содержащийся в ней виджет до его размера, а также обрабатывает события ввода. Ниже приведена сложная и медленная версия:
local inner_widget = screen[1].mytaglist
local inner_width, inner_height = 200, 40
-- No idea how to pick a good width and height for the wibox.
local w = wibox{ x = 100, y = 100, width = 100, height = 20, visible = true }
local own_widget = wibox.widget.base.make_widget()
w:set_widget(own_widget)
local offset_x, offset_y = -20, 0
local own_context = { screen = screen[1], dpi = 92 } -- We have to invent something here... :-(
local hierarchy
hierarchy = wibox.hierarchy.new(own_context, inner_widget, inner_width, inner_height, function()
own_widget:emit_signal("widget::redraw_needed")
end, function()
hierarchy:update(own_context, inner_widget, inner_width, inner_height)
own_widget:emit_signal("widget::redraw_needed")
end, nil)
function own_widget:draw(context, cr, width, height)
-- This does the scrolling
cr:translate(offset_x, offset_y)
-- Then just draw the inner stuff directly
hierarchy:draw(own_context, cr)
end
-- Start a timer to simulate scrolling: Once per second we move things slightly
gears.timer.start_new(1, function()
offset_x = - offset_x
own_widget:emit_signal("widget::redraw_needed")
return true
end)
-- Finally, make input events work
local function button_signal(name)
-- This function is basically copy&paste from find_widgets() in
-- wibox.drawable
local function traverse_hierarchy_tree(h, x, y, ...)
local m = h:get_matrix_from_device()
-- Is (x,y) inside of this hierarchy or any child (aka the draw extents)?
-- If not, we can stop searching.
local x1, y1 = m:transform_point(x, y)
local x2, y2, w2, h2 = h:get_draw_extents()
if x1 < x2 or x1 >= x2 + w2 then
return
end
if y1 < y2 or y1 >= y2 + h2 then
return
end
-- Is (x,y) inside of this widget?
-- If yes, we have to emit the signal on the widget.
local width, height = h:get_size()
if x1 >= 0 and y1 >= 0 and x1 <= width and y1 <= height then
h:get_widget():emit_signal(name, x1, y1, ...)
end
-- Continue searching in all children.
for _, child in ipairs(h:get_children()) do
traverse_hierarchy_tree(child, x, y, ...)
end
end
own_widget:connect_signal(name, function(_, x, y, ...)
-- Translate to "local" coordinates
x = x - offset_x
y = y - offset_y
-- Figure out which widgets were hit and emit the signal on them
traverse_hierarchy_tree(hierarchy, x, y, ...)
end)
end
button_signal("button::press")
button_signal("button::release")
Вместо того, чтобы позволить AwesomeWM справиться со всем и просто поместить еще один виджет в :layout
, этот код делает больше сам. А именно, он напрямую управляет деревом виджетов (называемым "иерархией" в AwesomeWM) и рисует его сам. Половина этого кода затем отвечает за обработку событий кнопок: когда они приходят, этот код перенаправляет их в нужный виджет, принимая во внимание текущую прокрутку.
Обратите внимание, что это перерисовывает все, что показывает этот пользовательский виджет, всякий раз, когда что-либо изменяется. Я предполагаю, что для вашей проблемы с прокруткой это необходимо в любом случае, потому что «все меняется», когда вы немного прокручиваете. Однако, когда AwesomeWM сам рисует некоторые виджеты, он пытается перерисовать только ту часть, которая действительно изменилась. Например, если часы обновляются из-за изменения времени, будут перерисованы только часы. Этот код здесь вместо этого всегда перерисовывает все.
(И да, я знаю, что этот код довольно сомнительный и плохой, но он должен помочь вам определить необходимые ингредиенты.)
person
Uli Schlachter
schedule
09.05.2019