Refactor window handling code

Currently when we want to show/raise the window in reaction to the tray icon/notification being clicked etc we do this by emitting a signal on the controller.
This is connected to in main.qml, which does some things, then calls back to controller to do more things.

This is quite convoluted. Instead introduce a new class WindowController that is responsible for all things window, in particular showing/raising and config saving
This commit is contained in:
Nicolas Fella
2022-09-01 22:58:43 +02:00
committed by Tobias Fella
parent 736c4b02ed
commit 55847cb9cc
10 changed files with 106 additions and 84 deletions

View File

@@ -38,6 +38,7 @@ add_library(neochat STATIC
joinrulesevent.cpp
collapsestateproxymodel.cpp
urlhelper.cpp
windowcontroller.cpp
)
add_executable(neochat-app

View File

@@ -12,7 +12,6 @@
#include <KWindowConfig>
#ifdef HAVE_WINDOWSYSTEM
#include <KWindowEffects>
#include <KWindowSystem>
#endif
#include <QAuthenticator>
@@ -53,6 +52,7 @@
#include "roommanager.h"
#include "settings.h"
#include "utils.h"
#include "windowcontroller.h"
#include <qt_connection_util.h>
#include <KStandardShortcut>
@@ -131,6 +131,11 @@ Controller &Controller::instance()
return _instance;
}
void Controller::showWindow()
{
WindowController::instance().showAndRaiseWindow(QString());
}
inline QString accessTokenFileName(const AccountSettings &account)
{
QString fileName = account.userId();
@@ -589,21 +594,9 @@ void Controller::setActiveConnection(Connection *connection)
Q_EMIT activeConnectionChanged();
}
void Controller::restoreWindowGeometry(QWindow *window)
void Controller::saveWindowGeometry()
{
KConfig dataResource("data", KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
KConfigGroup windowGroup(&dataResource, "Window");
KWindowConfig::restoreWindowSize(window, windowGroup);
KWindowConfig::restoreWindowPosition(window, windowGroup);
}
void Controller::saveWindowGeometry(QQuickWindow *window)
{
KConfig dataResource("data", KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
KConfigGroup windowGroup(&dataResource, "Window");
KWindowConfig::saveWindowPosition(window, windowGroup);
KWindowConfig::saveWindowSize(window, windowGroup);
dataResource.sync();
WindowController::instance().saveGeometry();
}
NeochatDeleteDeviceJob::NeochatDeleteDeviceJob(const QString &deviceId, const Omittable<QJsonObject> &auth)
@@ -681,13 +674,6 @@ 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

View File

@@ -95,7 +95,6 @@ public:
Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user);
Q_INVOKABLE void setBlur(QQuickItem *item, bool blur);
Q_INVOKABLE void raiseWindow(QWindow *window);
Q_INVOKABLE QString plainText(QQuickTextDocument *document) const;
bool encryptionSupported() const;
@@ -118,6 +117,7 @@ private:
private Q_SLOTS:
void invokeLogin();
void showWindow();
Q_SIGNALS:
void busyChanged();
@@ -137,7 +137,6 @@ Q_SIGNALS:
void activeConnectionChanged();
void aboutDataChanged();
void passwordStatus(Controller::PasswordStatus _t1);
void showWindow();
void userConsentRequired(QUrl url);
void testConnectionResult(const QString &connection, bool usable);
void isOnlineChanged(bool isOnline);
@@ -146,8 +145,7 @@ public Q_SLOTS:
void logout(Quotient::Connection *conn, bool serverSideLogout);
void changeAvatar(Quotient::Connection *conn, const QUrl &localFile);
static void markAllMessagesAsRead(Quotient::Connection *conn);
void restoreWindowGeometry(QWindow *);
void saveWindowGeometry(QQuickWindow *);
void saveWindowGeometry();
};
// TODO libQuotient 0.7: Drop

View File

