From a52431954dc6b7ab18ecbf1344dbf13e94601f24 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Tue, 18 Jun 2013 15:16:17 +0200 Subject: Fix switching of active window. When getting a surface leave/surface enter pair, the enter event was lost. It could be seen when opening a popup menu. This patch uses a wl_callback to activate the right window. Change-Id: Ibd35fcaa0d43f4723dd7aeff71264d6145411a08 Reviewed-by: Andy Nichols --- .../wayland_common/qwaylandinputdevice.cpp | 37 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp') diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp index 4c965dd4..c426db7b 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp @@ -71,6 +71,7 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) : QtWayland::wl_seat(display->wl_registry(), id) , mQDisplay(display) , mDisplay(display->wl_display()) + , mFocusCallback(0) , mCaps(0) , mTransferDevice(0) , mPointerFocus(0) @@ -455,10 +456,14 @@ void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surfa if (!surface) return; + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); mKeyboardFocus = window; - mQDisplay->setLastKeyboardFocusInputDevice(this); - QWindowSystemInterface::handleWindowActivated(window->window()); + + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } } void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface) @@ -467,8 +472,32 @@ void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surfa Q_UNUSED(surface); mKeyboardFocus = NULL; - mQDisplay->setLastKeyboardFocusInputDevice(0); - QWindowSystemInterface::handleWindowActivated(0); + + // Use a callback to set the focus because we may get a leave/enter pair, and + // the latter one would be lost in the QWindowSystemInterface queue, if + // we issue the handleWindowActivated() calls immediately. + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } +} + +const wl_callback_listener QWaylandInputDevice::callback = { + QWaylandInputDevice::focusCallback +}; + +void QWaylandInputDevice::focusCallback(void *data, struct wl_callback *callback, uint32_t time) +{ + Q_UNUSED(time); + Q_UNUSED(callback); + QWaylandInputDevice *self = static_cast(data); + if (self->mFocusCallback) { + wl_callback_destroy(self->mFocusCallback); + self->mFocusCallback = 0; + } + + self->mQDisplay->setLastKeyboardFocusInputDevice(self->mKeyboardFocus ? self : 0); + QWindowSystemInterface::handleWindowActivated(self->mKeyboardFocus ? self->mKeyboardFocus->window() : 0); } void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -- cgit v1.2.1