QWidget* QGraphicsViewAdapter::getWidgetAt(const QPoint& pos)
{
   QWidget* childAt = _graphicsView->childAt(pos);
   if(childAt) 
   {
       return childAt;
   }
  
   QGraphicsItem* item = _graphicsView->itemAt(pos);
   if(item && item->contains(item->mapFromScene(pos)))
   {
      QGraphicsProxyWidget* p = dynamic_cast<QGraphicsProxyWidget*>(item);
      if(p)
      {  
         childAt = p->widget();
         QWidget* c;
         while( (c = childAt->childAt(childAt->mapFromGlobal(pos)))!=0 )
         {
            childAt = c;
         }
         return childAt;
      }
   }
   return NULL;
}
void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
{
    if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type()))
        return;

    QWidget *rootWidget = m_widget;
    QPoint pos = event->pos();

    // Use proper popup window for wheel event. Some QPA sends the wheel
    // event to the root menu, so redirect it to the proper popup window.
    QWidget *activePopupWidget = QApplication::activePopupWidget();
    if (activePopupWidget && activePopupWidget != m_widget) {
        rootWidget = activePopupWidget;
        pos = rootWidget->mapFromGlobal(event->globalPos());
    }

    // which child should have it?
    QWidget *widget = rootWidget->childAt(pos);

    if (!widget)
        widget = rootWidget;

    QPoint mapped = widget->mapFrom(rootWidget, pos);

    QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source());
    QGuiApplication::sendSpontaneousEvent(widget, &translated);
}
bool 
BioWidget::sendMouseEvent( QMouseEvent* event ) 
{
    QWidget* w = m_widgetTextObject->widgetAtPoint( event->pos());

    if ( !w )
        return false;

    QRectF wRect = m_widgetTextObject->widgetRect( w );
    QPoint pos = event->pos() - wRect.toRect().topLeft();

    QWidget* childWidget = w->childAt( event->pos());

    if( !childWidget )
        childWidget = w;
    else
        pos = childWidget->mapTo( w, pos );

    QMouseEvent* widgetMouseEvent = new QMouseEvent( event->type(), pos, event->button(), event->buttons(), event->modifiers());

    QCoreApplication::postEvent( childWidget, widgetMouseEvent );
    event->accept();

    return true;
}
bool 
BioWidget::eventFilter( QObject* o, QEvent* e )
{
    QWidget* w = qobject_cast<QWidget*>( o );

    if ( viewport() == w )
    {
        if ( QEvent::MouseMove != e->type() )
            return false;

        QMouseEvent* event = static_cast<QMouseEvent*>(e);
        //respect child widget cursor
        QWidget* w = m_widgetTextObject->widgetAtPoint(event->pos() );

        if ( w != m_currentHoverWidget )
        {
            m_currentHoverWidget = w;

            if( 0 == w )
                viewport()->unsetCursor();
            else
            {
                QWidget* c = w->childAt(event->pos());
                c = c ? c : w;
                viewport()->setCursor( c->cursor());
            }
        }

        return false;
    }
    return false;
}
Exemple #5
0
QWidget *QWidgetProto::childAt(const QPoint &p) const
{
  QWidget *item = qscriptvalue_cast<QWidget*>(thisObject());
  if (item)
    return item->childAt(p);
  return 0;
}
Exemple #6
0
QWidget *QWidgetProto::childAt(int x, int y) const
{
  QWidget *item = qscriptvalue_cast<QWidget*>(thisObject());
  if (item)
    return item->childAt(x, y);
  return 0;
}
QWidget* QtWidgetsTweakletImpl::FindControl(const QList<Shell::Pointer>& shells, const QPoint& location)
{
  for (QList<Shell::Pointer>::const_iterator iter = shells.begin();
      iter != shells.end(); ++iter)
  {
    QWidget* shellWidget = static_cast<QWidget*>((*iter)->GetControl());
    QWidget* control = shellWidget->childAt(location.x(), location.y());
    if (control) return control;
  }

  return nullptr;
}
Exemple #8
0
bool WindowManager::mousePressEvent(QObject *object, QEvent *event)
{
    // cast event and check buttons/modifiers
    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    if (!(Qt::NoModifier==mouseEvent->modifiers() && Qt::LeftButton==mouseEvent->button())) {
        return false;
    }

    // check lock
    if (isLocked()) {
        return false;
    } else {
        setLocked(true);
    }

    // cast to widget
    QWidget *widget = static_cast<QWidget*>(object);

    // check if widget can be dragged from current position
    if (isBlackListed(widget) || !canDrag(widget)) {
        return false;
    }

    // retrieve widget's child at event position
    QPoint position(mouseEvent->pos());
    QWidget *child = widget->childAt(position);
    if (!canDrag(widget, child, position)) {
        return false;
    }

    // save target and drag point
    _target = widget;
    _dragPoint = position;
    _globalDragPoint = mouseEvent->globalPos();
    _dragAboutToStart = true;

    // send a move event to the current child with same position
    // if received, it is caught to actually start the drag
    QPoint localPoint(_dragPoint);
    if (child) {
        localPoint = child->mapFrom(widget, localPoint);
    } else {
        child = widget;
    }
    QMouseEvent localMouseEvent(QEvent::MouseMove, localPoint, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    qApp->sendEvent(child, &localMouseEvent);
    // never eat event
    return false;
}
Exemple #9
0
	void UiManager::mousePressEvent(QMouseEvent *event)
	{
		QWidget *pressedWidget = NULL;
	
		// get the clicked item through the view (respects view and item transformations)
		QGraphicsItem* itemAt = mWidgetView->itemAt(event->pos());
		if ((itemAt) && (itemAt->isWidget()))
		{
			QGraphicsProxyWidget *proxyWidget = qgraphicsitem_cast<QGraphicsProxyWidget *>(itemAt);
			if (proxyWidget)
			{
				QWidget *embeddedWidget = proxyWidget->widget();
	
				// if the widget has children, use them, otherwise use the widget directly
				if (embeddedWidget->children().size() > 0)
				{
					QPoint widgetPoint = proxyWidget->mapFromScene(mWidgetView->mapToScene(event->pos())).toPoint();
					pressedWidget = embeddedWidget->childAt(widgetPoint);
				}
				else
				{
					pressedWidget = embeddedWidget;
				}
			}
		}
	
		// if there was a focused widget and there is none or a different one now, defocus
		if (mFocusedWidget && (!pressedWidget || pressedWidget != mFocusedWidget))
		{
			QEvent foe(QEvent::FocusOut);
			QApplication::sendEvent(mFocusedWidget, &foe);
			mFocusedWidget = NULL;
			mTopLevelWidget->setFocus();
		}
	
		// set the new focus
		if (pressedWidget)
		{
			QEvent fie(QEvent::FocusIn);
			QApplication::sendEvent(pressedWidget, &fie);
			pressedWidget->setFocus(Qt::MouseFocusReason);
			mFocusedWidget = pressedWidget;
		}
	
		QApplication::sendEvent(mWidgetView->viewport(), event);
	}
void QApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
{

    if (!e->widget)
        return;

//    QPoint localPoint = ev.pos();
    QPoint globalPoint = e->globalPos;
//    bool trustLocalPoint = !!tlw; //is there something the local point can be local to?
    QWidget *mouseWidget;

    qt_last_x = globalPoint.x();
    qt_last_y = globalPoint.y();

     QWidget *mouseWindow = e->widget.data();

     // find the tlw if we didn't get it from the plugin
     if (!mouseWindow) {
         mouseWindow = QApplication::topLevelAt(globalPoint);
     }

     if (!mouseWindow)
         return;

     mouseWidget = mouseWindow;

     if (app_do_modal && !qt_try_modal(mouseWindow, QEvent::Wheel) ) {
         qDebug() << "modal blocked wheel event" << mouseWindow;
         return;
     }
     QPoint p = mouseWindow->mapFromGlobal(globalPoint);
     QWidget *w = mouseWindow->childAt(p);
     if (w) {
         mouseWidget = w;
         p = mouseWidget->mapFromGlobal(globalPoint);
     }

     QWheelEvent ev(p, globalPoint, e->delta, buttons, QApplication::keyboardModifiers(),
                   e->orient);
     QApplication::sendSpontaneousEvent(mouseWidget, &ev);
}
bool KisTabletSupportX11::nativeEventFilter(const QByteArray &/*eventType*/, void *ev, long * /*unused_on_X11*/)
{
    XEvent *event = static_cast<XEvent*>(ev);

    // Eat the choked mouse event...
    if (kis_tabletChokeMouse &&
        (event->type == ButtonRelease ||
         event->type == ButtonPress ||
         event->type == MotionNotify)) {

        kis_tabletChokeMouse = false;

        // Mhom-mhom...
        return true;
    }

    if (kis_haveEvdevTablets && event->type == EnterNotify) {
        evdevEventsActivationWorkaround((WId)event->xany.window);
    }

    QTabletDeviceDataList *tablets = qt_tablet_devices();
    for (int i = 0; i < tablets->size(); ++i) {
        QTabletDeviceData &tab = tablets->operator [](i);
        if (event->type == tab.xinput_motion
            || event->type == tab.xinput_button_release
            || event->type == tab.xinput_button_press) {

            QWidget *widget = QApplication::activePopupWidget();

            if (!widget) {
                widget = QApplication::activeModalWidget();
            }

            if (!widget) {
                widget = QWidget::find((WId)event->xany.window);
            }

            bool retval = widget ? translateXinputEvent(event, &tab, widget) : false;

            if (retval) {
                /**
                 * If the tablet event is accepted, no mouse event
                 * should arrive. Otherwise, the popup widgets (at
                 * least) will not work correctly
                 */
                kis_tabletChokeMouse = true;
            }

            return retval;
        } else if (event->type == tab.xinput_proximity_in ||
                   event->type == tab.xinput_proximity_out) {

            const XProximityNotifyEvent *proximity =
                reinterpret_cast<const XProximityNotifyEvent*>(event);
            XID device_id = proximity->deviceid;

            QTabletDeviceDataList *tablet_list = qt_tablet_devices();
            for (int i = 0; i < tablet_list->size(); ++i) {
                QTabletDeviceData &tab = tablet_list->operator[](i);
                if (device_id == static_cast<XDevice *>(tab.device)->device_id &&
                    tab.isTouchWacomTablet) {

                    QWidget *widget = QApplication::activePopupWidget();

                    if (!widget) {
                        widget = QApplication::activeModalWidget();
                    }

                    if (!widget) {
                        widget = QWidget::find((WId)event->xany.window);
                    }

                    if (widget) {
                        QPoint curr(proximity->x, proximity->y);
                        QWidget *child = widget->childAt(curr);

                        if (child) {
                            widget = child;
                        }

                        QEvent::Type type = (QEvent::Type)
                            (event->type == tab.xinput_proximity_in ?
                             KisTabletEvent::TouchProximityInEx :
                             KisTabletEvent::TouchProximityOutEx);

                        QEvent e(type);
                        e.ignore();
                        QApplication::sendEvent(widget, &e);
                    }

                    return true;
                }
            }
        }
    }

    return false;
}
bool translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet, QWidget *defaultWidget)
{
    Q_ASSERT(defaultWidget);

#if defined (Q_OS_IRIX)
#endif

    Q_ASSERT(tablet != 0);

    QWidget *w = defaultWidget;
    QPoint global,
        curr;
    QPointF hiRes;
    qreal pressure = 0;
    int xTilt = 0,
        yTilt = 0,
        z = 0;
    qreal tangentialPressure = 0;
    qreal rotation = 0;
    int deviceType = QTabletEvent::NoDevice;
    int pointerType = QTabletEvent::UnknownPointer;
    const XDeviceMotionEvent *motion = 0;
    XDeviceButtonEvent *button = 0;
    KisTabletEvent::ExtraEventType t = KisTabletEvent::TabletMoveEx;
    Qt::KeyboardModifiers modifiers = 0;

    modifiers = QApplication::queryKeyboardModifiers();

#if !defined (Q_OS_IRIX)
    XID device_id = 0;
#endif

    if (ev->type == tablet->xinput_motion) {
        motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
        t = KisTabletEvent::TabletMoveEx;
        global = QPoint(motion->x_root, motion->y_root);
        curr = QPoint(motion->x, motion->y);
#if !defined (Q_OS_IRIX)
        device_id = motion->deviceid;
#endif
    } else if (ev->type == tablet->xinput_button_press || ev->type == tablet->xinput_button_release) {
        if (ev->type == tablet->xinput_button_press) {
            t = KisTabletEvent::TabletPressEx;
        } else {
            t = KisTabletEvent::TabletReleaseEx;
        }
        button = (XDeviceButtonEvent*)ev;
        global = QPoint(button->x_root, button->y_root);
        curr = QPoint(button->x, button->y);
#if !defined (Q_OS_IRIX)
        device_id = button->deviceid;
#endif
    } else {
        qFatal("Unknown event type! Probably, 'proximity', "
               "but we don't handle it here, so this is a bug");
    }

    qint64 wacomSerialId = 0;
    qint64 wacomDeviceId = 0;
#if defined (Q_OS_IRIX)
#else
    // We've been passed in data for a tablet device that handles this type
    // of event, but it isn't necessarily the tablet device that originated
    // the event.  Use the device id to find the originating device if we
    // have it.
    QTabletDeviceDataList *tablet_list = qt_tablet_devices();
    for (int i = 0; i < tablet_list->size(); ++i) {
        QTabletDeviceData &tab = tablet_list->operator[](i);
        if (device_id == static_cast<XDevice *>(tab.device)->device_id) {
            // Replace the tablet passed in with this one.
            tablet = &tab;
            deviceType = tab.deviceType;
            if (tab.deviceType == QTabletEvent::XFreeEraser) {
                deviceType = QTabletEvent::Stylus;
                pointerType = QTabletEvent::Eraser;
            } else if (tab.deviceType == QTabletEvent::Stylus) {
                pointerType = QTabletEvent::Pen;
            }
            break;
        }
    }

    /**
     * Touch events from Wacom tablets should not be sent as real
     * tablet events
     */
    if (tablet->isTouchWacomTablet) return false;

    fetchWacomToolId(wacomSerialId, wacomDeviceId, tablet);

    if (wacomDeviceId && deviceType == QTabletEvent::Stylus) {
        deviceType = parseWacomDeviceId(wacomDeviceId);
    }

    QRect screenArea = qApp->desktop()->rect();

    /**
     * Some 'nice' tablet drivers (evdev) do not return the value
     * of all the axes each time. Instead they tell about the
     * recenty changed axes only, so we have to keep the state of
     * all the axes internally and update the relevant part only.
     */
    bool hasSaneData = false;
    if (motion) {
        hasSaneData =
            tablet->savedAxesData.updateAxesData(motion->first_axis,
                                                 motion->axes_count,
                                                 motion->axis_data);
    } else if (button) {
        hasSaneData =
            tablet->savedAxesData.updateAxesData(button->first_axis,
                                                 button->axes_count,
                                                 button->axis_data);
    }

    if (!hasSaneData) return false;

    hiRes = tablet->savedAxesData.position(tablet, screenArea);
    pressure = tablet->savedAxesData.pressure();
    xTilt = tablet->savedAxesData.xTilt();
    yTilt = tablet->savedAxesData.yTilt();


    if (deviceType == QTabletEvent::Airbrush) {
        tangentialPressure =
            std::fmod(qreal(tablet->savedAxesData.rotation() - tablet->minRotation) /
                      (tablet->maxRotation - tablet->minRotation) , 2.0);
    } else {
        rotation =
            std::fmod(qreal(tablet->savedAxesData.rotation() - tablet->minRotation) /
                      (tablet->maxRotation - tablet->minRotation) + 0.5, 1.0) * 360.0;
    }

#endif

    if (tablet->widgetToGetPress) {
        w = tablet->widgetToGetPress;
    } else {
        QWidget *child = w->childAt(curr);
        if (child)
            w = child;
    }
    curr = w->mapFromGlobal(global);

    if (t == KisTabletEvent::TabletPressEx) {
        tablet->widgetToGetPress = w;
    } else if (t == KisTabletEvent::TabletReleaseEx && tablet->widgetToGetPress) {
        w = tablet->widgetToGetPress;
        curr = w->mapFromGlobal(global);
        tablet->widgetToGetPress = 0;
    }

    Qt::MouseButton qtbutton = Qt::NoButton;
    Qt::MouseButtons qtbuttons;

    if (motion) {
        qtbuttons = translateMouseButtons(motion->state);
    } else if (button) {
        qtbuttons = translateMouseButtons(button->state);
        qtbutton = translateMouseButton(button->button);
    }

    KisTabletEvent e(t, curr, global, hiRes,
                     deviceType, pointerType,
                     qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
                     xTilt, yTilt, tangentialPressure, rotation, z, modifiers, wacomSerialId,
                     qtbutton, qtbuttons);

    e.ignore();
    QApplication::sendEvent(w, &e);

    return e.isAccepted();
}
Exemple #13
0
// generateTouchEvent - iterates through existing touches and creates a QTouchEvent.
// For the primary finger, it also creates a mouse event if the location has move
void QPAHiddTpHandler::generateTouchEvent()
{
	if (m_touches.empty())
		return;
	
	QList<QTouchEvent::TouchPoint> touchPoints;
	QList<HiddTouch>::const_iterator it;

	QWidget* widget = QWidget::mouseGrabber();
	if (!widget) {
		QWidget* window = QApplication::topLevelAt(m_lastTouchDown);
		if (window)
			widget = window->childAt(window->mapFromGlobal(m_lastTouchDown));
	}

	if (!widget) {
		QPoint dummyPt(10, 10);
		QWidget* window = QApplication::topLevelAt(dummyPt);
		if (window)
			widget = window->childAt(window->mapFromGlobal(dummyPt));
	}
	if(!widget) {
	    widget = QApplication::activeWindow();
	    if(QApplication::focusWidget())
	    {
		widget = QApplication::focusWidget();
	    }
	}
	Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers();

	if (widget && m_sendPenCancel) {
		//printf("Mouse Up for Pen Cancel: %d, %d\n", m_penCancelPoint.x(), m_penCancelPoint.y());
		QMouseEvent ev(QEvent::MouseButtonRelease, m_penCancelPoint, m_penCancelPoint, true,
				Qt::LeftButton, Qt::NoButton, keyboardModifiers);
		qt_sendSpontaneousEvent((QObject*) widget, &ev);							
		m_sendPenCancel = false;
		m_penCancelPoint = QPoint (0,0);
	}
	
	for (it = m_touches.begin(); it != m_touches.end(); ++it) {
		QTouchEvent::TouchPoint touchPoint;
		touchPoint.setId(it->id);
		touchPoint.setPos(QPoint(it->x, it->y));

		touchPoint.setScreenPos(touchPoint.pos());
		switch (it->state) {
		case QPAHiddTpHandler::FingerDown:
			touchPoint.setState(Qt::TouchPointPressed);
			break;
		case QPAHiddTpHandler::FingerUp:
			touchPoint.setState(Qt::TouchPointReleased);
			break;
		case QPAHiddTpHandler::FingerMove:
			touchPoint.setState(Qt::TouchPointMoved);
			break;
		default:
			touchPoint.setState(Qt::TouchPointStationary);
			break;
		}

		if (it->isPrimary) {
			touchPoint.setState(touchPoint.state() | Qt::TouchPointPrimary);
		}

		touchPoints.append(touchPoint);
//		printf ("%s: adding touch point id %d (hiddId %llu) for pos (%d, %d) primary %d\n", 
//			__func__, it->id, it->hiddId, it->x, it->y, it->isPrimary);

		if (it->isPrimary) {

			QPoint mousePos = QPoint(it->x, it->y);
			if (widget) {
				
				if (it->state == QPAHiddTpHandler::FingerDown) {

					uint32_t currTime = m_touchTimer.elapsed();
					int dx = mousePos.x() - m_mousePress.x();
					int dy = mousePos.y() - m_mousePress.y();
					
					if (((currTime - m_mousePressTime) < (uint32_t) QApplication::doubleClickInterval()) &&
						((dx * dx + dy * dy) <= 144)) {

						//printf("Mouse Double Click: %d, %d\n", mousePos.x(), mousePos.y());
						QMouseEvent ev(QEvent::MouseButtonDblClick, mousePos, mousePos,
									   Qt::LeftButton, Qt::LeftButton, keyboardModifiers);
						qt_sendSpontaneousEvent((QObject*) widget, &ev);

						m_mousePressTime = 0;
					}
					else {

						//printf("Mouse Down: %d, %d\n", mousePos.x(), mousePos.y());
						QMouseEvent ev(QEvent::MouseButtonPress, mousePos, mousePos,
									   Qt::LeftButton, Qt::LeftButton, keyboardModifiers);
						qt_sendSpontaneousEvent((QObject*) widget, &ev);

						m_mousePress = mousePos;

						m_mousePressTime = currTime;
					}

				} else if (it->state == QPAHiddTpHandler::FingerMove) {
					//printf("Mouse Move: %d, %d\n", mousePos.x(), mousePos.y());
					QMouseEvent ev(QEvent::MouseMove, mousePos, mousePos,
								   Qt::LeftButton, Qt::LeftButton, keyboardModifiers);
					qt_sendSpontaneousEvent((QObject*) widget, &ev);							
				}
			}
		}
	}
	
	//printf ("sending touch event\n");
	qt_translateRawTouchEvent(QApplication::activeWindow(), QTouchEvent::TouchScreen, touchPoints);

	for (it = m_touches.begin(); it != m_touches.end(); ++it) {

		if (it->isPrimary) {

			QPoint mousePos = QPoint(it->x, it->y);
			if (widget) {
			
				if (it->state == QPAHiddTpHandler::FingerUp) {
					//printf("Mouse Up: %d, %d\n", mousePos.x(), mousePos.y());
					QMouseEvent ev(QEvent::MouseButtonRelease, mousePos, mousePos,
								   Qt::LeftButton, Qt::NoButton, keyboardModifiers);
					qt_sendSpontaneousEvent((QObject*) widget, &ev);			
				}
			}
		}
	}
}
Exemple #14
0
bool QPAHiddTpHandler::updateTouchEvents(QList<QPAHiddTpHandler::HiddTouch>& hiddTouches) 
{
	bool triggerTouchEvent = false;

	for (QList<HiddTouch>::iterator it = m_touches.begin(); it != m_touches.end(); ++it) {
		it->seenInScan = false;
	}

	for (int i = 0; i < hiddTouches.size(); ++i) {
		
		//int oldMetaActiveTouches = m_metaActiveTouchesCount;
	    HiddTouch& touch = hiddTouches[i];
	    if (touch.state == FingerDown) {
			addNewTouch(touch);
			triggerTouchEvent = true;
	    } else {
			if (updateOldTouch(touch))
				triggerTouchEvent = true;
	    }
/*
	    if (m_metaActiveTouchesCount && m_metaActiveTouchesCount != oldMetaActiveTouches && !oldMetaActiveTouches) {
			//QWSServer::processKeyEvent(-1, Qt::Key_CoreNavi_Meta, Qt::MetaModifier, true, false);
			HostBase::instance()->setMetaModifier(true);
		} else if (oldMetaActiveTouches && !m_metaActiveTouchesCount) {
			//QWSServer::processKeyEvent(-1, Qt::Key_CoreNavi_Meta, Qt::NoModifier, false, false);
			HostBase::instance()->setMetaModifier(false);
		}
*/

	    if (touch.gestureKey != Qt::Key_unknown) {
			if (touch.gestureKey != Qt::Key_Flick) {
				//printf ("Sending Gesture Event %d\n", touch.gestureKey);
				//QWSServer::processKeyEvent(-1, touch.gestureKey, Qt::NoModifier, true, false);
				//QWSServer::processKeyEvent(-1, touch.gestureKey, Qt::NoModifier, false, false);
			}
			if (touch.gestureKey == Qt::Key_Flick
#if !defined(TARGET_DESKTOP)
		   || touch.gestureKey == Qt::Key_CoreNavi_SwipeDown
#endif
			) {

				m_screenEdgeFlickGesture->m_edge = ScreenEdgeFlickGesture::EdgeUnknown;
				
				if (advancedGestures)/*Preferences::instance()->sysUiEnableNextPrevGestures())*/ {

					const int INVALID_COORD = 0xFFFFFFFF;
					int xDown = INVALID_COORD;
					int yDown = INVALID_COORD;

					// finding the old touch to update
					for (QList<HiddTouch>::iterator it = m_touches.begin(); it != m_touches.end(); ++it) {
						if (it->hiddId == touch.hiddId) {
							xDown = it->xDown;
							yDown = it->yDown;						
							break;
						}
					}

					if (xDown != INVALID_COORD && yDown != INVALID_COORD) {

						const int borderWidth = 25;
						const int minimumYLength = 25;

						if ((xDown < borderWidth) &&
						    (abs(touch.x) > minimumYLength) &&
							(touch.xVelocity > 0) &&
							(abs(touch.xVelocity) > abs(touch.yVelocity))) {
							printf("flick on left border. distance: %d, yDist = %d\n", abs(touch.x), touch.x - xDown);
							if((touch.x - xDown) >= minimumYLength) {
								m_screenEdgeFlickGesture->m_edge = ScreenEdgeFlickGesture::EdgeLeft;
								m_screenEdgeFlickGesture->m_yDistance = (touch.x - xDown);
							} else {
								printf("Rejected Flick\n");
							}
						}
						else if ((xDown > (m_deviceWidth - borderWidth)) &&
     							 (abs(touch.x - m_deviceWidth) > minimumYLength) &&
								 (touch.xVelocity < 0) &&
								 (abs(touch.xVelocity) > abs(touch.yVelocity))) {
							printf("flick on right border. distance: %d, yDist = %d\n", abs(touch.x - m_deviceWidth), xDown - touch.x);
							if((xDown - touch.x) >= minimumYLength){
								m_screenEdgeFlickGesture->m_edge = ScreenEdgeFlickGesture::EdgeRight;
								m_screenEdgeFlickGesture->m_yDistance = (xDown - touch.x) ;
							} else {
								printf("Rejected Flick\n");
							}
						}
						else if ((yDown < borderWidth) &&
    							 (abs(touch.y) > minimumYLength) &&
								 (touch.yVelocity > 0) &&
								 (abs(touch.yVelocity) > abs(touch.xVelocity))) {
							printf("flick on top border. distance: %d, yDist = %d\n", abs(touch.y), touch.y - yDown);
							if((touch.y - yDown) >= minimumYLength) {
								m_screenEdgeFlickGesture->m_edge = ScreenEdgeFlickGesture::EdgeTop;
								m_screenEdgeFlickGesture->m_yDistance = (touch.y - yDown);
							} else {
								printf("Rejected Flick\n");
							}
						}
						else if ((yDown > (m_deviceHeight - borderWidth)) &&
    							 (abs(touch.y - m_deviceHeight) > minimumYLength) &&
								 (touch.yVelocity < 0) &&
								 (abs(touch.yVelocity) > abs(touch.xVelocity))) {
							printf("flick on bottom border. distance: %d, yDist = %d\n", abs(touch.y - m_deviceHeight), yDown - touch.y);
							if((yDown - touch.y) >= minimumYLength) {
								m_screenEdgeFlickGesture->m_edge = ScreenEdgeFlickGesture::EdgeBottom;
								m_screenEdgeFlickGesture->m_yDistance = (yDown - touch.y);
							} else {
								printf("Rejected Flick\n");
							}
						}								  
					}

					if (m_screenEdgeFlickGesture->m_edge != ScreenEdgeFlickGesture::EdgeUnknown) {

						QList<QGesture *> gestureStartedList;
						QList<QGesture *> gestureFinishedList;

						m_screenEdgeFlickGesture->setHotSpot(m_lastTouchDown);
					
						m_screenEdgeFlickGesture->setState(Qt::GestureStarted);
						gestureStartedList.append(m_screenEdgeFlickGesture);

						// determine which widget this event will go to
						QWidget* window = QApplication::topLevelAt(m_lastTouchDown);
						if (window) {
							QWidget* widget = window->childAt(window->mapFromGlobal(m_lastTouchDown));
							if (widget) {

								QGestureEvent gestureStartedEvent(gestureStartedList);
								QApplication::sendEvent((QObject*) widget, &gestureStartedEvent);

								m_screenEdgeFlickGesture->setState(Qt::GestureFinished);
								gestureFinishedList.append(m_screenEdgeFlickGesture);

								QGestureEvent gestureFinishedEvent(gestureFinishedList);
								QApplication::sendEvent((QObject*) widget, &gestureFinishedEvent);
							}
						}
					}
				}

				if (m_screenEdgeFlickGesture->m_edge == ScreenEdgeFlickGesture::EdgeUnknown) {

					QList<QGesture *> gestureStartedList;
					QList<QGesture *> gestureFinishedList;

					flickGesture->m_endPos = QPoint(touch.x, touch.y);
					flickGesture->m_velocity = transMap(QPoint(touch.xVelocity, touch.yVelocity));
					//flickGesture->m_velocity = HostBase::instance()->map(QPoint(touch.xVelocity, touch.yVelocity));
					flickGesture->setHotSpot(m_lastTouchDown);
					
					flickGesture->setState(Qt::GestureStarted);
					gestureStartedList.append(flickGesture);

					// determine which widget this event will go to
					QWidget* window = QApplication::topLevelAt(m_lastTouchDown);
					if (window) {
						QWidget* widget = window->childAt(window->mapFromGlobal(m_lastTouchDown));
						if (widget) {
							QGestureEvent gestureStartedEvent(gestureStartedList);
							QApplication::sendEvent((QObject*) widget, &gestureStartedEvent);

							flickGesture->setState(Qt::GestureFinished);
							gestureFinishedList.append(flickGesture);

							QGestureEvent gestureFinishedEvent(gestureFinishedList);
							QApplication::sendEvent((QObject*) widget, &gestureFinishedEvent);
						}
					}
				}
			}
	    
	    }

	}

	for (QList<HiddTouch>::iterator it = m_touches.begin(); it != m_touches.end(); ++it) {
		if (!it->seenInScan) {
			g_critical("%s: Finger %lld went missing. lifting it up",
					  __PRETTY_FUNCTION__, it->hiddId);
			// FIXME: this should be FingerCancel
			it->state = FingerUp;
/*
			if (it->isMetaTouch) {
				--m_metaActiveTouchesCount;			
				if (m_metaActiveTouchesCount == 0) {
					//QWSServer::processKeyEvent(-1, Qt::Key_CoreNavi_Meta, Qt::NoModifier, false, false);
					HostBase::instance()->setMetaModifier(false);
				}
			}
*/
			triggerTouchEvent = true;
		}
	}
	
	if (triggerTouchEvent) {
		generateTouchEvent();
		removeReleasedTouches();
		return true;
	}

	return false;
}
void QApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
{
    if (!e->widget)
       return;

    // qDebug() << "handleMouseEvent" << tlw << ev.pos() << ev.globalPos() << hex << ev.buttons();
    static QWeakPointer<QWidget> implicit_mouse_grabber;

    QEvent::Type type;
    // move first
    Qt::MouseButtons stateChange = e->buttons ^ buttons;
    if (e->globalPos != QPoint(qt_last_x, qt_last_y) && (stateChange != Qt::NoButton)) {
        QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
                new QWindowSystemInterfacePrivate::MouseEvent(e->widget.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
        QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
        stateChange = Qt::NoButton;
    }

    QWidget * tlw = e->widget.data();

    QPoint localPoint = e->localPos;
    QPoint globalPoint = e->globalPos;
    QWidget *mouseWindow = tlw;

    Qt::MouseButton button = Qt::NoButton;


    if (qt_last_x != globalPoint.x() || qt_last_y != globalPoint.y()) {
        type = QEvent::MouseMove;
        qt_last_x = globalPoint.x();
        qt_last_y = globalPoint.y();
        if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
            qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
            mousePressButton = Qt::NoButton;
    }
    else { // check to see if a new button has been pressed/released
        for (int check = Qt::LeftButton;
             check <= Qt::XButton2;
             check = check << 1) {
            if (check & stateChange) {
                button = Qt::MouseButton(check);
                break;
            }
        }
        if (button == Qt::NoButton) {
            // Ignore mouse events that don't change the current state
            return;
        }
        buttons = e->buttons;
        if (button & e->buttons) {
            if ((e->timestamp - mousePressTime) < static_cast<ulong>(QApplication::doubleClickInterval()) && button == mousePressButton) {
                type = QEvent::MouseButtonDblClick;
                mousePressButton = Qt::NoButton;
            }
            else {
                type = QEvent::MouseButtonPress;
                mousePressTime = e->timestamp;
                mousePressButton = button;
                mousePressX = qt_last_x;
                mousePressY = qt_last_y;
            }
        }
        else
            type = QEvent::MouseButtonRelease;
    }

    if (self->inPopupMode()) {
        //popup mouse handling is magical...
        mouseWindow = qApp->activePopupWidget();

        implicit_mouse_grabber.clear();
        //### how should popup mode and implicit mouse grab interact?

    } else if (tlw && app_do_modal && !qt_try_modal(tlw, QEvent::MouseButtonRelease) ) {
        //even if we're blocked by modality, we should deliver the mouse release event..
        //### this code is not completely correct: multiple buttons can be pressed simultaneously
        if (!(implicit_mouse_grabber && buttons == Qt::NoButton)) {
            //qDebug() << "modal blocked mouse event to" << tlw;
            return;
        }
    }

    // find the tlw if we didn't get it from the plugin
    if (!mouseWindow) {
        mouseWindow = QApplication::topLevelAt(globalPoint);
    }

    if (!mouseWindow && !implicit_mouse_grabber)
        mouseWindow = QApplication::desktop();

    if (mouseWindow && mouseWindow != tlw) {
        //we did not get a sensible localPoint from the window system, so let's calculate it
        localPoint = mouseWindow->mapFromGlobal(globalPoint);
    }

    // which child should have it?
    QWidget *mouseWidget = mouseWindow;
    if (mouseWindow) {
        QWidget *w =  mouseWindow->childAt(localPoint);
        if (w) {
            mouseWidget = w;
        }
    }

    //handle implicit mouse grab
    if (type == QEvent::MouseButtonPress && !implicit_mouse_grabber) {
        implicit_mouse_grabber = mouseWidget;

        Q_ASSERT(mouseWindow);
        mouseWindow->activateWindow(); //focus
    } else if (implicit_mouse_grabber) {
        mouseWidget = implicit_mouse_grabber.data();
        mouseWindow = mouseWidget->window();
        if (mouseWindow != tlw)
            localPoint = mouseWindow->mapFromGlobal(globalPoint);
    }

    Q_ASSERT(mouseWidget);

    //localPoint is local to mouseWindow, but it needs to be local to mouseWidget
    localPoint = mouseWidget->mapFrom(mouseWindow, localPoint);

    if (buttons == Qt::NoButton) {
        //qDebug() << "resetting mouse grabber";
        implicit_mouse_grabber.clear();
    }

    if (mouseWidget != qt_last_mouse_receiver) {
        dispatchEnterLeave(mouseWidget, qt_last_mouse_receiver);
        qt_last_mouse_receiver = mouseWidget;
    }

    // Remember, we might enter a modal event loop when sending the event,
    // so think carefully before adding code below this point.

    // qDebug() << "sending mouse ev." << ev.type() << localPoint << globalPoint << ev.button() << ev.buttons() << mouseWidget << "mouse grabber" << implicit_mouse_grabber;

    QMouseEvent ev(type, localPoint, globalPoint, button, buttons, QApplication::keyboardModifiers());

    QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
    foreach (QWeakPointer<QPlatformCursor> cursor, cursors) {
        if (cursor)
            cursor.data()->pointerEvent(ev);
    }

    int oldOpenPopupCount = openPopupCount;
    QApplication::sendSpontaneousEvent(mouseWidget, &ev);

#ifndef QT_NO_CONTEXTMENU
    if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
        QContextMenuEvent e(QContextMenuEvent::Mouse, localPoint, globalPoint, QApplication::keyboardModifiers());
        QApplication::sendSpontaneousEvent(mouseWidget, &e);
    }
#endif // QT_NO_CONTEXTMENU
}
Exemple #16
0
void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
{
    if (qApp->d_func()->inPopupMode()) {
        QWidget *activePopupWidget = qApp->activePopupWidget();
        QWidget *popup = activePopupWidget;
        QPoint mapped = event->pos();
        if (popup != m_widget)
            mapped = popup->mapFromGlobal(event->globalPos());
        bool releaseAfter = false;
        QWidget *popupChild  = popup->childAt(mapped);

        if (popup != qt_popup_down) {
            qt_button_down = 0;
            qt_popup_down = 0;
        }

        switch (event->type()) {
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonDblClick:
            qt_button_down = popupChild;
            qt_popup_down = popup;
            break;
        case QEvent::MouseButtonRelease:
            releaseAfter = true;
            break;
        default:
            break; // nothing for mouse move
        }

        int oldOpenPopupCount = openPopupCount;

        if (popup->isEnabled()) {
            // deliver event
            qt_replay_popup_mouse_event = false;
            QWidget *receiver = popup;
            QPoint widgetPos = mapped;
            if (qt_button_down)
                receiver = qt_button_down;
            else if (popupChild)
                receiver = popupChild;
            if (receiver != popup)
                widgetPos = receiver->mapFromGlobal(event->globalPos());
            QWidget *alien = m_widget->childAt(m_widget->mapFromGlobal(event->globalPos()));
            QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
            e.setTimestamp(event->timestamp());
            QApplicationPrivate::sendMouseEvent(receiver, &e, alien, m_widget, &qt_button_down, qt_last_mouse_receiver);
        } else {
            // close disabled popups when a mouse button is pressed or released
            switch (event->type()) {
            case QEvent::MouseButtonPress:
            case QEvent::MouseButtonDblClick:
            case QEvent::MouseButtonRelease:
                popup->close();
                break;
            default:
                break;
            }
        }

        if (qApp->activePopupWidget() != activePopupWidget
            && qt_replay_popup_mouse_event) {
            if (m_widget->windowType() != Qt::Popup)
                qt_button_down = 0;
            qt_replay_popup_mouse_event = false;
#ifndef QT_NO_CONTEXTMENU
        } else if (event->type() == QEvent::MouseButtonPress
                   && event->button() == Qt::RightButton
                   && (openPopupCount == oldOpenPopupCount)) {
            QWidget *popupEvent = popup;
            if (qt_button_down)
                popupEvent = qt_button_down;
            else if(popupChild)
                popupEvent = popupChild;
            QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
            QApplication::sendSpontaneousEvent(popupEvent, &e);
#endif
        }

        if (releaseAfter) {
            qt_button_down = 0;
            qt_popup_down = 0;
        }
        return;
    }

    // modal event handling
    if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type()))
        return;

    // which child should have it?
    QWidget *widget = m_widget->childAt(event->pos());
    QPoint mapped = event->pos();

    if (!widget)
        widget = m_widget;

    if (event->type() == QEvent::MouseButtonPress && !qt_button_down)
        qt_button_down = widget;

    QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(),
                                                               qt_button_down, widget);

    if (!receiver) {
        if (event->type() == QEvent::MouseButtonRelease)
            QApplicationPrivate::mouse_buttons &= ~event->button();
        return;
    }

    QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
    translated.setTimestamp(event->timestamp());
    QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget, &qt_button_down,
                                        qt_last_mouse_receiver);