@@ -75,6 +75,7 @@
#include "userdirectorylistmodel.h"
#include "userlistmodel.h"
#include "webshortcutmodel.h"
#include "windowcontroller.h"
#include <room.h>
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
@@ -95,21 +96,6 @@ class NetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory
}
};
#ifdef HAVE_WINDOWSYSTEM
static void raiseWindow(QWindow *window)
{
#if KWINDOWSYSTEM_VERSION >= QT_VERSION_CHECK(5, 91, 0)
KWindowSystem::updateStartupId(window);
#else
if (KWindowSystem::isPlatformWayland()) {
KWindowSystem::setCurrentXdgActivationToken(qEnvironmentVariable("XDG_ACTIVATION_TOKEN"));
}
#endif
KWindowSystem::activateWindow(window->winId());
window->raise();
}
#endif
static QWindow *windowFromEngine(QQmlApplicationEngine *engine)
{
const auto rootObjects = engine->rootObjects();
@@ -238,12 +224,6 @@ int main(int argc, char *argv[])
qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*");
qRegisterMetaType<QMimeType>("QMimeType");
#ifdef HAVE_WINDOWSYSTEM
qmlRegisterSingletonType<KWindowSystem>("org.kde.kwindowsystem.private", 1, 0, "KWindowSystem", [](QQmlEngine *, QJSEngine *) -> QObject * {
return KWindowSystem::self();
});
#endif
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
qRegisterMetaTypeStreamOperators<Emoji>();
#endif
@@ -291,12 +271,9 @@ int main(int argc, char *argv[])
Q_UNUSED(workingDirectory);
QWindow *window = windowFromEngine(&engine);
KWindowSystem::updateStartupId(window);
if (!window->isVisible()) {
window->show();
}
raiseWindow(window);
WindowController::instance().showAndRaiseWindow(QString());
// Open matrix uri
if (arguments.isEmpty()) {
@@ -312,9 +289,8 @@ int main(int argc, char *argv[])
QWindow *window = windowFromEngine(&engine);
if (window->isVisible()) {
Controller::instance().restoreWindowGeometry(window);
}
WindowController::instance().setWindow(window);
WindowController::instance().restoreGeometry();
return app.exec();
}

View File

@@ -19,6 +19,7 @@
#include "controller.h"
#include "neochatconfig.h"
#include "roommanager.h"
#include "windowcontroller.h"
NotificationsManager &NotificationsManager::instance()
{
@@ -57,11 +58,8 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
notification->setDefaultAction(i18n("Open NeoChat in this room"));
connect(notification, &KNotification::defaultActivated, this, [=]() {
#if defined(HAVE_WINDOWSYSTEM) && KNOTIFICATIONS_VERSION >= QT_VERSION_CHECK(5, 90, 0)
KWindowSystem::setCurrentXdgActivationToken(notification->xdgActivationToken());
#endif
RoomManager::instance().enterRoom(room);
Q_EMIT Controller::instance().showWindow();
WindowController::instance().showAndRaiseWindow(notification->xdgActivationToken());
});
if (canReply) {
@@ -95,12 +93,9 @@ void NotificationsManager::postInviteNotification(NeoChatRoom *room, const QStri
notification->setFlags(KNotification::Persistent);
notification->setDefaultAction(i18n("Open this invitation in NeoChat"));
connect(notification, &KNotification::defaultActivated, this, [=]() {
#if defined(HAVE_WINDOWSYSTEM) && KNOTIFICATIONS_VERSION >= QT_VERSION_CHECK(5, 90, 0)
KWindowSystem::setCurrentXdgActivationToken(notification->xdgActivationToken());
#endif
notification->close();
RoomManager::instance().enterRoom(room);
Q_EMIT Controller::instance().showWindow();
WindowController::instance().showAndRaiseWindow(notification->xdgActivationToken());
});
notification->setActions({i18n("Accept Invitation"), i18n("Reject Invitation")});
connect(notification, &KNotification::action1Activated, this, [this, room, notification]() {

View File

@@ -8,6 +8,7 @@
#include "roomlistmodel.h"
#include "roommanager.h"
#include "runner.h"
#include "windowcontroller.h"
RemoteImage Runner::serializeImage(const QImage &image)
{
@@ -90,5 +91,6 @@ void Runner::Run(const QString &id, const QString &actionId)
}
RoomManager::instance().enterRoom(room);
Q_EMIT Controller::instance().showWindow();
WindowController::instance().showAndRaiseWindow(QString());
}

55
src/windowcontroller.cpp Normal file
View File

@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: 2022 Nicolas Fella <nicolas.fella@gmx.de>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "windowcontroller.h"
#include <KConfig>
#include <KWindowConfig>
#ifdef HAVE_WINDOWSYSTEM
#include <KWindowSystem>
#endif
#include <QStandardPaths>
WindowController &WindowController::instance()
{
static WindowController instance;
return instance;
}
void WindowController::setWindow(QWindow *window)
{
m_window = window;
}
void WindowController::restoreGeometry()
{
KConfig dataResource("data", KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
KConfigGroup windowGroup(&dataResource, "Window");
KWindowConfig::restoreWindowSize(m_window, windowGroup);
KWindowConfig::restoreWindowPosition(m_window, windowGroup);
}
void WindowController::saveGeometry()
{
KConfig dataResource("data", KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
KConfigGroup windowGroup(&dataResource, "Window");
KWindowConfig::saveWindowPosition(m_window, windowGroup);
KWindowConfig::saveWindowSize(m_window, windowGroup);
}
void WindowController::showAndRaiseWindow(const QString &xdgActivationToken)
{
if (!m_window->isVisible()) {
m_window->show();
}
#ifdef HAVE_WINDOWSYSTEM
if (!xdgActivationToken.isEmpty()) {
KWindowSystem::setCurrentXdgActivationToken(xdgActivationToken);
}
KWindowSystem::activateWindow(m_window);
#endif
}

26
src/windowcontroller.h Normal file
View File

@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2022 Nicolas Fella <nicolas.fella@gmx.de>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QObject>
#include <QWindow>
class WindowController : public QObject
{
Q_OBJECT
public:
static WindowController &instance();
void setWindow(QWindow *window);
void restoreGeometry();
void saveGeometry();
void showAndRaiseWindow(const QString &xdgActivationToken);
private:
WindowController() = default;
QWindow *m_window = nullptr;
};