From 058940d7532a17a7c79f2abdf66c2edf2e31a33c Mon Sep 17 00:00:00 2001 From: Wang Zichong Date: Thu, 15 Jan 2026 19:08:34 +0800 Subject: [PATCH 1/2] feat: add move_xembed_window protocol for later use Log: --- plugins/application-tray/xembedprotocolhandler.cpp | 12 ++++++++++-- src/protocol/plugin-manager-v1.xml | 11 +++++++++++ src/tray-wayland-integration/CMakeLists.txt | 3 ++- .../pluginmanagerintegration.cpp | 7 +++++++ .../pluginmanagerintegration_p.h | 4 ++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/plugins/application-tray/xembedprotocolhandler.cpp b/plugins/application-tray/xembedprotocolhandler.cpp index f611f7abe..1e820d0ae 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,15 @@ 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") { + // Get `plugin_id` and `item_key` from EmbedPlugin. + auto plugin = Plugin::EmbedPlugin::get(window()->windowHandle()); + // use move_xembed_window to move m_containerWid to plugin_id. + // TODO: ...? + } 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..be058761f 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/pluginmanagerintegration.cpp b/src/tray-wayland-integration/pluginmanagerintegration.cpp index a997b6022..fac49e134 100644 --- a/src/tray-wayland-integration/pluginmanagerintegration.cpp +++ b/src/tray-wayland-integration/pluginmanagerintegration.cpp @@ -48,6 +48,12 @@ void PluginManagerIntegration::requestMessage(const QString &plugin_id, const QS request_message(plugin_id, item_key, msg); } +struct ::wl_callback *PluginManagerIntegration::moveXembedWindow(uint32_t xembedWinId, const QString &pluginId, const QString &itemKey) +{ + auto callback = move_xembed_window(xembedWinId, pluginId, itemKey); + return callback; +} + void PluginManagerIntegration::plugin_manager_v1_position_changed(uint32_t dock_position) { if (dock_position != m_dockPosition) { @@ -122,4 +128,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..d07764fbf 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,6 +21,7 @@ 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); Q_SIGNALS: void eventMessage(const QString &msg); @@ -40,5 +42,7 @@ class PluginManagerIntegration : public QtWaylandClient::QWaylandShellIntegratio private: uint32_t m_dockPosition; uint32_t m_dockColorType; + static PluginManagerIntegration *s_instance; }; + } From 8bccff2983777a4c2963c41034470923c91f6d5d Mon Sep 17 00:00:00 2001 From: Wang Zichong Date: Mon, 19 Jan 2026 15:12:12 +0800 Subject: [PATCH 2/2] feat: call move_xembed_window api we added Log: --- .../xembedprotocolhandler.cpp | 19 ++++++++++++++++--- src/protocol/plugin-manager-v1.xml | 2 +- src/tray-wayland-integration/plugin.h | 2 ++ .../pluginmanagerintegration.cpp | 15 +++++++++++++++ .../pluginmanagerintegration_p.h | 2 ++ .../pluginsurface.cpp | 5 +++++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/plugins/application-tray/xembedprotocolhandler.cpp b/plugins/application-tray/xembedprotocolhandler.cpp index 1e820d0ae..107551a82 100644 --- a/plugins/application-tray/xembedprotocolhandler.cpp +++ b/plugins/application-tray/xembedprotocolhandler.cpp @@ -302,10 +302,23 @@ QPoint XembedProtocolHandler::updateEmbedWindowPosForGetInputEvent() { // update pos if (qgetenv("XDG_SESSION_TYPE") == "wayland") { - // Get `plugin_id` and `item_key` from EmbedPlugin. auto plugin = Plugin::EmbedPlugin::get(window()->windowHandle()); - // use move_xembed_window to move m_containerWid to plugin_id. - // TODO: ...? + + 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()); diff --git a/src/protocol/plugin-manager-v1.xml b/src/protocol/plugin-manager-v1.xml index be058761f..b246e26ed 100644 --- a/src/protocol/plugin-manager-v1.xml +++ b/src/protocol/plugin-manager-v1.xml @@ -115,7 +115,7 @@ 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/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 fac49e134..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,9 +49,18 @@ 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; } @@ -95,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(); diff --git a/src/tray-wayland-integration/pluginmanagerintegration_p.h b/src/tray-wayland-integration/pluginmanagerintegration_p.h index d07764fbf..03fce1a91 100644 --- a/src/tray-wayland-integration/pluginmanagerintegration_p.h +++ b/src/tray-wayland-integration/pluginmanagerintegration_p.h @@ -22,10 +22,12 @@ 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: 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);