Search code examples
widgetawesome-wm

A way to scroll a layout's widgets using mouse?


Can you help me on how to scroll a layout's content using mouse? Or is it possible?

I created this notification-center widget and I used wibox.layout.fixed.vertical() to act the storage of the widgets/notifications. My problem is having too many widgets will consume all the space and there will be no enough space to display the other widgets. So I've been trying to make the widget inside the wibox.layout.fixed.vertical() scrollable but I'm always reaching a dead end. I also tried the wibox.container.scroll but as the documentation says:

Please note that mouse events do not propagate to widgets inside of the scroll container.

This is the simple code I'm using:

-- Layout
local notifbox_layout = wibox.layout.fixed.vertical()

-- Add these textbox widgets to layout
-- Make this widgets scrollable if there's too many of them
notifbox_layout:insert(1, wibox.widget.textbox('String 1'))
notifbox_layout:insert(1, wibox.widget.textbox('String 2'))
notifbox_layout:insert(1, wibox.widget.textbox('String 3'))
notifbox_layout:insert(1, wibox.widget.textbox('String 4'))
notifbox_layout:insert(1, wibox.widget.textbox('String 5'))

-- Mouse event
notifbox_layout:buttons(
    gears.table.join(
        awful.button(
            {},
            4,
            nil,
            function()
                -- some magic here to scroll up
            end
        ),
        awful.button(
            {},
            5,
            nil,
            function()
                -- some magic here to scroll down
            end
        )
    )
)

This is the notification center with no enough space to show the other widgets

Sorry if I explained this bad. I'm not really that good in english.


Solution

  • Nevermind. I tried Uli Schlachter's answer here. And it works perfectly. I modified it a bit and then it looks like this.

    local w = wibox{ x = 100, y = 100, width = 100, height = 20, visible = true }
    
    my_wiget = function()
        return some_widget
    end
    
    local own_widget = wibox.widget.base.make_widget()
    local offset_x, offset_y = -20, 0
    function own_widget:layout(context, width, height)
        -- No idea how to pick good widths and heights for the inner widget.
        return { wibox.widget.base.place_widget_at(my_widget(), offset_x, offset_y, 200, 40) }
    end
    
    own_widget:buttons(
        awful.util.table.join(
            awful.button(
                {},
                4,
                function()
                    if offset_y <= 490 then
                        offset_y = offset_y + 5
                    end
                    own_widget:emit_signal("widget::layout_changed")
                end
            ),
            awful.button(
                {},
                5,
                function()
                    if offset_y >= 5 then
                        offset_y = offset_y - 5
                    end
                    own_widget:emit_signal("widget::layout_changed")
                end
            )
        )
    )
    
    w:set_widget(own_widget)