From b5160ae1182aa0a76f02c7ff836fb51d2c45d097 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Wed, 22 Jun 2022 19:02:59 +0400 Subject: [PATCH] Client: get activation token automatically whenever possible This allows the application to change focus between its own windows without any code change whenever possbile I.e. if application already has a focused window or the token is specified in XDG_ACTIVATION_TOKEN environment variable Pick-to: 6.4 6.3 Change-Id: I6f54d12197ac0c10bfda2a517aa11bc291e3b471 Reviewed-by: Qt CI Bot Reviewed-by: Aleix Pol Gonzalez --- .../xdg-shell/qwaylandxdgshell.cpp | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 3d2fc61d3da..e227971ba95 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -10,6 +10,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -477,8 +478,29 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial) bool QWaylandXdgSurface::requestActivate() { if (auto *activation = m_shell->activation()) { - activation->activate(m_activationToken, window()->wlSurface()); - return true; + if (!m_activationToken.isEmpty()) { + activation->activate(m_activationToken, window()->wlSurface()); + m_activationToken = {}; + return true; + } else if (const auto token = qEnvironmentVariable("XDG_ACTIVATION_TOKEN"); !token.isEmpty()) { + activation->activate(token, window()->wlSurface()); + qunsetenv("XDG_ACTIVATION_TOKEN"); + return true; + } else if (const auto focusWindow = QGuiApplication::focusWindow()) { + const auto wlWindow = static_cast(focusWindow->handle()); + if (const auto xdgSurface = qobject_cast(wlWindow->shellSurface())) { + if (const auto seat = wlWindow->display()->lastInputDevice()) { + const auto tokenProvider = activation->requestXdgActivationToken( + wlWindow->display(), wlWindow->wlSurface(), seat->serial(), xdgSurface->m_appId); + connect(tokenProvider, &QWaylandXdgActivationTokenV1::done, this, + [this, tokenProvider](const QString &token) { + m_shell->activation()->activate(token, window()->wlSurface()); + tokenProvider->deleteLater(); + }); + return true; + } + } + } } return false; }