termux / termux-x11

Termux X11 add-on application.
https://termux.dev
GNU General Public License v3.0
1.85k stars 290 forks source link

[Bug]: input event send via different device #598

Closed KawaiiNahida closed 3 months ago

KawaiiNahida commented 4 months ago

Problem description

When using an external mouse device without "Capture External Mouse" enabled mouse movements are reported using "Lorie absolute mouse" while all the buttons reported using "Lorie mouse"

Device: Xiaomi Pad 6 Pro / Android 13 Kernel: 5.10.185-android12-9-g21b4b61e459a

What steps will reproduce the bug?

using an external mouse device without "Capture External Mouse" enabled

What is the expected behavior?

events reported using the same virtual device

KawaiiNahida commented 4 months ago

After some simple testing, I found that sending absolute coordinates with the flag POINTER_ABSOLUTE directly to the lorieMouseRelative device seems to be fine, and I'm curious if there's any particular reason for the use of the standalone absolute device

                        if (e.mouse.relative) {
                            flags = POINTER_RELATIVE | POINTER_ACCELERATE;
                            valuator_mask_set_double(&mask, 0, (double) e.mouse.x);
                            valuator_mask_set_double(&mask, 1, (double) e.mouse.y);
                            QueuePointerEvents(lorieMouseRelative, MotionNotify, 0, flags, &mask);
                        } else {
                            flags = POINTER_ABSOLUTE | POINTER_SCREEN | POINTER_NORAW;
                            valuator_mask_set_double(&mask, 0, (double) e.mouse.x);
                            valuator_mask_set_double(&mask, 1, (double) e.mouse.y);
                            QueuePointerEvents(lorieMouseRelative, MotionNotify, 0, flags, &mask);
                        }
                        break;
twaik commented 4 months ago

[Uploading app-universal-debug.zip…]() Try this.

KawaiiNahida commented 3 months ago

Uploading app-universal-debug.zip… Try this.

The link doesn't seem to be working

firefox_wLyxSdltoM
twaik commented 3 months ago

app-universal-debug.zip

KawaiiNahida commented 3 months ago

I've noticed that the current version is still sending scroll and move events through different virtual devices, and applications are still unable to scroll while the mouse is moving.

# xinput
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Lorie mouse                               id=6    [slave  pointer  (2)]
⎜   ↳ Lorie absolute mouse                      id=7    [slave  pointer  (2)]
⎜   ↳ Lorie touch                               id=8    [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Lorie keyboard                            id=9    [slave  keyboard (3)]
EVENT type 6 (Motion)
    device: 7 (7)
    time: 312376952
    detail: 0
    flags: 
    root: 1047.00/807.00
    event: 1047.00/807.00
    buttons:
    modifiers: locked 0 latched 0 base 0 effective: 0
    group: locked 0 latched 0 base 0 effective: 0
    valuators:
        0: 23847.82
        1: 31110.32
    windows: root 0x511 event 0x511 child 0x602dfb
EVENT type 17 (RawMotion)
    device: 2 (6)
    time:   312912912
    detail: 0
    flags: 
    valuators:
          3: 0.83 (0.83)

EVENT type 6 (Motion)
    device: 6 (6)
    time: 312912912
    detail: 0
    flags: 
    root: 541.00/833.00
    event: 541.00/833.00
    buttons:
    modifiers: locked 0 latched 0 base 0 effective: 0
    group: locked 0 latched 0 base 0 effective: 0
    valuators:
        3: 92.41
    windows: root 0x511 event 0x511 child 0x602dfb
EVENT type 15 (RawButtonPress)
    device: 2 (6)
    time:   312912912
    detail: 5
    flags: emulated
    valuators:

EVENT type 4 (ButtonPress)
    device: 6 (6)
    time: 312912912
    detail: 5
    flags: emulated
    root: 541.00/833.00
    event: 541.00/833.00
    buttons:
    modifiers: locked 0 latched 0 base 0 effective: 0
    group: locked 0 latched 0 base 0 effective: 0
    valuators:
    windows: root 0x511 event 0x511 child 0x602dfb
EVENT type 16 (RawButtonRelease)
    device: 2 (6)
    time:   312912912
    detail: 5
    flags: emulated
    valuators:

EVENT type 5 (ButtonRelease)
    device: 6 (6)
    time: 312912912
    detail: 5
    flags: emulated
    root: 541.00/833.00
    event: 541.00/833.00
    buttons: 5
    modifiers: locked 0 latched 0 base 0 effective: 0
    group: locked 0 latched 0 base 0 effective: 0
    valuators:
    windows: root 0x511 event 0x511 child 0x602dfb
twaik commented 3 months ago

I've noticed that the current version is still sending

What about the version I posted in the previous message?

KawaiiNahida commented 3 months ago

i am using the version you posted in this issue https://github.com/termux/termux-x11/files/14968339/app-universal-debug.zip

twaik commented 3 months ago

app-universal-debug.zip Try this one.

KawaiiNahida commented 3 months ago

still the same

twaik commented 3 months ago

Ok, I remembered why I did this.

In the case of hardware mouse without capturing android sends only absolute MotionEvents. It is not possible to get relative coordinates for event and not stuck with pointer sync between android and X11 because:

  1. Extracting current pointer coordinates inside X server is not very straightforward and requires patching sources.
  2. There are enough X11 programs which can send synthetic pointer events and interfere with code in android.c.

I am going to investigate something for a few hours and probably fix this.

twaik commented 3 months ago

Ok. So

  1. Popular GUI toolkits and some programs scan for device capabilities during startup or when device list is being updated and when they do not get what they expect (like raw events on physical mouse) they might break.
  2. It seems like GetPointerEvents does some calculations so we can mix relative and absolute events on the same device. But I do not know what are long-term consequences for this. Probably the best way to know is trial-and-error because raw X11 protocol does not allow programs to read raw valuators in the case if there was no raw event. And it seems like XTest-related code explicitly uses relative-only device to send absolute pointer events so I am assuming it will work.
twaik commented 3 months ago

Fixed by 67abb3c14483a092242910f26b0c64fee1e83c58