From 1a40ec4f8dd333386250fa1ba01826ce83c8e1a0 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Fri, 6 Sep 2013 15:30:15 +0200 Subject: Support application internal mouse grabbing for popup windows Mouse grabbing is used to close a popup window when the user clicks on another window. Wayland doesn't support mouse grabbing by design and sends an event when the user clicks on a window of another application. This patch fakes mouse grabbing for the windows of the application the popup belongs to, so that it closes when the user clicks on a window of the same application. Change-Id: Iac210bed0ca0fc6d3ffdbdb76d069886de51cf04 Reviewed-by: Jan Arne Petersen Reviewed-by: Pier Luigi Fiorini Reviewed-by: Laszlo Agocs Reviewed-by: Andrew Knight Reviewed-by: Andy Nichols --- .../wayland_common/qwaylandinputdevice.cpp | 30 +++++++++++++++++----- 1 file changed, 24 insertions(+), 6 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 e081601d..3fe6ca30 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp @@ -223,8 +223,11 @@ void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surf mSerial = serial; mEnterSerial = serial; - window->handleMouseEnter(this); - window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + QWaylandWindow *grab = QWaylandWindow::mouseGrab(); + if (!grab) { + window->handleMouseEnter(this); + window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + } } void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface) @@ -234,8 +237,10 @@ void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surfac if (!surface) return; - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseLeave(this); + if (!QWaylandWindow::mouseGrab()) { + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); + window->handleMouseLeave(this); + } mPointerFocus = 0; mButtons = Qt::NoButton; @@ -264,7 +269,15 @@ void QWaylandInputDevice::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl mGlobalPos = global; mTime = time; - window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + QWaylandWindow *grab = QWaylandWindow::mouseGrab(); + if (grab && grab != window) { + // We can't know the true position since we're getting events for another surface, + // so we just set it outside of the window boundaries. + pos = QPointF(-1, -1); + global = grab->window()->mapToGlobal(pos.toPoint()); + grab->handleMouse(this, time, pos, global, mButtons, Qt::NoModifier); + } else + window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } void QWaylandInputDevice::pointer_button(uint32_t serial, uint32_t time, @@ -304,7 +317,12 @@ void QWaylandInputDevice::pointer_button(uint32_t serial, uint32_t time, mTime = time; mSerial = serial; - if (window) + QWaylandWindow *grab = QWaylandWindow::mouseGrab(); + if (grab && grab != mPointerFocus) { + QPointF pos = QPointF(-1, -1); + QPointF global = grab->window()->mapToGlobal(pos.toPoint()); + grab->handleMouse(this, time, pos, global, mButtons, Qt::NoModifier); + } else if (window) window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } -- cgit v1.2.1