Search code examples
widgetopacitytitlebarawesome-wm

slider widget in titlebars


I'd like to put a slider in each client's titlebar so it can control its opacity.
In official rc.lua, in the titlebar config we can find :
awful.titlebar.widget.floatingbutton (c)
so the client's id is sent to the widget

I thought of something like the code below :

local MAX = 1
local MIN = 0
--
-- le widget slider
opaciteControle = wibox.widget {
   --forced_width        = 100,
   bar_shape           = gears.shape.rounded_rect,
   bar_height          = 1,
   bar_color           = beautiful.border_color,
   --handle_color        = beautiful.bg_normal,
   handle_color        = "#FFFFFF",
   handle_shape        = gears.shape.circle,
   handle_border_color = beautiful.border_color,
   handle_border_width = 1,
   minimum             = MIN,
   maximum             = MAX,
   value               = .8,
   widget              = wibox.widget.slider,
}
-- le widget text
opaciteTexte = wibox.widget {
   text                = "opacite",
   align               = "center",
   widget              = wibox.widget.textbox,
}
-- le widget à afficher
opacite = wibox.widget {
   opaciteTexte,
   opaciteControle,
   vertical_offset=5,
   layout=wibox.layout.stack
}
-- actualisation
opaciteControle:connect_signal("widget::redraw_needed", function(c)
                     local v=opaciteControle.value
                     --
                     c.opacity=v
end)

and finally insert this widget in the titlebar's layout but this dosesn't work ; client's id doesn't seem to be properly pass to the function.

Thanks for helping me
David


Solution

  • Add opacity_button(c), e.g. before awful.titlebar.widget.floatingbutton(c), in your config. Somewhere earlier add the following to your config:

    local function opacity_button(c)
        local SCALE = 100
        local slider = wibox.widget {
           --forced_width        = 100,
           bar_shape           = gears.shape.rounded_rect,
           bar_height          = 1,
           bar_color           = beautiful.border_color,
           --handle_color        = beautiful.bg_normal,
           handle_color        = "#FFFFFF",
           handle_shape        = gears.shape.circle,
           handle_border_color = beautiful.border_color,
           handle_border_width = 1,
           minimum             = 0,
           maximum             = SCALE,
           value               = c.opacity * SCALE,
           widget              = wibox.widget.slider,
        }
    
        c:connect_signal("property::opacity", function()
            slider.value = c.opacity * SCALE
        end)
        slider:connect_signal("property::value", function()
            c.opacity = slider.value / SCALE
        end)
    
        -- Wrap other widgets around slider here if you want,
        -- e.g. your stack widget and the textbox
        local result = slider
        return slider
    end
    

    I do not know why you use the widget::redraw_signal signal. This instead uses the property::value signal of the slider. Also, this widget updates the slider in case the opacity of a client changes through some external means (i.e. outside of this widget).

    Oh and: This scales the value that came from the widget by 100 since the slider widget only produces integer values (at least in my testing).

    Note that this code passes the client object to the widget in the same way as e.g. the floatingbutton: As a an upvalue to a signal connection function. I do not know how you found widget::redraw_needed, but it does not get a client as its first argument.