Skip to content

Touchpad swipe triggers never fire when a second touchpad-tagged device is connected #481

Closed as not planned

Description

@SmallTardigrade

Summary

InputBackend::firstTouchpad() returns the first touchpad in the device list rather than the one generating the event, so on a system with more than one touchpad-tagged device all swipe/pinch/hold gestures are attributed to the wrong device and silently never match.

Environment

  • InputActions KWin plugin, built from taj-ny/InputActions main (537a1fc, 2026-06-06)
  • KWin 6.7.4, Fedora 44, Wayland
  • Plugin built against KWin 6.7.4, KWIN_6_5_OR_GREATER and KWIN_6_7_OR_GREATER both defined
  • Two devices tagged ID_INPUT_TOUCHPAD=1:
    • /dev/input/event8 — "Logitech USB Receiver" (a wireless receiver's touchpad endpoint; no fingers are ever on it)
    • /dev/input/event12 — "ELAN06FA:00 04F3:327E Touchpad" (the actual laptop touchpad)

What happens

With the Logitech receiver plugged in, no swipe trigger of any finger count ever fires. last_trigger_id stays empty. 2-finger triggers do fire.

Unplugging the receiver makes 2-, 3- and 4-finger triggers all work immediately, with no config change.

Cause

kwin/src/input/KWinInputBackend.cpp resolves the device for every pointer gesture through firstTouchpad():

return touchpadSwipeBegin(firstTouchpad(), fingerCount);

and lib/core/src/libinputactions/input/backends/InputBackend.cpp:

InputDevice *InputBackend::firstTouchpad() const
{
    for (auto *device : m_devices) {
        if (device->type() == InputDeviceType::Touchpad) {
            return device;
        }
    }
    return {};
}

KWin's PointerSwipeGestureBeginEvent carries a finger count but the device is looked up positionally, so whichever touchpad happens to be first wins. Here that is the Logitech endpoint at event8, which enumerates ahead of the real pad at event12. The gesture is then evaluated against that device's evdev state, which has no fingers on it, and the fingers condition never matches.

2-finger triggers are unaffected because libinput delivers two-finger motion as POINTER_SCROLL_FINGER on the real device rather than as a swipe gesture, so that path never calls firstTouchpad(). That asymmetry is what makes the symptom confusing — it looks like a finger-count problem rather than a device-resolution one.

Reproduction

  1. Plug in any second device tagged ID_INPUT_TOUCHPAD=1 that enumerates before the real touchpad.
  2. Configure any touchpad swipe trigger with 3 fingers.
  3. Perform the gesture — nothing fires, and inputactions variables list shows last_trigger_id empty.
  4. Unplug the second device — the same gesture works.

Workaround

A device rule ignoring the other device restores normal behaviour:

device_rules:
  - conditions: $name contains Logitech
    ignore: true

Suggested fix

Resolve the device from the event rather than positionally, or fall back to currentMultiTouchDevice() where the compositor does not supply a device.

Note

libinput debug-events confirms the hardware and libinput are fine throughout — clean 3-finger GESTURE_SWIPE_BEGIN/UPDATE/END with correct finger counts in both directions.

Activity

  1. github-actions commented on Aug 31, 2026

    @github-actions

    Opening issues is restricted to maintainers. Users should use discussions instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions