backends/wayland: port away from most remaining manual memory management

This commit is contained in:
Xaver Hugl 2022-06-29 14:15:48 +02:00
parent 297971006b
commit b0c852aa76
7 changed files with 124 additions and 155 deletions

View file

@ -65,16 +65,16 @@ namespace Wayland
using namespace KWayland::Client;
WaylandCursor::WaylandCursor(WaylandBackend *backend)
: QObject(backend)
, m_backend(backend)
: m_backend(backend)
{
resetSurface();
}
WaylandCursor::~WaylandCursor() = default;
void WaylandCursor::resetSurface()
{
delete m_surface;
m_surface = backend()->compositor()->createSurface(this);
m_surface.reset(backend()->compositor()->createSurface());
}
void WaylandCursor::init()
@ -82,11 +82,6 @@ void WaylandCursor::init()
installImage();
}
WaylandCursor::~WaylandCursor()
{
delete m_surface;
}
void WaylandCursor::installImage()
{
const QImage image = Cursors::self()->currentCursor()->image();
@ -106,7 +101,7 @@ void WaylandCursor::doInstallImage(wl_buffer *image, const QSize &size, qreal sc
if (!pointer || !pointer->isValid()) {
return;
}
pointer->setCursor(m_surface, image ? Cursors::self()->currentCursor()->hotspot() : QPoint());
pointer->setCursor(m_surface.get(), image ? Cursors::self()->currentCursor()->hotspot() : QPoint());
drawSurface(image, size, scale);
}
@ -124,6 +119,8 @@ WaylandSubSurfaceCursor::WaylandSubSurfaceCursor(WaylandBackend *backend)
{
}
WaylandSubSurfaceCursor::~WaylandSubSurfaceCursor() = default;
void WaylandSubSurfaceCursor::init()
{
if (auto *pointer = backend()->seat()->pointerDevice()->nativePointer()) {
@ -131,15 +128,9 @@ void WaylandSubSurfaceCursor::init()
}
}
WaylandSubSurfaceCursor::~WaylandSubSurfaceCursor()
{
delete m_subSurface;
}
void WaylandSubSurfaceCursor::changeOutput(WaylandOutput *output)
{
delete m_subSurface;
m_subSurface = nullptr;
m_subSurface.reset();
m_output = output;
if (!output) {
return;
@ -157,15 +148,14 @@ void WaylandSubSurfaceCursor::createSubSurface()
return;
}
resetSurface();
m_subSurface = backend()->subCompositor()->createSubSurface(surface(), m_output->surface(), this);
m_subSurface.reset(backend()->subCompositor()->createSubSurface(surface(), m_output->surface()));
m_subSurface->setMode(SubSurface::Mode::Desynchronized);
}
void WaylandSubSurfaceCursor::doInstallImage(wl_buffer *image, const QSize &size, qreal scale)
{
if (!image) {
delete m_subSurface;
m_subSurface = nullptr;
m_subSurface.reset();
return;
}
createSubSurface();
@ -201,8 +191,7 @@ void WaylandSubSurfaceCursor::move(const QPointF &globalPosition)
}
WaylandInputDevice::WaylandInputDevice(KWayland::Client::Keyboard *keyboard, WaylandSeat *seat)
: InputDevice(seat)
, m_seat(seat)
: m_seat(seat)
, m_keyboard(keyboard)
{
connect(keyboard, &Keyboard::keyChanged, this, [this](quint32 key, Keyboard::KeyState nativeState, quint32 time) {
@ -231,8 +220,7 @@ WaylandInputDevice::WaylandInputDevice(KWayland::Client::Keyboard *keyboard, Way
}
WaylandInputDevice::WaylandInputDevice(KWayland::Client::Pointer *pointer, WaylandSeat *seat)
: InputDevice(seat)
, m_seat(seat)
: m_seat(seat)
, m_pointer(pointer)
{
connect(pointer, &Pointer::entered, this, [this](quint32 serial, const QPointF &relativeToSurface) {
@ -315,8 +303,7 @@ WaylandInputDevice::WaylandInputDevice(KWayland::Client::Pointer *pointer, Wayla
}
WaylandInputDevice::WaylandInputDevice(KWayland::Client::RelativePointer *relativePointer, WaylandSeat *seat)
: InputDevice(seat)
, m_seat(seat)
: m_seat(seat)
, m_relativePointer(relativePointer)
{
connect(relativePointer, &RelativePointer::relativeMotion, this, [this](const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 timestamp) {
@ -325,8 +312,7 @@ WaylandInputDevice::WaylandInputDevice(KWayland::Client::RelativePointer *relati
}
WaylandInputDevice::WaylandInputDevice(KWayland::Client::Touch *touch, WaylandSeat *seat)
: InputDevice(seat)
, m_seat(seat)
: m_seat(seat)
, m_touch(touch)
{
connect(touch, &Touch::sequenceCanceled, this, [this]() {
@ -503,17 +489,16 @@ WaylandSeat::~WaylandSeat()
void WaylandSeat::createPointerDevice()
{
m_pointerDevice = new WaylandInputDevice(m_seat->createPointer(), this);
Q_EMIT deviceAdded(m_pointerDevice);
m_pointerDevice = std::make_unique<WaylandInputDevice>(m_seat->createPointer(), this);
Q_EMIT deviceAdded(m_pointerDevice.get());
}
void WaylandSeat::destroyPointerDevice()
{
if (m_pointerDevice) {
Q_EMIT deviceRemoved(m_pointerDevice);
Q_EMIT deviceRemoved(m_pointerDevice.get());
destroyRelativePointer();
delete m_pointerDevice;
m_pointerDevice = nullptr;
m_pointerDevice.reset();
}
}
@ -521,59 +506,56 @@ void WaylandSeat::createRelativePointer()
{
KWayland::Client::RelativePointerManager *manager = m_backend->relativePointerManager();
if (manager) {
m_relativePointerDevice = new WaylandInputDevice(manager->createRelativePointer(m_pointerDevice->nativePointer()), this);
Q_EMIT deviceAdded(m_relativePointerDevice);
m_relativePointerDevice = std::make_unique<WaylandInputDevice>(manager->createRelativePointer(m_pointerDevice->nativePointer()), this);
Q_EMIT deviceAdded(m_relativePointerDevice.get());
}
}
void WaylandSeat::destroyRelativePointer()
{
if (m_relativePointerDevice) {
Q_EMIT deviceRemoved(m_relativePointerDevice);
delete m_relativePointerDevice;
m_relativePointerDevice = nullptr;
Q_EMIT deviceRemoved(m_relativePointerDevice.get());
m_relativePointerDevice.reset();
}
}
void WaylandSeat::createKeyboardDevice()
{
m_keyboardDevice = new WaylandInputDevice(m_seat->createKeyboard(), this);
Q_EMIT deviceAdded(m_keyboardDevice);
m_keyboardDevice = std::make_unique<WaylandInputDevice>(m_seat->createKeyboard(), this);
Q_EMIT deviceAdded(m_keyboardDevice.get());
}
void WaylandSeat::destroyKeyboardDevice()
{
if (m_keyboardDevice) {
Q_EMIT deviceRemoved(m_keyboardDevice);
delete m_keyboardDevice;
m_keyboardDevice = nullptr;
Q_EMIT deviceRemoved(m_keyboardDevice.get());
m_keyboardDevice.reset();
}
}
void WaylandSeat::createTouchDevice()
{
m_touchDevice = new WaylandInputDevice(m_seat->createTouch(), this);
Q_EMIT deviceAdded(m_touchDevice);
m_touchDevice = std::make_unique<WaylandInputDevice>(m_seat->createTouch(), this);
Q_EMIT deviceAdded(m_touchDevice.get());
}
void WaylandSeat::destroyTouchDevice()
{
if (m_touchDevice) {
Q_EMIT deviceRemoved(m_touchDevice);
delete m_touchDevice;
m_touchDevice = nullptr;
Q_EMIT deviceRemoved(m_touchDevice.get());
m_touchDevice.reset();
}
}
WaylandBackend::WaylandBackend(QObject *parent)
: Platform(parent)
, m_display(nullptr)
, m_eventQueue(new EventQueue(this))
, m_registry(new Registry(this))
, m_compositor(new KWayland::Client::Compositor(this))
, m_subCompositor(new KWayland::Client::SubCompositor(this))
, m_shm(new ShmPool(this))
, m_connectionThreadObject(new ConnectionThread(nullptr))
, m_eventQueue(std::make_unique<EventQueue>())
, m_registry(std::make_unique<Registry>())
, m_compositor(std::make_unique<KWayland::Client::Compositor>())
, m_subCompositor(std::make_unique<KWayland::Client::SubCompositor>())
, m_shm(std::make_unique<ShmPool>())
, m_connectionThreadObject(std::make_unique<ConnectionThread>(nullptr))
, m_connectionThread(nullptr)
{
connect(this, &WaylandBackend::connectionFailed, qApp, &QCoreApplication::quit);
@ -602,7 +584,7 @@ WaylandBackend::~WaylandBackend()
if (m_pointerConstraints) {
m_pointerConstraints->release();
}
delete m_waylandCursor;
m_waylandCursor.reset();
m_eventQueue->release();
destroyOutputs();
@ -613,12 +595,11 @@ WaylandBackend::~WaylandBackend()
m_subCompositor->release();
m_compositor->release();
m_registry->release();
delete m_seat;
m_seat.reset();
m_shm->release();
m_connectionThread->quit();
m_connectionThread->wait();
m_connectionThreadObject->deleteLater();
#if HAVE_WAYLAND_EGL
gbm_device_destroy(m_gbmDevice);
#endif
@ -627,19 +608,19 @@ WaylandBackend::~WaylandBackend()
bool WaylandBackend::initialize()
{
connect(m_registry, &Registry::compositorAnnounced, this, [this](quint32 name, quint32 version) {
connect(m_registry.get(), &Registry::compositorAnnounced, this, [this](quint32 name, quint32 version) {
if (version < 4) {
qFatal("wl_compositor version 4 or later is required");
}
m_compositor->setup(m_registry->bindCompositor(name, version));
});
connect(m_registry, &Registry::subCompositorAnnounced, this, [this](quint32 name) {
connect(m_registry.get(), &Registry::subCompositorAnnounced, this, [this](quint32 name) {
m_subCompositor->setup(m_registry->bindSubCompositor(name, 1));
});
connect(m_registry, &Registry::shmAnnounced, this, [this](quint32 name) {
connect(m_registry.get(), &Registry::shmAnnounced, this, [this](quint32 name) {
m_shm->setup(m_registry->bindShm(name, 1));
});
connect(m_registry, &Registry::relativePointerManagerUnstableV1Announced, this, [this](quint32 name, quint32 version) {
connect(m_registry.get(), &Registry::relativePointerManagerUnstableV1Announced, this, [this](quint32 name, quint32 version) {
if (m_relativePointerManager) {
return;
}
@ -648,7 +629,7 @@ bool WaylandBackend::initialize()
Q_EMIT pointerLockSupportedChanged();
}
});
connect(m_registry, &Registry::pointerConstraintsUnstableV1Announced, this, [this](quint32 name, quint32 version) {
connect(m_registry.get(), &Registry::pointerConstraintsUnstableV1Announced, this, [this](quint32 name, quint32 version) {
if (m_pointerConstraints) {
return;
}
@ -657,23 +638,23 @@ bool WaylandBackend::initialize()
Q_EMIT pointerLockSupportedChanged();
}
});
connect(m_registry, &Registry::pointerGesturesUnstableV1Announced, this, [this](quint32 name, quint32 version) {
connect(m_registry.get(), &Registry::pointerGesturesUnstableV1Announced, this, [this](quint32 name, quint32 version) {
if (m_pointerGestures) {
return;
}
m_pointerGestures = m_registry->createPointerGestures(name, version, this);
});
connect(m_registry, &Registry::interfacesAnnounced, this, &WaylandBackend::createOutputs);
connect(m_registry, &Registry::interfacesAnnounced, this, [this]() {
connect(m_registry.get(), &Registry::interfacesAnnounced, this, &WaylandBackend::createOutputs);
connect(m_registry.get(), &Registry::interfacesAnnounced, this, [this]() {
const auto seatInterface = m_registry->interface(Registry::Interface::Seat);
if (seatInterface.name == 0) {
return;
}
m_seat = new WaylandSeat(m_registry->createSeat(seatInterface.name, std::min(2u, seatInterface.version), this), this);
m_seat = std::make_unique<WaylandSeat>(m_registry->createSeat(seatInterface.name, std::min(2u, seatInterface.version), this), this);
Q_EMIT seatCreated();
m_waylandCursor = new WaylandCursor(this);
m_waylandCursor = std::make_unique<WaylandCursor>(this);
});
if (!deviceIdentifier().isEmpty()) {
m_connectionThreadObject->setSocketName(deviceIdentifier());
@ -691,14 +672,13 @@ bool WaylandBackend::initialize()
}
});
connect(this, &WaylandBackend::pointerLockChanged, this, [this](bool locked) {
delete m_waylandCursor;
if (locked) {
m_waylandCursor = new WaylandSubSurfaceCursor(this);
m_waylandCursor = std::make_unique<WaylandSubSurfaceCursor>(this);
m_waylandCursor->move(input()->pointer()->pos());
m_seat->createRelativePointer();
} else {
m_seat->destroyRelativePointer();
m_waylandCursor = new WaylandCursor(this);
m_waylandCursor = std::make_unique<WaylandCursor>(this);
}
m_waylandCursor->init();
});
@ -709,21 +689,21 @@ bool WaylandBackend::initialize()
void WaylandBackend::initConnection()
{
connect(
m_connectionThreadObject, &ConnectionThread::connected, this, [this]() {
m_connectionThreadObject.get(), &ConnectionThread::connected, this, [this]() {
// create the event queue for the main gui thread
m_display = m_connectionThreadObject->display();
m_eventQueue->setup(m_connectionThreadObject);
m_registry->setEventQueue(m_eventQueue);
m_eventQueue->setup(m_connectionThreadObject.get());
m_registry->setEventQueue(m_eventQueue.get());
// setup registry
m_registry->create(m_display);
m_registry->setup();
},
Qt::QueuedConnection);
connect(
m_connectionThreadObject, &ConnectionThread::connectionDied, this, [this]() {
m_connectionThreadObject.get(), &ConnectionThread::connectionDied, this, [this]() {
setReady(false);
Q_EMIT systemCompositorDied();
delete m_seat;
m_seat.reset();
m_shm->destroy();
destroyOutputs();
@ -740,10 +720,10 @@ void WaylandBackend::initConnection()
}
},
Qt::QueuedConnection);
connect(m_connectionThreadObject, &ConnectionThread::failed, this, &WaylandBackend::connectionFailed, Qt::QueuedConnection);
connect(m_connectionThreadObject.get(), &ConnectionThread::failed, this, &WaylandBackend::connectionFailed, Qt::QueuedConnection);
m_connectionThread = new QThread(this);
m_connectionThreadObject->moveToThread(m_connectionThread);
m_connectionThread = std::make_unique<QThread>();
m_connectionThreadObject->moveToThread(m_connectionThread.get());
m_connectionThread->start();
m_connectionThreadObject->initConnection();
@ -765,7 +745,7 @@ void WaylandBackend::createOutputs()
const auto xdgIface = m_registry->interface(Registry::Interface::XdgShellStable);
if (xdgIface.name != 0) {
m_xdgShell = m_registry->createXdgShell(xdgIface.name, xdgIface.version, this);
m_xdgShell.reset(m_registry->createXdgShell(xdgIface.name, xdgIface.version));
}
// we need to multiply the initial window size with the scale in order to
@ -781,14 +761,14 @@ void WaylandBackend::createOutputs()
WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &size)
{
auto surface = m_compositor->createSurface(this);
std::unique_ptr<KWayland::Client::Surface> surface{m_compositor->createSurface()};
if (!surface || !surface->isValid()) {
qCCritical(KWIN_WAYLAND_BACKEND) << "Creating Wayland Surface failed";
return nullptr;
}
if (ssdManager()) {
auto decoration = ssdManager()->create(surface, this);
auto decoration = ssdManager()->create(surface.get(), this);
connect(decoration, &ServerSideDecoration::modeChanged, this, [decoration] {
if (decoration->mode() != ServerSideDecoration::Mode::Server) {
decoration->requestMode(ServerSideDecoration::Mode::Server);
@ -799,7 +779,7 @@ WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &si
WaylandOutput *waylandOutput = nullptr;
if (m_xdgShell && m_xdgShell->isValid()) {
waylandOutput = new XdgShellOutput(name, surface, m_xdgShell, this, m_nextId++);
waylandOutput = new XdgShellOutput(name, std::move(surface), m_xdgShell.get(), this, m_nextId++);
}
if (!waylandOutput) {
@ -958,7 +938,7 @@ void WaylandBackend::createDpmsFilter()
// already another output is off
return;
}
m_dpmsFilter.reset(new DpmsInputEventFilter);
m_dpmsFilter = std::make_unique<DpmsInputEventFilter>();
input()->prependInputEventFilter(m_dpmsFilter.get());
}

View file

@ -71,12 +71,11 @@ class WaylandSeat;
class WaylandOutput;
class WaylandEglBackend;
class WaylandCursor : public QObject
class WaylandCursor
{
Q_OBJECT
public:
explicit WaylandCursor(WaylandBackend *backend);
~WaylandCursor() override;
virtual ~WaylandCursor();
virtual void init();
virtual void move(const QPointF &globalPosition)
@ -93,7 +92,7 @@ protected:
KWayland::Client::Surface *surface() const
{
return m_surface;
return m_surface.get();
}
WaylandBackend *backend() const
{
@ -101,13 +100,12 @@ protected:
}
private:
WaylandBackend *m_backend;
KWayland::Client::Surface *m_surface = nullptr;
WaylandBackend *const m_backend;
std::unique_ptr<KWayland::Client::Surface> m_surface;
};
class WaylandSubSurfaceCursor : public WaylandCursor
{
Q_OBJECT
public:
explicit WaylandSubSurfaceCursor(WaylandBackend *backend);
~WaylandSubSurfaceCursor() override;
@ -123,7 +121,7 @@ private:
QPointF absoluteToRelativePosition(const QPointF &position);
WaylandOutput *m_output = nullptr;
KWayland::Client::SubSurface *m_subSurface = nullptr;
std::unique_ptr<KWayland::Client::SubSurface> m_subSurface;
};
class WaylandInputDevice : public InputDevice
@ -159,7 +157,7 @@ public:
KWayland::Client::Pointer *nativePointer() const;
private:
WaylandSeat *m_seat;
WaylandSeat *const m_seat;
std::unique_ptr<KWayland::Client::Keyboard> m_keyboard;
std::unique_ptr<KWayland::Client::Touch> m_touch;
@ -200,19 +198,19 @@ public:
WaylandInputDevice *pointerDevice() const
{
return m_pointerDevice;
return m_pointerDevice.get();
}
WaylandInputDevice *relativePointerDevice() const
{
return m_relativePointerDevice;
return m_relativePointerDevice.get();
}
WaylandInputDevice *keyboardDevice() const
{
return m_keyboardDevice;
return m_keyboardDevice.get();
}
WaylandInputDevice *touchDevice() const
{
return m_touchDevice;
return m_touchDevice.get();
}
void createRelativePointer();
@ -233,10 +231,10 @@ private:
KWayland::Client::Seat *m_seat;
WaylandBackend *m_backend;
WaylandInputDevice *m_pointerDevice = nullptr;
WaylandInputDevice *m_relativePointerDevice = nullptr;
WaylandInputDevice *m_keyboardDevice = nullptr;
WaylandInputDevice *m_touchDevice = nullptr;
std::unique_ptr<WaylandInputDevice> m_pointerDevice;
std::unique_ptr<WaylandInputDevice> m_relativePointerDevice;
std::unique_ptr<WaylandInputDevice> m_keyboardDevice;
std::unique_ptr<WaylandInputDevice> m_touchDevice;
};
/**
@ -266,7 +264,7 @@ public:
WaylandSeat *seat() const
{
return m_seat;
return m_seat.get();
}
KWayland::Client::PointerGestures *pointerGestures() const
{
@ -330,25 +328,25 @@ private:
WaylandOutput *createOutput(const QString &name, const QSize &size);
wl_display *m_display;
KWayland::Client::EventQueue *m_eventQueue;
KWayland::Client::Registry *m_registry;
KWayland::Client::Compositor *m_compositor;
KWayland::Client::SubCompositor *m_subCompositor;
KWayland::Client::XdgShell *m_xdgShell = nullptr;
KWayland::Client::ShmPool *m_shm;
KWayland::Client::ConnectionThread *m_connectionThreadObject;
std::unique_ptr<KWayland::Client::EventQueue> m_eventQueue;
std::unique_ptr<KWayland::Client::Registry> m_registry;
std::unique_ptr<KWayland::Client::Compositor> m_compositor;
std::unique_ptr<KWayland::Client::SubCompositor> m_subCompositor;
std::unique_ptr<KWayland::Client::XdgShell> m_xdgShell;
std::unique_ptr<KWayland::Client::ShmPool> m_shm;
std::unique_ptr<KWayland::Client::ConnectionThread> m_connectionThreadObject;
WaylandSeat *m_seat = nullptr;
std::unique_ptr<WaylandSeat> m_seat;
KWayland::Client::RelativePointerManager *m_relativePointerManager = nullptr;
KWayland::Client::PointerConstraints *m_pointerConstraints = nullptr;
KWayland::Client::PointerGestures *m_pointerGestures = nullptr;
WaylandEglBackend *m_eglBackend = nullptr;
QThread *m_connectionThread;
std::unique_ptr<QThread> m_connectionThread;
QVector<WaylandOutput *> m_outputs;
int m_pendingInitialOutputs = 0;
WaylandCursor *m_waylandCursor = nullptr;
std::unique_ptr<WaylandCursor> m_waylandCursor;
std::unique_ptr<DpmsInputEventFilter> m_dpmsFilter;
@ -369,17 +367,17 @@ inline wl_display *WaylandBackend::display()
inline KWayland::Client::Compositor *WaylandBackend::compositor()
{
return m_compositor;
return m_compositor.get();
}
inline KWayland::Client::SubCompositor *WaylandBackend::subCompositor()
{
return m_subCompositor;
return m_subCompositor.get();
}
inline KWayland::Client::ShmPool *WaylandBackend::shmPool()
{
return m_shm;
return m_shm.get();
}
} // namespace Wayland

View file

@ -80,7 +80,7 @@ bool WaylandEglOutput::init()
return false;
}
m_overlay = overlay;
m_fbo.reset(new GLFramebuffer(0, nativeSize));
m_fbo = std::make_unique<GLFramebuffer>(0, nativeSize);
EGLSurface eglSurface = EGL_NO_SURFACE;
if (m_backend->havePlatformBase()) {
@ -114,7 +114,7 @@ GLFramebuffer *WaylandEglOutput::fbo() const
void WaylandEglOutput::updateSize()
{
const QSize nativeSize = m_waylandOutput->geometry().size() * m_waylandOutput->scale();
m_fbo.reset(new GLFramebuffer(0, nativeSize));
m_fbo = std::make_unique<GLFramebuffer>(0, nativeSize);
wl_egl_window_resize(m_overlay, nativeSize.width(), nativeSize.height(), 0, 0);
resetBufferAge();
@ -364,7 +364,7 @@ bool WaylandEglBackend::initBufferConfigs()
std::shared_ptr<KWin::GLTexture> WaylandEglBackend::textureForOutput(KWin::Output *output) const
{
std::shared_ptr<GLTexture> texture(new GLTexture(GL_RGBA8, output->pixelSize()));
auto texture = std::make_unique<GLTexture>(GL_RGBA8, output->pixelSize());
GLFramebuffer::pushFramebuffer(m_outputs[output]->fbo());
GLFramebuffer renderTarget(texture.get());
renderTarget.blitFromFramebuffer(QRect(0, texture->height(), texture->width(), -texture->height()));

View file

@ -24,10 +24,10 @@ namespace Wayland
using namespace KWayland::Client;
static const int s_refreshRate = 60000; // TODO: can we get refresh rate data from Wayland host?
WaylandOutput::WaylandOutput(const QString &name, Surface *surface, WaylandBackend *backend)
WaylandOutput::WaylandOutput(const QString &name, std::unique_ptr<Surface> &&surface, WaylandBackend *backend)
: Output(backend)
, m_renderLoop(std::make_unique<RenderLoop>())
, m_surface(surface)
, m_surface(std::move(surface))
, m_backend(backend)
{
setInformation(Information{
@ -36,7 +36,7 @@ WaylandOutput::WaylandOutput(const QString &name, Surface *surface, WaylandBacke
.capabilities = Capability::Dpms,
});
connect(surface, &Surface::frameRendered, this, &WaylandOutput::frameRendered);
connect(m_surface.get(), &Surface::frameRendered, this, &WaylandOutput::frameRendered);
m_turnOffTimer.setSingleShot(true);
m_turnOffTimer.setInterval(dimAnimationTime());
connect(&m_turnOffTimer, &QTimer::timeout, this, [this] {
@ -47,7 +47,6 @@ WaylandOutput::WaylandOutput(const QString &name, Surface *surface, WaylandBacke
WaylandOutput::~WaylandOutput()
{
m_surface->destroy();
delete m_surface;
}
RenderLoop *WaylandOutput::renderLoop() const
@ -113,15 +112,15 @@ void WaylandOutput::updateEnabled(bool enabled)
setState(next);
}
XdgShellOutput::XdgShellOutput(const QString &name, Surface *surface, XdgShell *xdgShell, WaylandBackend *backend, int number)
: WaylandOutput(name, surface, backend)
XdgShellOutput::XdgShellOutput(const QString &name, std::unique_ptr<Surface> &&waylandSurface, XdgShell *xdgShell, WaylandBackend *backend, int number)
: WaylandOutput(name, std::move(waylandSurface), backend)
, m_xdgShellSurface(xdgShell->createSurface(surface()))
, m_number(number)
{
m_xdgShellSurface = xdgShell->createSurface(surface, this);
updateWindowTitle();
connect(m_xdgShellSurface, &XdgShellSurface::configureRequested, this, &XdgShellOutput::handleConfigure);
connect(m_xdgShellSurface, &XdgShellSurface::closeRequested, qApp, &QCoreApplication::quit);
connect(m_xdgShellSurface.get(), &XdgShellSurface::configureRequested, this, &XdgShellOutput::handleConfigure);
connect(m_xdgShellSurface.get(), &XdgShellSurface::closeRequested, qApp, &QCoreApplication::quit);
connect(this, &WaylandOutput::enabledChanged, this, &XdgShellOutput::updateWindowTitle);
connect(this, &WaylandOutput::dpmsModeChanged, this, &XdgShellOutput::updateWindowTitle);
@ -142,13 +141,12 @@ XdgShellOutput::XdgShellOutput(const QString &name, Surface *surface, XdgShell *
updateWindowTitle();
});
surface->commit(KWayland::Client::Surface::CommitFlag::None);
surface()->commit(KWayland::Client::Surface::CommitFlag::None);
}
XdgShellOutput::~XdgShellOutput()
{
m_xdgShellSurface->destroy();
delete m_xdgShellSurface;
}
void XdgShellOutput::handleConfigure(const QSize &size, XdgShellSurface::States states, quint32 serial)
@ -194,8 +192,7 @@ void XdgShellOutput::lockPointer(Pointer *pointer, bool lock)
{
if (!lock) {
const bool surfaceWasLocked = m_pointerLock && m_hasPointerLock;
delete m_pointerLock;
m_pointerLock = nullptr;
m_pointerLock.reset();
m_hasPointerLock = false;
if (surfaceWasLocked) {
Q_EMIT backend()->pointerLockChanged(false);
@ -204,21 +201,17 @@ void XdgShellOutput::lockPointer(Pointer *pointer, bool lock)
}
Q_ASSERT(!m_pointerLock);
m_pointerLock = backend()->pointerConstraints()->lockPointer(surface(), pointer, nullptr,
PointerConstraints::LifeTime::OneShot,
this);
m_pointerLock.reset(backend()->pointerConstraints()->lockPointer(surface(), pointer, nullptr, PointerConstraints::LifeTime::OneShot));
if (!m_pointerLock->isValid()) {
delete m_pointerLock;
m_pointerLock = nullptr;
m_pointerLock.reset();
return;
}
connect(m_pointerLock, &LockedPointer::locked, this, [this]() {
connect(m_pointerLock.get(), &LockedPointer::locked, this, [this]() {
m_hasPointerLock = true;
Q_EMIT backend()->pointerLockChanged(true);
});
connect(m_pointerLock, &LockedPointer::unlocked, this, [this]() {
delete m_pointerLock;
m_pointerLock = nullptr;
connect(m_pointerLock.get(), &LockedPointer::unlocked, this, [this]() {
m_pointerLock.reset();
m_hasPointerLock = false;
Q_EMIT backend()->pointerLockChanged(false);
});

View file

@ -39,7 +39,7 @@ class WaylandOutput : public Output
{
Q_OBJECT
public:
WaylandOutput(const QString &name, KWayland::Client::Surface *surface, WaylandBackend *backend);
WaylandOutput(const QString &name, std::unique_ptr<KWayland::Client::Surface> &&surface, WaylandBackend *backend);
~WaylandOutput() override;
RenderLoop *renderLoop() const override;
@ -61,7 +61,7 @@ public:
KWayland::Client::Surface *surface() const
{
return m_surface;
return m_surface.get();
}
void setDpmsMode(DpmsMode mode) override;
@ -81,7 +81,7 @@ protected:
private:
std::unique_ptr<RenderLoop> m_renderLoop;
KWayland::Client::Surface *m_surface;
std::unique_ptr<KWayland::Client::Surface> m_surface;
WaylandBackend *m_backend;
QTimer m_turnOffTimer;
};
@ -90,7 +90,7 @@ class XdgShellOutput : public WaylandOutput
{
public:
XdgShellOutput(const QString &name,
KWayland::Client::Surface *surface,
std::unique_ptr<KWayland::Client::Surface> &&surface,
KWayland::Client::XdgShell *xdgShell,
WaylandBackend *backend, int number);
~XdgShellOutput() override;
@ -101,9 +101,9 @@ private:
void handleConfigure(const QSize &size, KWayland::Client::XdgShellSurface::States states, quint32 serial);
void updateWindowTitle();
KWayland::Client::XdgShellSurface *m_xdgShellSurface = nullptr;
std::unique_ptr<KWayland::Client::XdgShellSurface> m_xdgShellSurface;
int m_number;
KWayland::Client::LockedPointer *m_pointerLock = nullptr;
std::unique_ptr<KWayland::Client::LockedPointer> m_pointerLock;
bool m_hasPointerLock = false;
bool m_hasBeenConfigured = false;
};

View file

@ -44,7 +44,6 @@ WaylandQPainterOutput::WaylandQPainterOutput(WaylandOutput *output)
WaylandQPainterOutput::~WaylandQPainterOutput()
{
qDeleteAll(m_slots);
m_slots.clear();
}
@ -63,7 +62,7 @@ void WaylandQPainterOutput::remapBuffer()
qCDebug(KWIN_WAYLAND_BACKEND) << "Remapped back buffer of surface" << m_waylandOutput->surface();
const QSize nativeSize(m_waylandOutput->geometry().size() * m_waylandOutput->scale());
for (WaylandQPainterBufferSlot *slot : qAsConst(m_slots)) {
for (const auto &slot : m_slots) {
slot->image = QImage(slot->buffer->address(), nativeSize.width(), nativeSize.height(), QImage::Format_ARGB32);
}
}
@ -72,14 +71,13 @@ void WaylandQPainterOutput::updateSize(const QSize &size)
{
Q_UNUSED(size)
m_back = nullptr;
qDeleteAll(m_slots);
m_slots.clear();
}
void WaylandQPainterOutput::present()
{
for (WaylandQPainterBufferSlot *slot : qAsConst(m_slots)) {
if (slot == m_back) {
for (const auto &slot : m_slots) {
if (slot.get() == m_back) {
slot->age = 1;
} else if (slot->age > 0) {
slot->age++;
@ -100,9 +98,9 @@ WaylandQPainterBufferSlot *WaylandQPainterOutput::back() const
WaylandQPainterBufferSlot *WaylandQPainterOutput::acquire()
{
for (WaylandQPainterBufferSlot *slot : qAsConst(m_slots)) {
for (const auto &slot : m_slots) {
if (slot->buffer->isReleased()) {
m_back = slot;
m_back = slot.get();
slot->buffer->setReleased(false);
return m_back;
}
@ -115,8 +113,8 @@ WaylandQPainterBufferSlot *WaylandQPainterOutput::acquire()
return nullptr;
}
m_back = new WaylandQPainterBufferSlot(buffer);
m_slots.append(m_back);
m_slots.push_back(std::make_unique<WaylandQPainterBufferSlot>(buffer));
m_back = m_slots.back().get();
// qCDebug(KWIN_WAYLAND_BACKEND) << "Created a new back buffer for output surface" << m_waylandOutput->surface();
return m_back;

View file

@ -71,7 +71,7 @@ private:
KWayland::Client::ShmPool *m_pool;
DamageJournal m_damageJournal;
QVector<WaylandQPainterBufferSlot *> m_slots;
std::vector<std::unique_ptr<WaylandQPainterBufferSlot>> m_slots;
WaylandQPainterBufferSlot *m_back = nullptr;
friend class WaylandQPainterBackend;