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>
This commit is contained in:
parent
f5edf2b6fb
commit
048918d4bd
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user