Open-Source Wikis

/

Bubble Tea

/

Features

/

Mouse

charmbracelet/bubbletea

Mouse

Active contributors: aymanbagabas, meowgorithm

Purpose

Bubble Tea programs can opt into mouse input by setting View.MouseMode. The runtime handles enabling SGR and X10 mouse modes, parsing mouse events, and delivering them as typed messages.

Enabling mouse mode

mouse.go defines three modes (defined as MouseMode in tea.go):

Mode Effect
MouseModeNone Mouse disabled (default).
MouseModeCellMotion Click, release, wheel, and drag (motion while a button is pressed).
MouseModeAllMotion All of the above plus motion when no button is pressed.
func (m model) View() tea.View {
    v := tea.NewView("Hello")
    v.MouseMode = tea.MouseModeCellMotion
    return v
}

The renderer issues CSI ? 1000 h (button events) plus CSI ? 1006 h (SGR extended coordinates) for cell motion, or CSI ? 1003 h (any event) plus SGR for all motion.

Message types

The MouseMsg interface (mouse.go) covers four typed sub-messages. All embed a common Mouse struct (X, Y, Button, Mod).

Message When it fires
MouseClickMsg Button press.
MouseReleaseMsg Button release.
MouseWheelMsg Scroll wheel up/down/left/right.
MouseMotionMsg Pointer movement (only delivered when mouse mode is enabled, and respects CellMotion vs AllMotion).
case tea.MouseClickMsg:
    if msg.Button == tea.MouseLeft {
        m.handleClick(msg.X, msg.Y)
    }
case tea.MouseWheelMsg:
    if msg.Button == tea.MouseWheelDown {
        m.scroll(+1)
    }

To handle every mouse event uniformly, switch on the interface:

case tea.MouseMsg:
    e := msg.Mouse()
    fmt.Println(e.X, e.Y, e.Button, e.Mod)

Button constants

MouseNone, MouseLeft, MouseMiddle, MouseRight,
MouseWheelUp, MouseWheelDown, MouseWheelLeft, MouseWheelRight,
MouseBackward, MouseForward, MouseButton10, MouseButton11

These are aliases re-exported from uv (mouse.go).

View-level mouse handlers

View.OnMouse is an optional func(MouseMsg) Cmd that runs before the model sees a mouse message. It is called by cursedRenderer.onMouse, which is invoked from Program.eventLoop for MouseClick, MouseRelease, MouseWheel, and MouseMotion. Use it to scope mouse handling to a hit-tested area of the rendered content:

content := "Hello, World!"
v := tea.NewView(content)
v.OnMouse = func(msg tea.MouseMsg) tea.Cmd {
    m := msg.Mouse()
    start := strings.Index(content, "World!")
    end := start + len("World!")
    if m.Y == 0 && m.X >= start && m.X < end {
        return func() tea.Msg { return MyHotspotMsg{} }
    }
    return nil
}

v1 → v2 changes

The v1 MouseMsg was a struct with Action and Button fields. In v2 the message is an interface and the action is encoded by the type:

v1 v2
tea.WithMouseCellMotion() view.MouseMode = tea.MouseModeCellMotion
tea.MouseMsg{Action: MouseActionPress} tea.MouseClickMsg
tea.MouseButtonLeft tea.MouseLeft
tea.MouseEvent tea.Mouse

See UPGRADE_GUIDE_V2.md for the full table.

Examples

examples/mouse/main.go demonstrates basic click handling. examples/clickable/ shows a clickable region using View.OnMouse. See the Examples package page for the full list.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Mouse – Bubble Tea wiki | Factory