【问题标题】:Awesomewm update watch widget on keypressAwesomewm 在按键上更新手表小部件
【发布时间】:2020-06-20 19:26:28
【问题描述】:

我是 awesomewm 的新用户(但之前使用过其他 WM:i3、bspwm、xmonad 等)。我喜欢在我的 wibar 中编写一些 shell 脚本(我认为这就是它的名称,屏幕顶部带有 taglist 的栏)来显示电池、音频等内容(据我所知很常见) .目前我正在使用“wibar.widget.watch”来执行此操作,如下所示。

        -- Right widgets
    layout = wibox.layout.fixed.horizontal,
    awful.widget.watch('musicbar', 5),
    wibox.widget.textbox('  |  '),
    awful.widget.watch('wifibar', 5),
    wibox.widget.textbox('  |  '),
    awful.widget.watch('audiobar', 0.5),
    wibox.widget.textbox('  |  '),
    awful.widget.watch('batbar', 5),

在上面的代码中,诸如“audiobar”之类的东西是作为标准输出返回信息的脚本。这一切都很完美,甚至可以很好地显示表情符号:)。我有一个问题(也许只是优化)。

目前我的音频条每秒运行两次,这是因为这是唯一一个根据我的输入(改变音量)直接改变的音频条,所以我希望它立即改变(显然这仍然有

所以,我想知道是否有办法在我更改音量时更新它,我已经绑定到 rc.lua 中的 XF86 音频键,而不是根据计时器进行更改。根据我对文档的阅读,手表小部件无法做到这一点,但正如我所说,我是新来的。

以下是我绑定键的方式(不应该有所作为,但我想这就是要进行更改的地方)。

awful.key(
 {},
 "XF86AudioLowerVolume",
 function()
        awful.spawn("amixer -q set Master 5%-")
 end,
 {description = "lower volume", group = "control"}
),

我知道我可以使用 github 上的一些预制小部件来显示音量和内容,但我喜欢 shell 脚本,因为它们让我可以轻松地在 WM 之间移动并且比那些小部件更简单(我喜欢它,因为这意味着我可以更轻松地解决他们的问题,让他们准确地展示我想要的东西,以及学习)。

edit:我愿意学习用lua做这个,我只是想先看看我是否可以用shell脚本轻松地做到这一点。

【问题讨论】:

    标签: awesome-wm


    【解决方案1】:

    您需要保留对 awful.widget.watch 在内部创建的计时器的引用。为此,您需要在全局上下文中执行类似的操作(即在小部件或键绑定的定义之外):

    local musicbar_widget, musicbar_timer = awful.widget.watch('musicbar', 5)
    

    您现在将musicbar_widget 添加到您的wibox(而不是在那里调用awful.widget.watch)。现在,您可以通过musicbar_timer:emit_signal("timeout")“强制更新”小部件。这“假装”小部件再次发生超时。

    在您的键绑定中(是的,我在这里混合了您的小部件,很可能musicbarvolume 无关):

    awful.key(
     {},
     "XF86AudioLowerVolume",
     function()
            awful.spawn("amixer -q set Master 5%-")
            musicbar_timer:emit_signal("timeout")
     end,
     {description = "lower volume", group = "control"}
    ),
    

    请注意,这可能有效,也可能无效。 awful.spawn 只启动命令,但不等待它完成。因此,现在您在查询音量的同时更改音量。如果查询完成的速度比更改卷快,则实际上不会发生更新。

    要仅在更改音量后更新小部件,请执行以下操作:

    awful.spawn.with_line_callback(
        "amixer -q set Master 5%-", {
        exit = function()
            musicbar_timer:emit_signal("timeout")
        end
    })
    

    【讨论】:

    • 太棒了,效果很好。感谢您的帮助!
    【解决方案2】:

    我遇到了与 streetturtle 的 volumearc widget 类似的问题。默认情况下,它运行一个更新命令:

    • 每次通过小部件修改音量
    • 每秒捕捉任何外部音量变化(例如在rc.lua 中定义的键绑定)。
    watch(get_volume_cmd, 1, update_graphic, volumearc)
    

    当然这样有以下缺点:

    • 音量更新轻微延迟(一秒钟后仍然非常明显)。
    • 在我的机器上,恒定 1% CPU 负载 仅用于此任务。我知道一些小事,但小事加起来。

    使用返回的更新函数

    一种可能的解决方案是返回一个更新函数,在rc.lua 的上下文中可用,并在卷修改时调用此更新。

    volumearc.lua中,在worker函数中,我们把widget update放到了一个专门的函数中:

    local ext_update = function()
            spawn.easy_async(get_volume_cmd,
                function(stdout, stderr, exitreason, exitcode)
                update_graphic(volumearc, stdout, stderr, exitreason, exitcode) end)
          end
    

    我们从 worker 函数返回它:

    return volumearc, ext_update
    

    以及从小部件本身:

    volumearc, ext_update = { __call = function(_, ...) return worker(...) end }
    return setmetatable(widget, volumearc), ext_update
    

    现在我们可以在rc.lua中使用它:

    local volumearc_widget = require("widgets.volume-widget.volumearc")
    -- ...
    local GET_VOLUME = "amixer sget Master"
    local INC_VOLUME = "amixer sset Master 3%+"
    local DEC_VOLUME = "amixer sset Master 3%-"
    local TOG_VOLUME = "amixer sset Master toggle"
    myvolume, volume_update = volumearc_widget({get_volume_cmd=GET_VOLUME,
                               inc_volume_cmd=INC_VOLUME,
                               dec_volume_cmd=DEC_VOLUME,
                               tog_volume_cmd=TOG_VOLUME})
    -- `myvolume` is the widget that can be added as usual in the wibox.
    -- `volume_update` is the function to call in order to trigger an update.
    -- ...
    -- In the key bindings:
        awful.key({}, "XF86AudioMute",
          function () awful.spawn(TOG_VOLUME) volume_update() end,
          {description="mute", group = "media"}),
        awful.key({}, "XF86AudioRaiseVolume",
          function () awful.spawn(INC_VOLUME) volume_update() end,
          {description="raise volume", group = "media"}),
        awful.key({}, "XF86AudioLowerVolume",
          function () awful.spawn(DEC_VOLUME) volume_update() end,
          {description="lower volume", group="media"}),
    

    现在音量将在从小部件或媒体键更改时更新,立即无需轮询

    警告

    • 这不会捕获通过其他接口所做的更改,例如alsamixer。要捕捉这些变化,您可能希望以非常低的时间频率(例如每分钟一次)运行 watch 函数。
    • 此处给出的代码特定于 streetturtle 的小部件,但返回内部更新函数的概念适用于任何小部件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-05
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      • 1970-01-01
      • 2013-05-08
      相关资源
      最近更新 更多