Client: Remove QWaylandWindow wl_surface inheritance

...and introduce a client-side QWaylandSurface.

The goal of this is to remove the assumption that a QWaylandWindow maps 1:1
with a wl_surface and also to be able to share implementation with the cursor
implementation and other parts of the plugin that needs to use surfaces, but
are not QWaylandWindows.

QWaylandWindow and QWaylandSurface are still tightly coupled and a lot of the
implementation remains as part of QWaylandWindow, but I'm hoping to fix this in
later patch sets.

Task-number: QTBUG-74373
Change-Id: Ia5a192c8d133847336d266f63ec216fb3639b8c5
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
Johan Klokkhammer Helsing 2019-04-05 12:50:19 +02:00 committed by Johan Helsing
parent dfa4796eae
commit 24be607d50
7 changed files with 267 additions and 92 deletions

View File

@ -45,6 +45,7 @@ SOURCES += qwaylandintegration.cpp \
qwaylandshellsurface.cpp \ qwaylandshellsurface.cpp \
qwaylandextendedsurface.cpp \ qwaylandextendedsurface.cpp \
qwaylandsubsurface.cpp \ qwaylandsubsurface.cpp \
qwaylandsurface.cpp \
qwaylandtouch.cpp \ qwaylandtouch.cpp \
qwaylandqtkey.cpp \ qwaylandqtkey.cpp \
../shared/qwaylandmimehelper.cpp \ ../shared/qwaylandmimehelper.cpp \
@ -70,6 +71,7 @@ HEADERS += qwaylandintegration_p.h \
qwaylandshellsurface_p.h \ qwaylandshellsurface_p.h \
qwaylandextendedsurface_p.h \ qwaylandextendedsurface_p.h \
qwaylandsubsurface_p.h \ qwaylandsubsurface_p.h \
qwaylandsurface_p.h \
qwaylandtouch_p.h \ qwaylandtouch_p.h \
qwaylandqtkey_p.h \ qwaylandqtkey_p.h \
qwaylandabstractdecoration_p.h \ qwaylandabstractdecoration_p.h \

View File

@ -41,6 +41,7 @@
#include "qwaylandintegration_p.h" #include "qwaylandintegration_p.h"
#include "qwaylandwindow_p.h" #include "qwaylandwindow_p.h"
#include "qwaylandsurface_p.h"
#include "qwaylandabstractdecoration_p.h" #include "qwaylandabstractdecoration_p.h"
#include "qwaylandscreen_p.h" #include "qwaylandscreen_p.h"
#include "qwaylandcursor_p.h" #include "qwaylandcursor_p.h"

View File

@ -93,6 +93,7 @@ class QWaylandWindow;
class QWaylandIntegration; class QWaylandIntegration;
class QWaylandHardwareIntegration; class QWaylandHardwareIntegration;
class QWaylandShellSurface; class QWaylandShellSurface;
class QWaylandSurface;
class QWaylandCursor; class QWaylandCursor;
class QWaylandCursorTheme; class QWaylandCursorTheme;

View File

@ -0,0 +1,113 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandsurface_p.h"
#include "qwaylanddisplay_p.h"
#include "qwaylandscreen_p.h"
#include <QtGui/QGuiApplication>
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
QWaylandSurface::QWaylandSurface(QWaylandDisplay *display)
: wl_surface(display->createSurface(this))
{
connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandSurface::handleScreenRemoved);
}
QWaylandSurface::~QWaylandSurface()
{
destroy();
}
QWaylandScreen *QWaylandSurface::oldestEnteredScreen()
{
return m_screens.value(0, nullptr);
}
QWaylandSurface *QWaylandSurface::fromWlSurface(::wl_surface *surface)
{
return static_cast<QWaylandSurface *>(static_cast<QtWayland::wl_surface *>(wl_surface_get_user_data(surface)));
}
void QWaylandSurface::handleScreenRemoved(QScreen *qScreen)
{
auto *screen = static_cast<QWaylandScreen *>(qScreen->handle());
if (m_screens.removeOne(screen))
emit screensChanged();
}
void QWaylandSurface::surface_enter(wl_output *output)
{
auto addedScreen = QWaylandScreen::fromWlOutput(output);
if (m_screens.contains(addedScreen)) {
qCWarning(lcQpaWayland)
<< "Ignoring unexpected wl_surface.enter received for output with id:"
<< wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output))
<< "screen name:" << addedScreen->name() << "screen model:" << addedScreen->model()
<< "This is most likely a bug in the compositor.";
return;
}
m_screens.append(addedScreen);
emit screensChanged();
}
void QWaylandSurface::surface_leave(wl_output *output)
{
auto *removedScreen = QWaylandScreen::fromWlOutput(output);
bool wasRemoved = m_screens.removeOne(removedScreen);
if (!wasRemoved) {
qCWarning(lcQpaWayland)
<< "Ignoring unexpected wl_surface.leave received for output with id:"
<< wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output))
<< "screen name:" << removedScreen->name()
<< "screen model:" << removedScreen->model()
<< "This is most likely a bug in the compositor.";
return;
}
emit screensChanged();
}
} // namespace QtWaylandClient
QT_END_NAMESPACE

