shdown / luastatus

universal status bar content generator
GNU General Public License v3.0
295 stars 12 forks source link

Is there a way to manually trigger the callback within a widget? #48

Closed cdlscpmv closed 5 years ago

cdlscpmv commented 5 years ago

I would like to be able to hide a widget after some time by returning nil to the callback function. Is there a way to accomplish this?

shdown commented 5 years ago

For most plugins (except for xkb and xtitle), there is a way to do this. Which plugin does your widget use?

cdlscpmv commented 5 years ago

There are two plugins: alsa and backlight.

shdown commented 5 years ago

backlight has this behavior by default, doesn’t it?

As for alsa, there is a way, but it’s hacky/ugly. Rather, I will add the timeout functionality to the plugin soon.

cdlscpmv commented 5 years ago

backlight has this behavior by default, doesn’t it?

Yeah, it does. I've missed it somehow.

As for alsa, there is a way, but it’s hacky/ugly. Rather, I will add the timeout functionality to the plugin soon.

That would be great!

shdown commented 5 years ago

Done, now the alsa plugin supports the timeout option.

Suggested use is:

widget = {
    plugin = 'alsa',
    opts = {
        -- your options here
        timeout = 3,
    },
    cb = function(t)
        if t == nil then
            return nil
        end
        if t.mute then
            return {full_text = '[mute]', color = '#e03838'}
        else
            local percent = (t.vol.cur - t.vol.min)
                          / (t.vol.max - t.vol.min)
                          * 100
            return {full_text = string.format('[%3d%%]', math.floor(0.5 + percent)),
                    color = '#718ba6'}
        end
    end,
    -- probably an 'event' function here
}

P.S. see also this example for i3 for hiding/showing info on click.

cdlscpmv commented 5 years ago

Thank you!

But here is a small nitpick if you don't mind. Why did you move the timeout option into the opts table? This isn't the case with the backlight module where this option is packed straight into widget. Isn't it better to have some consistency across modules?

shdown commented 5 years ago

backlight is a derived plugin, that is, a plugins written in Lua that uses another plugin; alsa is a proper plugin written in C.

widget.opts is the normal, expected way that a widget passes options to a proper plugin (written in C).

Derived plugins, on the other hand, provide the widget function that returns the table that luastatus expects to see as the global widget variable. Thus, when using a derived plugin, you usually do the following:

widget = luastatus.require_plugin('<NAME_OF_DERIVED_PLUGIN>').widget{
    -- some parameters (anything that the derived plugin supports)
}
-- Note this is *very* different from
--   widget = {
--      plugin = '<NAME_OF_PROPER_PLUGIN>',
--      -- some parameters (`opts`, `cb`, `event`)
--   }

But the semantics of the argument of this widget function is vastly different from the semantics of the global widget variable (that this function constructs). Thus, it makes sense for them to be inconsistent in ways they take options, both from practical (Lua plugins has to extract options from the opts subtable?) and theoretical points of view.

For better understanding, you can read the code of the backlight plugin: https://github.com/shdown/luastatus/blob/master/plugins/backlight-linux/backlight-linux.lua (it isn’t that big :)

shdown commented 5 years ago

P.S. Trying to implement the same for the pulse plugin, I ended up filing a bug against PulseAudio: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/merge_requests/104

So no timeouts for the pulse plugin, for now.

cdlscpmv commented 5 years ago

I can see the difference now. But still, I think it is better to remove the destinction between proper and derived plugins for the end user. It should not matter to them whether a plugin is a shared library or just a lua script. Or are there any subtleties to treating them in the same way?

shdown commented 5 years ago

You may have a point there. However,

  1. I believe in the Worse is Better philosophy, particulary, in that the simplicity of implementation is paramount, and that consistency can be sacrificed for its sake;

  2. the change you propose would break backward compatibility.