2024-02-29 03:55:49 +00:00
|
|
|
#include "session_lock.hpp"
|
|
|
|
|
|
|
|
#include <qcolor.h>
|
2024-02-29 05:30:06 +00:00
|
|
|
#include <qcoreapplication.h>
|
2024-02-29 03:55:49 +00:00
|
|
|
#include <qguiapplication.h>
|
|
|
|
#include <qlogging.h>
|
|
|
|
#include <qobject.h>
|
|
|
|
#include <qqmlcomponent.h>
|
|
|
|
#include <qqmlengine.h>
|
2024-02-29 05:30:06 +00:00
|
|
|
#include <qqmllist.h>
|
2024-02-29 03:55:49 +00:00
|
|
|
#include <qquickitem.h>
|
|
|
|
#include <qquickwindow.h>
|
|
|
|
#include <qscreen.h>
|
|
|
|
#include <qtmetamacros.h>
|
|
|
|
#include <qtypes.h>
|
|
|
|
|
2024-02-29 05:30:06 +00:00
|
|
|
#include "../core/qmlscreen.hpp"
|
|
|
|
#include "../core/reload.hpp"
|
2024-02-29 03:55:49 +00:00
|
|
|
#include "session_lock/session_lock.hpp"
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLock::onReload(QObject* oldInstance) {
|
|
|
|
auto* old = qobject_cast<WlSessionLock*>(oldInstance);
|
2024-02-29 03:55:49 +00:00
|
|
|
|
|
|
|
if (old != nullptr) {
|
|
|
|
QObject::disconnect(old->manager, nullptr, old, nullptr);
|
|
|
|
this->manager = old->manager;
|
|
|
|
this->manager->setParent(this);
|
|
|
|
} else {
|
|
|
|
this->manager = new SessionLockManager(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// clang-format off
|
2024-03-11 13:02:11 +00:00
|
|
|
QObject::connect(this->manager, &SessionLockManager::locked, this, &WlSessionLock::secureStateChanged);
|
|
|
|
QObject::connect(this->manager, &SessionLockManager::unlocked, this, &WlSessionLock::secureStateChanged);
|
2024-02-29 03:55:49 +00:00
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
QObject::connect(this->manager, &SessionLockManager::unlocked, this, &WlSessionLock::unlock);
|
2024-02-29 03:55:49 +00:00
|
|
|
|
|
|
|
auto* app = QCoreApplication::instance();
|
|
|
|
auto* guiApp = qobject_cast<QGuiApplication*>(app);
|
|
|
|
|
|
|
|
if (guiApp != nullptr) {
|
2024-03-11 13:02:11 +00:00
|
|
|
QObject::connect(guiApp, &QGuiApplication::primaryScreenChanged, this, &WlSessionLock::onScreensChanged);
|
|
|
|
QObject::connect(guiApp, &QGuiApplication::screenAdded, this, &WlSessionLock::onScreensChanged);
|
|
|
|
QObject::connect(guiApp, &QGuiApplication::screenRemoved, this, &WlSessionLock::onScreensChanged);
|
2024-02-29 03:55:49 +00:00
|
|
|
}
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
if (this->lockTarget) {
|
2024-02-29 07:02:53 +00:00
|
|
|
if (!this->manager->lock()) this->lockTarget = false;
|
2024-02-29 03:55:49 +00:00
|
|
|
this->updateSurfaces(old);
|
|
|
|
} else {
|
|
|
|
this->setLocked(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLock::updateSurfaces(WlSessionLock* old) {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->manager->isLocked()) {
|
|
|
|
auto screens = QGuiApplication::screens();
|
|
|
|
|
|
|
|
auto map = this->surfaces.toStdMap();
|
|
|
|
for (auto& [screen, surface]: map) {
|
|
|
|
if (!screens.contains(screen)) {
|
|
|
|
this->surfaces.remove(screen);
|
|
|
|
surface->deleteLater();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->mSurfaceComponent == nullptr) {
|
2024-03-11 13:02:11 +00:00
|
|
|
qWarning() << "WlSessionLock.surface is null. Aborting lock.";
|
2024-02-29 03:55:49 +00:00
|
|
|
this->unlock();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto* screen: screens) {
|
|
|
|
if (!this->surfaces.contains(screen)) {
|
2024-03-04 05:38:21 +00:00
|
|
|
auto* instanceObj =
|
|
|
|
this->mSurfaceComponent->create(QQmlEngine::contextForObject(this->mSurfaceComponent));
|
2024-03-11 13:02:11 +00:00
|
|
|
auto* instance = qobject_cast<WlSessionLockSurface*>(instanceObj);
|
2024-02-29 03:55:49 +00:00
|
|
|
|
|
|
|
if (instance == nullptr) {
|
2024-03-12 21:55:51 +00:00
|
|
|
qWarning(
|
|
|
|
) << "WlSessionLock.surface does not create a WlSessionLockSurface. Aborting lock.";
|
2024-03-02 14:22:14 +00:00
|
|
|
if (instanceObj != nullptr) instanceObj->deleteLater();
|
2024-02-29 03:55:49 +00:00
|
|
|
this->unlock();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
instance->setParent(this);
|
|
|
|
instance->setScreen(screen);
|
|
|
|
|
|
|
|
auto* oldInstance = old == nullptr ? nullptr : old->surfaces.value(screen, nullptr);
|
|
|
|
instance->onReload(oldInstance);
|
|
|
|
|
|
|
|
this->surfaces[screen] = instance;
|
2024-02-29 05:41:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (auto* surface: this->surfaces.values()) {
|
|
|
|
surface->show();
|
2024-02-29 03:55:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLock::unlock() {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->isLocked()) {
|
|
|
|
this->lockTarget = false;
|
|
|
|
this->manager->unlock();
|
|
|
|
|
|
|
|
for (auto* surface: this->surfaces) {
|
|
|
|
surface->deleteLater();
|
|
|
|
}
|
|
|
|
|
|
|
|
this->surfaces.clear();
|
|
|
|
|
|
|
|
emit this->lockStateChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLock::onScreensChanged() { this->updateSurfaces(); }
|
2024-02-29 03:55:49 +00:00
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
bool WlSessionLock::isLocked() const {
|
2024-02-29 03:55:49 +00:00
|
|
|
return this->manager == nullptr ? this->lockTarget : this->manager->isLocked();
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
bool WlSessionLock::isSecure() const {
|
2024-02-29 05:41:30 +00:00
|
|
|
return this->manager != nullptr && SessionLockManager::isSecure();
|
2024-02-29 03:55:49 +00:00
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLock::setLocked(bool locked) {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->isLocked() == locked) return;
|
|
|
|
this->lockTarget = locked;
|
|
|
|
|
|
|
|
if (this->manager == nullptr) {
|
|
|
|
emit this->lockStateChanged();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (locked) {
|
2024-02-29 07:02:53 +00:00
|
|
|
if (!this->manager->lock()) this->lockTarget = false;
|
2024-02-29 03:55:49 +00:00
|
|
|
this->updateSurfaces();
|
|
|
|
if (this->lockTarget) emit this->lockStateChanged();
|
|
|
|
} else {
|
|
|
|
this->unlock(); // emits lockStateChanged
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
QQmlComponent* WlSessionLock::surfaceComponent() const { return this->mSurfaceComponent; }
|
2024-02-29 03:55:49 +00:00
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLock::setSurfaceComponent(QQmlComponent* surfaceComponent) {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->mSurfaceComponent != nullptr) this->mSurfaceComponent->deleteLater();
|
|
|
|
if (surfaceComponent != nullptr) surfaceComponent->setParent(this);
|
|
|
|
|
|
|
|
this->mSurfaceComponent = surfaceComponent;
|
|
|
|
emit this->surfaceComponentChanged();
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
WlSessionLockSurface::WlSessionLockSurface(QObject* parent)
|
2024-02-29 03:55:49 +00:00
|
|
|
: Reloadable(parent)
|
|
|
|
, mContentItem(new QQuickItem())
|
|
|
|
, ext(new LockWindowExtension(this)) {
|
2024-03-09 02:33:01 +00:00
|
|
|
QQmlEngine::setObjectOwnership(this->mContentItem, QQmlEngine::CppOwnership);
|
2024-02-29 03:55:49 +00:00
|
|
|
this->mContentItem->setParent(this);
|
|
|
|
|
|
|
|
// clang-format off
|
2024-03-11 13:02:11 +00:00
|
|
|
QObject::connect(this, &WlSessionLockSurface::widthChanged, this, &WlSessionLockSurface::onWidthChanged);
|
|
|
|
QObject::connect(this, &WlSessionLockSurface::heightChanged, this, &WlSessionLockSurface::onHeightChanged);
|
2024-02-29 03:55:49 +00:00
|
|
|
// clang-format on
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
WlSessionLockSurface::~WlSessionLockSurface() {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->window != nullptr) {
|
|
|
|
this->window->deleteLater();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLockSurface::onReload(QObject* oldInstance) {
|
|
|
|
if (auto* old = qobject_cast<WlSessionLockSurface*>(oldInstance)) {
|
2024-02-29 03:55:49 +00:00
|
|
|
this->window = old->disownWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->window == nullptr) {
|
|
|
|
this->window = new QQuickWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
this->mContentItem->setParentItem(this->window->contentItem());
|
|
|
|
|
|
|
|
this->mContentItem->setWidth(this->width());
|
|
|
|
this->mContentItem->setHeight(this->height());
|
|
|
|
|
|
|
|
if (this->mScreen != nullptr) this->window->setScreen(this->mScreen);
|
|
|
|
this->window->setColor(this->mColor);
|
|
|
|
|
|
|
|
// clang-format off
|
2024-03-11 13:02:11 +00:00
|
|
|
QObject::connect(this->window, &QWindow::visibilityChanged, this, &WlSessionLockSurface::visibleChanged);
|
|
|
|
QObject::connect(this->window, &QWindow::widthChanged, this, &WlSessionLockSurface::widthChanged);
|
|
|
|
QObject::connect(this->window, &QWindow::heightChanged, this, &WlSessionLockSurface::heightChanged);
|
|
|
|
QObject::connect(this->window, &QWindow::screenChanged, this, &WlSessionLockSurface::screenChanged);
|
|
|
|
QObject::connect(this->window, &QQuickWindow::colorChanged, this, &WlSessionLockSurface::colorChanged);
|
2024-02-29 03:55:49 +00:00
|
|
|
// clang-format on
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
if (auto* parent = qobject_cast<WlSessionLock*>(this->parent())) {
|
2024-02-29 05:30:06 +00:00
|
|
|
if (!this->ext->attach(this->window, parent->manager)) {
|
2024-02-29 03:55:49 +00:00
|
|
|
qWarning(
|
|
|
|
) << "Failed to attach LockWindowExtension to window. Surface will not behave correctly.";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
qWarning(
|
2024-03-11 13:02:11 +00:00
|
|
|
) << "WlSessionLockSurface parent is not a WlSessionLock. Surface will not behave correctly.";
|
2024-02-29 03:55:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
QQuickWindow* WlSessionLockSurface::disownWindow() {
|
2024-02-29 03:55:49 +00:00
|
|
|
QObject::disconnect(this->window, nullptr, this, nullptr);
|
|
|
|
this->mContentItem->setParentItem(nullptr);
|
|
|
|
|
|
|
|
auto* window = this->window;
|
|
|
|
this->window = nullptr;
|
|
|
|
return window;
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLockSurface::show() { this->ext->setVisible(); }
|
2024-02-29 03:55:49 +00:00
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
QQuickItem* WlSessionLockSurface::contentItem() const { return this->mContentItem; }
|
2024-02-29 03:55:49 +00:00
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
bool WlSessionLockSurface::isVisible() const { return this->window->isVisible(); }
|
2024-02-29 03:55:49 +00:00
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
qint32 WlSessionLockSurface::width() const {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->window == nullptr) return 0;
|
|
|
|
else return this->window->width();
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
qint32 WlSessionLockSurface::height() const {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->window == nullptr) return 0;
|
|
|
|
else return this->window->height();
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
QuickshellScreenInfo* WlSessionLockSurface::screen() const {
|
2024-02-29 03:55:49 +00:00
|
|
|
QScreen* qscreen = nullptr;
|
|
|
|
|
|
|
|
if (this->window == nullptr) {
|
|
|
|
if (this->mScreen != nullptr) qscreen = this->mScreen;
|
|
|
|
} else {
|
|
|
|
qscreen = this->window->screen();
|
|
|
|
}
|
|
|
|
|
|
|
|
return new QuickshellScreenInfo(
|
2024-03-11 13:02:11 +00:00
|
|
|
const_cast<WlSessionLockSurface*>(this), // NOLINT
|
2024-02-29 03:55:49 +00:00
|
|
|
qscreen
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLockSurface::setScreen(QScreen* qscreen) {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->mScreen != nullptr) {
|
|
|
|
QObject::disconnect(this->mScreen, nullptr, this, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qscreen != nullptr) {
|
2024-03-11 13:02:11 +00:00
|
|
|
QObject::connect(qscreen, &QObject::destroyed, this, &WlSessionLockSurface::onScreenDestroyed);
|
2024-02-29 03:55:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this->window == nullptr) {
|
|
|
|
this->mScreen = qscreen;
|
|
|
|
emit this->screenChanged();
|
|
|
|
} else this->window->setScreen(qscreen);
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLockSurface::onScreenDestroyed() { this->mScreen = nullptr; }
|
2024-02-29 03:55:49 +00:00
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
QColor WlSessionLockSurface::color() const {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->window == nullptr) return this->mColor;
|
|
|
|
else return this->window->color();
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLockSurface::setColor(QColor color) {
|
2024-02-29 03:55:49 +00:00
|
|
|
if (this->window == nullptr) {
|
|
|
|
this->mColor = color;
|
|
|
|
emit this->colorChanged();
|
|
|
|
} else this->window->setColor(color);
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
QQmlListProperty<QObject> WlSessionLockSurface::data() {
|
2024-02-29 03:55:49 +00:00
|
|
|
return this->mContentItem->property("data").value<QQmlListProperty<QObject>>();
|
|
|
|
}
|
|
|
|
|
2024-03-11 13:02:11 +00:00
|
|
|
void WlSessionLockSurface::onWidthChanged() { this->mContentItem->setWidth(this->width()); }
|
|
|
|
void WlSessionLockSurface::onHeightChanged() { this->mContentItem->setHeight(this->height()); }
|