View File

@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDSURFACE_P_H
#define QWAYLANDSURFACE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtGui/QScreen>
#include <QtWaylandClient/private/qwayland-wayland.h>
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
class QWaylandScreen;
class QWaylandWindow;
class QWaylandDisplay;
class QWaylandSurface : public QObject, public QtWayland::wl_surface
{
Q_OBJECT
public:
explicit QWaylandSurface(QWaylandDisplay *display);
~QWaylandSurface() override;
QWaylandScreen *oldestEnteredScreen();
static QWaylandSurface *fromWlSurface(::wl_surface *surface);
signals:
void screensChanged();
private slots:
void handleScreenRemoved(QScreen *qScreen);
protected:
void surface_enter(struct ::wl_output *output) override;
void surface_leave(struct ::wl_output *output) override;
QVector<QWaylandScreen *> m_screens; //As seen by wl_surface.enter/leave events. Chronological order.
QWaylandWindow *m_window = nullptr;
friend class QWaylandWindow; // TODO: shouldn't need to be friends
};
} // namespace QtWaylandClient
QT_END_NAMESPACE
#endif // QWAYLANDSURFACE_P_H

View File

@ -41,6 +41,7 @@
#include "qwaylandbuffer_p.h" #include "qwaylandbuffer_p.h"
#include "qwaylanddisplay_p.h" #include "qwaylanddisplay_p.h"
#include "qwaylandsurface_p.h"
#include "qwaylandinputdevice_p.h" #include "qwaylandinputdevice_p.h"
#include "qwaylandscreen_p.h" #include "qwaylandscreen_p.h"
#include "qwaylandshellsurface_p.h" #include "qwaylandshellsurface_p.h"
@ -77,7 +78,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
{ {
static WId id = 1; static WId id = 1;
mWindowId = id++; mWindowId = id++;
connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandWindow::handleScreenRemoved);
initializeWlSurface(); initializeWlSurface();
} }
@ -87,7 +87,7 @@ QWaylandWindow::~QWaylandWindow()
delete mWindowDecoration; delete mWindowDecoration;
if (isInitialized()) if (mSurface)
reset(false); reset(false);
const QWindow *parent = window(); const QWindow *parent = window();
@ -112,7 +112,7 @@ void QWaylandWindow::initWindow()
if (window()->type() == Qt::Desktop) if (window()->type() == Qt::Desktop)
return; return;
if (!isInitialized()) { if (!mSurface) {
initializeWlSurface(); initializeWlSurface();
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
QGuiApplication::sendEvent(window(), &e); QGuiApplication::sendEvent(window(), &e);
@ -177,7 +177,7 @@ void QWaylandWindow::initWindow()
// typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale() // typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale()
// to inform the compositor that high-resolution buffers will be provided. // to inform the compositor that high-resolution buffers will be provided.
if (mDisplay->compositorVersion() >= 3) if (mDisplay->compositorVersion() >= 3)
set_buffer_scale(scale()); mSurface->set_buffer_scale(scale());
if (QScreen *s = window()->screen()) if (QScreen *s = window()->screen())
setOrientationMask(s->orientationUpdateMask()); setOrientationMask(s->orientationUpdateMask());
@ -195,7 +195,11 @@ void QWaylandWindow::initWindow()
void QWaylandWindow::initializeWlSurface() void QWaylandWindow::initializeWlSurface()
{ {
init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); Q_ASSERT(!mSurface);
mSurface.reset(new QWaylandSurface(mDisplay));
connect(mSurface.data(), &QWaylandSurface::screensChanged,
this, &QWaylandWindow::handleScreensChanged);
mSurface->m_window = this;
} }
bool QWaylandWindow::shouldCreateShellSurface() const bool QWaylandWindow::shouldCreateShellSurface() const
@ -219,7 +223,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
void QWaylandWindow::reset(bool sendDestroyEvent) void QWaylandWindow::reset(bool sendDestroyEvent)
{ {
if (isInitialized() && sendDestroyEvent) { if (mSurface && sendDestroyEvent) {
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed); QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
QGuiApplication::sendEvent(window(), &e); QGuiApplication::sendEvent(window(), &e);
} }
@ -227,11 +231,10 @@ void QWaylandWindow::reset(bool sendDestroyEvent)
mShellSurface = nullptr; mShellSurface = nullptr;
delete mSubSurfaceWindow; delete mSubSurfaceWindow;
mSubSurfaceWindow = nullptr; mSubSurfaceWindow = nullptr;
if (isInitialized()) { if (mSurface) {
emit wlSurfaceDestroyed(); emit wlSurfaceDestroyed();
destroy(); mSurface.reset();
} }
mScreens.clear();
if (mFrameCallback) { if (mFrameCallback) {
wl_callback_destroy(mFrameCallback); wl_callback_destroy(mFrameCallback);
@ -244,7 +247,9 @@ void QWaylandWindow::reset(bool sendDestroyEvent)
QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
{ {
return static_cast<QWaylandWindow *>(static_cast<QtWayland::wl_surface *>(wl_surface_get_user_data(surface))); if (auto *s = QWaylandSurface::fromWlSurface(surface))
return s->m_window;
return nullptr;
} }
WId QWaylandWindow::winId() const WId QWaylandWindow::winId() const
@ -372,7 +377,12 @@ void QWaylandWindow::closePopups(QWaylandWindow *parent)
QWaylandScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const QWaylandScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const
{ {
return mScreens.isEmpty() ? waylandScreen() : mScreens.first(); if (mSurface) {
if (auto *screen = mSurface->oldestEnteredScreen())
return screen;
}
return waylandScreen();
} }
void QWaylandWindow::setVisible(bool visible) void QWaylandWindow::setVisible(bool visible)
@ -416,18 +426,18 @@ void QWaylandWindow::setMask(const QRegion &mask)
mMask = mask; mMask = mask;
if (!isInitialized()) if (!mSurface)
return; return;
if (mMask.isEmpty()) { if (mMask.isEmpty()) {
set_input_region(nullptr); mSurface->set_input_region(nullptr);
} else { } else {
struct ::wl_region *region = mDisplay->createRegion(mMask); struct ::wl_region *region = mDisplay->createRegion(mMask);
set_input_region(region); mSurface->set_input_region(region);
wl_region_destroy(region); wl_region_destroy(region);
} }
wl_surface::commit(); mSurface->commit();
} }
void QWaylandWindow::applyConfigureWhenPossible() void QWaylandWindow::applyConfigureWhenPossible()
@ -481,58 +491,6 @@ void QWaylandWindow::applyConfigure()
QWindowSystemInterface::flushWindowSystemEvents(); QWindowSystemInterface::flushWindowSystemEvents();
} }
void QWaylandWindow::surface_enter(wl_output *output)
{
QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents();
auto addedScreen = QWaylandScreen::fromWlOutput(output);
if (mScreens.contains(addedScreen)) {
qCWarning(lcQpaWayland)
<< "Ignoring unexpected wl_surface.enter received for output with id:"
<< wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output))
<< "screen name:" << addedScreen->name() << "screen model:" << addedScreen->model()
<< "This is most likely a bug in the compositor.";
return;
}
mScreens.append(addedScreen);
QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents();
if (oldScreen != newScreen) //currently this will only happen if the first wl_surface.enter is for a non-primary screen
handleScreenChanged();
}
void QWaylandWindow::surface_leave(wl_output *output)
{
QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents();
auto *removedScreen = QWaylandScreen::fromWlOutput(output);
bool wasRemoved = mScreens.removeOne(removedScreen);
if (!wasRemoved) {
qCWarning(lcQpaWayland)
<< "Ignoring unexpected wl_surface.leave received for output with id:"
<< wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output))
<< "screen name:" << removedScreen->name()
<< "screen model:" << removedScreen->model()
<< "This is most likely a bug in the compositor.";
return;
}
QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents();
if (oldScreen != newScreen)
handleScreenChanged();
}
void QWaylandWindow::handleScreenRemoved(QScreen *qScreen)
{
QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents();
bool wasRemoved = mScreens.removeOne(static_cast<QWaylandScreen *>(qScreen->handle()));
if (wasRemoved) {
QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents();
if (oldScreen != newScreen)
handleScreenChanged();
}
}
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
{ {
Q_ASSERT(!buffer->committed()); Q_ASSERT(!buffer->committed());
@ -542,14 +500,14 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
} }
if (buffer) { if (buffer) {
mFrameCallback = frame(); mFrameCallback = mSurface->frame();
wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
mWaitingForFrameSync = true; mWaitingForFrameSync = true;
buffer->setBusy(); buffer->setBusy();
attach(buffer->buffer(), x, y); mSurface->attach(buffer->buffer(), x, y);
} else { } else {
QtWayland::wl_surface::attach(nullptr, 0, 0); mSurface->attach(nullptr, 0, 0);
} }
} }
@ -561,7 +519,7 @@ void QWaylandWindow::attachOffset(QWaylandBuffer *buffer)
void QWaylandWindow::damage(const QRect &rect) void QWaylandWindow::damage(const QRect &rect)
{ {
damage(rect.x(), rect.y(), rect.width(), rect.height()); mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height());
} }
void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage) void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage)
@ -591,20 +549,20 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage)
qCDebug(lcWaylandBackingstore) << "Buffer already committed, ignoring."; qCDebug(lcWaylandBackingstore) << "Buffer already committed, ignoring.";
return; return;
} }
if (!isInitialized()) if (!mSurface)
return; return;
attachOffset(buffer); attachOffset(buffer);
for (const QRect &rect: damage) for (const QRect &rect: damage)
wl_surface::damage(rect.x(), rect.y(), rect.width(), rect.height()); mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height());
Q_ASSERT(!buffer->committed()); Q_ASSERT(!buffer->committed());
buffer->setCommitted(); buffer->setCommitted();
wl_surface::commit(); mSurface->commit();
} }
void QWaylandWindow::commit() void QWaylandWindow::commit()
{ {
wl_surface::commit(); mSurface->commit();
} }
const wl_callback_listener QWaylandWindow::callbackListener = { const wl_callback_listener QWaylandWindow::callbackListener = {
@ -660,6 +618,11 @@ QRect QWaylandWindow::windowGeometry() const
return QRect(QPoint(), surfaceSize()); return QRect(QPoint(), surfaceSize());
} }
wl_surface *QWaylandWindow::wlSurface()
{
return mSurface ? mSurface->object() : nullptr;
}
QWaylandShellSurface *QWaylandWindow::shellSurface() const QWaylandShellSurface *QWaylandWindow::shellSurface() const
{ {
return mShellSurface; return mShellSurface;
@ -701,9 +664,9 @@ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orient
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
set_buffer_transform(transform); mSurface->set_buffer_transform(transform);
// set_buffer_transform is double buffered, we need to commit. // set_buffer_transform is double buffered, we need to commit.
wl_surface::commit(); mSurface->commit();
} }
void QWaylandWindow::setOrientationMask(Qt::ScreenOrientations mask) void QWaylandWindow::setOrientationMask(Qt::ScreenOrientations mask)
@ -942,16 +905,21 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe
} }
} }
void QWaylandWindow::handleScreenChanged() void QWaylandWindow::handleScreensChanged()
{ {
QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents();
if (newScreen == mLastReportedScreen)
return;
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
mLastReportedScreen = newScreen;
int scale = newScreen->scale(); int scale = newScreen->scale();
if (scale != mScale) { if (scale != mScale) {
mScale = scale; mScale = scale;
if (isInitialized() && mDisplay->compositorVersion() >= 3) if (mSurface && mDisplay->compositorVersion() >= 3)
set_buffer_scale(mScale); mSurface->set_buffer_scale(mScale);
ensureSize(); ensureSize();
} }
} }

