diff --git a/panels/dock/pluginmanagerextension.cpp b/panels/dock/pluginmanagerextension.cpp index dafc305a7..145d9de4d 100644 --- a/panels/dock/pluginmanagerextension.cpp +++ b/panels/dock/pluginmanagerextension.cpp @@ -115,6 +115,19 @@ void PluginSurface::plugin_dcc_icon(Resource *resource, const QString &icon) m_dccIcon = icon; } +void PluginSurface::plugin_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource); + Q_EMIT aboutToDestroy(); + m_manager->removePluginSurface(this); + delete this; +} + +void PluginSurface::plugin_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + void PluginSurface::setGlobalPos(const QPoint &pos) { QRect g = qApp->primaryScreen() ? qApp->primaryScreen()->geometry() : QRect(); @@ -207,6 +220,18 @@ void PluginPopup::plugin_popup_set_position(Resource *resource, int32_t x, int32 setY(y); } +void PluginPopup::plugin_popup_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource); + // TODO why we get a same address with the object when new PluginPopup, if we delete the object. + Q_EMIT aboutToDestroy(); + delete this; +} + +void PluginPopup::plugin_popup_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} PluginManager::PluginManager(QWaylandCompositor *compositor) : QWaylandCompositorExtensionTemplate(compositor) { @@ -313,15 +338,6 @@ void PluginManager::plugin_manager_v1_request_message(Resource *resource, const void PluginManager::plugin_manager_v1_create_plugin(Resource *resource, const QString &pluginId, const QString &itemKey, const QString &display_name, int32_t plugin_flags, int32_t type, int32_t size_policy, struct ::wl_resource *surface, uint32_t id) { QWaylandSurface *qwaylandSurface = QWaylandSurface::fromResource(surface); - connect(qwaylandSurface, &QWaylandSurface::surfaceDestroyed, this, [this, qwaylandSurface](){ - for (PluginSurface *plugin : m_pluginSurfaces) { - if (plugin->surface() == qwaylandSurface) { - Q_EMIT pluginSurfaceDestroyed(plugin); - m_pluginSurfaces.removeAll(plugin); - break; - } - } - }); QWaylandResource shellSurfaceResource(wl_resource_create(resource->client(), &::plugin_interface, wl_resource_get_version(resource->handle), id)); @@ -410,6 +426,12 @@ void PluginManager::setDockSize(const QSize &newDockSize) emit dockSizeChanged(); } +void PluginManager::removePluginSurface(PluginSurface *plugin) +{ + Q_EMIT pluginSurfaceDestroyed(plugin); + m_pluginSurfaces.removeAll(plugin); +} + QString PluginManager::dockSizeMsg() const { if (m_dockSize.isEmpty()) diff --git a/panels/dock/pluginmanagerextension_p.h b/panels/dock/pluginmanagerextension_p.h index 5d8a95bce..05a31ed4f 100644 --- a/panels/dock/pluginmanagerextension_p.h +++ b/panels/dock/pluginmanagerextension_p.h @@ -42,6 +42,8 @@ class PluginManager : public QWaylandCompositorExtensionTemplate, QSize dockSize() const; void setDockSize(const QSize &newDockSize); + void removePluginSurface(PluginSurface *plugin); + Q_SIGNALS: void pluginPopupCreated(PluginPopup*); void pluginSurfaceCreated(PluginSurface*); @@ -124,10 +126,13 @@ class PluginSurface : public QWaylandShellSurfaceTemplate, public void recvMouseEvent(QEvent::Type type); void marginsChanged(); + void aboutToDestroy(); protected: virtual void plugin_mouse_event(Resource *resource, int32_t type) override; virtual void plugin_dcc_icon(Resource *resource, const QString &icon) override; + virtual void plugin_destroy_resource(Resource *resource) override; + virtual void plugin_destroy(Resource *resource) override; private: PluginManager* m_manager; @@ -146,7 +151,7 @@ class PluginSurface : public QWaylandShellSurfaceTemplate, public int m_margins = 0; }; -class PluginPopup : public QWaylandShellSurfaceTemplate, public QtWaylandServer::plugin_popup +class PluginPopup : public QWaylandShellSurfaceTemplate, public QtWaylandServer::plugin_popup { Q_OBJECT Q_PROPERTY(int32_t x READ x WRITE setX NOTIFY xChanged) @@ -177,8 +182,13 @@ class PluginPopup : public QWaylandShellSurfaceTemplate, public Q int32_t popupType() const; +signals: + void aboutToDestroy(); + protected: virtual void plugin_popup_set_position(Resource *resource, int32_t x, int32_t y) override; + virtual void plugin_popup_destroy_resource(Resource *resource) override; + virtual void plugin_popup_destroy(Resource *resource) override; Q_SIGNALS: void xChanged(); diff --git a/panels/dock/tray/ShellSurfaceItemProxy.qml b/panels/dock/tray/ShellSurfaceItemProxy.qml index 8a9235df0..dfde8ef8e 100644 --- a/panels/dock/tray/ShellSurfaceItemProxy.qml +++ b/panels/dock/tray/ShellSurfaceItemProxy.qml @@ -7,18 +7,50 @@ import QtQuick.Controls import QtWayland.Compositor import org.deepin.ds.dock 1.0 -ShellSurfaceItem { +Item { + id: root + property var shellSurface: null + signal surfaceDestroyed() property bool autoClose: false - onVisibleChanged: function () { - if (autoClose && !visible) { - // surface is valid but client's shellSurface maybe invalid. - Qt.callLater(closeShellSurface) + property bool inputEventsEnabled: true + + width: impl.width + height: impl.height + implicitWidth: width + implicitHeight: height + + ShellSurfaceItem { + id: impl + shellSurface: root.shellSurface + inputEventsEnabled: root.inputEventsEnabled + onVisibleChanged: function () { + if (autoClose && !visible) { + // surface is valid but client's shellSurface maybe invalid. + Qt.callLater(closeShellSurface) + } + } + function closeShellSurface() + { + if (surface && shellSurface) { + DockCompositor.closeShellSurface(shellSurface) + } } } - function closeShellSurface() - { - if (surface && shellSurface) { - DockCompositor.closeShellSurface(shellSurface) + Component.onCompleted: function () { + impl.surfaceDestroyed.connect(root.surfaceDestroyed) + } + + Connections { + target: shellSurface + // TODO it's maybe a bug for qt, we force shellSurface's value to update + function onAboutToDestroy() + { + Qt.callLater(function() { + impl.shellSurface = null + impl.shellSurface = Qt.binding(function () { + return root.shellSurface + }) + }) } } }