#ifndef QT_NO_CONTEXTMENU
    if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::RightButton) {
        QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
        QGuiApplication::sendSpontaneousEvent(receiver, &e);
    }
#endif
}
void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
{
    static const QEvent::Type contextMenuTrigger =
        QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::ContextMenuOnMouseRelease).toBool() ?
        QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
    if (qApp->d_func()->inPopupMode()) {
        QWidget *activePopupWidget = qApp->activePopupWidget();
        QWidget *popup = activePopupWidget;
        QPoint mapped = event->pos();
        if (popup != m_widget)
            mapped = popup->mapFromGlobal(event->globalPos());
        bool releaseAfter = false;
        QWidget *popupChild  = popup->childAt(mapped);

        if (popup != qt_popup_down) {
            qt_button_down = 0;
            qt_popup_down = 0;
        }

        switch (event->type()) {
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonDblClick:
            qt_button_down = popupChild;
            qt_popup_down = popup;
            break;
        case QEvent::MouseButtonRelease:
            releaseAfter = true;
            break;
        default:
            break; // nothing for mouse move
        }

        int oldOpenPopupCount = openPopupCount;

        if (popup->isEnabled()) {
            // deliver event
            qt_replay_popup_mouse_event = false;
            QWidget *receiver = popup;
            QPoint widgetPos = mapped;
            if (qt_button_down)
                receiver = qt_button_down;
            else if (popupChild)
                receiver = popupChild;
            if (receiver != popup)
                widgetPos = receiver->mapFromGlobal(event->globalPos());
            QWidget *alien = m_widget->childAt(m_widget->mapFromGlobal(event->globalPos()));
            QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
            QGuiApplicationPrivate::setMouseEventSource(&e, QGuiApplicationPrivate::mouseEventSource(event));
            e.setTimestamp(event->timestamp());
            QApplicationPrivate::sendMouseEvent(receiver, &e, alien, m_widget, &qt_button_down, qt_last_mouse_receiver);
        } else {
            // close disabled popups when a mouse button is pressed or released
            switch (event->type()) {
            case QEvent::MouseButtonPress:
            case QEvent::MouseButtonDblClick:
            case QEvent::MouseButtonRelease:
                popup->close();
                break;
            default:
                break;
            }
        }

        if (qApp->activePopupWidget() != activePopupWidget
            && qt_replay_popup_mouse_event) {
            if (m_widget->windowType() != Qt::Popup)
                qt_button_down = 0;
            if (event->type() == QEvent::MouseButtonPress) {
                // the popup disappeared, replay the mouse press event
                QWidget *w = QApplication::widgetAt(event->globalPos());
                if (w && !QApplicationPrivate::isBlockedByModal(w)) {
                    // activate window of the widget under mouse pointer
                    if (!w->isActiveWindow()) {
                        w->activateWindow();
                        w->raise();
                    }

                    QWindow *win = w->windowHandle();
                    if (!win)
                        win = w->nativeParentWidget()->windowHandle();
                    if (win && win->geometry().contains(event->globalPos())) {
                        const QPoint localPos = win->mapFromGlobal(event->globalPos());
                        QMouseEvent e(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
                        QGuiApplicationPrivate::setMouseEventSource(&e, QGuiApplicationPrivate::mouseEventSource(event));
                        e.setTimestamp(event->timestamp());
                        QApplication::sendSpontaneousEvent(win, &e);
                    }
                }
            }
            qt_replay_popup_mouse_event = false;
#ifndef QT_NO_CONTEXTMENU
        } else if (event->type() == contextMenuTrigger
                   && event->button() == Qt::RightButton
                   && (openPopupCount == oldOpenPopupCount)) {
            QWidget *popupEvent = popup;
            if (qt_button_down)
                popupEvent = qt_button_down;
            else if(popupChild)
                popupEvent = popupChild;
            QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
            QApplication::sendSpontaneousEvent(popupEvent, &e);
#endif
        }

        if (releaseAfter) {
            qt_button_down = 0;
            qt_popup_down = 0;
        }
        return;
    }

    // modal event handling
    if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type()))
        return;

    // which child should have it?
    QWidget *widget = m_widget->childAt(event->pos());
    QPoint mapped = event->pos();

    if (!widget)
        widget = m_widget;

    if (event->type() == QEvent::MouseButtonPress)
        qt_button_down = widget;

    QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(),
                                                               qt_button_down, widget);

    if (!receiver) {
        if (event->type() == QEvent::MouseButtonRelease)
            QApplicationPrivate::mouse_buttons &= ~event->button();
        return;
    }
    if ((event->type() != QEvent::MouseButtonPress)
        || !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) {

        // The preceding statement excludes MouseButtonPress events which caused
        // creation of a MouseButtonDblClick event. QTBUG-25831
        QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(),
                               event->button(), event->buttons(), event->modifiers());
        QGuiApplicationPrivate::setMouseEventSource(&translated, QGuiApplicationPrivate::mouseEventSource(event));
        translated.setTimestamp(event->timestamp());
        QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget,
                                            &qt_button_down, qt_last_mouse_receiver);
    }