View File

@ -79,8 +79,9 @@ class QWaylandInputDevice;
class QWaylandScreen; class QWaylandScreen;
class QWaylandShmBackingStore; class QWaylandShmBackingStore;
class QWaylandPointerEvent; class QWaylandPointerEvent;
class QWaylandSurface;
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow, private QtWayland::wl_surface class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -108,12 +109,10 @@ public:
void applyConfigureWhenPossible(); //rename to possible? void applyConfigureWhenPossible(); //rename to possible?
using QtWayland::wl_surface::attach;
void attach(QWaylandBuffer *buffer, int x, int y); void attach(QWaylandBuffer *buffer, int x, int y);
void attachOffset(QWaylandBuffer *buffer); void attachOffset(QWaylandBuffer *buffer);
QPoint attachOffset() const; QPoint attachOffset() const;
using QtWayland::wl_surface::damage;
void damage(const QRect &rect); void damage(const QRect &rect);
void safeCommit(QWaylandBuffer *buffer, const QRegion &damage); void safeCommit(QWaylandBuffer *buffer, const QRegion &damage);
@ -128,7 +127,7 @@ public:
QSize surfaceSize() const; QSize surfaceSize() const;
QRect windowGeometry() const; QRect windowGeometry() const;
::wl_surface *wlSurface() { return object(); } ::wl_surface *wlSurface();
static QWaylandWindow *fromWlSurface(::wl_surface *surface); static QWaylandWindow *fromWlSurface(::wl_surface *surface);
QWaylandDisplay *display() const { return mDisplay; } QWaylandDisplay *display() const { return mDisplay; }
@ -203,11 +202,8 @@ signals:
void wlSurfaceDestroyed(); void wlSurfaceDestroyed();
protected: protected:
void surface_enter(struct ::wl_output *output) override;
void surface_leave(struct ::wl_output *output) override;
QVector<QWaylandScreen *> mScreens; //As seen by wl_surface.enter/leave events. Chronological order.
QWaylandDisplay *mDisplay = nullptr; QWaylandDisplay *mDisplay = nullptr;
QScopedPointer<QWaylandSurface> mSurface;
QWaylandShellSurface *mShellSurface = nullptr; QWaylandShellSurface *mShellSurface = nullptr;
QWaylandSubSurface *mSubSurfaceWindow = nullptr; QWaylandSubSurface *mSubSurfaceWindow = nullptr;
QVector<QWaylandSubSurface *> mChildren; QVector<QWaylandSubSurface *> mChildren;
@ -231,6 +227,7 @@ protected:
bool mSentInitialResize = false; bool mSentInitialResize = false;
QPoint mOffset; QPoint mOffset;
int mScale = 1; int mScale = 1;
QWaylandScreen *mLastReportedScreen = nullptr;
QIcon mWindowIcon; QIcon mWindowIcon;
@ -242,9 +239,6 @@ protected:
QWaylandBuffer *mQueuedBuffer = nullptr; QWaylandBuffer *mQueuedBuffer = nullptr;
QRegion mQueuedBufferDamage; QRegion mQueuedBufferDamage;
private slots:
void handleScreenRemoved(QScreen *qScreen);
private: private:
void setGeometry_helper(const QRect &rect); void setGeometry_helper(const QRect &rect);
void initWindow(); void initWindow();
@ -257,7 +251,7 @@ private:
QWaylandScreen *calculateScreenFromSurfaceEvents() const; QWaylandScreen *calculateScreenFromSurfaceEvents() const;
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e); void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
void handleScreenChanged(); void handleScreensChanged();
bool mUpdateRequested = false; bool mUpdateRequested = false;
QRect mLastExposeGeometry; QRect mLastExposeGeometry;