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 <paul.tvete@qt.io>
Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
This commit is contained in:
Johan Klokkhammer Helsing 2019-03-11 14:02:12 +01:00 committed by Johan Helsing
parent df531a6f3c
commit d749d553e4
13 changed files with 26 additions and 26 deletions

View File

@ -51,7 +51,7 @@ QWaylandFullScreenShellV1Surface::QWaylandFullScreenShellV1Surface(QtWayland::zw
, m_window(window)
{
auto screen = static_cast<QWaylandScreen *>(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());
}

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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)
{
}

View File

@ -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<QWaylandWindow *>(QGuiApplication::focusWindow()->handle())->object();
auto *surface = static_cast<QWaylandWindow *>(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<QWaylandWindow *>(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<QWaylandWindow *>(mCurrentWindow->handle())->object();
auto *surface = static_cast<QWaylandWindow *>(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<QWaylandWindow *>(window->handle())->object();
auto *surface = static_cast<QWaylandWindow *>(window->handle())->wlSurface();
if (surface) {
textInput()->enable(surface);
mCurrentWindow = window;

View File

@ -89,7 +89,7 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc
return const_cast<wl_compositor *>(m_integration->display()->wl_compositor());
if (lowerCaseResource == "surface") {
QWaylandWindow *w = static_cast<QWaylandWindow*>(window->handle());
return w ? w->object() : nullptr;
return w ? w->wlSurface() : nullptr;
}
if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration())

View File

@ -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; }