diff options
author | David Redondo <qt@david-redondo.de> | 2023-06-13 14:02:59 +0200 |
---|---|---|
committer | David Redondo <qt@david-redondo.de> | 2024-01-17 09:06:19 +0100 |
commit | 5085fa08226ff58543359ccf4e6cc34176d7d252 (patch) | |
tree | 6f68de080e49d5fb573e9912ac71779bf658552e /src/client/qwaylanddisplay.cpp | |
parent | f803f80c3e18d14946d8c46137211c3a710c3036 (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.cpp | 62 |
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)); |