Skip to content

Popups

Popups attach extra content to a bar node.

The parent widget controls whether the popup is visible. Popup child nodes use a position value of popup.<parent-id>.

If you also need several always-visible child nodes around the same trigger, combine this guide with Grouping.

Minimal popup

local calendar = easybar.add(easybar.kind.item, "calendar", {
    position = "right",
    order = 30,
    label = "Today",
    popup = {
        drawing = false,
    },
})

easybar.add(easybar.kind.item, "calendar_popup_label", {
    position = "popup." .. calendar.name,
    label = "Next event: 14:00",
})

Interactive popup items

Popup children subscribe to mouse events like bar items. Attach the subscription to the child node so event.target_widget_id identifies the control that was clicked.

local tools = easybar.add(easybar.kind.item, "tools", {
    position = "right",
    label = "Tools",
    popup = {
        drawing = true,
    },
})

local refresh = easybar.add(easybar.kind.item, "tools_refresh", {
    position = "popup." .. tools.name,
    label = "Refresh",
})

refresh:subscribe(easybar.events.mouse.clicked, function(event)
    if event.button == nil or event.button == easybar.events.mouse.left_button then
        refresh:set({ label = "Refreshing…" })
        -- Start the refresh work here.
    end
end)

Use a row or group when a popup needs several controls on the same line. Each child item can keep its own click handler.

Show on hover

calendar:subscribe(easybar.events.mouse.entered, function()
    calendar:set({
        popup = { drawing = true },
    })
end)

calendar:subscribe(easybar.events.mouse.exited, function()
    calendar:set({
        popup = { drawing = false },
    })
end)

Popup content inherits native-like defaults when you do not override them:

  • text color #cdd6f4
  • background #111111
  • border #444444
  • corner radius 8
  • padding 8 x 6
  • margin 0 x 8

Use the default popup styling when you want the built-in tooltip look.

Add explicit child background and padding when you want a more decorated inner surface.

local vpn = easybar.add(easybar.kind.item, "vpn", {
    position = "right",
    order = 40,
    popup = {
        drawing = true,
        padding_x = 10,
        padding_y = 8,
        background = {
            color = "#111111",
            border_color = "#444444",
            border_width = 1,
            corner_radius = 8,
        },
    },
})

easybar.add(easybar.kind.item, "vpn_popup_label", {
    position = "popup." .. vpn.name,
    padding_left = 12,
    padding_right = 12,
    padding_top = 8,
    padding_bottom = 8,
    background = {
        color = "#181818",
        border_color = "#555555",
        border_width = 1,
        corner_radius = 8,
    },
    label = "WireGuard active",
})