mirror of
https://github.com/belsabbagh/dotfiles.git
synced 2026-04-11 09:36:46 +00:00
quickshell and hyprland additions
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pam
|
||||
|
||||
// I just copied the default example and modified it. lol
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
signal unlocked()
|
||||
signal failed()
|
||||
|
||||
// These properties are in the context and not individual lock surfaces
|
||||
// so all surfaces can share the same state.
|
||||
property string currentText: ""
|
||||
property bool unlockInProgress: false
|
||||
property bool showFailure: false
|
||||
|
||||
// Clear the failure text once the user starts typing.
|
||||
onCurrentTextChanged: showFailure = false;
|
||||
|
||||
function tryUnlock() {
|
||||
if (currentText === "") return;
|
||||
|
||||
root.unlockInProgress = true;
|
||||
pam.start();
|
||||
}
|
||||
|
||||
PamContext {
|
||||
id: pam
|
||||
|
||||
// Its best to have a custom pam config for quickshell, as the system one
|
||||
// might not be what your interface expects, and break in some way.
|
||||
// This particular example only supports passwords.
|
||||
configDirectory: "pam"
|
||||
config: "password.conf"
|
||||
|
||||
// pam_unix will ask for a response for the password prompt
|
||||
onPamMessage: {
|
||||
if (this.responseRequired) {
|
||||
this.respond(root.currentText);
|
||||
}
|
||||
}
|
||||
|
||||
// pam_unix won't send any important messages so all we need is the completion status.
|
||||
onCompleted: result => {
|
||||
if (result == PamResult.Success) {
|
||||
root.unlocked();
|
||||
} else {
|
||||
root.currentText = "";
|
||||
root.showFailure = true;
|
||||
}
|
||||
|
||||
root.unlockInProgress = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
|
||||
Scope {
|
||||
// This stores all the information shared between the lock surfaces on each screen.
|
||||
LockContext {
|
||||
id: lockContext
|
||||
|
||||
onUnlocked: {
|
||||
// Unlock the screen before exiting, or the compositor will display a
|
||||
// fallback lock you can't interact with.
|
||||
lock.locked = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
WlSessionLock {
|
||||
id: lock
|
||||
|
||||
// Lock the session immediately when quickshell starts.
|
||||
locked: false
|
||||
|
||||
WlSessionLockSurface {
|
||||
LockSurface {
|
||||
anchors.fill: parent
|
||||
context: lockContext
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "lockscreen"
|
||||
function lock() {
|
||||
lock.locked = true;
|
||||
}
|
||||
function unlock() {
|
||||
lock.locked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
import "../../components/morphedPolygons/geometry/offset.js" as Offset
|
||||
import "../../components/morphedPolygons/material-shapes.js" as MaterialShapes // For polygons
|
||||
import "../../components/morphedPolygons/shapes/corner-rounding.js" as CornerRounding
|
||||
import QtQuick
|
||||
import QtQuick.Controls.Fusion
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Wayland
|
||||
import qs.config
|
||||
import qs.modules.functions
|
||||
import qs.modules.interface.background
|
||||
import qs.modules.components
|
||||
import qs.modules.components.morphedPolygons
|
||||
import qs.services
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
required property LockContext context
|
||||
|
||||
color: "transparent"
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
source: Config.runtime.appearance.background.path
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Metrics.spacing(20)
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
topMargin: Metrics.spacing(20)
|
||||
rightMargin: Metrics.spacing(30)
|
||||
}
|
||||
|
||||
MaterialSymbol {
|
||||
id: themeIcon
|
||||
|
||||
fill: 1
|
||||
icon: Config.runtime.appearance.theme === "light" ? "light_mode" : "dark_mode"
|
||||
iconSize: Metrics.fontSize("hugeass")
|
||||
}
|
||||
|
||||
MaterialSymbol {
|
||||
id: wifi
|
||||
|
||||
icon: Network.icon
|
||||
iconSize: Metrics.fontSize("hugeass")
|
||||
}
|
||||
|
||||
MaterialSymbol {
|
||||
id: btIcon
|
||||
|
||||
icon: Bluetooth.icon
|
||||
iconSize: Metrics.fontSize("hugeass")
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: keyboardLayoutIcon
|
||||
|
||||
text: SystemDetails.keyboardLayout
|
||||
font.pixelSize: Metrics.fontSize(Appearance.font.size.huge - 4)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
top: parent.top
|
||||
topMargin: Metrics.margin(150)
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: clock
|
||||
|
||||
visible: !Config.runtime.appearance.background.clock.isAnalog
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
animate: false
|
||||
renderType: Text.NativeRendering
|
||||
font.pixelSize: Metrics.fontSize(180)
|
||||
text: Time.format("hh:mm")
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: date
|
||||
|
||||
visible: !Config.runtime.appearance.background.clock.isAnalog
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
animate: false
|
||||
renderType: Text.NativeRendering
|
||||
font.pixelSize: Metrics.fontSize(50)
|
||||
text: Time.format("dddd, dd/MM")
|
||||
}
|
||||
|
||||
Item {
|
||||
id: analogClockContainer
|
||||
|
||||
property int hours: parseInt(Time.format("hh"))
|
||||
property int minutes: parseInt(Time.format("mm"))
|
||||
property int seconds: parseInt(Time.format("ss"))
|
||||
readonly property real cx: width / 2
|
||||
readonly property real cy: height / 2
|
||||
property var shapes: [MaterialShapes.getCookie7Sided, MaterialShapes.getCookie9Sided, MaterialShapes.getCookie12Sided, MaterialShapes.getPixelCircle, MaterialShapes.getCircle, MaterialShapes.getGhostish]
|
||||
|
||||
visible: Config.runtime.appearance.background.clock.isAnalog
|
||||
width: 350
|
||||
height: 350
|
||||
|
||||
// Polygon
|
||||
MorphedPolygon {
|
||||
id: shapeCanvas
|
||||
|
||||
anchors.fill: parent
|
||||
color: Appearance.m3colors.m3secondaryContainer
|
||||
roundedPolygon: analogClockContainer.shapes[Config.runtime.appearance.background.clock.shape]()
|
||||
}
|
||||
|
||||
ClockDial {
|
||||
anchors.fill: parent
|
||||
anchors.margins: parent.width * 0.12
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
z: 0
|
||||
}
|
||||
|
||||
// Hour hand
|
||||
StyledRect {
|
||||
z: 2
|
||||
width: 10
|
||||
height: parent.height * 0.3
|
||||
radius: Metrics.radius("full")
|
||||
color: Qt.darker(Appearance.m3colors.m3secondary, 0.8)
|
||||
x: analogClockContainer.cx - width / 2
|
||||
y: analogClockContainer.cy - height
|
||||
transformOrigin: Item.Bottom
|
||||
rotation: (analogClockContainer.hours % 12 + analogClockContainer.minutes / 60) * 30
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
anchors.centerIn: parent
|
||||
width: 16
|
||||
height: 16
|
||||
radius: width / 2
|
||||
color: Appearance.m3colors.m3secondary
|
||||
z: 99 // Ensures its on top of everthing
|
||||
|
||||
// Inner dot
|
||||
StyledRect {
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
radius: width / 2
|
||||
anchors.centerIn: parent
|
||||
z: 100
|
||||
color: Appearance.m3colors.m3primaryContainer
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Minute hand
|
||||
StyledRect {
|
||||
width: 14
|
||||
height: parent.height * 0.35
|
||||
radius: Metrics.radius("full")
|
||||
color: Appearance.m3colors.m3secondary
|
||||
x: analogClockContainer.cx - width / 2
|
||||
y: analogClockContainer.cy - height
|
||||
transformOrigin: Item.Bottom
|
||||
rotation: analogClockContainer.minutes * 6
|
||||
z: 10 // On top of all hands
|
||||
}
|
||||
|
||||
// Second hand
|
||||
StyledRect {
|
||||
visible: true
|
||||
width: 4
|
||||
height: parent.height * 0.28
|
||||
radius: Metrics.radius("full")
|
||||
color: Appearance.m3colors.m3error
|
||||
x: analogClockContainer.cx - width / 2
|
||||
y: analogClockContainer.cy - height
|
||||
transformOrigin: Item.Bottom
|
||||
rotation: analogClockContainer.seconds * 6
|
||||
z: 2
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: Time.format("hh")
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: Metrics.margin(60)
|
||||
font.pixelSize: Metrics.fontSize(100)
|
||||
font.bold: true
|
||||
opacity: 0.3
|
||||
animate: false
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: Time.format("mm")
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: Metrics.margin(150)
|
||||
font.pixelSize: Metrics.fontSize(100)
|
||||
font.bold: true
|
||||
opacity: 0.3
|
||||
animate: false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
// Commenting this will make the password entry visible on all monitors.
|
||||
visible: Window.active
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: Metrics.margin(20)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
StyledTextField {
|
||||
id: passwordBox
|
||||
|
||||
implicitWidth: 300
|
||||
padding: Metrics.padding(10)
|
||||
placeholder: root.context.showFailure ? "Incorrect Password" : "Enter Password"
|
||||
focus: true
|
||||
enabled: !root.context.unlockInProgress
|
||||
echoMode: TextInput.Password
|
||||
inputMethodHints: Qt.ImhSensitiveData
|
||||
// Update the text in the context when the text in the box changes.
|
||||
onTextChanged: root.context.currentText = this.text
|
||||
// Try to unlock when enter is pressed.
|
||||
onAccepted: root.context.tryUnlock()
|
||||
|
||||
// Update the text in the box to match the text in the context.
|
||||
// This makes sure multiple monitors have the same text.
|
||||
Connections {
|
||||
function onCurrentTextChanged() {
|
||||
passwordBox.text = root.context.currentText;
|
||||
}
|
||||
|
||||
target: root.context
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
StyledButton {
|
||||
icon: "chevron_right"
|
||||
padding: Metrics.padding(10)
|
||||
radius: Metrics.radius("unsharpenmore")
|
||||
// don't steal focus from the text box
|
||||
focusPolicy: Qt.NoFocus
|
||||
enabled: !root.context.unlockInProgress && root.context.currentText !== ""
|
||||
onClicked: root.context.tryUnlock()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
auth required pam_unix.so
|
||||
Reference in New Issue
Block a user