#ifndef QT_NO_CONTEXTMENU
    if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton) {
        QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
        QGuiApplication::sendSpontaneousEvent(receiver, &e);
    }
#endif
}
Exemple #18
0
void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
{
    static const QEvent::Type contextMenuTrigger =
        QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::ContextMenuOnMouseRelease).toBool() ?
        QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
    if (qApp->d_func()->inPopupMode()) {
        QWidget *activePopupWidget = qApp->activePopupWidget();
        QPoint mapped = event->pos();
        if (activePopupWidget != m_widget)
            mapped = activePopupWidget->mapFromGlobal(event->globalPos());
        bool releaseAfter = false;
        QWidget *popupChild  = activePopupWidget->childAt(mapped);

        if (activePopupWidget != qt_popup_down) {
            qt_button_down = 0;
            qt_popup_down = 0;
        }

        switch (event->type()) {
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonDblClick:
            qt_button_down = popupChild;
            qt_popup_down = activePopupWidget;
            break;
        case QEvent::MouseButtonRelease:
            releaseAfter = true;
            break;
        default:
            break; // nothing for mouse move
        }

        int oldOpenPopupCount = openPopupCount;

        if (activePopupWidget->isEnabled()) {
            // deliver event
            qt_replay_popup_mouse_event = false;
            QWidget *receiver = activePopupWidget;
            QPoint widgetPos = mapped;
            if (qt_button_down)
                receiver = qt_button_down;
            else if (popupChild)
                receiver = popupChild;
            if (receiver != activePopupWidget)
                widgetPos = receiver->mapFromGlobal(event->globalPos());
            QWidget *alien = receiver;

#if !defined(Q_OS_OSX) && !defined(Q_OS_IOS) // Cocoa tracks popups
            const bool reallyUnderMouse = activePopupWidget->rect().contains(mapped);
            const bool underMouse = activePopupWidget->underMouse();
            if (activePopupWidget != m_widget || (!underMouse && qt_button_down)) {
                // If active popup menu is not the first-level popup menu then we must emulate enter/leave events,
                // because first-level popup menu grabs the mouse and enter/leave events are delivered only to it
                // by QPA. Make an exception for first-level popup menu when the mouse button is pressed on widget.
                if (underMouse != reallyUnderMouse) {
                    if (reallyUnderMouse) {
                        QApplicationPrivate::dispatchEnterLeave(receiver, Q_NULLPTR, event->screenPos());
                        qt_last_mouse_receiver = receiver;
                    } else {
                        QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos());
                        qt_last_mouse_receiver = receiver;
                        receiver = activePopupWidget;
                    }
                }
            } else if (!reallyUnderMouse) {
                alien = Q_NULLPTR;
            }
#endif

            QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(),
                          event->button(), event->buttons(), event->modifiers(), event->source());
            e.setTimestamp(event->timestamp());
            QApplicationPrivate::sendMouseEvent(receiver, &e, alien, receiver->window(), &qt_button_down, qt_last_mouse_receiver);
            qt_last_mouse_receiver = receiver;
        } else {
            // close disabled popups when a mouse button is pressed or released
            switch (event->type()) {
            case QEvent::MouseButtonPress:
            case QEvent::MouseButtonDblClick:
            case QEvent::MouseButtonRelease:
                activePopupWidget->close();
                break;
            default:
                break;
            }
        }

        if (qApp->activePopupWidget() != activePopupWidget
            && qt_replay_popup_mouse_event
            && QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ReplayMousePressOutsidePopup).toBool()) {
            if (m_widget->windowType() != Qt::Popup)
                qt_button_down = 0;
            if (event->type() == QEvent::MouseButtonPress) {
                // the popup disappeared, replay the mouse press event
                QWidget *w = QApplication::widgetAt(event->globalPos());
                if (w && !QApplicationPrivate::isBlockedByModal(w)) {
                    // activate window of the widget under mouse pointer
                    if (!w->isActiveWindow()) {
                        w->activateWindow();
                        w->raise();
                    }

                    QWindow *win = w->windowHandle();
                    if (!win)
                        win = w->nativeParentWidget()->windowHandle();
                    if (win) {
                        const QRect globalGeometry = win->isTopLevel()
                            ? win->geometry()
                            : QRect(win->mapToGlobal(QPoint(0, 0)), win->size());
                        if (globalGeometry.contains(event->globalPos())) {
                            // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
                            const QPoint localPos = win->mapFromGlobal(event->globalPos());
                            QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(),
                                                             event->button(), event->buttons(), event->modifiers(), event->source());
                            QCoreApplicationPrivate::setEventSpontaneous(e, true);
                            e->setTimestamp(event->timestamp());
                            QCoreApplication::postEvent(win, e);
                        }
                    }
                }
            }
            qt_replay_popup_mouse_event = false;
