diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-03-06 10:36:43 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-03-14 02:14:00 +0000 |
commit | 048918d4bd73886e1a8999a06b7af2cd2ddbe5f2 (patch) | |
tree | b41dc86f2f6fa3ff3fcc83361de272271835f5d4 /src | |
parent | f5edf2b6fb20722bb63c8855793bc2552721748c (diff) |
eglfs: Generate enter and leave events
In addition the logic in QGuiApplication that picks the target window for input
events with a null window has to be enhanced to be compatible with how real windowing
systems work: mouse events following a press are delivered to the same window until the
release, even if the cursor has left the original target window.
Task-number: QTBUG-44814
Change-Id: I3fea84ac77a5ccebeae5def64f92d8d2e03d13ff
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 14 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 2 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformcursor.cpp | 5 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformcursor_p.h | 3 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformscreen.cpp | 42 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformscreen_p.h | 5 |
7 files changed, 69 insertions, 3 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 60b289bacb..3d21b4affc 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -147,12 +147,15 @@ QString *QGuiApplicationPrivate::displayName = 0; QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton; + ulong QGuiApplicationPrivate::mousePressTime = 0; Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton; int QGuiApplicationPrivate::mousePressX = 0; int QGuiApplicationPrivate::mousePressY = 0; int QGuiApplicationPrivate::mouse_double_click_distance = -1; +QWindow *QGuiApplicationPrivate::currentMousePressWindow = 0; + static Qt::LayoutDirection layout_direction = Qt::LeftToRight; static bool force_reverse = false; @@ -1703,6 +1706,17 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo if (e->nullWindow()) { window = QGuiApplication::topLevelAt(globalPoint.toPoint()); if (window) { + // Moves and the release following a press must go to the same + // window, even if the cursor has moved on over another window. + if (e->buttons != Qt::NoButton) { + if (!currentMousePressWindow) + currentMousePressWindow = window; + else + window = currentMousePressWindow; + } else if (currentMousePressWindow) { + window = currentMousePressWindow; + currentMousePressWindow = 0; + } QPointF delta = globalPoint - globalPoint.toPoint(); localPoint = window->mapFromGlobal(globalPoint.toPoint()) + delta; } diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 0c00e06499..7ae6e64b26 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -200,6 +200,7 @@ public: static Qt::MouseButtons tabletState; static QWindow *tabletPressTarget; static QWindow *currentMouseWindow; + static QWindow *currentMousePressWindow; static Qt::ApplicationState applicationState; #ifndef QT_NO_CLIPBOARD diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 06db4e81fa..06674d204d 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1599,6 +1599,8 @@ void QWindow::destroy() QGuiApplicationPrivate::focus_window = parent(); if (QGuiApplicationPrivate::currentMouseWindow == this) QGuiApplicationPrivate::currentMouseWindow = parent(); + if (QGuiApplicationPrivate::currentMousePressWindow == this) + QGuiApplicationPrivate::currentMousePressWindow = parent(); if (QGuiApplicationPrivate::tabletPressTarget == this) QGuiApplicationPrivate::tabletPressTarget = parent(); diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index bf23d52465..5023efbaf6 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -43,6 +43,7 @@ #include "qeglplatformcursor_p.h" #include "qeglplatformintegration_p.h" +#include "qeglplatformscreen_p.h" QT_BEGIN_NAMESPACE @@ -56,7 +57,7 @@ QT_BEGIN_NAMESPACE QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) : m_visible(true), - m_screen(screen), + m_screen(static_cast<QEGLPlatformScreen *>(screen)), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), @@ -300,6 +301,7 @@ void QEGLPlatformCursor::setPos(const QPoint &pos) const QRect oldCursorRect = cursorRect(); m_cursor.pos = pos; update(oldCursorRect | cursorRect()); + m_screen->handleCursorMove(m_cursor.pos); } void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) @@ -309,6 +311,7 @@ void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) const QRect oldCursorRect = cursorRect(); m_cursor.pos = event.screenPos().toPoint(); update(oldCursorRect | cursorRect()); + m_screen->handleCursorMove(m_cursor.pos); } void QEGLPlatformCursor::paintOnScreen() diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h index 481bb3c74c..b89dd1ca43 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE class QOpenGLShaderProgram; class QEGLPlatformCursor; +class QEGLPlatformScreen; class QEGLPlatformCursorDeviceListener : public QObject { @@ -127,7 +128,7 @@ private: } m_cursorAtlas; bool m_visible; - QPlatformScreen *m_screen; + QEGLPlatformScreen *m_screen; QOpenGLShaderProgram *m_program; int m_vertexCoordEntry; int m_textureCoordEntry; diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp index dd4a97cdf5..6e2fc81c42 100644 --- a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp @@ -32,6 +32,8 @@ ****************************************************************************/ #include "qeglplatformscreen_p.h" +#include <QtGui/qwindow.h> +#include <qpa/qwindowsysteminterface.h> #include <QtPlatformSupport/private/qopenglcompositor_p.h> QT_BEGIN_NAMESPACE @@ -45,7 +47,8 @@ QT_BEGIN_NAMESPACE */ QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy) - : m_dpy(dpy) + : m_dpy(dpy), + m_pointerWindow(0) { } @@ -54,4 +57,41 @@ QEGLPlatformScreen::~QEGLPlatformScreen() QOpenGLCompositor::destroy(); } +void QEGLPlatformScreen::handleCursorMove(const QPoint &pos) +{ + const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + + // Generate enter and leave events like a real windowing system would do. + if (windows.isEmpty()) + return; + + // First window is always fullscreen. + if (windows.count() == 1) { + QWindow *window = windows[0]->sourceWindow(); + if (m_pointerWindow != window) { + m_pointerWindow = window; + QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); + } + return; + } + + QWindow *enter = 0, *leave = 0; + for (int i = windows.count() - 1; i >= 0; --i) { + QWindow *window = windows[i]->sourceWindow(); + const QRect geom = window->geometry(); + if (geom.contains(pos)) { + if (m_pointerWindow != window) { + leave = m_pointerWindow; + m_pointerWindow = window; + enter = window; + } + break; + } + } + + if (enter && leave) + QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h index 33528e61a7..98a108c4b7 100644 --- a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h @@ -46,6 +46,7 @@ // #include <QtCore/QList> +#include <QtCore/QPoint> #include <QtCore/qtextstream.h> #include <qpa/qplatformscreen.h> #include <EGL/egl.h> @@ -53,6 +54,7 @@ QT_BEGIN_NAMESPACE class QOpenGLContext; +class QWindow; class QEGLPlatformWindow; class QEGLPlatformScreen : public QPlatformScreen @@ -63,8 +65,11 @@ public: EGLDisplay display() const { return m_dpy; } + void handleCursorMove(const QPoint &pos); + private: EGLDisplay m_dpy; + QWindow *m_pointerWindow; }; QT_END_NAMESPACE |