From d7667e96f2faa83ddb2d9465320fa30ba1891292 Mon Sep 17 00:00:00 2001 From: Jeremy Katz Date: Fri, 18 Dec 2009 15:25:22 +0100 Subject: queue VNC keyboard and mouse events for processing outside socket readyRead() Because QAbstractSocket::readyRead() isn't delivered recursively, code that has its own event loop (such as QMenu::exec()) doesn't receive mouse or keyboard events. This fixes that by queueing the event, with processing started by a 0 timer. --- src/plugins/graphicssystems/vnc/qvncserver.cpp | 45 +++++++++++++++++++++++--- src/plugins/graphicssystems/vnc/qvncserver.h | 6 ++++ 2 files changed, 47 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/graphicssystems/vnc/qvncserver.cpp b/src/plugins/graphicssystems/vnc/qvncserver.cpp index fcff255d3e..cbf6054d4b 100644 --- a/src/plugins/graphicssystems/vnc/qvncserver.cpp +++ b/src/plugins/graphicssystems/vnc/qvncserver.cpp @@ -389,6 +389,10 @@ void QVNCServer::init(uint port) qvnc_cursor = 0; #endif encoder = 0; + + eventTimer.setInterval(0); + eventTimer.setSingleShot(true); + connect(&eventTimer, SIGNAL(timeout()), this, SLOT(sendInputEvents())); } QVNCServer::~QVNCServer() @@ -819,6 +823,29 @@ static bool buttonChange(Qt::MouseButtons before, Qt::MouseButtons after, Qt::Mo return false; } +void QVNCServer::sendInputEvents() +{ + EventPair pair; + QMouseEvent *me; + QKeyEvent *ke; + + while(!eventList.isEmpty()) { + pair = eventList.takeFirst(); + switch(pair.first) { + case MouseEvent: + me = static_cast(pair.second); + QApplicationPrivate::handleMouseEvent(0, *me); + delete me; + break; + case KeyboardEvent: + ke = static_cast(pair.second); + QApplicationPrivate::handleKeyEvent(0, ke); + delete ke; + break; + } + } +} + void QVNCServer::pointerEvent() { QRfbPointerEvent ev; @@ -834,8 +861,13 @@ void QVNCServer::pointerEvent() bool isPress; if (buttonChange(buttons, ev.buttons, &button, &isPress)) type = isPress ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease; - QMouseEvent me(type, QPoint(ev.x, ev.y), QPoint(ev.x, ev.y), button, ev.buttons, keymod); - QApplicationPrivate::handleMouseEvent(0, me); + QMouseEvent * me = new QMouseEvent(type, QPoint(ev.x, ev.y), QPoint(ev.x, ev.y), button, ev.buttons, keymod); + EventPair pair; + pair.first = MouseEvent; + pair.second = me; + eventList.append(pair); + if (!eventTimer.isActive()) + eventTimer.start(); buttons = ev.buttons; handleMsg = false; } @@ -861,8 +893,13 @@ void QVNCServer::keyEvent() QString str; if (ev.unicode && ev.unicode != 0xffff) str = QString(ev.unicode); - QKeyEvent keyEvent(type, ev.keycode, keymod, str); - QApplicationPrivate::handleKeyEvent(0, &keyEvent); + QKeyEvent *keyEvent = new QKeyEvent(type, ev.keycode, keymod, str); + EventPair pair; + pair.first = KeyboardEvent; + pair.second = keyEvent; + eventList.append(pair); + if (!eventTimer.isActive()) + eventTimer.start(); } handleMsg = false; } diff --git a/src/plugins/graphicssystems/vnc/qvncserver.h b/src/plugins/graphicssystems/vnc/qvncserver.h index 79b2098de3..be84c3c7f9 100644 --- a/src/plugins/graphicssystems/vnc/qvncserver.h +++ b/src/plugins/graphicssystems/vnc/qvncserver.h @@ -482,6 +482,7 @@ private slots: void readClient(); void checkUpdate(); void discardClient(); + void sendInputEvents(); private: void init(uint port); @@ -519,6 +520,11 @@ private: QRfbEncoder *encoder; QVNCCursor *cursor; + + enum EventType { MouseEvent, KeyboardEvent }; + QTimer eventTimer; + typedef QPair EventPair; + QList eventList; }; -- cgit v1.2.3