mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-24 03:58:49 +03:00
Support window activation on wayland
This is a bit hacky, because we open a window to actually get a valid activation token, but...
This commit is contained in:
parent
8ea03e41e0
commit
234e05eef3
3 changed files with 53 additions and 3 deletions
|
@ -117,6 +117,7 @@ build-tw:
|
||||||
"cmake(Qt6Widgets)"
|
"cmake(Qt6Widgets)"
|
||||||
"cmake(Qt6Gui)"
|
"cmake(Qt6Gui)"
|
||||||
"qt6-qml-private-devel"
|
"qt6-qml-private-devel"
|
||||||
|
"qt6-gui-private-devel"
|
||||||
"pkgconfig(libcurl)"
|
"pkgconfig(libcurl)"
|
||||||
"pkgconfig(libevent)"
|
"pkgconfig(libevent)"
|
||||||
"pkgconfig(gstreamer-webrtc-1.0)"
|
"pkgconfig(gstreamer-webrtc-1.0)"
|
||||||
|
|
|
@ -902,6 +902,10 @@ target_link_libraries(nheko PRIVATE
|
||||||
lmdbxx::lmdbxx
|
lmdbxx::lmdbxx
|
||||||
liblmdb::lmdb)
|
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")
|
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0")
|
||||||
target_precompile_headers(nheko
|
target_precompile_headers(nheko
|
||||||
|
|
51
src/main.cpp
51
src/main.cpp
|
@ -10,7 +10,6 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
@ -20,6 +19,10 @@
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
#include <QtGui/qpa/qplatformwindow_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <kdsingleapplication.h>
|
#include <kdsingleapplication.h>
|
||||||
|
|
||||||
#include "Cache.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
|
// This check needs to happen _after_ process(), so that we actually print help for --help when
|
||||||
// Nheko is already running.
|
// Nheko is already running.
|
||||||
if (!singleapp.isPrimaryInstance()) {
|
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
|
// open uri in main instance
|
||||||
// TODO(Nico): Send also an activation token.
|
// TODO(Nico): Send also an activation token.
|
||||||
singleapp.sendMessage("activate");
|
singleapp.sendMessage("activate" + token);
|
||||||
|
|
||||||
if (!matrixUri.isEmpty()) {
|
if (!matrixUri.isEmpty()) {
|
||||||
std::cout << "Sending Matrix URL to main application: " << matrixUri.toStdString()
|
std::cout << "Sending Matrix URL to main application: " << matrixUri.toStdString()
|
||||||
|
@ -400,6 +440,11 @@ main(int argc, char *argv[])
|
||||||
ChatPage::instance(),
|
ChatPage::instance(),
|
||||||
[&](QByteArray message) {
|
[&](QByteArray message) {
|
||||||
if (message.isEmpty() || message.startsWith("activate")) {
|
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.show();
|
||||||
w.raise();
|
w.raise();
|
||||||
w.requestActivate();
|
w.requestActivate();
|
||||||
|
|
Loading…
Reference in a new issue