spix
spix copied to clipboard
[Qt6] Drawer element blocks mouseClick
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.
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...
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.
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.
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.
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.