diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-11-20 03:20:26 +0100 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-11-20 13:31:51 +0100 |
commit | 234e05eef3c6c2894ee7467efd20f7ebe03e3494 (patch) | |
tree | ffe3681721fc69677d01b65935392fb1712b0e44 | |
parent | Switch to KDSingleApplication (diff) | |
download | nheko-234e05eef3c6c2894ee7467efd20f7ebe03e3494.tar.xz |
Support window activation on wayland
This is a bit hacky, because we open a window to actually get a valid activation token, but...
-rw-r--r-- | .gitlab-ci.yml | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/main.cpp | 51 |
3 files changed, 53 insertions, 3 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5476f1ac..b8b1c247 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -117,6 +117,7 @@ build-tw: "cmake(Qt6Widgets)" "cmake(Qt6Gui)" "qt6-qml-private-devel" + "qt6-gui-private-devel" "pkgconfig(libcurl)" "pkgconfig(libevent)" "pkgconfig(gstreamer-webrtc-1.0)" diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f7eb942..53501db6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -902,6 +902,10 @@ target_link_libraries(nheko PRIVATE lmdbxx::lmdbxx liblmdb::lmdb) +if(UNIX) + # for wayland activation tokens + target_link_libraries(nheko PRIVATE Qt::GuiPrivate) +endif() if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") target_precompile_headers(nheko diff --git a/src/main.cpp b/src/main.cpp index e740b27a..3cf794f8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,6 @@ #include <QDir> #include <QFile> #include <QFontDatabase> -#include <QGuiApplication> #include <QLabel> #include <QLibraryInfo> #include <QMessageBox> @@ -20,6 +19,10 @@ #include <QStandardPaths> #include <QTranslator> +#ifdef Q_OS_UNIX +#include <QtGui/qpa/qplatformwindow_p.h> +#endif + #include <kdsingleapplication.h> #include "Cache.h" @@ -248,10 +251,47 @@ main(int argc, char *argv[]) // This check needs to happen _after_ process(), so that we actually print help for --help when // Nheko is already running. if (!singleapp.isPrimaryInstance()) { - std::cout << "Activating main app (instead of opening it a second time)." << std::endl; + auto token = qgetenv("XDG_ACTIVATION_TOKEN"); + +#ifdef Q_OS_UNIX + // getting a valid activation token on wayland is a bit of a pain, it works most reliably + // when you have an actual window, that has the focus... + auto waylandApp = app.nativeInterface<QNativeInterface::QWaylandApplication>(); + if (waylandApp) { + QQuickView window; + window.setTitle("Activate main instance"); + window.setMaximumSize(QSize(100, 50)); + window.setMinimumSize(QSize(100, 50)); + window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); + window.setSource(QUrl(QStringLiteral("qrc:///resources/qml/ui/Spinner.qml"))); + window.show(); + auto waylandWindow = + window.nativeInterface<QNativeInterface::Private::QWaylandWindow>(); + if (waylandWindow) { + std::cout << "Launching temp window to activate main instance!\n"; + QObject::connect( + waylandWindow, + &QNativeInterface::Private::QWaylandWindow::xdgActivationTokenCreated, + waylandWindow, + [&token, &app](QString newToken) { // clazy:exclude=lambda-in-connect + token = newToken.toUtf8(); + app.exit(); + }, + Qt::SingleShotConnection); + QTimer::singleShot(100, waylandWindow, [waylandWindow, waylandApp] { + waylandWindow->requestXdgActivationToken(waylandApp->lastInputSerial()); + }); + app.exec(); + } + } +#endif + + std::cout << "Activating main app (instead of opening it a second time)." + << token.toStdString() << std::endl; + // open uri in main instance // TODO(Nico): Send also an activation token. - singleapp.sendMessage("activate"); + singleapp.sendMessage("activate" + token); if (!matrixUri.isEmpty()) { std::cout << "Sending Matrix URL to main application: " << matrixUri.toStdString() @@ -400,6 +440,11 @@ main(int argc, char *argv[]) ChatPage::instance(), [&](QByteArray message) { if (message.isEmpty() || message.startsWith("activate")) { + auto token = message.remove(0, sizeof("activate") - 1); + if (!token.isEmpty()) { + nhlog::ui()->debug("Setting activation token to: {}", token.toStdString()); + qputenv("XDG_ACTIVATION_TOKEN", token); + } w.show(); w.raise(); w.requestActivate(); |