From deecb4b8544bfc17bbc42f22709969ed70448bb4 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 18 Jun 2012 16:57:31 +0300 Subject: [PATCH] Fix broken handling of inactive transient surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Makes tooltips and tooltip-like components like Create's locator show up properly. These should never get keyboard focus even though they are regular surfaces like any other. Change-Id: I0ade61845d9785cad19040683362a5532a04e6f6 Reviewed-by: Samuel Rødal --- src/compositor/compositor_api/waylandinput.cpp | 4 ++-- src/compositor/compositor_api/waylandinput.h | 2 +- src/compositor/compositor_api/waylandsurface.cpp | 9 +++++++++ src/compositor/compositor_api/waylandsurface.h | 2 ++ src/compositor/wayland_wrapper/wlinputdevice.cpp | 9 ++++++++- src/compositor/wayland_wrapper/wlinputdevice.h | 2 +- src/compositor/wayland_wrapper/wlshellsurface.cpp | 3 ++- src/compositor/wayland_wrapper/wlsurface.cpp | 1 + src/compositor/wayland_wrapper/wlsurface.h | 4 ++++ src/plugins/platforms/wayland/qwaylandshellsurface.cpp | 9 ++++++++- 10 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/compositor/compositor_api/waylandinput.cpp b/src/compositor/compositor_api/waylandinput.cpp index 2a5cb6b..290bfed 100644 --- a/src/compositor/compositor_api/waylandinput.cpp +++ b/src/compositor/compositor_api/waylandinput.cpp @@ -127,10 +127,10 @@ WaylandSurface *WaylandInputDevice::keyboardFocus() const return 0; } -void WaylandInputDevice::setKeyboardFocus(WaylandSurface *surface) +bool WaylandInputDevice::setKeyboardFocus(WaylandSurface *surface) { Wayland::Surface *wlsurface = surface?surface->handle():0; - d->setKeyboardFocus(wlsurface); + return d->setKeyboardFocus(wlsurface); } WaylandSurface *WaylandInputDevice::mouseFocus() const diff --git a/src/compositor/compositor_api/waylandinput.h b/src/compositor/compositor_api/waylandinput.h index be38511..90985ed 100644 --- a/src/compositor/compositor_api/waylandinput.h +++ b/src/compositor/compositor_api/waylandinput.h @@ -79,7 +79,7 @@ public: void sendFullTouchEvent(QTouchEvent *event); WaylandSurface *keyboardFocus() const; - void setKeyboardFocus(WaylandSurface *surface); + bool setKeyboardFocus(WaylandSurface *surface); WaylandSurface *mouseFocus() const; void setMouseFocus(WaylandSurface *surface, const QPointF &local_pos, const QPointF &global_pos = QPointF()); diff --git a/src/compositor/compositor_api/waylandsurface.cpp b/src/compositor/compositor_api/waylandsurface.cpp index 08b9291..69eb9d6 100644 --- a/src/compositor/compositor_api/waylandsurface.cpp +++ b/src/compositor/compositor_api/waylandsurface.cpp @@ -336,3 +336,12 @@ QString WaylandSurface::title() const Q_D(const WaylandSurface); return d->surface->title(); } + +/*! + * \return True if WL_SHELL_SURFACE_TRANSIENT_INACTIVE was set for this surface, meaning it should not receive keyboard focus. + */ +bool WaylandSurface::transientInactive() const +{ + Q_D(const WaylandSurface); + return d->surface->transientInactive(); +} diff --git a/src/compositor/compositor_api/waylandsurface.h b/src/compositor/compositor_api/waylandsurface.h index c271e2e..76e0840 100644 --- a/src/compositor/compositor_api/waylandsurface.h +++ b/src/compositor/compositor_api/waylandsurface.h @@ -151,6 +151,8 @@ public: QString title() const; + bool transientInactive() const; + signals: void mapped(); void unmapped(); diff --git a/src/compositor/wayland_wrapper/wlinputdevice.cpp b/src/compositor/wayland_wrapper/wlinputdevice.cpp index 29bfb57..0625fa6 100644 --- a/src/compositor/wayland_wrapper/wlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/wlinputdevice.cpp @@ -385,10 +385,17 @@ Surface *InputDevice::keyboardFocus() const return wayland_cast(keyboardDevice()->focus); } -void InputDevice::setKeyboardFocus(Surface *surface) +/*! + * \return True if the keyboard focus is changed successfully. False for inactive transient surfaces. + */ +bool InputDevice::setKeyboardFocus(Surface *surface) { + if (surface && surface->transientInactive()) + return false; + sendSelectionFocus(surface); wl_keyboard_set_focus(keyboardDevice(), surface ? surface->base() : 0); + return true; } Surface *InputDevice::mouseFocus() const diff --git a/src/compositor/wayland_wrapper/wlinputdevice.h b/src/compositor/wayland_wrapper/wlinputdevice.h index 9bfb423..58f4502 100644 --- a/src/compositor/wayland_wrapper/wlinputdevice.h +++ b/src/compositor/wayland_wrapper/wlinputdevice.h @@ -82,7 +82,7 @@ public: void sendFullTouchEvent(QTouchEvent *event); Surface *keyboardFocus() const; - void setKeyboardFocus(Surface *surface); + bool setKeyboardFocus(Surface *surface); Surface *mouseFocus() const; void setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos); diff --git a/src/compositor/wayland_wrapper/wlshellsurface.cpp b/src/compositor/wayland_wrapper/wlshellsurface.cpp index 12adf82..a0d3e93 100644 --- a/src/compositor/wayland_wrapper/wlshellsurface.cpp +++ b/src/compositor/wayland_wrapper/wlshellsurface.cpp @@ -223,7 +223,8 @@ void ShellSurface::set_transient(struct wl_client *client, shell_surface->m_transientParent = parent_shell_surface; shell_surface->m_xOffset = x; shell_surface->m_yOffset = y; - + if (flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE) + shell_surface->surface()->setTransientInactive(true); } void ShellSurface::set_fullscreen(struct wl_client *client, diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp index 70ebe07..87f7eae 100644 --- a/src/compositor/wayland_wrapper/wlsurface.cpp +++ b/src/compositor/wayland_wrapper/wlsurface.cpp @@ -85,6 +85,7 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) , m_extendedSurface(0) , m_subSurface(0) , m_shellSurface(0) + , m_transientInactive(false) { wl_list_init(&m_frame_callback_list); addClientResource(client, &base()->resource, id, &wl_surface_interface, diff --git a/src/compositor/wayland_wrapper/wlsurface.h b/src/compositor/wayland_wrapper/wlsurface.h index 0716172..9ab5cb0 100644 --- a/src/compositor/wayland_wrapper/wlsurface.h +++ b/src/compositor/wayland_wrapper/wlsurface.h @@ -126,6 +126,9 @@ public: QString title() const { return m_title; } void setTitle(const QString &title); + bool transientInactive() const { return m_transientInactive; } + void setTransientInactive(bool v) { m_transientInactive = v; } + private: Q_DISABLE_COPY(Surface) @@ -155,6 +158,7 @@ private: QPointF m_position; QSize m_size; QString m_title; + bool m_transientInactive; inline SurfaceBuffer *currentSurfaceBuffer() const; bool advanceBufferQueue(); diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp index 3a85a19..05e415b 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp @@ -88,11 +88,18 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left()); transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } + + uint32_t flags = 0; + Qt::WindowFlags wf = m_window->window()->windowFlags(); + if (wf.testFlag(Qt::ToolTip) + || wf.testFlag(Qt::WindowTransparentForInput)) + flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; + wl_shell_surface_set_transient(m_shell_surface, parent_wayland_window->shellSurface()->m_shell_surface, transientPos.x(), transientPos.y(), - 0); + flags); } void QWaylandShellSurface::setTitle(const char *title) -- 2.7.4