Details
-
Bug
-
Resolution: Done
-
P3: Somewhat important
-
5.5.1
-
None
-
Qt 5.5.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.2.1 20151028) on "xcb"
OS: Debian GNU/Linux stretch/sid [linux version 4.2.0-1-amd64]
-
e4fb521b3f3b9e59146b7569b72aee08dbaeb268
Description
If widget shows context menu the Leave event is not delivered to it -> there is a discrepancy in delivering the Leave event upon first click and all subsequent ones. Upon the first click (after launching the app), the Leave event is delivered (tested with QFrame, with QWidget the Leave event is not delivered).
If the menu shown upon left click Leave event is never delivered.
The consequence of this in our case is that we don't know that the mouse left our widget if the menu is closed by clicking both outside the menu itself and outside our widget.
Example:
leavewidget.h
#if !defined(LEAVEWIDGET_H) #define LEAVEWIDGET_H #include <QFrame> class LeaveWidget : public QFrame { Q_OBJECT public: LeaveWidget(QFrame * parent = 0, Qt::WindowFlags f = 0); protected: virtual bool event(QEvent * event) override; virtual void contextMenuEvent(QContextMenuEvent *event) override; private: void showMenu(); }; #endif //LEAVEWIDGET_H
leavevidget.cpp
#include "leavewidget.h" #include <QDebug> #include <QMouseEvent> #include <QMetaEnum> #include <QMenu> LeaveWidget::LeaveWidget(QFrame * parent, Qt::WindowFlags f) : QFrame(parent, f) { setFixedSize({200, 200}); } bool LeaveWidget::event(QEvent * event) { qDebug() << __FUNCTION__ << QEvent::staticMetaObject.enumerator(QEvent::staticMetaObject.indexOfEnumerator("Type")).valueToKey(event->type()); if (QEvent::MouseButtonPress == event->type() && Qt::LeftButton == dynamic_cast<QMouseEvent *>(event)->button()) showMenu(); return QFrame::event(event); } void LeaveWidget::contextMenuEvent(QContextMenuEvent *event) { showMenu(); QFrame::contextMenuEvent(event); } void LeaveWidget::showMenu() { QMenu * menu = new QMenu{this}; menu->setAttribute(Qt::WA_DeleteOnClose); menu->addAction(QStringLiteral("test1")); menu->addAction(QStringLiteral("test2")); menu->popup(QCursor::pos()); }
main.cpp
#include "leavewidget.h" #include <QApplication> int main(int argc, char * argv[]) { QApplication app{argc, argv}; LeaveWidget w; w.show(); return app.exec(); }
Output upon first right click (Leave event delivered in 80% of cases):
event Enter event WindowActivate event ActivationChange event InputMethodQuery event MouseButtonPress event ContextMenu event ChildAdded event ChildPolished event Leave event ChildRemoved event InputMethodQuery event WindowDeactivate event ActivationChange
Output upon all next right cliks:
event Enter event WindowActivate event ActivationChange event InputMethodQuery event MouseButtonPress event ContextMenu event ChildAdded event ChildPolished event ChildRemoved event InputMethodQuery event WindowDeactivate event ActivationChange
Should the Leave event be delivered or not?