forked from quickshell/quickshell
feat(slock): add user facing SessionLock and SessionLockSurface
This commit is contained in:
parent
1fa87b7c5a
commit
48bdcf4db2
10 changed files with 458 additions and 14 deletions
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;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue