muzqs
September 16, 2026, 8:07pm
1
Been chasing down A flaky click-through issue with the latest stock conky .
Desktop widgets (right/left-click sometimes not reaching the desktop context menu, fixed by openbox --restart).
Traced it all the way to conky’s C++ source and found the actual cause.
What’s actually happening
All our conky widgets use the same setup:
own_window = true,
own_window_type = 'desktop',
own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
This is supposed to make the widget fully click-through at the X11 level (conky sets an empty “input shape” on the window for exactly this case).
But conky 1.24.x still unconditionally subscribes to mouse button events on that window regardless of window type, even though nothing in our configs uses conky’s interactive lua_mouse_hook feature.
So every click gets intercepted by conky first, which then tries to manually re-forward it to whatever’s underneath.
opened 07:52PM - 16 Sep 26 UTC
## Description
When `own_window = true` and `own_window_type = 'desktop'` with … `undecorated` set in `own_window_hints`, conky already sets an empty XShape input region on its window (`x11.cc`, the `XShapeCombineRectangles(..., ShapeInput, 0, 0, nullptr, 0, ShapeSet, ...)` call), so clicks should pass straight through to whatever's below at the X protocol level — no interaction from conky needed.
However, `x11_init_window()` unconditionally selects `XI_ButtonPress`/`XI_ButtonRelease` via `XISelectEvents()` on the conky window whenever `own_window` is true, regardless of window type and regardless of whether a `lua_mouse_hook` is even configured:
```cpp
if (own) {
selected_events.clear_all();
selected_events.set(XI_ButtonPress);
selected_events.set(XI_ButtonRelease);
// It's not recommended to add event masks to special windows in X; causes
// a crash (thus own_window_type != window_type::DESKTOP)
if (own_window_type.get(l) != window_type::DESKTOP) {
selected_events.set(XI_Motion);
...
```
So conky still receives every click via XInput2 even on a desktop-type window with an empty input shape, and falls back to manually re-dispatching it in `propagate_x11_event()` (`src/output/x11.cc`) via `XSendEvent` to whatever window it finds below the pointer (excluding only conky's own window from the candidate list).
That manual re-dispatch doesn't account for the window manager's own frame/decorations around other windows, and picks the "topmost" candidate purely from `query_x11_windows_at_pos()`'s stacking snapshot at that instant — so which window actually receives the forwarded click is stacking-order-sensitive. In practice this makes clicks on desktop icons / WM-provided desktop context menus unreliable when a `desktop`-type conky widget with no interactive Lua content overlaps them: clicks intermittently land on the wrong target, and restarting the window manager (which reshuffles stacking order) can mask or reveal the bug.
## Reproduction
Minimal `.conkyrc` widget (this is the exact pattern used by Mabox Linux's stock conky widgets):
```lua
conky.config = {
own_window = true,
own_window_type = 'desktop',
own_window_transparent = true,
own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
-- ...
}
```
- Place this widget over desktop icons or an area where right/left-click opens a WM desktop context menu (e.g. Openbox).
- Click through the widget.
- Observe that clicks are sometimes swallowed or misrouted, and that behavior can change after `openbox --restart` (changes window stacking order).
- No `lua_mouse_hook` is registered anywhere in the widget's Lua config — conky has no legitimate reason to intercept these clicks in this setup.
## Expected
With an empty XShape input region already engaged for undecorated desktop-type windows, conky shouldn't need to see or forward `ButtonPress`/`ButtonRelease` at all unless the widget actually registers a `lua_mouse_hook`.
## Fix
Only select `XI_ButtonPress`/`XI_ButtonRelease` on the own window when it isn't a plain `desktop` window, or when a `lua_mouse_hook` is actually configured for it — mirroring the gate already used a few lines below for `XI_Motion`/`XI_Enter`/`XI_Leave`:
```diff
if (own) {
selected_events.clear_all();
- selected_events.set(XI_ButtonPress);
- selected_events.set(XI_ButtonRelease);
+ // Desktop windows rely on an empty XShape input region for
+ // click-through; only grab buttons if a mouse hook actually wants them.
+ bool wants_button_events =
+ own_window_type.get(l) != window_type::DESKTOP ||
+ !conky::lua_mouse_hook.get(l).empty();
+ if (wants_button_events) {
+ selected_events.set(XI_ButtonPress);
+ selected_events.set(XI_ButtonRelease);
+ }
// It's not recommended to add event masks to special windows in X; causes
// a crash (thus own_window_type != window_type::DESKTOP)
if (own_window_type.get(l) != window_type::DESKTOP) {
```
Tested against conky 1.24.2 across ~20 real-world desktop-type widgets (none use `lua_mouse_hook`) — click-through is now reliable and survives WM restarts, with no regressions since the branch that does use a hook is untouched. Happy to open a PR with this change if it's useful.
## Environment
- conky version: 1.24.2
- Build: X11, `BUILD_MOUSE_EVENTS=ON`, `BUILD_XSHAPE=ON` (conky's default configuration for X11 builds)
- WM: Openbox (Mabox Linux), but the underlying issue is WM-independent (X11 core protocol click routing)
2 Likes