9797#include < QTreeWidgetItem>
9898#include < QUuid>
9999#include < QWidgetAction>
100+ #include < QWindow>
100101#include < QtConcurrent>
101102#include < libraries/qttoolbareditor/src/toolbar_editor.hpp>
102103#include < memory>
@@ -773,9 +774,10 @@ void MainWindow::initWaylandGlobalShortcuts(SettingsService &settings, const QSt
773774
774775 _xdgShortcutManager->setShortcuts (shortcuts);
775776
776- // Connect the activation signal to trigger the corresponding action
777+ // Connect the activation signal to trigger the corresponding action.
778+ // The activationToken from the portal authorizes window activation on Wayland.
777779 connect (_xdgShortcutManager, &XdgGlobalShortcutManager::shortcutActivated, this ,
778- [this ](const QString &shortcutId) {
780+ [this ](const QString &shortcutId, const QString &activationToken ) {
779781 QAction *action = findAction (shortcutId);
780782 if (action == nullptr ) {
781783 qDebug () << " XDG GlobalShortcuts: failed to find action:" << shortcutId;
@@ -784,13 +786,19 @@ void MainWindow::initWaylandGlobalShortcuts(SettingsService &settings, const QSt
784786
785787 qDebug () << " XDG global shortcut action triggered:" << action->objectName ();
786788
789+ // Set the activation token so that showWindow() can use it to
790+ // request window activation from the Wayland compositor
791+ _waylandActivationToken = activationToken;
792+
787793 // Don't call showWindow() for the "Show/Hide application" action
788794 // because it will call it itself
789795 if (action->objectName () != QStringLiteral (" actionShow_Hide_application" )) {
790796 showWindow ();
791797 }
792798
793799 action->trigger ();
800+
801+ _waylandActivationToken.clear ();
794802 });
795803
796804 // Start the session creation and shortcut binding flow
@@ -6746,6 +6754,26 @@ void MainWindow::showWindow() {
67466754 // show the window in case we are using the system tray
67476755 show ();
67486756
6757+ #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
6758+ // On Wayland, use the XDG activation token (if available) to request
6759+ // window activation from the compositor. Without a valid token the
6760+ // compositor will refuse to raise/focus the window because Wayland
6761+ // does not allow applications to steal focus on their own.
6762+ if (!_waylandActivationToken.isEmpty () && windowHandle () != nullptr ) {
6763+ qputenv (" XDG_ACTIVATION_TOKEN" , _waylandActivationToken.toUtf8 ());
6764+ windowHandle ()->requestActivate ();
6765+ qunsetenv (" XDG_ACTIVATION_TOKEN" );
6766+
6767+ // Still un-minimize if needed
6768+ if (windowState () & Qt::WindowMinimized) {
6769+ setWindowState ((windowState () & ~Qt::WindowMinimized) | Qt::WindowActive);
6770+ }
6771+
6772+ startNavigationParser ();
6773+ return ;
6774+ }
6775+ #endif
6776+
67496777 // bring application window to the front
67506778 activateWindow (); // for Windows
67516779 setWindowState ((windowState () & ~Qt::WindowMinimized) | Qt::WindowActive);
0 commit comments