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

This commit is contained in:
Xaver Hugl 2022-06-29 13:57:45 +02:00
parent 5412ccb71c
commit 297971006b
12 changed files with 74 additions and 82 deletions

View file

@ -23,17 +23,15 @@ X11Cursor::X11Cursor(QObject *parent, bool xInputSupport)
: Cursor(parent)
, m_timeStamp(XCB_TIME_CURRENT_TIME)
, m_buttonMask(0)
, m_resetTimeStampTimer(new QTimer(this))
, m_mousePollingTimer(new QTimer(this))
, m_hasXInput(xInputSupport)
, m_needsPoll(false)
{
Cursors::self()->setMouse(this);
m_resetTimeStampTimer->setSingleShot(true);
connect(m_resetTimeStampTimer, &QTimer::timeout, this, &X11Cursor::resetTimeStamp);
m_resetTimeStampTimer.setSingleShot(true);
connect(&m_resetTimeStampTimer, &QTimer::timeout, this, &X11Cursor::resetTimeStamp);
// TODO: How often do we really need to poll?
m_mousePollingTimer->setInterval(50);
connect(m_mousePollingTimer, &QTimer::timeout, this, &X11Cursor::mousePolled);
m_mousePollingTimer.setInterval(50);
connect(&m_mousePollingTimer, &QTimer::timeout, this, &X11Cursor::mousePolled);
if (m_hasXInput) {
connect(qApp->eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, &X11Cursor::aboutToBlock);
@ -73,7 +71,7 @@ void X11Cursor::doGetPos()
}
m_buttonMask = pointer->mask;
updatePos(pointer->root_x, pointer->root_y);
m_resetTimeStampTimer->start(0);
m_resetTimeStampTimer.start(0);
}
void X11Cursor::resetTimeStamp()
@ -92,14 +90,14 @@ void X11Cursor::aboutToBlock()
void X11Cursor::doStartMousePolling()
{
if (!m_hasXInput) {
m_mousePollingTimer->start();
m_mousePollingTimer.start();
}
}
void X11Cursor::doStopMousePolling()
{
if (!m_hasXInput) {
m_mousePollingTimer->stop();
m_mousePollingTimer.stop();
}
}

View file

@ -10,6 +10,7 @@
#define KWIN_X11CURSOR_H
#include "cursor.h"
#include <QTimer>
#include <memory>
namespace KWin
@ -56,8 +57,8 @@ private Q_SLOTS:
private:
xcb_timestamp_t m_timeStamp;
uint16_t m_buttonMask;
QTimer *m_resetTimeStampTimer;
QTimer *m_mousePollingTimer;
QTimer m_resetTimeStampTimer;
QTimer m_mousePollingTimer;
bool m_hasXInput;
bool m_needsPoll;

View file

@ -102,7 +102,7 @@ bool XrandrEventFilter::event(xcb_generic_event_t *event)
X11StandalonePlatform::X11StandalonePlatform(QObject *parent)
: Platform(parent)
, m_updateOutputsTimer(new QTimer(this))
, m_updateOutputsTimer(std::make_unique<QTimer>())
, m_x11Display(QX11Info::display())
, m_renderLoop(std::make_unique<RenderLoop>())
{
@ -119,7 +119,7 @@ X11StandalonePlatform::X11StandalonePlatform(QObject *parent)
#endif
m_updateOutputsTimer->setSingleShot(true);
connect(m_updateOutputsTimer, &QTimer::timeout, this, &X11StandalonePlatform::updateOutputs);
connect(m_updateOutputsTimer.get(), &QTimer::timeout, this, &X11StandalonePlatform::updateOutputs);
setSupportsGammaControl(true);
}
@ -129,7 +129,6 @@ X11StandalonePlatform::~X11StandalonePlatform()
if (m_openGLFreezeProtectionThread) {
m_openGLFreezeProtectionThread->quit();
m_openGLFreezeProtectionThread->wait();
delete m_openGLFreezeProtectionThread;
}
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
eglTerminate(sceneEglDisplay());
@ -149,7 +148,7 @@ bool X11StandalonePlatform::initialize()
initOutputs();
if (Xcb::Extensions::self()->isRandrAvailable()) {
m_randrEventFilter.reset(new XrandrEventFilter(this));
m_randrEventFilter = std::make_unique<XrandrEventFilter>(this);
}
connect(Cursors::self(), &Cursors::hiddenChanged, this, &X11StandalonePlatform::updateCursor);
return true;
@ -275,17 +274,17 @@ void X11StandalonePlatform::createOpenGLSafePoint(OpenGLSafePoint safePoint)
case OpenGLSafePoint::PreFrame:
if (m_openGLFreezeProtectionThread == nullptr) {
Q_ASSERT(m_openGLFreezeProtection == nullptr);
m_openGLFreezeProtectionThread = new QThread(this);
m_openGLFreezeProtectionThread = std::make_unique<QThread>();
m_openGLFreezeProtectionThread->setObjectName("FreezeDetector");
m_openGLFreezeProtectionThread->start();
m_openGLFreezeProtection = new QTimer;
m_openGLFreezeProtection = std::make_unique<QTimer>();
m_openGLFreezeProtection->setInterval(15000);
m_openGLFreezeProtection->setSingleShot(true);
m_openGLFreezeProtection->start();
const QString configName = kwinApp()->config()->name();
m_openGLFreezeProtection->moveToThread(m_openGLFreezeProtectionThread);
m_openGLFreezeProtection->moveToThread(m_openGLFreezeProtectionThread.get());
connect(
m_openGLFreezeProtection, &QTimer::timeout, m_openGLFreezeProtection,
m_openGLFreezeProtection.get(), &QTimer::timeout, m_openGLFreezeProtection.get(),
[configName] {
auto group = KConfigGroup(KSharedConfig::openConfig(configName), "Compositing");
group.writeEntry(QLatin1String("OpenGLIsUnsafe"), true);
@ -296,7 +295,7 @@ void X11StandalonePlatform::createOpenGLSafePoint(OpenGLSafePoint safePoint)
Qt::DirectConnection);
} else {
Q_ASSERT(m_openGLFreezeProtection);
QMetaObject::invokeMethod(m_openGLFreezeProtection, QOverload<>::of(&QTimer::start), Qt::QueuedConnection);
QMetaObject::invokeMethod(m_openGLFreezeProtection.get(), QOverload<>::of(&QTimer::start), Qt::QueuedConnection);
}
break;
case OpenGLSafePoint::PostInit:
@ -305,15 +304,13 @@ void X11StandalonePlatform::createOpenGLSafePoint(OpenGLSafePoint safePoint)
// Deliberately continue with PostFrame
Q_FALLTHROUGH();
case OpenGLSafePoint::PostFrame:
QMetaObject::invokeMethod(m_openGLFreezeProtection, &QTimer::stop, Qt::QueuedConnection);
QMetaObject::invokeMethod(m_openGLFreezeProtection.get(), &QTimer::stop, Qt::QueuedConnection);
break;
case OpenGLSafePoint::PostLastGuardedFrame:
m_openGLFreezeProtection->deleteLater();
m_openGLFreezeProtection = nullptr;
m_openGLFreezeProtectionThread->quit();
m_openGLFreezeProtectionThread->wait();
delete m_openGLFreezeProtectionThread;
m_openGLFreezeProtectionThread = nullptr;
m_openGLFreezeProtectionThread.reset();
m_openGLFreezeProtection.reset();
break;
}
}
@ -347,7 +344,7 @@ void X11StandalonePlatform::updateCursor()
void X11StandalonePlatform::startInteractiveWindowSelection(std::function<void(KWin::Window *)> callback, const QByteArray &cursorName)
{
if (!m_windowSelector) {
m_windowSelector.reset(new WindowSelector);
m_windowSelector = std::make_unique<WindowSelector>();
}
m_windowSelector->start(callback, cursorName);
}
@ -355,7 +352,7 @@ void X11StandalonePlatform::startInteractiveWindowSelection(std::function<void(K
void X11StandalonePlatform::startInteractivePositionSelection(std::function<void(const QPoint &)> callback)
{
if (!m_windowSelector) {
m_windowSelector.reset(new WindowSelector);
m_windowSelector = std::make_unique<WindowSelector>();
}
m_windowSelector->start(callback);
}
@ -382,12 +379,12 @@ std::unique_ptr<OverlayWindow> X11StandalonePlatform::createOverlayWindow()
return std::make_unique<OverlayWindowX11>();
}
OutlineVisual *X11StandalonePlatform::createOutline(Outline *outline)
std::unique_ptr<OutlineVisual> X11StandalonePlatform::createOutline(Outline *outline)
{
// first try composited Outline
auto ret = Platform::createOutline(outline);
if (!ret) {
ret = new NonCompositedOutlineVisual(outline);
ret = std::make_unique<NonCompositedOutlineVisual>(outline);
}
return ret;
}

View file

@ -52,7 +52,7 @@ public:
void setupActionForGlobalAccel(QAction *action) override;
std::unique_ptr<OverlayWindow> createOverlayWindow() override;
OutlineVisual *createOutline(Outline *outline) override;
std::unique_ptr<OutlineVisual> createOutline(Outline *outline) override;
void invertScreen() override;
@ -85,9 +85,9 @@ private:
void updateCursor();
std::unique_ptr<XInputIntegration> m_xinputIntegration;
QThread *m_openGLFreezeProtectionThread = nullptr;
QTimer *m_openGLFreezeProtection = nullptr;
QTimer *m_updateOutputsTimer = nullptr;
std::unique_ptr<QThread> m_openGLFreezeProtectionThread;
std::unique_ptr<QTimer> m_openGLFreezeProtection;
std::unique_ptr<QTimer> m_updateOutputsTimer;
Display *m_x11Display;
std::unique_ptr<WindowSelector> m_windowSelector;
std::unique_ptr<X11EventFilter> m_screenEdgesFilter;

View file

@ -274,11 +274,11 @@ void XInputIntegration::startListening()
evmasks[0].mask = mask1;
XISelectEvents(display(), rootWindow(), evmasks, 1);
m_xiEventFilter.reset(new XInputEventFilter(m_xiOpcode));
m_xiEventFilter = std::make_unique<XInputEventFilter>(m_xiOpcode);
m_xiEventFilter->setCursor(m_x11Cursor);
m_xiEventFilter->setDisplay(display());
m_keyPressFilter.reset(new XKeyPressReleaseEventFilter(XCB_KEY_PRESS));
m_keyReleaseFilter.reset(new XKeyPressReleaseEventFilter(XCB_KEY_RELEASE));
m_keyPressFilter = std::make_unique<XKeyPressReleaseEventFilter>(XCB_KEY_PRESS);
m_keyReleaseFilter = std::make_unique<XKeyPressReleaseEventFilter>(XCB_KEY_RELEASE);
// install the input event spies also relevant for X11 platform
input()->installInputEventSpy(new ModifierOnlyShortcuts);

View file

@ -42,11 +42,6 @@
namespace KWin
{
X11WindowedInputDevice::X11WindowedInputDevice(QObject *parent)
: InputDevice(parent)
{
}
void X11WindowedInputDevice::setPointer(bool set)
{
m_pointer = set;
@ -142,9 +137,8 @@ bool X11WindowedInputDevice::isLidSwitch() const
return false;
}
X11WindowedInputBackend::X11WindowedInputBackend(X11WindowedBackend *backend, QObject *parent)
: InputBackend(parent)
, m_backend(backend)
X11WindowedInputBackend::X11WindowedInputBackend(X11WindowedBackend *backend)
: m_backend(backend)
{
}
@ -161,17 +155,16 @@ void X11WindowedInputBackend::initialize()
}
}
X11WindowedBackend::X11WindowedBackend(QObject *parent)
: Platform(parent)
X11WindowedBackend::X11WindowedBackend()
{
setSupportsPointerWarping(true);
}
X11WindowedBackend::~X11WindowedBackend()
{
delete m_pointerDevice;
delete m_keyboardDevice;
delete m_touchDevice;
m_pointerDevice.reset();
m_keyboardDevice.reset();
m_touchDevice.reset();
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
eglTerminate(sceneEglDisplay());
@ -217,12 +210,12 @@ bool X11WindowedBackend::initialize()
createCursor(c->image(), c->hotspot());
});
setReady(true);
m_pointerDevice = new X11WindowedInputDevice(this);
m_pointerDevice = std::make_unique<X11WindowedInputDevice>();
m_pointerDevice->setPointer(true);
m_keyboardDevice = new X11WindowedInputDevice(this);
m_keyboardDevice = std::make_unique<X11WindowedInputDevice>();
m_keyboardDevice->setKeyboard(true);
if (m_hasXInput) {
m_touchDevice = new X11WindowedInputDevice(this);
m_touchDevice = std::make_unique<X11WindowedInputDevice>();
m_touchDevice->setTouch(true);
}
Q_EMIT outputsQueried();
@ -309,7 +302,7 @@ void X11WindowedBackend::createOutputs()
void X11WindowedBackend::startEventReading()
{
QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection), QSocketNotifier::Read, this);
m_eventNotifier = std::make_unique<QSocketNotifier>(xcb_get_file_descriptor(m_connection), QSocketNotifier::Read);
auto processXcbEvents = [this] {
while (auto event = xcb_poll_for_event(m_connection)) {
handleEvent(event);
@ -317,7 +310,7 @@ void X11WindowedBackend::startEventReading()
}
xcb_flush(m_connection);
};
connect(notifier, &QSocketNotifier::activated, this, processXcbEvents);
connect(m_eventNotifier.get(), &QSocketNotifier::activated, this, processXcbEvents);
connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, processXcbEvents);
connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::awake, this, processXcbEvents);
}
@ -345,7 +338,7 @@ void X11WindowedBackend::handleEvent(xcb_generic_event_t *e)
break;
}
const QPointF position = output->mapFromGlobal(QPointF(event->root_x, event->root_y));
Q_EMIT m_pointerDevice->pointerMotionAbsolute(position, event->time, m_pointerDevice);
Q_EMIT m_pointerDevice->pointerMotionAbsolute(position, event->time, m_pointerDevice.get());
} break;
case XCB_KEY_PRESS:
case XCB_KEY_RELEASE: {
@ -361,12 +354,12 @@ void X11WindowedBackend::handleEvent(xcb_generic_event_t *e)
Q_EMIT m_keyboardDevice->keyChanged(event->detail - 8,
InputRedirection::KeyboardKeyPressed,
event->time,
m_keyboardDevice);
m_keyboardDevice.get());
} else {
Q_EMIT m_keyboardDevice->keyChanged(event->detail - 8,
InputRedirection::KeyboardKeyReleased,
event->time,
m_keyboardDevice);
m_keyboardDevice.get());
}
} break;
case XCB_CONFIGURE_NOTIFY:
@ -379,7 +372,7 @@ void X11WindowedBackend::handleEvent(xcb_generic_event_t *e)
break;
}
const QPointF position = output->mapFromGlobal(QPointF(event->root_x, event->root_y));
Q_EMIT m_pointerDevice->pointerMotionAbsolute(position, event->time, m_pointerDevice);
Q_EMIT m_pointerDevice->pointerMotionAbsolute(position, event->time, m_pointerDevice.get());
} break;
case XCB_CLIENT_MESSAGE:
handleClientMessage(reinterpret_cast<xcb_client_message_event_t *>(e));
@ -406,18 +399,18 @@ void X11WindowedBackend::handleEvent(xcb_generic_event_t *e)
switch (ge->event_type) {
case XI_TouchBegin: {
Q_EMIT m_touchDevice->touchDown(te->detail, position, te->time, m_touchDevice);
Q_EMIT m_touchDevice->touchFrame(m_touchDevice);
Q_EMIT m_touchDevice->touchDown(te->detail, position, te->time, m_touchDevice.get());
Q_EMIT m_touchDevice->touchFrame(m_touchDevice.get());
break;
}
case XI_TouchUpdate: {
Q_EMIT m_touchDevice->touchMotion(te->detail, position, te->time, m_touchDevice);
Q_EMIT m_touchDevice->touchFrame(m_touchDevice);
Q_EMIT m_touchDevice->touchMotion(te->detail, position, te->time, m_touchDevice.get());
Q_EMIT m_touchDevice->touchFrame(m_touchDevice.get());
break;
}
case XI_TouchEnd: {
Q_EMIT m_touchDevice->touchUp(te->detail, te->time, m_touchDevice);
Q_EMIT m_touchDevice->touchFrame(m_touchDevice);
Q_EMIT m_touchDevice->touchUp(te->detail, te->time, m_touchDevice.get());
Q_EMIT m_touchDevice->touchFrame(m_touchDevice.get());
break;
}
case XI_TouchOwnership: {
@ -531,7 +524,7 @@ void X11WindowedBackend::handleButtonPress(xcb_button_press_event_t *event)
delta,
InputRedirection::PointerAxisSourceUnknown,
event->time,
m_pointerDevice);
m_pointerDevice.get());
return;
}
uint32_t button = 0;
@ -551,12 +544,12 @@ void X11WindowedBackend::handleButtonPress(xcb_button_press_event_t *event)
}
const QPointF position = output->mapFromGlobal(QPointF(event->root_x, event->root_y));
Q_EMIT m_pointerDevice->pointerMotionAbsolute(position, event->time, m_pointerDevice);
Q_EMIT m_pointerDevice->pointerMotionAbsolute(position, event->time, m_pointerDevice.get());
if (pressed) {
Q_EMIT m_pointerDevice->pointerButtonChanged(button, InputRedirection::PointerButtonPressed, event->time, m_pointerDevice);
Q_EMIT m_pointerDevice->pointerButtonChanged(button, InputRedirection::PointerButtonPressed, event->time, m_pointerDevice.get());
} else {
Q_EMIT m_pointerDevice->pointerButtonChanged(button, InputRedirection::PointerButtonReleased, event->time, m_pointerDevice);
Q_EMIT m_pointerDevice->pointerButtonChanged(button, InputRedirection::PointerButtonReleased, event->time, m_pointerDevice.get());
}
}
@ -637,17 +630,17 @@ xcb_window_t X11WindowedBackend::rootWindow() const
X11WindowedInputDevice *X11WindowedBackend::pointerDevice() const
{
return m_pointerDevice;
return m_pointerDevice.get();
}
X11WindowedInputDevice *X11WindowedBackend::keyboardDevice() const
{
return m_keyboardDevice;
return m_keyboardDevice.get();
}
X11WindowedInputDevice *X11WindowedBackend::touchDevice() const
{
return m_touchDevice;
return m_touchDevice.get();
}
std::unique_ptr<OpenGLBackend> X11WindowedBackend::createOpenGLBackend()

View file

@ -23,6 +23,7 @@ struct _XDisplay;
typedef struct _XDisplay Display;
typedef struct _XCBKeySymbols xcb_key_symbols_t;
class NETWinInfo;
class QSocketNotifier;
namespace KWin
{
@ -34,7 +35,7 @@ class X11WindowedInputDevice : public InputDevice
Q_OBJECT
public:
explicit X11WindowedInputDevice(QObject *parent = nullptr);
explicit X11WindowedInputDevice() = default;
void setPointer(bool set);
void setKeyboard(bool set);
@ -72,7 +73,7 @@ class X11WindowedInputBackend : public InputBackend
Q_OBJECT
public:
explicit X11WindowedInputBackend(X11WindowedBackend *backend, QObject *parent = nullptr);
explicit X11WindowedInputBackend(X11WindowedBackend *backend);
void initialize() override;
@ -85,7 +86,7 @@ class KWIN_EXPORT X11WindowedBackend : public Platform
Q_OBJECT
public:
X11WindowedBackend(QObject *parent = nullptr);
explicit X11WindowedBackend();
~X11WindowedBackend() override;
bool initialize() override;
@ -154,15 +155,16 @@ private:
xcb_key_symbols_t *m_keySymbols = nullptr;
int m_screenNumber = 0;
X11WindowedInputDevice *m_pointerDevice = nullptr;
X11WindowedInputDevice *m_keyboardDevice = nullptr;
X11WindowedInputDevice *m_touchDevice = nullptr;
std::unique_ptr<X11WindowedInputDevice> m_pointerDevice;
std::unique_ptr<X11WindowedInputDevice> m_keyboardDevice;
std::unique_ptr<X11WindowedInputDevice> m_touchDevice;
xcb_atom_t m_protocols = XCB_ATOM_NONE;
xcb_atom_t m_deleteWindowProtocol = XCB_ATOM_NONE;
xcb_cursor_t m_cursor = XCB_CURSOR_NONE;
Display *m_display = nullptr;
bool m_keyboardGrabbed = false;
std::unique_ptr<QSocketNotifier> m_eventNotifier;
bool m_hasXInput = false;
int m_xiOpcode = 0;

View file

@ -34,7 +34,7 @@ X11WindowedEglOutput::~X11WindowedEglOutput()
void X11WindowedEglOutput::ensureFbo()
{
if (!m_fbo || m_fbo->size() != m_output->pixelSize()) {
m_fbo.reset(new GLFramebuffer(0, m_output->pixelSize()));
m_fbo = std::make_unique<GLFramebuffer>(0, m_output->pixelSize());
}
}

View file

@ -260,10 +260,10 @@ void Platform::updateXTime()
}
}
OutlineVisual *Platform::createOutline(Outline *outline)
std::unique_ptr<OutlineVisual> Platform::createOutline(Outline *outline)
{
if (Compositor::compositing()) {
return new CompositedOutlineVisual(outline);
return std::make_unique<CompositedOutlineVisual>(outline);
}
return nullptr;
}

View file

@ -257,7 +257,7 @@ public:
* Creates the OutlineVisual for the given @p outline.
* Default implementation creates an OutlineVisual suited for composited usage.
*/
virtual OutlineVisual *createOutline(Outline *outline);
virtual std::unique_ptr<OutlineVisual> createOutline(Outline *outline);
/**
* Platform specific way to invert the screen.

View file

@ -105,7 +105,7 @@ void Outline::createHelper()
if (m_visual) {
return;
}
m_visual.reset(kwinApp()->platform()->createOutline(this));
m_visual = kwinApp()->platform()->createOutline(this);
}
void Outline::compositingChanged()

View file

@ -15,6 +15,7 @@
#include <memory>
#include <kwin_export.h>
#include <memory>
class QQmlContext;
class QQmlComponent;