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:
parent
dfa4796eae
commit
24be607d50
@ -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 \
|
||||||
|
@ -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"
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
113
src/plugins/platforms/wayland/qwaylandsurface.cpp
Normal file
113
src/plugins/platforms/wayland/qwaylandsurface.cpp
Normal 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
|
96
src/plugins/platforms/wayland/qwaylandsurface_p.h
Normal file
96
src/plugins/platforms/wayland/qwaylandsurface_p.h
Normal 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
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user