m1k1o/neko · info

debounced button %v

Error message

debounced button %v

What it means

ButtonDown injects an X11 button press but debounces repeated presses: if the same button code was pressed too recently (present in debounce_button), the call is refused with 'debounced button %v'. This prevents duplicate press events from rapid retransmission. It is an intentional rate-limit rejection, not a hardware failure.

Source

Thrown at server/pkg/xorg/xorg.go:109

func Scroll(deltaX, deltaY int, controlKey bool) {
	mu.Lock()
	defer mu.Unlock()

	if controlKey {
		C.XSetKeyboardModifier(C.uchar(C.ControlMask), 1)
		defer C.XSetKeyboardModifier(C.uchar(C.ControlMask), 0)
	}

	C.XScroll(C.int(deltaX), C.int(deltaY))
}

func ButtonDown(code uint32) error {
	mu.Lock()
	defer mu.Unlock()

	if _, ok := debounce_button[code]; ok {
		return fmt.Errorf("debounced button %v", code)
	}

	debounce_button[code] = time.Now()

	C.XButton(C.uint(code), C.int(1))
	return nil
}

func KeyDown(code uint32) error {
	mu.Lock()
	defer mu.Unlock()

	if _, ok := debounce_key[code]; ok {
		return fmt.Errorf("debounced key %v", code)
	}

	debounce_key[code] = time.Now()

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Wait for ButtonUp(code) before issuing another ButtonDown(code)
  2. Deduplicate press events client-side before sending (ignore repeats for a held button)
  3. Increase the debounce window removal logic / clear debounce_button entry via ButtonUp if the state is stale
  4. Treat this error as a benign no-op in the caller (the button is already down)

Example fix

// before
if err := xorg.ButtonDown(btn); err != nil { log.Fatal(err) }
// after
if err := xorg.ButtonDown(btn); err != nil {
    // button already down from a recent press; ignore debounce rejection
    log.Printf("button %d already down: %v", btn, err)
}
Defensive patterns

Strategy: validation

Validate before calling

// track pressed state; only press when not already pressed
var pressed = map[uint32]bool{}
func safeButtonDown(code uint32) error {
    if pressed[code] { return nil }
    if err := xorg.ButtonDown(code); err != nil { return err }
    pressed[code] = true
    return nil
}

Type guard

func isDebouncedButton(err error) bool {
    return err != nil && strings.Contains(err.Error(), "debounced button")
}

Try / catch

if err := xorg.ButtonDown(code); err != nil && !isDebouncedButton(err) {
    return err // real failure; debounce rejection is benign
}

Prevention

When it happens

Trigger: Calling ButtonDown(code) twice in quick succession without an intervening ButtonUp(code); ButtonPress dispatching a code already held down.

Common situations: Client autorepeat generating repeated keydown-like events for held mouse buttons; network retransmission duplicating a click event; event pipeline calling both ButtonPress and ButtonDown for the same input.

Related errors


AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01). Data as JSON: /api/errors/6c1f79218f5dde97. Report an issue: GitHub.