spix icon indicating copy to clipboard operation
spix copied to clipboard

[Qt6] Drawer element blocks mouseClick

Open prototypicalpro opened this issue 3 years ago • 12 comments

I have a strange bug that I'm trying to wrap my head around. When using spix (modified to print the mouse events) with a minimal QML application on Qt6 everything works as expected:

ApplicationWindow {
    id: window
    visible: true

    Button {
        id: clickMe
        onClicked: console.log("clicked");
        text: "A Special Button"
    }
}
s = xmlrpc.client.ServerProxy('http://localhost:9000')
s.mouseClick("window/clickMe")
print(s.getErrors())
# Qt
Starting minimalDrawerBug...
QML debugging is enabled. Only use this in a safe environment.
QMouseEvent(MouseButtonPress LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=2470,944 dev=QPointingDevice("core pointer" Mouse id=1))
QMouseEvent(MouseButtonRelease LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=2470,944 dev=QPointingDevice("core pointer" Mouse id=1))
qml: clicked

# python
[]

When I update the QML application to include a Drawer element, however, spix is unable to click on the element:

ApplicationWindow {
    id: window
    visible: true

    Button {
        id: clickMe
        onClicked: console.log("clicked");
        text: "A Special Button"
    }
    
    // I tested placing drawer both before and after button
    Drawer {
        id: drawer
    }
}
# Qt
Starting minimalDrawerBug...
QML debugging is enabled. Only use this in a safe environment.
QMouseEvent(MouseButtonPress LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=2470,944 dev=QPointingDevice("core pointer" Mouse id=1))
QMouseEvent(MouseButtonRelease LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=2470,944 dev=QPointingDevice("core pointer" Mouse id=1))

# python
[]

I am still able to click the button with normal mouse interaction, but spix seems unable to replicate the same behavior using synthetic events. As far as I can tell spix is generating the same MouseEvent in both cases, so maybe it has something to do with how Drawer interacts with mouse events?

I'm on Ubuntu 20.04, Qt 6.2.3 and the latest spix from master (modified slightly to print mouse events). I'd be happy to post the full project that I test with if that's helpful.

prototypicalpro avatar Mar 09 '22 20:03 prototypicalpro

I have had some issues with the synthetic events in more complex cases, like drag&drop, where Qt seems to work directly with system events and not with the QEvents in its own queue. But that this would be caused by just adding a Drawer seems odd...

What happens if you use pyAutoGUI to create the events on the system level? If you post the code, I can have a look...

faaxm avatar Mar 11 '22 07:03 faaxm

Interaction with pyAutoGui seems to work. Test script:

import xmlrpc.client
import time
import pyautogui

def clickItem(path):
    # from https://github.com/faaxm/spix/blob/master/examples/RemoteCtrl/script/autogui.py
    # Query spix to get the location of the item
    bounds = s.getBoundingBox(path)
    # bounds = [x, y, width, height] as list
    center_x = bounds[0] + bounds[2] / 2
    center_y = bounds[1] + bounds[3] / 2

    # use pyautogui to move the cursor...
    pyautogui.moveTo(center_x, center_y, duration=1)
    # ...and click
    pyautogui.click()

s = xmlrpc.client.ServerProxy('http://localhost:9000')
print('Test synthetic click')
time.sleep(1)
s.mouseClick("window/clickMe")
print(s.getErrors())
time.sleep(1)

print('Test autogui click')
time.sleep(1)
clickItem("window/clickMe")
print(s.getErrors())
print('done')

Log without drawer:

Starting minimalDrawerBug...
QML debugging is enabled. Only use this in a safe environment.
QMouseEvent(MouseButtonPress LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=844,1400 dev=QPointingDevice("core pointer" Mouse id=1))
QMouseEvent(MouseButtonRelease LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=844,1400 dev=QPointingDevice("core pointer" Mouse id=1))
qml: clicked
qml: clicked

Log with drawer:

Starting minimalDrawerBug...
QML debugging is enabled. Only use this in a safe environment.
QMouseEvent(MouseButtonPress LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=1121,1226 dev=QPointingDevice("core pointer" Mouse id=1))
QMouseEvent(MouseButtonRelease LeftButton pos=60.1016,12.5 scn=60.1016,12.5 gbl=1121,1226 dev=QPointingDevice("core pointer" Mouse id=1))
qml: clicked

If you could take a look at the project that would be great, I am thoroughly stumped: minimalDrawerBug.zip. Let me know if you have any questions.

prototypicalpro avatar Mar 14 '22 18:03 prototypicalpro

Sorry for the long wait, I had less time to look into this than I had hoped... For now, I only had a quick look and have tested this with Qt5 as that is still my default version. With that version, I found that it seems to work as expected.

The output I get is:

# Qt
$ ./examples/Basic/SpixBasicExample
qml: clicked
qml: clicked

# python
$ python3 test_click.py 
Test synthetic click
[]
Test autogui click
[]
done

The synthetic click also works when running the app with -platform minimal.

faaxm avatar Mar 24 '22 13:03 faaxm

Hi there, very similar (or maybe same) problem is happening with our app, using quite complex UI elements. Spix works great with Qt 5.15.10 but all generated QEvents have no effect in Qt 6.4.2.

Note that some of the constructors that Spix is using (e.g. QMouseEvent are deprecated since Qt 6.4) but they should still work. Any idea how to solve this problem? The generated events pass through installed event filter, but maybe are not delivered to the receiver.

Update: The unit tests work with Qt 6.4.2 and if I use same QML contents from the tests in our app, it works as well.

MelodicsPavol avatar Feb 27 '23 20:02 MelodicsPavol

I've found through debugging that the issue was caused by an inactive Popup item attached to an Overlay and thus blocking mouse events. Interestingly regular mouse clicks worked, so did the pyautogui solution.

MelodicsPavol avatar Feb 28 '23 20:02 MelodicsPavol