eglfs: Send proper enter/leave events when multiple screens are in use

Given that there is only one mouse (which might change some day, but
hasn't yet), there can only be one window containing the mouse,
regardless of which screen it's on.  The implementation before was only
able to send enter/leave events when moving from one window to another
on the same screen; but we need the enter/leave events to be sent when
moving between two full-screen windows on two screens as well.

Also send an enter event the first time the mouse moves, to whichever
window that happens to be.  A Wayland compositor that renders its own
cursor will need to know which screen is in use at the beginning.

Pick-to: 5.15
Fixes: QTBUG-83973
Task-number: QTBUG-55161
Task-number: QTBUG-79924
Change-Id: Ie6f36cd33b103955a70bac73c1485bf475c08468
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Shawn Rutledge 2020-05-10 11:38:05 +02:00
parent 36e5a9d025
commit 30be6c41d5
3 changed files with 19 additions and 7 deletions

View File

@ -52,7 +52,9 @@
// //
#include "qeglfsglobal_p.h" #include "qeglfsglobal_p.h"
#include <QtCore/QPointer>
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include <QtGui/QWindow>
#include <qpa/qplatformintegration.h> #include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>
@ -106,6 +108,9 @@ public:
QFbVtHandler *vtHandler() { return m_vtHandler.data(); } QFbVtHandler *vtHandler() { return m_vtHandler.data(); }
QPointer<QWindow> pointerWindow() { return m_pointerWindow; }
void setPointerWindow(QWindow *pointerWindow) { m_pointerWindow = pointerWindow; }
private: private:
EGLNativeDisplayType nativeDisplay() const; EGLNativeDisplayType nativeDisplay() const;
void createInputHandlers(); void createInputHandlers();
@ -118,6 +123,7 @@ private:
QScopedPointer<QPlatformServices> m_services; QScopedPointer<QPlatformServices> m_services;
QScopedPointer<QFbVtHandler> m_vtHandler; QScopedPointer<QFbVtHandler> m_vtHandler;
QEvdevKeyboardManager *m_kbdMgr; QEvdevKeyboardManager *m_kbdMgr;
QPointer<QWindow> m_pointerWindow;
bool m_disableInputHandlers; bool m_disableInputHandlers;
}; };

View File

@ -39,6 +39,7 @@
#include <QtCore/qtextstream.h> #include <QtCore/qtextstream.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformcursor.h> #include <qpa/qplatformcursor.h>
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
@ -149,6 +150,7 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos)
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); const QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); const QList<QOpenGLCompositorWindow *> windows = compositor->windows();
QEglFSIntegration *platformIntegration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
// Generate enter and leave events like a real windowing system would do. // Generate enter and leave events like a real windowing system would do.
if (windows.isEmpty()) if (windows.isEmpty())
@ -157,8 +159,8 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos)
// First window is always fullscreen. // First window is always fullscreen.
if (windows.count() == 1) { if (windows.count() == 1) {
QWindow *window = windows[0]->sourceWindow(); QWindow *window = windows[0]->sourceWindow();
if (m_pointerWindow != window) { if (platformIntegration->pointerWindow() != window) {
m_pointerWindow = window; platformIntegration->setPointerWindow(window);
QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos);
} }
return; return;
@ -169,17 +171,22 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos)
QWindow *window = windows[i]->sourceWindow(); QWindow *window = windows[i]->sourceWindow();
const QRect geom = window->geometry(); const QRect geom = window->geometry();
if (geom.contains(pos)) { if (geom.contains(pos)) {
if (m_pointerWindow != window) { if (platformIntegration->pointerWindow() != window) {
leave = m_pointerWindow; leave = platformIntegration->pointerWindow();
m_pointerWindow = window; platformIntegration->setPointerWindow(window);
enter = window; enter = window;
} }
break; break;
} }
} }
if (enter && leave) if (enter && leave) {
QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos);
} else if (enter) {
QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(pos), pos);
} else if (leave) {
QWindowSystemInterface::handleLeaveEvent(leave);
}
#else #else
Q_UNUSED(pos); Q_UNUSED(pos);
#endif #endif

View File

@ -94,7 +94,6 @@ private:
void setPrimarySurface(EGLSurface surface); void setPrimarySurface(EGLSurface surface);
EGLDisplay m_dpy; EGLDisplay m_dpy;
QPointer<QWindow> m_pointerWindow;
EGLSurface m_surface; EGLSurface m_surface;
QPlatformCursor *m_cursor; QPlatformCursor *m_cursor;