-
-
Notifications
You must be signed in to change notification settings - Fork 659
Lua: 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.
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
endImportant
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.
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.
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 |
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.
When event.type is button_down, button_up, or button_scroll, the event
contains a mods table with held modifier keys:
-
shift— Shift -
control— Ctrl -
super— ⊞ Win / ⌘ Cmd -
caps_lock— Caps Lock -
num_lock— Num Lock
if event.type == "button_down" and event.mods.control then
print("Ctrl+click")
endNote
Modifier values depend on the
xkb configuration
and assume defaults. On Wayland, the mods table is always empty — see
implementation differences.
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 |
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.
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
endSome 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.
- Mouse button names are mapped from platform input event codes
(
linux/input-event-codes.hon Linux,dev/evdev/input-event-codes.hon FreeBSD). Only the five named buttons are recognized — useevent.button_codefor others.
- 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.buttonvalues are mapped from the same platform input event code headers as X11 and will benilfor non-standard buttons — useevent.button_codefor those.