app.statusbar - 状态栏图标 API

创建和管理独立的 macOS 状态栏(菜单栏)图标和菜单。

权限: L2 sensitive

方法

app.statusbar.create(opts?)

创建独立的状态栏图标。

参数:

  • opts (table, 可选):
    • title (string, 可选) - 显示文字
    • icon (string, 可选) - 图标,支持:
      • 文件路径: 自动缩放至 18×18
      • "sf:symbol.name": SF Symbol 名称(如 "sf:star.fill"
    • tooltip (string, 可选) - 鼠标悬停提示文字

返回值: string, error - 状态栏图标 ID

-- 仅文字
local id = app.statusbar.create({title = "MyPlugin"})

-- 仅图标
local id = app.statusbar.create({icon = "sf:bolt.fill"})

-- 文字 + 图标 + 提示
local id = app.statusbar.create({
    title = "⚡",
    icon = self:getInstallPath() .. "/icon.png",
    tooltip = "我的插件状态栏"
})

app.statusbar.delete(id)

删除状态栏图标。

参数:

  • id (string) - 图标 ID

返回值: boolean, error

app.statusbar.deleteAll()

删除当前插件的所有状态栏图标。

返回值: boolean

app.statusbar.setTitle(id, title)

更新状态栏图标的文字。

参数:

  • id (string) - 图标 ID
  • title (string) - 新文字

返回值: boolean, error

app.statusbar.setTitle(id, "运行中")

app.statusbar.setIcon(id, icon)

更新状态栏图标的图片。

参数:

  • id (string) - 图标 ID
  • icon (string) - 图标路径或 "sf:symbol.name"

返回值: boolean, error

app.statusbar.setIcon(id, "sf:checkmark.circle.fill")

app.statusbar.setTooltip(id, tooltip)

更新状态栏图标的提示文字。

参数:

  • id (string) - 图标 ID
  • tooltip (string) - 新提示文字

返回值: boolean, error

app.statusbar.setMenu(id, items, callback?)

设置状态栏图标的下拉菜单。

参数:

  • id (string) - 图标 ID
  • items (array) - 菜单项数组,每项:
    • title (string) - 菜单项文字
    • id (string, 可选) - 菜单项标识符(传给回调,默认用 title)
    • icon (string, 可选) - SF Symbol: "sf:symbol.name"
    • enabled (boolean, 可选) - 是否启用,默认 true
    • checked (boolean, 可选) - 是否显示勾选标记
    • separator (boolean, 可选) - 为 true 时创建分隔线
    • children (array
    , 可选) - 子菜单项
  • callback (function, 可选) - 菜单项点击回调,接收 menuItemId 参数
  • 返回值: boolean, error

    app.statusbar.setMenu(id, {
        {title = "开始", id = "start", icon = "sf:play.fill"},
        {title = "暂停", id = "pause", icon = "sf:pause.fill"},
        {separator = true},
        {title = "设置", id = "settings", children = {
            {title = "选项 A", id = "optA", checked = true},
            {title = "选项 B", id = "optB"},
        }},
        {separator = true},
        {title = "退出", id = "quit"},
    }, function(menuItemId)
        app.log.info("点击: " .. menuItemId)
        if menuItemId == "quit" then
            app.statusbar.delete(id)
        end
    end)
    

    app.statusbar.list()

    列出当前插件的状态栏图标。

    返回值: array<table> - 每项包含:

    • id (string) - 图标 ID
    • title (string, 可选) - 当前文字
    • tooltip (string, 可选) - 当前提示

    说明

    • 每个插件最多 3 个状态栏图标
    • 图标文件自动缩放至 18×18 像素
    • 设置 isTemplate = true 自动支持深色/浅色模式
    • 状态栏图标在插件卸载时自动移除
    • 重复调用 setMenu() 会替换之前的菜单和回调

    示例

    Pomodoro 番茄钟

    local mbId = nil
    local timerId = nil
    local remaining = 25 * 60  -- 25 分钟
    
    function MyPlugin:init()
        mbId = app.statusbar.create({
            title = "🍅 25:00",
            tooltip = "番茄钟"
        })
        self:updateMenu()
    end
    
    function MyPlugin:updateMenu()
        app.statusbar.setMenu(mbId, {
            {title = "开始", id = "start"},
            {title = "重置", id = "reset"},
            {separator = true},
            {title = "关闭", id = "close"},
        }, function(itemId)
            if itemId == "start" then
                self:startTimer()
            elseif itemId == "reset" then
                self:resetTimer()
            elseif itemId == "close" then
                app.statusbar.delete(mbId)
            end
        end)
    end
    
    function MyPlugin:startTimer()
        if timerId then return end
        timerId = app.timer.every(1, function()
            remaining = remaining - 1
            if remaining <= 0 then
                app.timer.cancel(timerId)
                timerId = nil
                app.statusbar.setTitle(mbId, "🍅 完成!")
                app.dock.bounce("critical")
                app.notification.show("番茄钟", "时间到!休息一下吧")
            else
                local min = math.floor(remaining / 60)
                local sec = remaining % 60
                app.statusbar.setTitle(mbId, string.format("🍅 %02d:%02d", min, sec))
            end
        end)
    end
    
    function MyPlugin:resetTimer()
        if timerId then
            app.timer.cancel(timerId)
            timerId = nil
        end
        remaining = 25 * 60
        app.statusbar.setTitle(mbId, "🍅 25:00")
    end