diff --git a/plugins/application-tray/xembedprotocolhandler.cpp b/plugins/application-tray/xembedprotocolhandler.cpp index f611f7abe..107551a82 100644 --- a/plugins/application-tray/xembedprotocolhandler.cpp +++ b/plugins/application-tray/xembedprotocolhandler.cpp @@ -8,6 +8,7 @@ #include "fdoselectionmanager.h" #include "util.h" +#include "plugin.h" #include #include @@ -300,8 +301,28 @@ QPixmap XembedProtocolHandler::getPixmapFromWidnow() QPoint XembedProtocolHandler::updateEmbedWindowPosForGetInputEvent() { // update pos - QPoint p = UTIL->getMousePos(); - UTIL->moveX11Window(m_containerWid, p.x(), p.y()); + if (qgetenv("XDG_SESSION_TYPE") == "wayland") { + auto plugin = Plugin::EmbedPlugin::get(window()->windowHandle()); + + QEventLoop loop; + connect(plugin, &Plugin::EmbedPlugin::xembedWindowMoved, &loop, &QEventLoop::quit); + QTimer timer; + timer.setSingleShot(true); + connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + timer.start(3000); + + plugin->requestMoveXembedWindow(m_containerWid); + loop.exec(); + + if (timer.isActive()) { + timer.stop(); + } else { + qDebug() << "requestMoveXembedWindow() timeout"; + } + } else { + QPoint p = UTIL->getMousePos(); + UTIL->moveX11Window(m_containerWid, p.x(), p.y()); + } // make window normal and above for get input UTIL->setX11WindowInputShape(m_containerWid, QSize(1, 1)); diff --git a/src/protocol/plugin-manager-v1.xml b/src/protocol/plugin-manager-v1.xml index 715a1033c..b246e26ed 100644 --- a/src/protocol/plugin-manager-v1.xml +++ b/src/protocol/plugin-manager-v1.xml @@ -109,6 +109,17 @@ + + + + This requests dde-shell to forward a request to the compositor (treeland) to move a xembed window to position. + dde-shell knows the xembed window's relative position, and then can request treeland to move the window to an absolute position based on a relative position. + + + + + + diff --git a/src/tray-wayland-integration/CMakeLists.txt b/src/tray-wayland-integration/CMakeLists.txt index 8d44aa850..9e17ca561 100644 --- a/src/tray-wayland-integration/CMakeLists.txt +++ b/src/tray-wayland-integration/CMakeLists.txt @@ -39,7 +39,8 @@ add_library(dockpluginmanager SHARED ) qt_generate_wayland_protocol_client_sources(dockpluginmanager - FILES +NO_INCLUDE_CORE_ONLY +FILES ${CMAKE_CURRENT_SOURCE_DIR}/../protocol/plugin-manager-v1.xml ) diff --git a/src/tray-wayland-integration/plugin.h b/src/tray-wayland-integration/plugin.h index cc5eacbbc..ebe0a3bf0 100644 --- a/src/tray-wayland-integration/plugin.h +++ b/src/tray-wayland-integration/plugin.h @@ -81,7 +81,9 @@ class EmbedPlugin : public QObject void pluginTypeChanged(); void pluginFlagsChanged(); void pluginSizePolicyChanged(); + void xembedWindowMoved(); void requestMessage(const QString &msg); + void requestMoveXembedWindow(uint32_t xembedWinId); void pluginRecvMouseEvent(int type); void rawGlobalPosChanged(); void pluginRequestShutdown(const QString &type); diff --git a/src/tray-wayland-integration/pluginmanagerintegration.cpp b/src/tray-wayland-integration/pluginmanagerintegration.cpp index a997b6022..74a5a4882 100644 --- a/src/tray-wayland-integration/pluginmanagerintegration.cpp +++ b/src/tray-wayland-integration/pluginmanagerintegration.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace Plugin { PluginManagerIntegration::PluginManagerIntegration() @@ -48,6 +49,21 @@ void PluginManagerIntegration::requestMessage(const QString &plugin_id, const QS request_message(plugin_id, item_key, msg); } +static const wl_callback_listener xembedWindowMovedListener = { + [](void *data, struct wl_callback *callback, uint32_t time) { + Q_UNUSED(time); + wl_callback_destroy(callback); + static_cast(data)->xembedWindowMovedCallback(); + } +}; + +struct ::wl_callback *PluginManagerIntegration::moveXembedWindow(uint32_t xembedWinId, const QString &pluginId, const QString &itemKey) +{ + auto callback = move_xembed_window(xembedWinId, pluginId, itemKey); + wl_callback_add_listener(callback, &xembedWindowMovedListener, this); + return callback; +} + void PluginManagerIntegration::plugin_manager_v1_position_changed(uint32_t dock_position) { if (dock_position != m_dockPosition) { @@ -89,6 +105,11 @@ void PluginManagerIntegration::plugin_manager_v1_theme_changed(const QString &th PlatformInterfaceProxy::instance()->setIconThemeName(icon_theme_name.toLocal8Bit()); } +void PluginManagerIntegration::xembedWindowMovedCallback() +{ + emit xembedWindowMoved(); +} + bool PluginManagerIntegration::tryCreatePopupForSubWindow(QWindow *window) { auto parentWindow = window->transientParent(); @@ -122,4 +143,5 @@ bool PluginManagerIntegration::tryCreatePopupForSubWindow(QWindow *window) return false; } + } diff --git a/src/tray-wayland-integration/pluginmanagerintegration_p.h b/src/tray-wayland-integration/pluginmanagerintegration_p.h index 88f53a2a4..03fce1a91 100644 --- a/src/tray-wayland-integration/pluginmanagerintegration_p.h +++ b/src/tray-wayland-integration/pluginmanagerintegration_p.h @@ -5,6 +5,7 @@ #pragma once #include "qwayland-plugin-manager-v1.h" +#include #include @@ -20,10 +21,13 @@ class PluginManagerIntegration : public QtWaylandClient::QWaylandShellIntegratio public: void requestMessage(const QString &plugin_id, const QString &item_key, const QString &msg); + struct ::wl_callback *moveXembedWindow(uint32_t xembedWinId, const QString &pluginId, const QString &itemKey); + void xembedWindowMovedCallback(); Q_SIGNALS: void eventMessage(const QString &msg); void dockPositionChanged(uint32_t position); + void xembedWindowMoved(); void dockColorThemeChanged(uint32_t colorType); protected: @@ -40,5 +44,7 @@ class PluginManagerIntegration : public QtWaylandClient::QWaylandShellIntegratio private: uint32_t m_dockPosition; uint32_t m_dockColorType; + static PluginManagerIntegration *s_instance; }; + } diff --git a/src/tray-wayland-integration/pluginsurface.cpp b/src/tray-wayland-integration/pluginsurface.cpp index a78271a9a..e4aa26111 100644 --- a/src/tray-wayland-integration/pluginsurface.cpp +++ b/src/tray-wayland-integration/pluginsurface.cpp @@ -33,6 +33,11 @@ PluginSurface::PluginSurface(PluginManagerIntegration *manager, QtWaylandClient: connect(manager, &PluginManagerIntegration::dockPositionChanged, m_plugin, &EmbedPlugin::dockPositionChanged); connect(manager, &PluginManagerIntegration::dockColorThemeChanged, m_plugin, &EmbedPlugin::dockColorThemeChanged); connect(manager, &PluginManagerIntegration::eventMessage, m_plugin, &EmbedPlugin::eventMessage); + connect(manager, &PluginManagerIntegration::xembedWindowMoved, m_plugin, &EmbedPlugin::xembedWindowMoved); + + connect(m_plugin, &EmbedPlugin::requestMoveXembedWindow, this, [manager, this](uint32_t xembedWinId) { + manager->moveXembedWindow(xembedWinId, m_plugin->pluginId(), m_plugin->itemKey()); + }); connect(m_plugin, &EmbedPlugin::requestMessage, manager, [manager, this](const QString &msg) { manager->requestMessage(m_plugin->pluginId(), m_plugin->itemKey(), msg);