Huge quickshell progress dump
Was requested
This commit is contained in:
parent
57d9f9a72e
commit
945793973e
42 changed files with 2140 additions and 142 deletions
149
modules/user/modules/quickshell/shell/lock/Controller.qml
Normal file
149
modules/user/modules/quickshell/shell/lock/Controller.qml
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
import ".."
|
||||
import "../.."
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
function init() {}
|
||||
|
||||
property bool locked: false;
|
||||
onLockedChanged: {
|
||||
if (locked) {
|
||||
lockContextLoader.active = true;
|
||||
lock.locked = true;
|
||||
} else {
|
||||
lockClearTimer.start();
|
||||
workspaceUnlockAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: lockClearTimer
|
||||
interval: 600
|
||||
onTriggered: {
|
||||
lock.locked = false;
|
||||
lockContextLoader.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
property var oldWorkspaces: ({});
|
||||
|
||||
function workspaceLockAnimation() {
|
||||
const focusedMonitor = Hyprland.focusedMonitor.id;
|
||||
|
||||
Hyprland.monitors.values.forEach(monitor => {
|
||||
if (monitor.activeWorkspace) {
|
||||
root.oldWorkspaces[monitor.id] = monitor.activeWorkspace.id;
|
||||
}
|
||||
|
||||
Hyprland.dispatch(`workspace name:lock_${monitor.name}`);
|
||||
});
|
||||
|
||||
Hyprland.dispatch(`focusmonitor ${focusedMonitor}`);
|
||||
}
|
||||
|
||||
function workspaceUnlockAnimation() {
|
||||
const focusedMonitor = Hyprland.focusedMonitor.id;
|
||||
|
||||
Hyprland.monitors.values.forEach(monitor => {
|
||||
const workspace = root.oldWorkspaces[monitor.id];
|
||||
if (workspace) Hyprland.dispatch(`workspace ${workspace}`);
|
||||
});
|
||||
|
||||
Hyprland.dispatch(`focusmonitor ${focusedMonitor}`);
|
||||
|
||||
root.oldWorkspaces = ({});
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
name: "lock"
|
||||
onPressed: {
|
||||
if (root.locked) root.locked = false;
|
||||
else root.locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: lockContextLoader
|
||||
|
||||
LockContext {
|
||||
onUnlocked: root.locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
WlSessionLock {
|
||||
id: lock
|
||||
|
||||
onSecureChanged: {
|
||||
if (secure) {
|
||||
Qt.callLater(() => root.workspaceLockAnimation());
|
||||
}
|
||||
}
|
||||
|
||||
WlSessionLockSurface {
|
||||
id: lockSurface
|
||||
color: "transparent"
|
||||
|
||||
// Ensure nothing spawns in the workspace behind the transparent lock
|
||||
// by filling in the background after animations complete.
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "gray"
|
||||
visible: backgroundImage.visible
|
||||
}
|
||||
|
||||
BackgroundImage {
|
||||
id: backgroundImage
|
||||
anchors.fill: parent
|
||||
screen: lockSurface.screen
|
||||
visible: !lockAnim.running
|
||||
asynchronous: true
|
||||
}
|
||||
|
||||
LockContent {
|
||||
id: lockContent
|
||||
context: lockContextLoader.item;
|
||||
|
||||
visible: false
|
||||
width: lockSurface.width
|
||||
height: lockSurface.height
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: lockAnim
|
||||
target: lockContent
|
||||
property: "y"
|
||||
to: 0
|
||||
duration: 600
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: [0.0, 0.75, 0.15, 1.0, 1.0, 1.0]
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
lockContent.y = -lockSurface.height
|
||||
console.log(`y ${lockContent.y}`)
|
||||
lockContent.visible = true;
|
||||
lockAnim.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
|
||||
function onLockedChanged() {
|
||||
if (!locked) {
|
||||
lockAnim.to = -lockSurface.height
|
||||
lockAnim.running = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
modules/user/modules/quickshell/shell/lock/LockButton.qml
Normal file
50
modules/user/modules/quickshell/shell/lock/LockButton.qml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import QtQuick
|
||||
import "root:."
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitHeight: 75
|
||||
implicitWidth: showProgress * 0.1
|
||||
|
||||
signal clicked();
|
||||
property string icon;
|
||||
property bool show: true;
|
||||
|
||||
property int showProgress: show ? 1000 : 0
|
||||
Behavior on showProgress {
|
||||
NumberAnimation {
|
||||
duration: 100
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
implicitWidth: 75
|
||||
implicitHeight: 75
|
||||
hoverEnabled: true
|
||||
|
||||
y: -(height + 30) * (1.0 - showProgress * 0.001)
|
||||
x: 12.5 - 50 * (1.0 - showProgress * 0.001)
|
||||
|
||||
Component.onCompleted: clicked.connect(root.clicked);
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 5
|
||||
color: ShellGlobals.interpolateColors(hoverColorInterp * 0.001, ShellGlobals.colors.widget, ShellGlobals.colors.widgetActive);
|
||||
border.width: 1
|
||||
border.color: ShellGlobals.colors.widgetOutline
|
||||
|
||||
property int hoverColorInterp: mouseArea.containsMouse || mouseArea.pressed ? 1000 : 0;
|
||||
Behavior on hoverColorInterp { SmoothedAnimation { velocity: 10000 } }
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 15
|
||||
|
||||
source: root.icon
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
modules/user/modules/quickshell/shell/lock/LockContent.qml
Normal file
113
modules/user/modules/quickshell/shell/lock/LockContent.qml
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import ".."
|
||||
|
||||
Item {
|
||||
id: root
|
||||
required property LockContext context;
|
||||
|
||||
property real focusAnim: focusAnimInternal * 0.001
|
||||
property int focusAnimInternal: Window.active ? 1000 : 0
|
||||
Behavior on focusAnimInternal { SmoothedAnimation { velocity: 5000 } }
|
||||
|
||||
Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: parent.height / 2 + textBox.height
|
||||
id: sep
|
||||
|
||||
implicitHeight: 6
|
||||
implicitWidth: 800
|
||||
radius: height / 2
|
||||
color: ShellGlobals.colors.widget
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
implicitWidth: sep.implicitWidth
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: sep.top
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
id: timeText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
font {
|
||||
pointSize: 120
|
||||
hintingPreference: Font.PreferFullHinting
|
||||
family: "Noto Sans"
|
||||
}
|
||||
|
||||
color: "white"
|
||||
renderType: Text.NativeRendering
|
||||
|
||||
text: {
|
||||
const hours = ShellGlobals.time.getHours().toString().padStart(2, '0');
|
||||
const minutes = ShellGlobals.time.getMinutes().toString().padStart(2, '0');
|
||||
return `${hours}:${minutes}`;
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitHeight: childrenRect.height * focusAnim
|
||||
implicitWidth: sep.implicitWidth
|
||||
clip: true
|
||||
|
||||
TextInput {
|
||||
id: textBox
|
||||
focus: true
|
||||
width: parent.width
|
||||
|
||||
color: enabled ?
|
||||
root.context.failed ? "#ffa0a0" : "white"
|
||||
: "#80ffffff";
|
||||
|
||||
font.pointSize: 24
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
echoMode: TextInput.Password
|
||||
inputMethodHints: Qt.ImhSensitiveData
|
||||
|
||||
onTextChanged: root.context.currentText = text;
|
||||
|
||||
Window.onActiveChanged: {
|
||||
if (Window.active) {
|
||||
text = root.context.currentText;
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
if (text != "") root.context.tryUnlock();
|
||||
}
|
||||
|
||||
enabled: !root.context.isUnlocking;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: sep.bottom
|
||||
implicitHeight: (childrenRect.height + 30) * focusAnim
|
||||
implicitWidth: sep.implicitWidth
|
||||
clip: true
|
||||
|
||||
RowLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: 50
|
||||
spacing: 0
|
||||
|
||||
LockButton {
|
||||
icon: "root:icons/monitor.svg"
|
||||
onClicked: root.context.dpms();
|
||||
}
|
||||
|
||||
LockButton {
|
||||
icon: "root:icons/pause.svg"
|
||||
show: context.mediaPlaying;
|
||||
onClicked: root.context.pauseMedia();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
modules/user/modules/quickshell/shell/lock/LockContext.qml
Normal file
57
modules/user/modules/quickshell/shell/lock/LockContext.qml
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Services.Mpris
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
signal unlocked();
|
||||
property string currentText: "";
|
||||
readonly property alias isUnlocking: pamtester.running;
|
||||
property bool failed: false;
|
||||
|
||||
onCurrentTextChanged: failed = false;
|
||||
|
||||
readonly property bool mediaPlaying: Mpris.players.values.some(player => {
|
||||
return player.playbackState === MprisPlaybackState.Playing && player.canPause;
|
||||
});
|
||||
|
||||
function pauseMedia() {
|
||||
Mpris.players.values.forEach(player => {
|
||||
if (player.playbackState === MprisPlaybackState.Playing && player.canPause) {
|
||||
player.playbackState = MprisPlaybackState.Paused;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dpms() {
|
||||
Hyprland.dispatch(`dpms`);
|
||||
}
|
||||
|
||||
Process {
|
||||
id: pamtester
|
||||
property bool failed: true
|
||||
|
||||
command: ["pamtester", "login", Quickshell.env("USER"), "authenticate"]
|
||||
|
||||
onStarted: this.write(`${currentText}\n`)
|
||||
|
||||
stdout: SplitParser {
|
||||
// fails go to stderr
|
||||
onRead: pamtester.failed = false
|
||||
}
|
||||
|
||||
onExited: {
|
||||
if (failed) {
|
||||
root.failed = true;
|
||||
} else {
|
||||
root.unlocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tryUnlock() {
|
||||
pamtester.running = true;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue