summaryrefslogtreecommitdiffstats
path: root/src/client/qwaylanddisplay.cpp
diff options
context:
space:
mode:
authorDavid Redondo <qt@david-redondo.de>2023-06-13 14:02:59 +0200
committerDavid Redondo <qt@david-redondo.de>2024-01-17 09:06:19 +0100
commit5085fa08226ff58543359ccf4e6cc34176d7d252 (patch)
tree6f68de080e49d5fb573e9912ac71779bf658552e /src/client/qwaylanddisplay.cpp
parentf803f80c3e18d14946d8c46137211c3a710c3036 (diff)
Make sure wayland object destructors are called
Always at least call the generated "interface"_destroy method which does destroy the proxy. For not already wrapped classes a small template is introduced to pass a function that is called in the destructor. Fixes: QTBUG-111576 Change-Id: I373463710764958ddea42ef0f7dc010c427b2ce8 Reviewed-by: David Edmundson <davidedmundson@kde.org> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/client/qwaylanddisplay.cpp')
-rw-r--r--src/client/qwaylanddisplay.cpp62
1 files changed, 44 insertions, 18 deletions
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index 0c73fdc37..890fed199 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -260,14 +260,14 @@ Q_LOGGING_CATEGORY(lcQpaWayland, "qt.qpa.wayland"); // for general (uncategorize
struct wl_surface *QWaylandDisplay::createSurface(void *handle)
{
- struct wl_surface *surface = mCompositor.create_surface();
+ struct wl_surface *surface = mGlobals.compositor->create_surface();
wl_surface_set_user_data(surface, handle);
return surface;
}
struct ::wl_region *QWaylandDisplay::createRegion(const QRegion &qregion)
{
- struct ::wl_region *region = mCompositor.create_region();
+ struct ::wl_region *region = mGlobals.compositor->create_region();
for (const QRect &rect : qregion)
wl_region_add(region, rect.x(), rect.y(), rect.width(), rect.height());
@@ -371,8 +371,12 @@ QWaylandDisplay::~QWaylandDisplay(void)
if (m_frameEventQueue)
wl_event_queue_destroy(m_frameEventQueue);
+ // Reset the globals manually since they need to be destroyed before the wl_display
mGlobals = {};
+ if (object())
+ wl_registry_destroy(object());
+
if (mDisplay)
wl_display_disconnect(mDisplay);
}
@@ -425,8 +429,6 @@ void QWaylandDisplay::reconnect()
QWindowSystemInterface::handleScreenRemoved(screen);
}
- // mCompositor
- mShm.reset();
mCursorThemes.clear();
mCursor.reset();
@@ -602,6 +604,16 @@ void QWaylandDisplay::handleScreenInitialized(QWaylandScreen *screen)
}
}
+template <typename T, auto f>
+struct WithDestructor : public T
+{
+ using T::T;
+ ~WithDestructor()
+ {
+ f(this->object());
+ }
+};
+
void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uint32_t version)
{
struct ::wl_registry *registry = object();
@@ -614,9 +626,11 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
if (interface == QLatin1String(QtWayland::wl_output::interface()->name)) {
mWaitingScreens << mWaylandIntegration->createPlatformScreen(this, version, id);
} else if (interface == QLatin1String(QtWayland::wl_compositor::interface()->name)) {
- mCompositor.init(registry, id, qMin((int)version, 6));
+ mGlobals.compositor.reset(
+ new WithDestructor<QtWayland::wl_compositor, wl_compositor_destroy>(
+ registry, id, qMin((int)version, 6)));
} else if (interface == QLatin1String(QWaylandShm::interface()->name)) {
- mShm.reset(new QWaylandShm(this, version, id));
+ mGlobals.shm.reset(new QWaylandShm(this, version, id));
} else if (interface == QLatin1String(QWaylandInputDevice::interface()->name)) {
QWaylandInputDevice *inputDevice = mWaylandIntegration->createInputDevice(this, version, id);
mInputDevices.append(inputDevice);
@@ -625,9 +639,13 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
mGlobals.dndSelectionHandler.reset(new QWaylandDataDeviceManager(this, version, id));
#endif
} else if (interface == QLatin1String(QtWayland::qt_surface_extension::interface()->name)) {
- mGlobals.surfaceExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1));
+ mGlobals.surfaceExtension.reset(
+ new WithDestructor<QtWayland::qt_surface_extension, qt_surface_extension_destroy>(
+ registry, id, 1));
} else if (interface == QLatin1String(QtWayland::wl_subcompositor::interface()->name)) {
- mGlobals.subCompositor.reset(new QtWayland::wl_subcompositor(registry, id, 1));
+ mGlobals.subCompositor.reset(
+ new WithDestructor<QtWayland::wl_subcompositor, wl_subcompositor_destroy>(registry,
+ id, 1));
} else if (interface == QLatin1String(QWaylandTouchExtension::interface()->name)) {
mGlobals.touchExtension.reset(new QWaylandTouchExtension(this, id));
} else if (interface == QLatin1String(QWaylandQtKeyExtension::interface()->name)) {
@@ -658,7 +676,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
}
mGlobals.textInputMethodManager.reset(
- new QtWayland::qt_text_input_method_manager_v1(registry, id, 1));
+ new WithDestructor<QtWayland::qt_text_input_method_manager_v1,
+ qt_text_input_method_manager_v1_destroy>(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInputMethod(new QWaylandTextInputMethod(
this,
@@ -678,7 +697,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
}
mGlobals.textInputManagerv1.reset(
- new QtWayland::zwp_text_input_manager_v1(registry, id, 1));
+ new WithDestructor<QtWayland::zwp_text_input_manager_v1,
+ zwp_text_input_manager_v1_destroy>(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) {
auto textInput =
new QWaylandTextInputv1(this, mGlobals.textInputManagerv1->create_text_input());
@@ -700,7 +720,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
}
mGlobals.textInputManagerv2.reset(
- new QtWayland::zwp_text_input_manager_v2(registry, id, 1));
+ new WithDestructor<QtWayland::zwp_text_input_manager_v2,
+ zwp_text_input_manager_v2_destroy>(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(new QWaylandTextInputv2(
this, mGlobals.textInputManagerv2->get_text_input(inputDevice->wl_seat())));
@@ -715,9 +736,9 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInputMethod(nullptr);
}
-
mGlobals.textInputManagerv3.reset(
- new QtWayland::zwp_text_input_manager_v3(registry, id, 1));
+ new WithDestructor<QtWayland::zwp_text_input_manager_v3,
+ zwp_text_input_manager_v3_destroy>(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(new QWaylandTextInputv3(
this, mGlobals.textInputManagerv3->get_text_input(inputDevice->wl_seat())));
@@ -738,16 +759,21 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
screen->initXdgOutput(xdgOutputManager());
} else if (interface == QLatin1String(QtWayland::wp_fractional_scale_manager_v1::interface()->name)) {
mGlobals.fractionalScaleManager.reset(
- new QtWayland::wp_fractional_scale_manager_v1(registry, id, 1));
+ new WithDestructor<QtWayland::wp_fractional_scale_manager_v1,
+ wp_fractional_scale_manager_v1_destroy>(registry, id, 1));
} else if (interface == QLatin1String("wp_viewporter")) {
- mGlobals.viewporter.reset(new QtWayland::wp_viewporter(registry, id, qMin(1u, version)));
+ mGlobals.viewporter.reset(
+ new WithDestructor<QtWayland::wp_viewporter, wp_viewporter_destroy>(
+ registry, id, qMin(1u, version)));
} else if (interface == QLatin1String(QtWayland::wp_cursor_shape_manager_v1::interface()->name)) {
- mGlobals.cursorShapeManager.reset(
- new QtWayland::wp_cursor_shape_manager_v1(registry, id, std::min(1u, version)));
+ mGlobals.cursorShapeManager.reset(new WithDestructor<QtWayland::wp_cursor_shape_manager_v1,
+ wp_cursor_shape_manager_v1_destroy>(
+ registry, id, std::min(1u, version)));
} else if (
interface == QLatin1String(QtWayland::qt_toplevel_drag_manager_v1::interface()->name)) {
mGlobals.xdgToplevelDragManager.reset(
- new QtWayland::qt_toplevel_drag_manager_v1(registry, id, 1));
+ new WithDestructor<QtWayland::qt_toplevel_drag_manager_v1,
+ qt_toplevel_drag_manager_v1_destroy>(registry, id, 1));
}
mRegistryGlobals.append(RegistryGlobal(id, interface, version, registry));