#ifndef QT_NO_CONTEXTMENU
        } else if (event->type() == contextMenuTrigger
                   && event->button() == Qt::RightButton
                   && (openPopupCount == oldOpenPopupCount)) {
            QWidget *popupEvent = activePopupWidget;
            if (qt_button_down)
                popupEvent = qt_button_down;
            else if(popupChild)
                popupEvent = popupChild;
            QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
            QApplication::sendSpontaneousEvent(popupEvent, &e);
#endif
        }

        if (releaseAfter) {
            qt_button_down = 0;
            qt_popup_down = 0;
        }
        return;
    }

    // modal event handling
    if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type()))
        return;

    // which child should have it?
    QWidget *widget = m_widget->childAt(event->pos());
    QPoint mapped = event->pos();

    if (!widget)
        widget = m_widget;

    if (event->type() == QEvent::MouseButtonPress)
        qt_button_down = widget;

    QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(),
                                                               qt_button_down, widget);

    if (!receiver) {
        if (event->type() == QEvent::MouseButtonRelease)
            QApplicationPrivate::mouse_buttons &= ~event->button();
        return;
    }
    if ((event->type() != QEvent::MouseButtonPress)
        || !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) {

        // The preceding statement excludes MouseButtonPress events which caused
        // creation of a MouseButtonDblClick event. QTBUG-25831
        QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(),
                               event->button(), event->buttons(), event->modifiers(), event->source());
        translated.setTimestamp(event->timestamp());
        QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget,
                                            &qt_button_down, qt_last_mouse_receiver);
        event->setAccepted(translated.isAccepted());
    }
#ifndef QT_NO_CONTEXTMENU
    if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton
        && m_widget->rect().contains(event->pos())) {
        QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
        QGuiApplication::sendSpontaneousEvent(receiver, &e);
    }
#endif
}