forked from quickshell/quickshell
feat(slock): add user facing SessionLock and SessionLockSurface
This commit is contained in:
parent
1fa87b7c5a
commit
48bdcf4db2
|
@ -134,8 +134,10 @@ void ProxyWindowBase::setScreen(QuickshellScreenInfo* screen) {
|
||||||
QObject::connect(qscreen, &QObject::destroyed, this, &ProxyWindowBase::onScreenDestroyed);
|
QObject::connect(qscreen, &QObject::destroyed, this, &ProxyWindowBase::onScreenDestroyed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->window == nullptr) this->mScreen = qscreen;
|
if (this->window == nullptr) {
|
||||||
else this->window->setScreen(qscreen);
|
this->mScreen = qscreen;
|
||||||
|
emit this->screenChanged();
|
||||||
|
} else this->window->setScreen(qscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyWindowBase::onScreenDestroyed() { this->mScreen = nullptr; }
|
void ProxyWindowBase::onScreenDestroyed() { this->mScreen = nullptr; }
|
||||||
|
|
|
@ -46,6 +46,7 @@ endfunction()
|
||||||
|
|
||||||
qt_add_library(quickshell-wayland STATIC
|
qt_add_library(quickshell-wayland STATIC
|
||||||
wlr_layershell.cpp
|
wlr_layershell.cpp
|
||||||
|
session_lock.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_add_qml_module(quickshell-wayland URI Quickshell.Wayland)
|
qt_add_qml_module(quickshell-wayland URI Quickshell.Wayland)
|
||||||
|
|
|
@ -3,5 +3,6 @@ description = "Wayland specific Quickshell types"
|
||||||
headers = [
|
headers = [
|
||||||
"wlr_layershell/window.hpp",
|
"wlr_layershell/window.hpp",
|
||||||
"wlr_layershell.hpp",
|
"wlr_layershell.hpp",
|
||||||
|
"session_lock.hpp",
|
||||||
]
|
]
|
||||||
-----
|
-----
|
||||||
|
|
284
src/wayland/session_lock.cpp
Normal file
284
src/wayland/session_lock.cpp
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
#include "session_lock.hpp"
|
||||||
|
|
||||||
|
#include <qcolor.h>
|
||||||
|
#include <qguiapplication.h>
|
||||||
|
#include <qlogging.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlcomponent.h>
|
||||||
|
#include <qqmlengine.h>
|
||||||
|
#include <qquickitem.h>
|
||||||
|
#include <qquickwindow.h>
|
||||||
|
#include <qscreen.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
|
||||||
|
#include "session_lock/session_lock.hpp"
|
||||||
|
|
||||||
|
void SessionLock::onReload(QObject* oldInstance) {
|
||||||
|
auto* old = qobject_cast<SessionLock*>(oldInstance);
|
||||||
|
|
||||||
|
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
|
||||||
|
QObject::connect(this->manager, &SessionLockManager::locked, this, &SessionLock::secureStateChanged);
|
||||||
|
QObject::connect(this->manager, &SessionLockManager::unlocked, this, &SessionLock::secureStateChanged);
|
||||||
|
|
||||||
|
QObject::connect(this->manager, &SessionLockManager::unlocked, this, &SessionLock::unlock);
|
||||||
|
|
||||||
|
auto* app = QCoreApplication::instance();
|
||||||
|
auto* guiApp = qobject_cast<QGuiApplication*>(app);
|
||||||
|
|
||||||
|
if (guiApp != nullptr) {
|
||||||
|
QObject::connect(guiApp, &QGuiApplication::primaryScreenChanged, this, &SessionLock::onScreensChanged);
|
||||||
|
QObject::connect(guiApp, &QGuiApplication::screenAdded, this, &SessionLock::onScreensChanged);
|
||||||
|
QObject::connect(guiApp, &QGuiApplication::screenRemoved, this, &SessionLock::onScreensChanged);
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
if (this->lockTarget) {
|
||||||
|
this->manager->lock();
|
||||||
|
this->updateSurfaces(old);
|
||||||
|
} else {
|
||||||
|
this->setLocked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLock::updateSurfaces(SessionLock* old) {
|
||||||
|
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) {
|
||||||
|
qWarning() << "SessionLock.surface is null. Aborting lock.";
|
||||||
|
this->unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto* screen: screens) {
|
||||||
|
if (!this->surfaces.contains(screen)) {
|
||||||
|
auto* instanceObj = this->mSurfaceComponent->create(QQmlEngine::contextForObject(this));
|
||||||
|
auto* instance = qobject_cast<SessionLockSurface*>(instanceObj);
|
||||||
|
|
||||||
|
if (instance == nullptr) {
|
||||||
|
qWarning() << "SessionLock.surface does not create a SessionLockSurface. Aborting lock.";
|
||||||
|
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;
|
||||||
|
instance->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLock::unlock() {
|
||||||
|
if (this->isLocked()) {
|
||||||
|
this->lockTarget = false;
|
||||||
|
this->manager->unlock();
|
||||||
|
|
||||||
|
for (auto* surface: this->surfaces) {
|
||||||
|
surface->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->surfaces.clear();
|
||||||
|
|
||||||
|
emit this->lockStateChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLock::onScreensChanged() { this->updateSurfaces(); }
|
||||||
|
|
||||||
|
bool SessionLock::isLocked() const {
|
||||||
|
return this->manager == nullptr ? this->lockTarget : this->manager->isLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SessionLock::isSecure() const {
|
||||||
|
return this->manager != nullptr && SessionLockManager::sessionLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLock::setLocked(bool locked) {
|
||||||
|
if (this->isLocked() == locked) return;
|
||||||
|
this->lockTarget = locked;
|
||||||
|
|
||||||
|
if (this->manager == nullptr) {
|
||||||
|
emit this->lockStateChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locked) {
|
||||||
|
this->manager->lock();
|
||||||
|
this->updateSurfaces();
|
||||||
|
if (this->lockTarget) emit this->lockStateChanged();
|
||||||
|
} else {
|
||||||
|
this->unlock(); // emits lockStateChanged
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlComponent* SessionLock::surfaceComponent() const { return this->mSurfaceComponent; }
|
||||||
|
|
||||||
|
void SessionLock::rip() {
|
||||||
|
if (this->isLocked()) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLock::setSurfaceComponent(QQmlComponent* surfaceComponent) {
|
||||||
|
if (this->mSurfaceComponent != nullptr) this->mSurfaceComponent->deleteLater();
|
||||||
|
if (surfaceComponent != nullptr) surfaceComponent->setParent(this);
|
||||||
|
|
||||||
|
this->mSurfaceComponent = surfaceComponent;
|
||||||
|
emit this->surfaceComponentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionLockSurface::SessionLockSurface(QObject* parent)
|
||||||
|
: Reloadable(parent)
|
||||||
|
, mContentItem(new QQuickItem())
|
||||||
|
, ext(new LockWindowExtension(this)) {
|
||||||
|
this->mContentItem->setParent(this);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
QObject::connect(this, &SessionLockSurface::widthChanged, this, &SessionLockSurface::onWidthChanged);
|
||||||
|
QObject::connect(this, &SessionLockSurface::heightChanged, this, &SessionLockSurface::onHeightChanged);
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionLockSurface::~SessionLockSurface() {
|
||||||
|
if (this->window != nullptr) {
|
||||||
|
this->window->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLockSurface::onReload(QObject* oldInstance) {
|
||||||
|
if (auto* old = qobject_cast<SessionLockSurface*>(oldInstance)) {
|
||||||
|
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
|
||||||
|
QObject::connect(this->window, &QWindow::visibilityChanged, this, &SessionLockSurface::visibleChanged);
|
||||||
|
QObject::connect(this->window, &QWindow::widthChanged, this, &SessionLockSurface::widthChanged);
|
||||||
|
QObject::connect(this->window, &QWindow::heightChanged, this, &SessionLockSurface::heightChanged);
|
||||||
|
QObject::connect(this->window, &QWindow::screenChanged, this, &SessionLockSurface::screenChanged);
|
||||||
|
QObject::connect(this->window, &QQuickWindow::colorChanged, this, &SessionLockSurface::colorChanged);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
if (auto* parent = qobject_cast<SessionLock*>(this->parent())) {
|
||||||
|
if (!this->ext->attach(window, parent->manager)) {
|
||||||
|
qWarning(
|
||||||
|
) << "Failed to attach LockWindowExtension to window. Surface will not behave correctly.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning(
|
||||||
|
) << "SessionLockSurface parent is not a SessionLock. Surface will not behave correctly.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// without this the dangling screen pointer wont be updated to a real screen
|
||||||
|
emit this->screenChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickWindow* SessionLockSurface::disownWindow() {
|
||||||
|
QObject::disconnect(this->window, nullptr, this, nullptr);
|
||||||
|
this->mContentItem->setParentItem(nullptr);
|
||||||
|
|
||||||
|
auto* window = this->window;
|
||||||
|
this->window = nullptr;
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLockSurface::show() { this->ext->setVisible(); }
|
||||||
|
|
||||||
|
QQuickItem* SessionLockSurface::contentItem() const { return this->mContentItem; }
|
||||||
|
|
||||||
|
bool SessionLockSurface::isVisible() const { return this->window->isVisible(); }
|
||||||
|
|
||||||
|
qint32 SessionLockSurface::width() const {
|
||||||
|
if (this->window == nullptr) return 0;
|
||||||
|
else return this->window->width();
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32 SessionLockSurface::height() const {
|
||||||
|
if (this->window == nullptr) return 0;
|
||||||
|
else return this->window->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickshellScreenInfo* SessionLockSurface::screen() const {
|
||||||
|
QScreen* qscreen = nullptr;
|
||||||
|
|
||||||
|
if (this->window == nullptr) {
|
||||||
|
if (this->mScreen != nullptr) qscreen = this->mScreen;
|
||||||
|
} else {
|
||||||
|
qscreen = this->window->screen();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new QuickshellScreenInfo(
|
||||||
|
const_cast<SessionLockSurface*>(this), // NOLINT
|
||||||
|
qscreen
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLockSurface::setScreen(QScreen* qscreen) {
|
||||||
|
if (this->mScreen != nullptr) {
|
||||||
|
QObject::disconnect(this->mScreen, nullptr, this, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qscreen != nullptr) {
|
||||||
|
QObject::connect(qscreen, &QObject::destroyed, this, &SessionLockSurface::onScreenDestroyed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->window == nullptr) {
|
||||||
|
this->mScreen = qscreen;
|
||||||
|
emit this->screenChanged();
|
||||||
|
} else this->window->setScreen(qscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLockSurface::onScreenDestroyed() { this->mScreen = nullptr; }
|
||||||
|
|
||||||
|
QColor SessionLockSurface::color() const {
|
||||||
|
if (this->window == nullptr) return this->mColor;
|
||||||
|
else return this->window->color();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLockSurface::setColor(QColor color) {
|
||||||
|
if (this->window == nullptr) {
|
||||||
|
this->mColor = color;
|
||||||
|
emit this->colorChanged();
|
||||||
|
} else this->window->setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlListProperty<QObject> SessionLockSurface::data() {
|
||||||
|
return this->mContentItem->property("data").value<QQmlListProperty<QObject>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionLockSurface::onWidthChanged() { this->mContentItem->setWidth(this->width()); }
|
||||||
|
void SessionLockSurface::onHeightChanged() { this->mContentItem->setHeight(this->height()); }
|
151
src/wayland/session_lock.hpp
Normal file
151
src/wayland/session_lock.hpp
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qcolor.h>
|
||||||
|
#include <qcontainerfwd.h>
|
||||||
|
#include <qguiapplication.h>
|
||||||
|
#include <qmap.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlcomponent.h>
|
||||||
|
#include <qqmlintegration.h>
|
||||||
|
#include <qquickitem.h>
|
||||||
|
#include <qquickwindow.h>
|
||||||
|
#include <qscreen.h>
|
||||||
|
#include <qtclasshelpermacros.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
|
||||||
|
#include "../core/doc.hpp"
|
||||||
|
#include "../core/qmlscreen.hpp"
|
||||||
|
#include "../core/reload.hpp"
|
||||||
|
#include "session_lock/session_lock.hpp"
|
||||||
|
|
||||||
|
class SessionLockSurface;
|
||||||
|
|
||||||
|
/// Note: Very untested. Do anything outside of the obvious use cases and you WILL red screen.
|
||||||
|
class SessionLock: public Reloadable {
|
||||||
|
Q_OBJECT;
|
||||||
|
// clang-format off
|
||||||
|
/// Note: only one SessionLock may be locked at a time.
|
||||||
|
Q_PROPERTY(bool locked READ isLocked WRITE setLocked NOTIFY lockStateChanged);
|
||||||
|
/// Returns the *compositor* lock state, which will only be set to true after all surfaces are in place.
|
||||||
|
Q_PROPERTY(bool secure READ isSecure NOTIFY secureStateChanged);
|
||||||
|
/// Component that will be instantiated for each screen. Must be a `SessionLockSurface`.
|
||||||
|
Q_PROPERTY(QQmlComponent* surface READ surfaceComponent WRITE setSurfaceComponent NOTIFY surfaceComponentChanged);
|
||||||
|
// clang-format on
|
||||||
|
QML_ELEMENT;
|
||||||
|
Q_CLASSINFO("DefaultProperty", "surface");
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SessionLock(QObject* parent = nullptr): Reloadable(parent) {}
|
||||||
|
|
||||||
|
void onReload(QObject* oldInstance) override;
|
||||||
|
|
||||||
|
[[nodiscard]] bool isLocked() const;
|
||||||
|
void setLocked(bool locked);
|
||||||
|
|
||||||
|
[[nodiscard]] bool isSecure() const;
|
||||||
|
|
||||||
|
[[nodiscard]] QQmlComponent* surfaceComponent() const;
|
||||||
|
void setSurfaceComponent(QQmlComponent* surfaceComponent);
|
||||||
|
|
||||||
|
QSDOC_HIDE Q_INVOKABLE void rip();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void lockStateChanged();
|
||||||
|
void secureStateChanged();
|
||||||
|
void surfaceComponentChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void unlock();
|
||||||
|
void onScreensChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateSurfaces(SessionLock* old = nullptr);
|
||||||
|
|
||||||
|
SessionLockManager* manager = nullptr;
|
||||||
|
QQmlComponent* mSurfaceComponent = nullptr;
|
||||||
|
QMap<QScreen*, SessionLockSurface*> surfaces;
|
||||||
|
bool lockTarget = false;
|
||||||
|
|
||||||
|
friend class SessionLockSurface;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SessionLockSurface: public Reloadable {
|
||||||
|
Q_OBJECT;
|
||||||
|
// clang-format off
|
||||||
|
Q_PROPERTY(QQuickItem* contentItem READ contentItem);
|
||||||
|
/// If the window has been presented yet.
|
||||||
|
Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged);
|
||||||
|
Q_PROPERTY(qint32 width READ width NOTIFY widthChanged);
|
||||||
|
Q_PROPERTY(qint32 height READ height NOTIFY heightChanged);
|
||||||
|
/// The screen that the window currently occupies.
|
||||||
|
///
|
||||||
|
/// > [!INFO] This cannot be changed after windowConnected.
|
||||||
|
Q_PROPERTY(QuickshellScreenInfo* screen READ screen NOTIFY screenChanged);
|
||||||
|
/// The background color of the window. Defaults to white.
|
||||||
|
///
|
||||||
|
/// > [!WARNING] This seems to behave weirdly when using transparent colors on some systems.
|
||||||
|
/// > Using a colored content item over a transparent window is the recommended way to work around this:
|
||||||
|
/// > ```qml
|
||||||
|
/// > ProxyWindow {
|
||||||
|
/// > Rectangle {
|
||||||
|
/// > anchors.fill: parent
|
||||||
|
/// > color: "#20ffffff"
|
||||||
|
/// >
|
||||||
|
/// > // your content here
|
||||||
|
/// > }
|
||||||
|
/// > }
|
||||||
|
/// > ```
|
||||||
|
/// > ... but you probably shouldn't make a transparent lock,
|
||||||
|
/// > and most compositors will ignore an attempt to do so.
|
||||||
|
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged);
|
||||||
|
Q_PROPERTY(QQmlListProperty<QObject> data READ data);
|
||||||
|
// clang-format on
|
||||||
|
QML_ELEMENT;
|
||||||
|
Q_CLASSINFO("DefaultProperty", "data");
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SessionLockSurface(QObject* parent = nullptr);
|
||||||
|
~SessionLockSurface() override;
|
||||||
|
Q_DISABLE_COPY_MOVE(SessionLockSurface);
|
||||||
|
|
||||||
|
void onReload(QObject* oldInstance) override;
|
||||||
|
QQuickWindow* disownWindow();
|
||||||
|
|
||||||
|
void show();
|
||||||
|
|
||||||
|
[[nodiscard]] QQuickItem* contentItem() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool isVisible() const;
|
||||||
|
|
||||||
|
[[nodiscard]] qint32 width() const;
|
||||||
|
[[nodiscard]] qint32 height() const;
|
||||||
|
|
||||||
|
[[nodiscard]] QuickshellScreenInfo* screen() const;
|
||||||
|
void setScreen(QScreen* qscreen);
|
||||||
|
|
||||||
|
[[nodiscard]] QColor color() const;
|
||||||
|
void setColor(QColor color);
|
||||||
|
|
||||||
|
[[nodiscard]] QQmlListProperty<QObject> data();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void visibleChanged();
|
||||||
|
void widthChanged();
|
||||||
|
void heightChanged();
|
||||||
|
void screenChanged();
|
||||||
|
void colorChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onScreenDestroyed();
|
||||||
|
void onWidthChanged();
|
||||||
|
void onHeightChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QQuickWindow* window = nullptr;
|
||||||
|
QQuickItem* mContentItem;
|
||||||
|
QScreen* mScreen = nullptr;
|
||||||
|
QColor mColor = Qt::white;
|
||||||
|
LockWindowExtension* ext;
|
||||||
|
};
|
|
@ -17,10 +17,10 @@ QSWaylandSessionLock::~QSWaylandSessionLock() { this->unlock(); }
|
||||||
|
|
||||||
void QSWaylandSessionLock::unlock() {
|
void QSWaylandSessionLock::unlock() {
|
||||||
if (this->isInitialized()) {
|
if (this->isInitialized()) {
|
||||||
if (this->locked) this->unlock_and_destroy();
|
if (this->finished) this->destroy();
|
||||||
else this->destroy();
|
else this->unlock_and_destroy();
|
||||||
|
|
||||||
this->locked = false;
|
this->secure = false;
|
||||||
this->manager->active = nullptr;
|
this->manager->active = nullptr;
|
||||||
|
|
||||||
emit this->unlocked();
|
emit this->unlocked();
|
||||||
|
@ -29,14 +29,15 @@ void QSWaylandSessionLock::unlock() {
|
||||||
|
|
||||||
bool QSWaylandSessionLock::active() const { return this->isInitialized(); }
|
bool QSWaylandSessionLock::active() const { return this->isInitialized(); }
|
||||||
|
|
||||||
bool QSWaylandSessionLock::hasCompositorLock() const { return this->locked; }
|
bool QSWaylandSessionLock::hasCompositorLock() const { return this->secure; }
|
||||||
|
|
||||||
void QSWaylandSessionLock::ext_session_lock_v1_locked() {
|
void QSWaylandSessionLock::ext_session_lock_v1_locked() {
|
||||||
this->locked = true;
|
this->secure = true;
|
||||||
emit this->compositorLocked();
|
emit this->compositorLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSWaylandSessionLock::ext_session_lock_v1_finished() {
|
void QSWaylandSessionLock::ext_session_lock_v1_finished() {
|
||||||
this->locked = false;
|
this->secure = false;
|
||||||
|
this->finished = true;
|
||||||
this->unlock();
|
this->unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,5 +34,6 @@ private:
|
||||||
QSWaylandSessionLockManager* manager; // static and not dealloc'd
|
QSWaylandSessionLockManager* manager; // static and not dealloc'd
|
||||||
|
|
||||||
// true when the compositor determines the session is locked
|
// true when the compositor determines the session is locked
|
||||||
bool locked = false;
|
bool secure = false;
|
||||||
|
bool finished = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ static QSWaylandSessionLockManager* manager() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionLockManager::lock() {
|
bool SessionLockManager::lock() {
|
||||||
if (SessionLockManager::sessionLocked()) return false;
|
if (this->isLocked() || SessionLockManager::sessionLocked()) return false;
|
||||||
this->mLock = manager()->acquireLock();
|
this->mLock = manager()->acquireLock();
|
||||||
this->mLock->setParent(this);
|
this->mLock->setParent(this);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ class SessionLockManager: public QObject {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SessionLockManager(QObject* parent = nullptr): QObject(parent) {}
|
explicit SessionLockManager(QObject* parent = nullptr): QObject(parent) {}
|
||||||
Q_DISABLE_COPY_MOVE(SessionLockManager);
|
Q_DISABLE_COPY_MOVE(SessionLockManager);
|
||||||
|
|
||||||
// Returns true if a lock was acquired.
|
// Returns true if a lock was acquired.
|
||||||
|
@ -57,7 +57,7 @@ class LockWindowExtension: public QObject {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LockWindowExtension(QObject* parent = nullptr): QObject(parent) {}
|
explicit LockWindowExtension(QObject* parent = nullptr): QObject(parent) {}
|
||||||
~LockWindowExtension() override;
|
~LockWindowExtension() override;
|
||||||
|
|
||||||
// Attach this lock extension to the given window.
|
// Attach this lock extension to the given window.
|
||||||
|
|
|
@ -40,7 +40,10 @@ QSWaylandSessionLockSurface::QSWaylandSessionLockSurface(QtWaylandClient::QWayla
|
||||||
this->init(this->ext->lock->get_lock_surface(window->waylandSurface()->object(), output));
|
this->init(this->ext->lock->get_lock_surface(window->waylandSurface()->object(), output));
|
||||||
}
|
}
|
||||||
|
|
||||||
QSWaylandSessionLockSurface::~QSWaylandSessionLockSurface() { this->destroy(); }
|
QSWaylandSessionLockSurface::~QSWaylandSessionLockSurface() {
|
||||||
|
if (this->ext != nullptr) this->ext->surface = nullptr;
|
||||||
|
this->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
bool QSWaylandSessionLockSurface::isExposed() const { return this->configured; }
|
bool QSWaylandSessionLockSurface::isExposed() const { return this->configured; }
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ bool QSWaylandSessionLockSurface::handleExpose(const QRegion& region) {
|
||||||
|
|
||||||
void QSWaylandSessionLockSurface::setExtension(LockWindowExtension* ext) {
|
void QSWaylandSessionLockSurface::setExtension(LockWindowExtension* ext) {
|
||||||
if (ext == nullptr) {
|
if (ext == nullptr) {
|
||||||
this->window()->window()->close();
|
if (this->window() != nullptr) this->window()->window()->close();
|
||||||
} else {
|
} else {
|
||||||
if (this->ext != nullptr) {
|
if (this->ext != nullptr) {
|
||||||
this->ext->surface = nullptr;
|
this->ext->surface = nullptr;
|
||||||
|
|
Loading…
Reference in a new issue