From 265fcbfead4beda92585364529b2a9e872ad9eb4 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Fri, 3 Sep 2021 20:31:12 +0200 Subject: [PATCH] Fix wayland activation Adds support for xdg_activation_v1 when calling the application from the system tray by using KStatusNotifier which supports it. Listens to XDG_ACTIVATION_TOKEN as it's passed when we are started from dbus. --- qml/main.qml | 1 + src/CMakeLists.txt | 7 ++++++- src/controller.cpp | 12 +++++++++++- src/controller.h | 1 + src/main.cpp | 15 ++++++++++++++- src/trayicon_sni.cpp | 25 +++++++++++++++++++++++++ src/trayicon_sni.h | 19 +++++++++++++++++++ 7 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/trayicon_sni.cpp create mode 100644 src/trayicon_sni.h diff --git a/qml/main.qml b/qml/main.qml index edd199699..356a8f43b 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -158,6 +158,7 @@ Kirigami.ApplicationWindow { root.show() root.raise() root.requestActivate() + Controller.raiseWindow(root) } contextDrawer: RoomDrawer { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 249904692..7840e8099 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,7 +48,12 @@ ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png) target_sources(neochat PRIVATE ${NEOCHAT_ICON}) if(NOT ANDROID) - target_sources(neochat PRIVATE trayicon.cpp colorschemer.cpp) + target_sources(neochat PRIVATE colorschemer.cpp) + if (NOT WIN32 AND NOT APPLE) + target_sources(neochat PRIVATE trayicon_sni.cpp) + else() + target_sources(neochat PRIVATE trayicon.cpp) + endif() target_link_libraries(neochat PRIVATE KF5::ConfigWidgets KF5::WindowSystem KF5::SonnetCore) target_compile_definitions(neochat PRIVATE -DHAVE_COLORSCHEME) target_compile_definitions(neochat PRIVATE -DHAVE_WINDOWSYSTEM) diff --git a/src/controller.cpp b/src/controller.cpp index 3651c3006..7184570f2 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -12,6 +12,7 @@ #include #ifdef HAVE_WINDOWSYSTEM #include +#include #endif #include @@ -55,8 +56,10 @@ #include "utils.h" #include -#ifndef Q_OS_ANDROID +#if defined(Q_OS_WIN) || defined(Q_OS_MAC) #include "trayicon.h" +#elif !defined(Q_OS_ANDROID) +#include "trayicon_sni.h" #endif using namespace Quotient; @@ -634,6 +637,13 @@ void Controller::setBlur(QQuickItem *item, bool blur) #endif } +void Controller::raiseWindow(QWindow *window) +{ +#ifdef HAVE_WINDOWSYSTEM + KWindowSystem::activateWindow(window->winId()); +#endif +} + bool Controller::hasWindowSystem() const { #ifdef HAVE_WINDOWSYSTEM diff --git a/src/controller.h b/src/controller.h index d0568b92f..67077ad80 100644 --- a/src/controller.h +++ b/src/controller.h @@ -91,6 +91,7 @@ public: Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user); Q_INVOKABLE void setBlur(QQuickItem *item, bool blur); + Q_INVOKABLE void raiseWindow(QWindow *window); private: explicit Controller(QObject *parent = nullptr); diff --git a/src/main.cpp b/src/main.cpp index e5469d9f9..d308f017f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,6 +22,7 @@ #include #ifdef HAVE_KDBUSADDONS #include +#include #endif #include #include @@ -66,6 +67,18 @@ using namespace Quotient; +#ifdef HAVE_KDBUSADDONS +static void raiseWindow(QWindow *window) +{ + if (KWindowSystem::isPlatformWayland()) { + KWindowSystem::setCurrentXdgActivationToken(qEnvironmentVariable("XDG_ACTIVATION_TOKEN")); + KWindowSystem::activateWindow(window->winId()); + } else { + window->raise(); + } +} +#endif + #ifdef Q_OS_ANDROID Q_DECL_EXPORT #endif @@ -232,7 +245,7 @@ int main(int argc, char *argv[]) auto view = qobject_cast(obj); if (view) { view->show(); - view->raise(); + raiseWindow(view); return; } } diff --git a/src/trayicon_sni.cpp b/src/trayicon_sni.cpp new file mode 100644 index 000000000..651884a70 --- /dev/null +++ b/src/trayicon_sni.cpp @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez +// SPDX-License-Identifier: GPL-3.0-only + +#include "trayicon_sni.h" +#include + +TrayIcon::TrayIcon(QObject *parent) + : KStatusNotifierItem(parent) +{ + setIconByName("org.kde.neochat"); + connect(this, &KStatusNotifierItem::activateRequested, this, [this] { + KWindowSystem::setCurrentXdgActivationToken(providedToken()); + Q_EMIT showWindow(); + }); +} + +void TrayIcon::show() +{ + setStatus(Active); +} + +void TrayIcon::hide() +{ + setStatus(Passive); +} diff --git a/src/trayicon_sni.h b/src/trayicon_sni.h new file mode 100644 index 000000000..82f06ccab --- /dev/null +++ b/src/trayicon_sni.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez +// SPDX-License-Identifier: GPL-3.0-only + +#pragma once + +#include + +class TrayIcon : public KStatusNotifierItem +{ + Q_OBJECT +public: + TrayIcon(QObject *parent = nullptr); + + void show(); + void hide(); + +Q_SIGNALS: + void showWindow(); +};