Skip to content

Lua: Mouse Events

Tin Švagelj edited this page Apr 17, 2026 · 1 revision

Mouse Events

Conky supports mouse event handling when compiled with the BUILD_MOUSE_EVENTS option. Support varies between X11 and Wayland — see implementation differences for details.

Setup

Add a lua_mouse_hook to your conky.conf:

conky.config = {
    -- other options...
    lua_load = "./script.lua",
    lua_mouse_hook = "on_mouse",
}

The hook function must be defined in a file specified by lua_load. It receives a single table parameter containing event information and must return a boolean indicating whether the event was consumed:

function conky_on_mouse(event)
    if event.type == "button_down" and event.button == "left" then
        print("clicked at " .. event.x .. ", " .. event.y)
        return true   -- event consumed, won't reach windows below
    end
    return false  -- event passes through to the compositor / windows below
end

Important

The return value controls whether the event is consumed or passed through. Returning true means Conky handles the event and it won't reach the compositor or any window beneath Conky. Returning false lets the event fall through as if Conky wasn't there. Always return false for events you don't handle — otherwise clicks and scrolls will silently disappear for the user.

Event Types

The event.type field indicates what kind of event occurred:

Type Triggered when
button_down A mouse button is pressed
button_up A mouse button is released
button_scroll A scroll action occurs
mouse_move The pointer moves over the Conky window
mouse_enter The pointer enters the Conky window
mouse_leave The pointer leaves the Conky window

Tip

If your hook function does expensive work, return early for event types you don't need. mouse_move fires very frequently — on every few pixels of movement. If you're handling many different event types, consider splitting each into its own function and dispatching from the hook.

An example hook that prints all event information can be found in the original PR.

Event Fields

Common Fields

All events contain these fields:

Field Description
x Window-relative cursor X position
y Window-relative cursor Y position
x_abs Display-relative cursor X position
y_abs Display-relative cursor Y position
time Milliseconds since epoch

Mouse Buttons

When event.type is button_down or button_up, the event contains:

Field Description
button Button name: left, right, middle, back, or forward
button_code Numeric event code (for non-standard buttons)

middle corresponds to mouse wheel press. back and forward are side buttons present on some mice.

Modifiers

When event.type is button_down, button_up, or button_scroll, the event contains a mods table with held modifier keys:

  • shiftShift
  • controlCtrl
  • super⊞ Win / ⌘ Cmd
  • caps_lockCaps Lock
  • num_lockNum Lock
if event.type == "button_down" and event.mods.control then
    print("Ctrl+click")
end

Note

Modifier values depend on the xkb configuration and assume defaults. On Wayland, the mods table is always empty — see implementation differences.

Movement Delta

mouse_move events also contain movement delta fields:

Field Description
move_delta Total movement delta
move_delta_x Horizontal movement delta
move_delta_y Vertical movement delta

Scroll Information

When event.type is button_scroll:

Field Description
direction Scroll direction: up, down, left, or right
scroll_delta Total scroll delta
scroll_delta_x Horizontal scroll delta
scroll_delta_y Vertical scroll delta

Note

Scroll delta is always in the range -1 to 1 if BUILD_XINPUT is disabled. Scroll events also generate button events for backwards compatibility.

Example: Click Regions

A common pattern is checking whether a click falls within a rectangular region:

local function in_rect(x, y, rx, ry, rw, rh)
    return x >= rx and x <= rx + rw and y >= ry and y <= ry + rh
end

function conky_on_mouse(event)
    if event.type == "button_down" and event.button == "left" then
        if in_rect(event.x, event.y, 10, 10, 100, 30) then
            os.execute("xdg-open https://example.com &")
            return true
        end
    end
    return false
end

Fixing X11 Quirks

Some X11 input devices may have unexpected valuator indices, causing cursor motion to behave like scrolling or vice versa. Fix this by setting Conky-specific xinput properties:

xinput set-prop "My Mouse Device" --type=atom "ConkyValuatorMoveX" "0"
xinput set-prop "My Mouse Device" --type=atom "ConkyValuatorMoveY" "1"
xinput set-prop "My Mouse Device" --type=atom "ConkyValuatorScrollX" "2"
xinput set-prop "My Mouse Device" --type=atom "ConkyValuatorScrollY" "3"

To find your device name or ID, use xinput list. To find the correct valuator indices, run xinput list "My Mouse Device" and check the valuator names. Movement valuators are commonly labeled "Rel X" / "Rel Y", scroll ones "Rel Horiz Scroll" / "Rel Vert Scroll" — though labels may differ for your device. If labels are blank or missing, use xinput test-xi2 and observe generated events while moving and scrolling. Note that scroll events also generate button events for backwards compatibility, so you may need to check the last 3–4 events to identify the correct valuators.

If motion events are reported as constant scrolling in one direction, the device is reporting absolute values when Conky expects relative ones:

xinput set-prop "My Mouse Device" --type=atom "ConkyValuatorScrollMode" "relative"
xinput set-prop "My Mouse Device" --type=atom "ConkyValuatorMoveMode" "relative"

Tip

Add these commands to your .xinitrc to persist them across sessions.

Implementation Differences

X11

  • Mouse button names are mapped from platform input event codes (linux/input-event-codes.h on Linux, dev/evdev/input-event-codes.h on FreeBSD). Only the five named buttons are recognized — use event.button_code for others.

Wayland

  • Keyboard modifiers aren't reported. Wayland requires applications to process keyboard events and manage keyboard state to support modifiers — on X11 they're included in mouse events directly.
  • Wayland provides numeric event codes for mouse buttons. Named event.button values are mapped from the same platform input event code headers as X11 and will be nil for non-standard buttons — use event.button_code for those.

Clone this wiki locally