diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp index df9adf3238c..f426a088c92 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include @@ -114,20 +115,20 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, Analyzer::IAnalyzerT groupLayout->setContentsMargins(0, 0, 0, 0); groupLayout->setSpacing(0); - d->m_mainView = new QQuickView(); + d->m_mainView = new QmlProfilerQuickView(this); d->m_mainView->setResizeMode(QQuickView::SizeRootObjectToView); QWidget *mainViewContainer = QWidget::createWindowContainer(d->m_mainView); mainViewContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *toolsLayout = new QHBoxLayout; - d->m_timebar = new QQuickView(); + d->m_timebar = new QmlProfilerQuickView(this); d->m_timebar->setResizeMode(QQuickView::SizeRootObjectToView); QWidget *timeBarContainer = QWidget::createWindowContainer(d->m_timebar); timeBarContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); timeBarContainer->setFixedHeight(24); - d->m_overview = new QQuickView(); + d->m_overview = new QmlProfilerQuickView(this); d->m_overview->setResizeMode(QQuickView::SizeRootObjectToView); QWidget *overviewContainer = QWidget::createWindowContainer(d->m_overview); overviewContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); @@ -407,6 +408,11 @@ void QmlProfilerTraceView::resizeEvent(QResizeEvent *event) //////////////////////////////////////////////////////////////// // Context menu void QmlProfilerTraceView::contextMenuEvent(QContextMenuEvent *ev) +{ + showContextMenu(ev->globalPos()); +} + +void QmlProfilerTraceView::showContextMenu(QPoint position) { QMenu menu; QAction *viewAllAction = 0; @@ -431,7 +437,7 @@ void QmlProfilerTraceView::contextMenuEvent(QContextMenuEvent *ev) viewAllAction = menu.addAction(tr("Reset Zoom")); } - QAction *selectedAction = menu.exec(ev->globalPos()); + QAction *selectedAction = menu.exec(position); if (selectedAction) { if (selectedAction == viewAllAction) { @@ -509,5 +515,41 @@ void QmlProfilerTraceView::serverRecordingChanged() setRecording(d->m_profilerState->serverRecording()); } +bool QmlProfilerQuickView::event(QEvent *ev) +{ + // We assume context menus can only be triggered by mouse press, mouse release, or + // pre-synthesized events from the window system. + + bool relayed = false; + switch (ev->type()) { + case QEvent::ContextMenu: + // In the case of mouse clicks the active popup gets automatically closed before they show + // up here. That's not necessarily the case with keyboard triggered context menu events, so + // we just ignore them if there is a popup already. Also, the event's pos() and globalPos() + // don't make much sense in this case, so we just put the menu in the upper left corner. + if (QApplication::activePopupWidget() == 0) { + ev->accept(); + parent->showContextMenu(parent->mapToGlobal(QPoint(0,0))); + relayed = true; + } + break; + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: { + QMouseEvent *orig = static_cast(ev); + QCoreApplication::instance()->postEvent(parent->window()->windowHandle(), + new QMouseEvent(orig->type(), parent->window()->mapFromGlobal(orig->globalPos()), + orig->button(), orig->buttons(), orig->modifiers())); + relayed = true; + break; + } + default: + break; + } + + // QQuickView will eat mouse events even if they're not accepted by any QML construct. So we + // ignore the return value of event() above. + return QQuickView::event(ev) || relayed; +} + } // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h index f1b16894f8c..02005d77ac3 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.h +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.h @@ -75,6 +75,7 @@ public: bool hasValidSelection() const; qint64 selectionStart() const; qint64 selectionEnd() const; + void showContextMenu(QPoint position); public slots: void clearDisplay(); @@ -95,6 +96,7 @@ private slots: protected: virtual void resizeEvent(QResizeEvent *event); + virtual void contextMenuEvent(QContextMenuEvent *event); private slots: void profilerStateChanged(); @@ -117,7 +119,6 @@ signals: void resized(); private: - void contextMenuEvent(QContextMenuEvent *); QWidget *createToolbar(); void setRecording(bool recording); @@ -128,6 +129,14 @@ private: QmlProfilerTraceViewPrivate *d; }; +class QmlProfilerQuickView : public QQuickView { +public: + QmlProfilerQuickView(QmlProfilerTraceView *parent) : parent(parent) {} +protected: + QmlProfilerTraceView *parent; + bool event(QEvent *ev); +}; + } // namespace Internal } // namespace QmlProfiler