Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
6.3.1, 6.8.0
Description
Hello!
According to our current understanding, Qt fundamentally can't handle creation of modal objects (menus, mainly) on mouse down events properly. The problem seems to be that Qt has a hard-coded mechanism of exclusively grabbing (similar to "capturing" in Windows API terms) the mouse upon a button down event to the QuickItem which accepted the event and the said grab is active until all mouse button downs are released. It doesn't seem that this mechanism can be overridden, at least not in a required way.
The problem with this mechanism in particular is that if one creates a modal menu on this button down event, the menu modality (that is the expectation that more or less all mouse input goes to this menu exclusively) is overridden by the said hard-coded grab mechanism, and the mouse input doesn't go to the menu until all mouse buttons are released and the hard-coded grab is released too.
This yields the following symptoms:
- "one-click" menu operations (clicking on the button which activates the menu on button down, moving over the menu items while still holding the button pressed and releasing the button over the desired menu item) do not work properly. The menu neither updates its item highlight while the mouse is moved over the menu, nor does it react to the mouse button release. Only after all mouse buttons are released the first time (and the hard-coded exclusive grab is released) the menu starts to react to the mouse moves and one can issue a second mouse click to select the menu item.
- In our specific situation we also had a special generic handling of mouse button up events. This handling was expected to kick in in cases when mouse down event does not create a menu (while, in cases when menu is created on mouse down, the opening of a modal menu would steal the mouse, and thus the mouse up would normally not arrive at the original item). After migration to Qt the mouse up event always arrives at the original item, even if a modal menu is created, and we had to change the UI logic at such places.
It does not seem possible to properly workaround the situation by the existing Qt mechanism. The problem is that the hard-coded exclusive grab is happening inside the Qt framework after we return from our QuickItem's mouse down handler routine and thus we don't have execution control anymore to undo this grab. We probably could try to undo the grab upon whatever next event arrives at the said QuickItem, but that might be too late, and we also have an impression that the menu modality is already somewhat generally broken by the said hard-coded grab and we don't know how to fully restore it.
Even if somehow the said workaround could be made to work, all in all we do not believe that such complexities are appropriate for such a generic operation as "one-click menu handling". The example code below also illustrates that the problem doesn't seem to be with the (rather complicated) way we're dealing with menus in our C++ code, but already exists in a basic Qml example.
Example repro steps 1:
- click on the button, but don't release mouse button just yet. Instead move the mouse over the menu. Expected: the menu highlight follows the mouse. Observed: nothing happens.
- while still holding the mouse button down, position the mouse over one of the menu items and release the mouse. Expected: the menu item is selected and the menu is closed. Observed: nothing happens.
Example repro steps 2:
- click on the button, move the mouse a little bit and release mouse button while mouse cursor is still over the button and not over the menu or the background. Expected: nothing happens, the menu just stays open. Observed: the button color is changed (because the button receives a mouse up event, which we didn't expect to receive, since the mouse must be grabbed by the menu at this point). Strangely this doesn't happen if the mouse is not moved in between, we have no explanation for this discrepancy in the behavior.
import QtQuick 2.15 import QtQuick.Controls 2.15FocusScope { id: root anchors.fill: parent component MyItem: MenuItem { text: hovered ? `Hovered ${text}` : text hoverEnabled: true onReleased: button.background.color = "green" HoverHandler { id: mouse acceptedDevices: PointerDevice.Mouse cursorShape: Qt.PointingHandCursor } } Menu { id: menu x: 0 y: 32 modal: true MyItem { text: "A" } MyItem { text: "B" } } Button { text: "Open Menu" id: button background : Rectangle { color: "red" } width: 150 height: 32 onPressed: { button.background.color = "red" menu.open() } onReleased: button.background.color = "blue" } }
Attachments
Issue Links
- depends on
-
QTBUG-68103 add an Item.modal property to block event propagation
- Reported
-
QTBUG-68080 we need to move popup event forwarding logic from QWidgetWindow::handleMouseEvent() to QGuiApplication
- Closed
-
QTBUG-69558 Implement support for native Popups and Menus
- Open
- relates to
-
QTBUG-112449 QtQuick: Focus changes on mouse down/up breaks mouse event routing
- Reported