From 8458e06b25c07ebc8cf6b210fc1ea4cc9aeb42eb Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sat, 6 Sep 2014 22:55:07 +0200 Subject: Sanitize popup behavior. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Popups are pretty important for widget apps. Menus, combobox dropdows and such are all popups. Currently they are completely borked when activated via keyboard or touch. This is because of the bizarre set_popup request in the protocol, and Weston's current implementation, that ignore the fact that a popup can be opened as a result of a keyboard event too or may not originate from an input event at all. Pass the last input device and serial we have seen, regardless of the type, by tracking it globally in the QWaylandDisplay. With this patch menus and such will not freeze the application anymore when activated with keyboard or touch without sending a mouse event to the window first. The behavior is still broken in some ways, especially with keyboard due to immediately getting a popup_done, but at least applications remain usable. Task-number: QTBUG-41142 Task-number: QTBUG-41147 Change-Id: I18de501004ae8a62ff8667e72225d08c2d3ba491 Reviewed-by: Laszlo Agocs Reviewed-by: Jørgen Lind --- src/client/qwaylandinputdevice.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/client/qwaylandinputdevice.cpp') diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index ad369bb32..14575146d 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -476,7 +476,6 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { - Q_UNUSED(serial); QWaylandWindow *window = mFocus; Qt::MouseButton qt_button; @@ -509,6 +508,8 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time mParent->mTime = time; mParent->mSerial = serial; + if (state) + mParent->mQDisplay->setLastInputDevice(mParent, serial, window); QWaylandWindow *grab = QWaylandWindow::mouseGrab(); if (grab && grab != mFocus) { @@ -754,7 +755,6 @@ void QWaylandInputDevice::Keyboard::focusCallback(void *data, struct wl_callback void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - Q_UNUSED(serial); QWaylandWindow *window = mFocus; uint32_t code = key + 8; bool isDown = state != 0; @@ -769,6 +769,9 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, return; } + if (isDown) + mParent->mQDisplay->setLastInputDevice(mParent, serial, window); + #ifndef QT_NO_WAYLAND_XKB if (!mXkbMap) return; @@ -875,6 +878,7 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial, mParent->mTime = time; mParent->mSerial = serial; mFocus = QWaylandWindow::fromWlSurface(surface); + mParent->mQDisplay->setLastInputDevice(mParent, serial, mFocus); mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); } -- cgit v1.2.3