From d749d553e483a3e1c177574b8d0cd19f0aa23494 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Mon, 11 Mar 2019 14:02:12 +0100 Subject: [PATCH] Client: Make QWaylandWindow's wl_surface inheritance private QWaylandWindow inheriting wl_surface is a leftover from the old days, and today it is sometimes causing great problems. Especially on xdg_shell and other shells where the wl_surface needs to recreated with a different role if the QWindow::type changes. This is currently worked around by calling reset() on the surface, which will destroy the wl_surface, and emit some necessary events and signals. However, much of the rest of the code still assumes that a QWaylandWindow maps directly to a single wl_surface which won't change over the lifetime of the QWaylandWindow. Today, it would make sense to implement this with composition rather than inheritance. This is a major undertaking and so this is the first small step; hide the inheritance in QWaylandWindow's public API. This makes it much more visible when and where the rest of the QPA plugin is using it, so we can eventually move it into its own class later. Task-number: QTBUG-74373 Change-Id: I257729e33c3a5368cef4bb1e16148ba392e65bd2 Reviewed-by: Paul Olav Tvete Reviewed-by: Pier Luigi Fiorini --- .../qwaylandfullscreenshellv1surface.cpp | 2 +- .../wl-shell/qwaylandwlshellintegration.cpp | 2 +- .../wl-shell/qwaylandwlshellsurface.cpp | 19 +++++++++---------- .../xdg-shell-v5/qwaylandxdgshellv5.cpp | 4 ++-- .../xdg-shell-v5/qwaylandxdgsurfacev5.cpp | 2 +- .../xdg-shell-v6/qwaylandxdgshellv6.cpp | 2 +- .../xdg-shell/qwaylandxdgshell.cpp | 2 +- .../platforms/wayland/qwaylanddatadevice.cpp | 2 +- .../platforms/wayland/qwaylanddisplay.cpp | 2 +- .../wayland/qwaylandextendedsurface.cpp | 2 +- .../wayland/qwaylandinputcontext.cpp | 8 ++++---- .../wayland/qwaylandnativeinterface.cpp | 2 +- .../platforms/wayland/qwaylandwindow_p.h | 3 ++- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.cpp index 9a829f6e9e9..26f598895c3 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.cpp @@ -51,7 +51,7 @@ QWaylandFullScreenShellV1Surface::QWaylandFullScreenShellV1Surface(QtWayland::zw , m_window(window) { auto screen = static_cast(m_window->screen()); - m_shell->present_surface(m_window->object(), + m_shell->present_surface(m_window->wlSurface(), QtWayland::zwp_fullscreen_shell_v1::present_method_default, screen->output()); } diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp index 1edb24b3c01..f396e840267 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellintegration.cpp @@ -70,7 +70,7 @@ bool QWaylandWlShellIntegration::initialize(QWaylandDisplay *display) QWaylandShellSurface *QWaylandWlShellIntegration::createShellSurface(QWaylandWindow *window) { - return new QWaylandWlShellSurface(m_wlShell->get_shell_surface(window->object()), window); + return new QWaylandWlShellSurface(m_wlShell->get_shell_surface(window->wlSurface()), window); } void *QWaylandWlShellIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp index 4506c312ae4..48e14c753fe 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp @@ -62,9 +62,9 @@ QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_ Qt::WindowType type = window->window()->type(); auto *transientParent = window->transientParent(); - if (type == Qt::Popup && transientParent && transientParent->object()) + if (type == Qt::Popup && transientParent && transientParent->wlSurface()) setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial()); - else if (transientParent && transientParent->object()) + else if (transientParent && transientParent->wlSurface()) updateTransientParent(transientParent->window()); else setTopLevel(); @@ -234,11 +234,9 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent) || testShowWithoutActivating(m_window->window())) flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; - Q_ASSERT(parent_wayland_window->object()); - set_transient(parent_wayland_window->object(), - transientPos.x(), - transientPos.y(), - flags); + auto *parentSurface = parent_wayland_window->wlSurface(); + Q_ASSERT(parentSurface); + set_transient(parentSurface, transientPos.x(), transientPos.y(), flags); } void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, uint serial) @@ -261,9 +259,10 @@ void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevic transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } - Q_ASSERT(parent_wayland_window->object()); - set_popup(device->wl_seat(), serial, parent_wayland_window->object(), - transientPos.x(), transientPos.y(), 0); + auto *parentSurface = parent_wayland_window->wlSurface(); + Q_ASSERT(parentSurface); + uint flags = 0; + set_popup(device->wl_seat(), serial, parentSurface, transientPos.x(), transientPos.y(), flags); } void QWaylandWlShellSurface::shell_surface_ping(uint32_t serial) diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp index 4cbafbd71b5..fa9d0d8cfc9 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp @@ -71,7 +71,7 @@ QWaylandXdgSurfaceV5 *QWaylandXdgShellV5::createXdgSurface(QWaylandWindow *windo QWaylandXdgPopupV5 *QWaylandXdgShellV5::createXdgPopup(QWaylandWindow *window, QWaylandInputDevice *inputDevice) { QWaylandWindow *parentWindow = m_popups.empty() ? window->transientParent() : m_popups.last(); - ::wl_surface *parentSurface = parentWindow->object(); + ::wl_surface *parentSurface = parentWindow->wlSurface(); if (m_popupSerial == 0) m_popupSerial = inputDevice->serial(); @@ -81,7 +81,7 @@ QWaylandXdgPopupV5 *QWaylandXdgShellV5::createXdgPopup(QWaylandWindow *window, Q int x = position.x() + parentWindow->frameMargins().left(); int y = position.y() + parentWindow->frameMargins().top(); - auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->object(), parentSurface, seat, m_popupSerial, x, y), window); + auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), window); m_popups.append(window); QObject::connect(popup, &QWaylandXdgPopupV5::destroyed, [this, window](){ m_popups.removeOne(window); diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp index e9f64e2e6cb..e8bff91935e 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp @@ -54,7 +54,7 @@ namespace QtWaylandClient { QWaylandXdgSurfaceV5::QWaylandXdgSurfaceV5(QWaylandXdgShellV5 *shell, QWaylandWindow *window) : QWaylandShellSurface(window) - , QtWayland::xdg_surface_v5(shell->get_xdg_surface(window->object())) + , QtWayland::xdg_surface_v5(shell->get_xdg_surface(window->wlSurface())) , m_window(window) , m_shell(shell) { diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp index 60540fb0c81..9e2c8e6d24a 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp @@ -418,7 +418,7 @@ QWaylandXdgShellV6::~QWaylandXdgShellV6() QWaylandXdgSurfaceV6 *QWaylandXdgShellV6::getXdgSurface(QWaylandWindow *window) { - return new QWaylandXdgSurfaceV6(this, get_xdg_surface(window->object()), window); + return new QWaylandXdgSurfaceV6(this, get_xdg_surface(window->wlSurface()), window); } void QWaylandXdgShellV6::zxdg_shell_v6_ping(uint32_t serial) diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 78b7b45c8ab..acce08b5a09 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -455,7 +455,7 @@ QWaylandXdgShell::~QWaylandXdgShell() QWaylandXdgSurface *QWaylandXdgShell::getXdgSurface(QWaylandWindow *window) { - return new QWaylandXdgSurface(this, get_xdg_surface(window->object()), window); + return new QWaylandXdgSurface(this, get_xdg_surface(window->wlSurface()), window); } void QWaylandXdgShell::xdg_wm_base_ping(uint32_t serial) diff --git a/src/plugins/platforms/wayland/qwaylanddatadevice.cpp b/src/plugins/platforms/wayland/qwaylanddatadevice.cpp index 300c9de0aa8..fde0f71a250 100644 --- a/src/plugins/platforms/wayland/qwaylanddatadevice.cpp +++ b/src/plugins/platforms/wayland/qwaylanddatadevice.cpp @@ -111,7 +111,7 @@ void QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) if (!origin) origin = m_display->currentInputDevice()->touchFocus(); - start_drag(m_dragSource->object(), origin->object(), icon->object(), m_display->currentInputDevice()->serial()); + start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial()); } void QWaylandDataDevice::cancelDrag() diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index fc4241f82da..77db05f1d57 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -111,7 +111,7 @@ struct ::wl_region *QWaylandDisplay::createRegion(const QRegion &qregion) return nullptr; } - return mSubCompositor->get_subsurface(window->object(), parent->object()); + return mSubCompositor->get_subsurface(window->wlSurface(), parent->wlSurface()); } QWaylandClientBufferIntegration * QWaylandDisplay::clientBufferIntegration() const diff --git a/src/plugins/platforms/wayland/qwaylandextendedsurface.cpp b/src/plugins/platforms/wayland/qwaylandextendedsurface.cpp index c5db6d7baf2..a7836e292ec 100644 --- a/src/plugins/platforms/wayland/qwaylandextendedsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandextendedsurface.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window) - : QtWayland::qt_extended_surface(window->display()->windowExtension()->get_extended_surface(window->object())) + : QtWayland::qt_extended_surface(window->display()->windowExtension()->get_extended_surface(window->wlSurface())) , m_window(window) { } diff --git a/src/plugins/platforms/wayland/qwaylandinputcontext.cpp b/src/plugins/platforms/wayland/qwaylandinputcontext.cpp index e85faaf8e28..55e7641e530 100644 --- a/src/plugins/platforms/wayland/qwaylandinputcontext.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputcontext.cpp @@ -120,7 +120,7 @@ void QWaylandTextInput::updateState(Qt::InputMethodQueries queries, uint32_t fla if (!QGuiApplication::focusWindow() || !QGuiApplication::focusWindow()->handle()) return; - struct ::wl_surface *surface = static_cast(QGuiApplication::focusWindow()->handle())->object(); + auto *surface = static_cast(QGuiApplication::focusWindow()->handle())->wlSurface(); if (!surface || (surface != m_surface)) return; @@ -423,7 +423,7 @@ static ::wl_surface *surfaceForWindow(QWindow *window) return nullptr; auto *waylandWindow = static_cast(window->handle()); - return waylandWindow->wl_surface::object(); + return waylandWindow->wlSurface(); } void QWaylandInputContext::update(Qt::InputMethodQueries queries) @@ -529,7 +529,7 @@ void QWaylandInputContext::setFocusObject(QObject *) if (mCurrentWindow && mCurrentWindow->handle()) { if (mCurrentWindow.data() != window || !inputMethodAccepted()) { - struct ::wl_surface *surface = static_cast(mCurrentWindow->handle())->object(); + auto *surface = static_cast(mCurrentWindow->handle())->wlSurface(); if (surface) textInput()->disable(surface); mCurrentWindow.clear(); @@ -538,7 +538,7 @@ void QWaylandInputContext::setFocusObject(QObject *) if (window && window->handle() && inputMethodAccepted()) { if (mCurrentWindow.data() != window) { - struct ::wl_surface *surface = static_cast(window->handle())->object(); + auto *surface = static_cast(window->handle())->wlSurface(); if (surface) { textInput()->enable(surface); mCurrentWindow = window; diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp index 76acb526bf3..cf227d489a5 100644 --- a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp @@ -89,7 +89,7 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc return const_cast(m_integration->display()->wl_compositor()); if (lowerCaseResource == "surface") { QWaylandWindow *w = static_cast(window->handle()); - return w ? w->object() : nullptr; + return w ? w->wlSurface() : nullptr; } if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration()) diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 19c71627b56..7791c5e41e2 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -80,7 +80,7 @@ class QWaylandScreen; class QWaylandShmBackingStore; class QWaylandPointerEvent; -class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow, public QtWayland::wl_surface +class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow, private QtWayland::wl_surface { Q_OBJECT public: @@ -128,6 +128,7 @@ public: QSize surfaceSize() const; QRect windowGeometry() const; + ::wl_surface *wlSurface() { return object(); } static QWaylandWindow *fromWlSurface(::wl_surface *surface); QWaylandDisplay *display() const { return mDisplay; }