From a64b477deaba210102bae11bcf054d973803d3f3 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 18 Jun 2024 17:14:51 -0700 Subject: [PATCH] lockscreen: replace lockscreen example The new one uses the pam module and looks much nicer. --- lockscreen/AuthContext.qml | 43 --------------- lockscreen/LockContext.qml | 54 ++++++++++++++++++ lockscreen/LockSurface.qml | 104 +++++++++++++++++++++++++++++++++++ lockscreen/Lockscreen.qml | 52 ------------------ lockscreen/README.md | 4 +- lockscreen/image.png | Bin 22081 -> 21411 bytes lockscreen/pam/password.conf | 1 + lockscreen/shell.qml | 37 +++++-------- lockscreen/test.qml | 21 ++++--- 9 files changed, 190 insertions(+), 126 deletions(-) delete mode 100644 lockscreen/AuthContext.qml create mode 100644 lockscreen/LockContext.qml create mode 100644 lockscreen/LockSurface.qml delete mode 100644 lockscreen/Lockscreen.qml create mode 100644 lockscreen/pam/password.conf diff --git a/lockscreen/AuthContext.qml b/lockscreen/AuthContext.qml deleted file mode 100644 index f5c5745..0000000 --- a/lockscreen/AuthContext.qml +++ /dev/null @@ -1,43 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Io - -QtObject { - property int status: AuthContext.Status.FirstLogin - signal unlocked(); - - enum Status { - FirstLogin, - Authenticating, - LoginFailed - } - - property string password - - property var pamtester: Process { - property bool failed: true - - command: ["pamtester", "login", Quickshell.env("USER"), "authenticate"] - - onStarted: this.write(`${password}\n`) - - stdout: SplitParser { - // fails go to stderr - onRead: pamtester.failed = false - } - - onExited: { - if (failed) { - status = AuthContext.Status.LoginFailed; - } else { - unlocked(); - } - } - } - - function tryLogin(password: string) { - this.password = password - status = AuthContext.Status.Authenticating; - pamtester.running = true; - } -} diff --git a/lockscreen/LockContext.qml b/lockscreen/LockContext.qml new file mode 100644 index 0000000..73cdb5b --- /dev/null +++ b/lockscreen/LockContext.qml @@ -0,0 +1,54 @@ +import QtQuick +import Quickshell +import Quickshell.Services.Pam + +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; + } + } +} diff --git a/lockscreen/LockSurface.qml b/lockscreen/LockSurface.qml new file mode 100644 index 0000000..08d107b --- /dev/null +++ b/lockscreen/LockSurface.qml @@ -0,0 +1,104 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls.Fusion +import Quickshell.Wayland + +Rectangle { + id: root + required property LockContext context + readonly property ColorGroup colors: Window.active ? palette.active : palette.inactive + + color: colors.window + + Button { + text: "Its not working, let me out" + onClicked: context.unlocked(); + } + + Label { + id: clock + property var date: new Date() + + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: 100 + } + + // The native font renderer tends to look nicer at large sizes. + renderType: Text.NativeRendering + font.pointSize: 80 + + // updates the clock every second + Timer { + running: true + repeat: true + interval: 1000 + + onTriggered: clock.date = new Date(); + } + + // updated when the date changes + text: { + const hours = this.date.getHours().toString().padStart(2, '0'); + const minutes = this.date.getMinutes().toString().padStart(2, '0'); + return `${hours}:${minutes}`; + } + } + + ColumnLayout { + // Uncommenting this will make the password entry invisible except on the active monitor. + // visible: Window.active + + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.verticalCenter + } + + RowLayout { + TextField { + id: passwordBox + + implicitWidth: 400 + padding: 10 + + 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 { + target: root.context + + function onCurrentTextChanged() { + passwordBox.text = root.context.currentText; + } + } + } + + Button { + text: "Unlock" + padding: 10 + + // don't steal focus from the text box + focusPolicy: Qt.NoFocus + + enabled: !root.context.unlockInProgress && root.context.currentText !== ""; + onClicked: root.context.tryUnlock(); + } + } + + Label { + visible: root.context.showFailure + text: "Incorrect password" + } + } +} diff --git a/lockscreen/Lockscreen.qml b/lockscreen/Lockscreen.qml deleted file mode 100644 index 83f58b2..0000000 --- a/lockscreen/Lockscreen.qml +++ /dev/null @@ -1,52 +0,0 @@ -import QtQuick -import QtQuick.Controls.Basic - -Item { - required property AuthContext context - - Item { - anchors.centerIn: parent - - TextField { - id: entryBox - anchors.centerIn: parent - width: 600 - font.pointSize: 24 - - enabled: context.status != AuthContext.Status.Authenticating - focus: true - horizontalAlignment: TextInput.AlignHCenter - echoMode: TextInput.Password - inputMethodHints: Qt.ImhSensitiveData - placeholderText: "Enter password" - - onAccepted: { - if (text != "") context.tryLogin(text) - } - - onEnabledChanged: { - if (enabled) text = "" - } - } - - Text { - id: status - color: "white" - font.pointSize: 24 - - anchors { - horizontalCenter: entryBox.horizontalCenter - top: entryBox.bottom - topMargin: 40 - } - - text: { - switch (context.status) { - case AuthContext.Status.FirstLogin: return "" - case AuthContext.Status.Authenticating: return "Authenticating" - case AuthContext.Status.LoginFailed: return "Login Failed" - } - } - } - } -} diff --git a/lockscreen/README.md b/lockscreen/README.md index 9a1f1b0..1926b9b 100644 --- a/lockscreen/README.md +++ b/lockscreen/README.md @@ -1,7 +1,7 @@ # Lockscreen -This is a barebones lockscreen with a password input box. -Note that you MUST have `pamtester` installed or you won't be able to log in. +This is a simple but functional lockscreen that follows the system color scheme. +The only authentication method it supports is a password. You can run the lockscreen with `quickshell -p shell.qml`. diff --git a/lockscreen/image.png b/lockscreen/image.png index 956c8aac5bc2bfd1af34a1fc74d45ea3dd008fc2..f9d25d3a579825277cf0efd160802abe4edd8148 100644 GIT binary patch literal 21411 zcmeAS@N?(olHy`uVBq!ia0y~yU~gbxV6os}VqjoM-xwysz!03}>EaktaqG>UpXF1( zHvahd(|g(Szhzdo!Rf2k=H_O*d!E?0UWc=h#py=seV3c!fjU}TT3wqs7Cq`>;_B$= z2oSiL+TNn7qB7xW+Qasfds`Y<^Y-5FO8T|y`Paj>+s<#UnfKxF?}B&x{~p(W|KsHO zx{vSe|62ZeQ1|Qe|36P<%l}>f|A&o%fq@}|{oh-4``@l1IYD)ag^uTielR{Q(cSU7 zy#CKm{racpg+PjKc{cp}KL4N1diTOAzqlGNu|EMqmy3#af9vS-{Zaq_XZ$}MMg|6k z1%FvyG%XThoFX5SmRDC2Gl_v0r2DOwL%H@F+39mQ?br0ov0;<~3Eqlt(ChO)*B~F} z<`)hXif%afK2T=%6vytKM;8yf^=X{gcW~K`bIff$QsxU*d|tb+ZAqSUTc6ZzYyIEx zZyzpC=e__k>cT&!lJAdh9QiV#=Ux5ZFDE*4i+`uFicjWd_nBo`>9haJwYB#rFPX>h zH_xuvW&NES@4xTS-5&qr&AeZyc!jO+CS=#VXWh;G{F={+-B+hiH2QS+(z4|BJg5F0 zw@&Amuq}OdZf3o?a@r0PNkptS|PwJ8IbZQc?2mynB(-79X7M zuX&JE^uKa<_W3#s)6J!?zpE5}c+C~f+dEj>4~!=L$av%Pr!`*{8AiNc$M zjEdLSUfFnZ=SuUL(=Q0Wo-^mu+UMrln{N9^{`>av*yMbk_a$#nZ8>v}$pjQ>TedUY z-MS$Cc*~UuTmD>Qn0wJM^#ixHfA}>s)0j0D#ouze|7y#5`Fi-u8sy)7xN4U}ZS3jg z`?fv0&_0(wB*}-fXctw|&MO!SgjWOSCQs zaG01}nfksaJMH_H2fwCV%$HxcE_cV3h~UV3MVCGm{}#8M@b&D$;&vVDg0%OS7#IGv zR{J(<>&q`cPsN_!8dF@5U3EUae2V<)%;~3TON@VbPQOopbTSx|eGo zm(-U0eQ7-3&OGkDgTXm-FVn`uSq{Qg^$mtTV#d{PWglTkhJp?aSny&B3?yj5glh(0cn+mbBEX z*IDP}<4mi6ao;{CQ&}G5c8GW0)%%`OAN@2O(&Hqx@*ixL<_o*V%Jj9d?N{;du(L1b z%I^Ai{Mz);t0rdG!{=vL2Be>#`|nNXqZ#|(@5m$0w?+IZ^LwAVZ#vNh>h z=XY$eGrpHEX=I|`e%(j+%#JFLV-4>2ZdY$JE7|7o^&#*1@8|cuT&gDG7rpPX&*|80 zHg|u$dOUxRft9x5)?Bf3GSQY+uV1a9>?8_El&G8nc0g??7Qrh)eF3He$BYv z$9^t1)@0cdjpg2n+b0=b7T2E}GokG1ht)~mVsG;;$}|2iTo-{E&&ykJ z({jIt<`(By2hz8No5$Yx{c6g=yIj9`>z_@&r>5D@y*poS+_}n0tAXv)lEPtNX5my^s4AP?l8ie@2}CJH9#5w)?zaNL8J?RkiWchlPi$?^UKm z{C~IC?R;FcREEW;Q_MFPuASL>{>_dHF<+l*2X}q0E|LCpg`Iuhz4|TR-n=>~dEIu! zYgOL*N?PpAbDDmoFY|6SPt~i(#b0+% zvx&K+ZsF(}Tf9zMxBk$su33-U`QFt1znI9pOT2&f_MbVAf6BgJd;9m*+x|RyFK-v0 zX*!!OeJ+3AT~);`^+oq@Mr*x3pBHab8sS)Xe$ht#Je$z)olj@Vd7AIKa)l?S&qz>&1_niYqIN_pRZTnGrupF2?7Lb$R*Qo2HX5 zM{i%|QeOS3yIWM=_f&UYbg{6ZD))DDld1dc|DD>n@~409{)o+gKQ=u`y4Aee&vbsY z_0HQ<|8D-Zw@4#k|M#8u4t_pn|KZlfW1Gy|((jl2`Ezr&e#{M<)f=8xzq-NiH?{uT zt#OT1^~Je`M;Arj)-#)b+d@@; z>(?84{WUR?H-0DmzcKCo%j7uwixC??Ui1s^^Of21=5?F*Q~9{hD*1YbA`8U%&v4A! z@;f+M@5-Aw_67^z8hw(x8xXj?IL`AluiJB9&+u z^P;GOm#wp3?XRm$xV^0Dq_ozo)7NdMNZ*MP;kmHdJ$>8T`NldT3#!}al^vQOdR*FH zPySbLVz5#1VwMb0sh*L~xGOraB*yE+REE3OwmW8AD1Wyupds(>ETOqpU!MLg{hGeN z>iNx=&0U|GLQUQsORCbpb3b5fVpQGjSywi$K5rrub76Vvlb%Vg?b7G!t#)3%`u8!r zp8chezb}T$AjO1~bMlbNkO%WsXu+$*2%PA;wRhUQ|eQBbwO7*{9oFbyM3B%ZE)z@ zbLzX6yB$yEuX~*0{Bl?1V)uBvyB7qL+w8VH`21OXyG>lh-xH6ohqCbLzMfrEn)+>v z|9NxS_-_uUnfDD~nuD4e2et!M!ch$r!K8r6zHuC$O6K7gh zN8c{tVSDlE`|;AO=*cEoPgk}%>wop_?>a5_>)Xm_m$loM#}|8Sw~WqywXbHGg_WMA zp2Pz0`x4Vi|859R`4(Sh67cKXgfr8$ZT?^V{5R?I{2zN>otWe}_qU#AO7kp^W^ruMO!xhIebC3w5}w%^zAiuuJw{;OQQ`O)Q!m4lFv{D6H+KeoXcFm)Jk0$w%9TcgNV;EPTJm zwlqD=-)Hwr+1RNDZ{7wp`0@K4501ZPc5RMzXxXMOQA^qFXH2`fsrcKJfCjyn6_+pW z>WdE#{QUIJpC8)UMa$RQ$8Uf9GVWsdx05qIo&0%guKzcW%$q+KZWTRSIyLpaMR-Bx z<>0-G|JOY^G;MkG=Et)pHi!SacJkR~ZTXx^mzC3*zpUulw)UVWzf8;}Yt0=J_CI7gvQZM{SQ&wo~4m zaptl1{(TiIA3a`qchS1r3zI*dKFIJlA@BCAB@?y%O=W6U=0}C(M7?)yms)K<|K8JA z|2Ec&$!4th_hsUPfI{Z!?Mx-lz8>D@DY^Sq$>D>llb_|;)t9_n(6i!)U2*yR`#%p| zskGLc6K$`ny~Y35;q241Pv4W7SNiq98BX~*xmFvKLXu8@_glzdyZghe#L2tQ-i?jl zS$ArJy7`=S>u>B^5dZ6{v77i=ezq6wdiMkSk8g|PV0*DGSy-R_#e)+U?>@^}z4Er* z^7NA1*S2iTpK3Zkws^66<=krwclSSaR8950Te0uq>x8ZQAD)Yx?98~U{P^s?YpH*3 zbtS0v?cSvJ+^b>VCjab)ck^UKXPbUGd+AuPcKh=GkGp%ic$d9Bmb{+dXXh@X+DE^N z5B_JID=0cU$f7=e!JozKn{RC^ll%T~XIpc3wK|)4H1n4SJ=w>7{Lc4vLEH7UtS|h2 z+FBh^Yu&>3;(7J*HnD1(PnDrZ+azbMjb1}!fM`t2>Q#%#?@`@Z7Z+L;IMH>|sDygmHGo{M|M-f+%|wKUs)`0Tmci!Ptx4c%I8 zmaEVIum1ToQ_0%tGJ5y-eawHJz0LOK=T92~@6P-4$m#J%^W!S9mRiO?q%VlRR(sy+ zmce`BI?wDm_T}ZVPk*&s8=2Shc<*`W>>>R*EHdH0H*-?nuLZkoWVkL=7KUGY;u9~)CSyl%})vrK2#&o}$!&hY6yv-wq7`Zm0{ zD=2zp7TdDm$QWLJL+FS4cf1~xb_Uv;t2J0?Q zJ-j}P_d;^Ce!M_9Xf2g`@7b>4JF5aF6-VMr{~F+dv>lQ*9F^kl4hFq@7C?=`pTcq zDxUml`FfkE=)KRcE{ycl?G9`WXDTT;AJA~mKzZ}q8!e6t8ElOdx6Ck0d-}2M*eBWd zXXgHV@wnUmUVYB(Wwxg2VZI){nYLfmLw%Rulb&AlxAv&YG5%U@i3Pu7_jRAyr~h_s z=BgVTYo0Y6dS@Bi)z#)x`)jTLy%|%)??{DzxiM|kti##!t5dvAH%r~z{ke2;DIe>L z^iN6a*PNUu#&e;#$}RS$dTo)0gSblTyG1`Xp4XDnm#HZKHsjErraOP`)gHIq`et&! z-1~VY&6+1_3XX1ccyMKTvHSP4uRk6*68=5JJpRw8o&O4_$2T-t-qtgldwW|(&iqM- z950LI-P`^?nl!3iJLAzP5-7RKlxJav*>#3sJeyQmMz=% zwD{qfd*$+Pr(dXgWA5^O*8aa|CWfEgBE!z%HzRZ5M_I-Z5yryk%UD^4je=on^e;~4Q@3Z$dwd=l2KHg;&6F1qm z_H5^;;Ogo26Kc-p72b8zyH)kcskZimNoc$I9t#cYm8HSwdiwq5{i#Un&pzgJsy@m4 z=Etj#jn?0BUCz1wyrE4PdIq+B-ZoXf{`bMtEPQF_FZ1?TcdRMMq-&&KUA0~5q->db1i}mt*&&uyl_`7a>|9q?Bbvcid zTV?;%Z8`TiOwMlC$CK*}!>^_I{(KPe^4Rg}ZEt59)_uJg9GxZ_Q>oMG`gmGR;g_1+ z*cZXY`*N<|YCUYFdN+eh$oiRY#HOupoD?iNw?5}zKik^G^w}$x(s^I*?K}0Wt?k#Y zSHkmc>@#0=)h@Lb`_h#^_fgNm^ZWMy{Uq{!)_wDe&7CVFzq><+Z0<3Y9Q-RQtRyh` zilL^lqNb|WqQ!YjoMW&G&AY@npx7eCz$4D`$Rp zKh6mmC)&qUGQH{dBH2q;&@w@LShrB#a z?$Or@L!@M@^56GYSnNx_*lDb(_kAzEywQu?`SSy_m*4q+ z@2%heLmjK@kH7bE^8CM#?$`e+{&Dc{m*@X~p0Yy$V)>fPhmY3Y{udS;EL`Ul9cTQXg8`hnYtrlf-nLIEe`Qto zXiE6>{rjrF&ueRI%by?5`r@15f_k0z2eyA)9sl1mV3cBTXb@Yl|F?fp)UtAi1~vu|7FfXg;{A`$+uvI6VFslr zCKHARhQEvZ`)BTq^_ye!vzCj6>0y5Tox{RN^0I|BIXO9ZHkaT3_m@5I@Q)w1KkmxE zU%PT8XYqU8==b}c$Gtz$ui+qXUH7MZ?QKwL1_~v41v@h{vv+s5zyB(l?>EP2ZSeJ` z-S74-e|q4i|GA&nc`iIY=FjtgN0i)@@&{)87moMO|B-O@)p5D`u_1S!&#Qi)ZK<_> zfd@3ie%L)q4i3J&@9*#X5g)HD(Y$Q^T=dS@-S%la+GF4)cb zLRj5zUDV#RYw`16+}!>C>7zg8FgHbu%FmuP>)U(#4Uf)lSNETLQFZ@s-t5H;ca+D1e6v8x(a>oB|HtuJ z+1ZEhylLeYum9a{U;q5MuZL%S!ix?AqfOS8?4UpfVa8wXIe(65KD_+o)Af5hM4!+7 zdE@cJ^S>`0Itn+>q2Zt4@1p174=<-o|MQLsRH?z-bmh#P53!$KH?!woT*;aNPsw@b z8GkLEF5dcnQooIrcY_$nyC5vD{Q33$e+w5aQaY1sW@2)ux_%3Tt^+eTw~E``&7YU`(cK^->l!ao}ak*SRaaxKM&7;zk2m*>(1S;xW(%}|F*yT z>huhoQn%6@=Qp3<{{SA{EHC6IcLpzO&7XLB+Wu#(NU7l4)pd6tMyKRm&x->USYZ6o z&`9#;+(YdrnA!K4{RSmX5Pp<=L`<(vwWedvzY~ko;-RI4Lru?_x#jnRBP;FB)Uq-) z+TRz?{e}pJ6FjnZS~aaPTdR6kii08ngyogDeZ1`ZP&?)QK4zc247?1m2z_zm$g*Y2 z49r8r%3k$Zzc>2|vKNFOC8x}*s>=JpV)^~%^E11Vw8a1YwO!qB4o|WB*|TR0J6Ar7 zML5hSuyFo|zlEQlNBitTXxUgEzE6IieV@$V1)fMwDn7sW`_`C(8MjxiTet6ZdA-R? zki{VUC^<#Vf3BdN-M&pZJ0-;zoV9>Cc;nsbZ*BekmUBO!*};%|jFABn_a{=Gmhr~R zeSdd5eHS=g!m`#QRqw;okFPXNo0Z2H1ud=wlcHl~wOHKb-w|PWrQ%87OWzKDT_njxKL8_t~>&Wgk!W zf#eOSu9u;g^lJ+4e7TvnSqGdmAmMW4-v5Ns9}g^Yo@Ahir~LaeoliGh;@Pj&t5&_+ z^;-^AcGrMDkUzHIq^+P!CY(&uy6Gy2=we*ZRe%6m(P z?aRv*{?woSch64O_ytT)eJ4Zh@ww&Gr_SXn{OdT4&iGX4VE&QR80u6XnYBU7wTNNN}_ov-u zvM0aomwQZ{0v=A>b1!hd)mWs|#Ty{PC|doVRYa7#tIH!;@TG^~hD$6jRi}J-IJ475 zc+#0~Yo6DhTWu-+`qzOL>%(uVebuu6rmeSS0QVt4_JEqw43J?N1O;k$GeA0^$kaBF z2AEDzuZe*ib3h#h1_p4y7eS$#2IYYo!5}M9-H349f%>W29xr=({=U(J#mo%#(GRDu z{Lp<>R6qV?=GMnTK}nA%uiE<|v5o(lz7Dv#_pkEP^ZZPslA@ZwVw}8DOn-P=;};y# z4}K`VT03svBcULxlu}ufl8}QR4rS@oG)P9?J;eT6Tny~g|2E8aRuiu5@XZN|^2yENWojRRHxWK%uALzYjt*iR{jJA zUZ{!>^Z70~yQQX?-^ZWnreRx=80V62S zuXx93rMI+f_MSTBU@UcE=!xh!9zg)?feDZ7bQ$8uXvO6CbD|KHj zbD8avd1G1i!H$iO+rGZOwx+CT%Gvn2w|2yyS5!XUD}Bp+x98d=8k09>`Wjd9OPl89 zIMzLPGZk9wdo5?)&Ga8HHYT%uKb19Mnn0@2y0FuJf8E;D*}uJ*F;6PjC}er*^nZ)F zj*Ib~IK5)FO#IiBnwq_3vFts1GS<7|{ccBjUQ`o)mHvcBOGn0fRsQubQ=!E+_QI2- z%FamJq@9@|_%k+YiK@$NpS(F&lRYYmD$cJ-)BG5yCLBDg?44;zPU6E0?__7Iv@Y^d zTWWg#oV?w-f-e*9^tg2f)|ot-l)dfEwe%x94h1&v-kLi>K>X|RwWU9f=f*rd;dpcH z<;RPC|9yOHwxIa*E=9&&n;2|se_rhVeQ*E1nud3^*SnODvftmkay@jY_kTTeNl-Im zvE9FaSB`qu|JhlQbiKX&srf2_rr=pTwJ$!;KQHp%vhv}LZ?4;)E)C~6n5oM>KW6Xy zoS7#-@6WAEE}Cv7x+wQ-+4VgezCGA!H2FE-+UlRT`nGCK*>P*8`M!N0w|}nZ6BC#H z@oJ`F?q#i(_g~g+-}m+HMebC!^M5vdx|paNto`Ion{C>j{hwWCI_um0eSGORyUEH4 zJ;JlU?R`J_leg8**N3aC%-0AsO^y;f6a6oEr>gAzeHl@Hd$}sjm%d%0zVAkONSUX* znf{KY!Ed=Pnyo$D@_fJM?j?^-Oj>t-Md8yYp{CaH|6eUT9Ilt?^!f_d!`*)G&T^mD zfBEL#)c(G#c`=IV*WcGZuf8vLVJ`(l6g^r^R#Z*MN2`CHO(yNbhecKZj~t^C0aY@puxf?aGcu6*0B_j{|) zBdyCnzv=GVSUa;OZ1Ly2@iLn0az5SZ&-cxUTo!iyTy?_Tk6!BM-&Li$Og8$dv-iAk zw122s#mg_-{dsdfq_6GE4*77YJY7p#$8KX{-1}Xrvx+_+GOyQIRr2Y@tm@)ZC2w2I zgzayX@7r{;yM5aId7;a))l2uJzFaS^HG9v7`jfnGgZ|C&d25yYb)whx%6H4lk8Rf| zZYn-IuXuITrFYlc&Gmv;zy4C6<1Ola>)V}%FZR-3LV4TvZup$Dbh5gc-KEWbGk@JF zdDEmd-DG!muaWQ0t4qFr3){Nn-BAYzu$9Sm|NV;GwWNWXT!U=cdz%RO<{ZS;p`sG&)@%idpmn``kr0?4!kUWt`}od zUh@3*<+k!&HZejA_E#;4fBC&^|Fe_lzscB_KfJTE`1yI6d*9xzDUAKU=lQ$6>+ADw zzFVArPIRtqbV$js59|Epbx!cr*B-f(?J^U1Tcx(Hfe~(*NsrT#b zUU>C=I`8r8@}J-Bd!)tQ&95hS{mJ)Tvo3tu<Ob%P z=cN6oWzCj8KC@MQ^*o#1Z$G}9Zk^Mc$L|(>=_PNmb^N;xrB(K_wVs!6$J=FF)LvM9 zak|OUqfd()rTeSW?;p+Z-nH%G`%=>@k7lX1cP-Y<4B317>E6Fno(4|;a_PZoS+kXw zdrSkTg=~5I@y}^lGt>Nc%U*b&^88b~DeS&_nMkN@<)hOtBd6d0w!-?!)Ax(@SH69^ z-BwC$-&XTelj>q?d_Uj6e`d$7n@9K;>t?<`6xgdb|NGr%)6Or}effJj+tPTw_cP0D zOO;MdDzmw_``gn`_ue-0E?=yZd3jErsowPO_x$tvw=FTfY#jVgnyKV}(?eOS=PZ&H z=_(HU%~w|MT>pK}#y=h(8(qzxy5~Lft<1iEw7I%0C;sCfUEyOqlI7R6XZMTC#}~gp zaKF9%j1K38TJL=uFRxJFXBk*iblloltw+wF=v4Fkx4OG3GG6vH^{M`!RsHyO^|@G! z9nYTLKGy%jxZuf&ll*&rU2{IX>F|G(Jt_|OuUp$(D?M?=wc2m~y}ci{Db76DZ?9f6 zgUJNkGP-KyU_SH1#r)}u{#owG@VR?}^Tb*;eS5jm4L_z|Z@bblr{PZGt?SDd`^DY( z>ofm}$DKD;>BWIpP8Q!kce*#`wZhixkMGBJSXDloJu`A*u~Rm0)yw7Gf$IM2X5CUN z;wsx4$jvX}KG){g$&R6~aKNNgXm95&p!SP9KyPA1jolb%$H=FxC6_1?S=d*$X)%ENC z*StS5o8{!p&E|7^_bqwbU(&nBbHcRG5eFun%iFQu`H64St=c$_m`k#2m6j(g=dU!* z@SK15hQ%i}$Hj*7EP9zWPkftph)uTRj<~eXyzRQsg8y?F_7=Q9x+wOu`jm4ea{phQ zD|WY^ZMeay;a&CN>ficuk)_ug?wl^4YW#7hZ2I}U`ofUybNFs1%iXJZb*3-;*t5_Y ziKUEI`G5Yd<`a{R{QjfGuKwXcZfIV7%n+OZ<@SCz{-o($-}l*V2-8@0@koCki%;C2 ze>de;E?hn9{-#GM2cGU-jaNnQ0d+x*YYxFKe)!yj|$TzgSa zlGEGwKdcHorQg4tAu;*F&wXbdy{-OUUAy*i@}z1TsSopxFZDh?-8W09Yo+0X*7;1+ zzZ{(LYvBwl<$D$aJC>MpziLU6`t!Q^KGXCsN$JNq+v!T&j-$NksOHedAQ*@T&^y_rgWyuT?t?`B|0&eu7A?BB0C z{$l#KIrclh?Q4Aae%9_^M|RHD|Fb$+m0wwCL4VEHZ->sh`~CUw@k^6j{lkgzVz6F7 zLzcvX^;xygr!Q~ry3r|WZpMAIY)^i2z>eJ|PZodVb^2)8|Bi>Nd^+Dg+cka~JI{05 zv$gJi6d(68S~(>7g!J#`cb^`;Q!k$ETzY(8y+y{SKi7U63p??y|No}q!jqf%@3LgO z@(ZIsO!8Z|W2a|M((h_>F;>0IlUrYI)V#_6f2wNlD$(f0*Nf{@J)47)U-QiRFFx%{ z$oeBU*cRXCj=Qv-KcziswqMMz@M%*DOJiO~@8gKObZT~Voap_J?|2)%t#&=Rb&X&OfurxzYPpS^e}U zGu$TIS&Hpg^40j3dd$^N*Fu-;vF>v>Sn67nbIkTN)AW)zle48l|1;dp|FEIQ?`{*% zj>n%DAN_rQ{*>@{uWi%TSVYx4n0s=svUzcS)QX0efP6nOw_ES^ZYLL9narauU+8h6ZFp6x@lU-pTov`vyUwKT5Dzy z8h^uZeYTg++lA}d^)nxz;p;SfnS7r&?$Y$&=%dF?_Ssp4%Ky$untUO2ZC>pVxhAv){b<#gkjV*-B2oFi*ew@r2}s z$f-6x9u0PzJ{^3WrhmWw-IHt6)t|H3e>x5Cx(3KHmjs<-zRz~$(PrtiRF#&bOP}W7 zlD+W5udcBAbb!XPvV*JlvzY8#?46$>^6&m-?)#j(at<&2e%w{B^L9njg{`_>-*qLz zjLk|)Pp@>mzHP^kzn}jGB{>&Lmb1s+e)Q*?`zN7f=Z`n}^El&zmhZR`P_%w|Ijhdg zE8^R?@3t}vNq(@}@%lE4ZC~0>Jb!jo^6RixUz ze*U~OQ&a#`2iml~eM{Z8p zRQRxZznJ^k1)Dd6j1s>7XqSJ#i+;^zBPIEp;==dqUcGwZ9c8yO^ojECBq8hbG2&ZY z<^E+jJwD<7?dXyxXMdahnsiU@-|wGmO@G@8oBoae^Kt6Gt=?*{`D%4vO*;3!X4Ucc z;kw@V@oOVfvFv-CIm{|9kwx``52^-#90pykWL|ZO^_XqT9E0)TG2~OsRZt zesTJil%&Ha+`qL770ca{s`Y#?a!t2VZTU0%-LGrDsES_EnYkwP!>{v!)4$vet_|{1 zdo8-JS|P#HvUB3eA8x|-KXrdidUuX%>Yp83=j_tTx@x!Y(X?%<_IW2I%iZHI<$J4{ z?brIYU(ta-cm7q=hQBjhJ8}JZxBt7ClIy06+57fX-rH3BTu<)L zk8_TylVf-LRuzX|Y<0fBr|fvk#9H=VIos5G+4*OsFIoQacYa<|yh+8O{r|kl^~WE* z?>_gg?)SHObDQPs;Uh$=QXBY=E-9J$F*MY7&5sjZ*0P=I;B>-1OC5r}pd2x?mAvHPi0P(z~H^V{6|1zV5!{_|&*{yFSh^uV1(7@VvYK z-W-Tp>Mn9S>Cz+SP}O6XXUn~t8f7J!W&U;Z{Z(E)>igzh)m>R)wDI!Yc(>@Fw3?SG zUhkM+uZ{}(xL*GL4YPG6o810Qz8@C)MgL8#$-bjkmrgEa+rMY^D%H9FAAS|=^>$9F z`FoMOe$}eOVsC589Dd2?+nDSv`}j|5`j)2;<4V2MCr97k^QK^`_ph|D?X#9nUMZVi z6M0ost*d|CE?eWRC7aT&?|i-b*Md`zoaf)WVYaelli&H{tK%;1`+nTqUt{hX`v*s3 zT|@O=_CD-=r0;*sRPLkO6xF>K_Q$=PY<#8Y5PRUXFA?XXmQLn;tFGU>X^G{{`kJVO zqUF~6S9~&(aS!)@KOx3y=CtbjyH-u#^5xmJ&a2Dq+_^6>w{JWD=2v*imtFrJ`j^XD zg@%;q{aOCv$v@rhwEp+Mjyr5Wx&E!qj-RcsH~stJ^>45D_xJIJ=@o8Io;{HCuK)LO z^Ua@2|KBQoqwHNKXIuR*=Eprh**lv)tP7m`@6Y~SrSpG$x%9qoj;5AX@v}EGh1s|1 z&9mJQ{NuHA`r13c4rw`_>JZ@IdDt-$+pHTyHX+_H9_ywS$mUswF(R7H4A*7K&$wUbW!9y68x z`{vnWQ8oXZ%0!>bpE`B-eKlR5XJ486YdM zc`NRucs;)@{y${l)cN)we(v3yb!_VFH509iU+(Mj{*`)i?%kl%Z;khr{rkIGD?TVJ zXy?h6FOL1Se{Z*PdH>4$xAm>?DPJ{HxsP{_C5ukq^0n1)tG zNGp7*cKKG^|8MKMysiFRZT>4A7n`>!?b(&1_F!+=?oX$xDhRpOjt4Z9iFS$@|0Ea_?>{EWDEv^?bJdiW1MwyRY}^ zn@4Jw-&#IZFVn4T?I-)Z($DE@*X&rb*?y1x*5s(ItIh{9mCSE+zLlExU)t(v*{PRT zcV_$ju7AB->$<7(?)2$-J0(MTQc}LZm^69z#IO7R_is838zBy;WiC1Sa&_9_RC~)#S9I$lq!l<=e z%WQu?oTa<_+nam)-d(=_Or&h3eE7?hnz?1lY5RVBytQ`s_cy=F-X7P#Ypk?6FX!px zm$Jw2d_Q%m^mf_%pLwrm@z0+hcwybQt5f~dOx_qhZ2WopT0Xyj-p@~em*>B~zsl|D zbRCbZImLGmbBE{L*_eL*obPIJ+q&ZSX_-^~)y&^p{`^=TmdoY;?#7OyhlkCdnEI_O znIFD%+bip@FTd}*v8VX_ytmTR^eYmQ%9@{?QqSHZUGe;L_x@W#anHAv&fjZQT@$wV zh?n~Mbyo{t#Omw*{B`?-)&AJuC%ui`)329X3wvwFa0rdOZxF&=kM?N ze`` z%+-}?PsP3b)=V{hHZOeIy1QbP=hpswaWwO=)si-?xjw5V|6PCcvpv6l=J$1L9w z-(S^P_(^{ImSumJ*?qhxK3mB?Pujk|_@3#`UZ;&$*V_Hx&vW6w4{X%H&Vl*QU#2e& zif^sb!mHu400Ijb{~c!BwIKJn-qkpG6~dCi0A5A}nu=$X`th9o#h-tyxmG3Xa7|(~ zz?N_|Fz|9*n9BCz-e0!u=U#-og%3|UG_VPPmOp}KR0I|`-xgEKH_HO_$H2Cp6(>gEe-ydCOJ1d3{+u@T*Q|E+P z>nW<5*{!_AEuZ!y;qM_P&~PefA`Ikx#L^=H@UC<41QJ+qEl3I2Xb=N5e~4Iu1l5U3 zp&I~R0|5$;(N$8Yp#Ykm8VytQP`D)q3KK;711BG7nnDdfC=cBL@S!?rX&ahCp~j$6 zP-9T3QA5G8Fs!mWOGY%ZZw<&8!-IBbShgrnwjC=VLns1&8KFR);=ngpdE)Z_!@ zK?`403K|=z6l$bEd6dQt)EHE1s2j>ST1|q|8*1`_@=#+M${Xqtj+%R*JgA3JDX520 zDH6OtNUF(y%Vn+AK#f0%EBn7jy%F+JY=CZxfNsl%^iv#Acmj}p+zJpmD31etAQJ;B zkHrL(ei)!~P#zPs?Ff;B@)*HKH!`5`piW_c$U%8fr=aqnPJzlnc~GaI@}N$E%0YQh nhoSPIPJzlnc@U@IbLIgx;nr^)!iI?(KwkHB^>bP0l+XkKcFT16 literal 22081 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 diff --git a/lockscreen/pam/password.conf b/lockscreen/pam/password.conf new file mode 100644 index 0000000..7e5d75a --- /dev/null +++ b/lockscreen/pam/password.conf @@ -0,0 +1 @@ +auth required pam_unix.so diff --git a/lockscreen/shell.qml b/lockscreen/shell.qml index c873c68..c1e9b1e 100644 --- a/lockscreen/shell.qml +++ b/lockscreen/shell.qml @@ -1,38 +1,31 @@ -import QtQuick -import QtQuick.Controls.Basic import Quickshell import Quickshell.Wayland ShellRoot { - AuthContext { - id: authContext - onUnlocked: lock.locked = false + // 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; + + Qt.quit(); + } } WlSessionLock { id: lock + + // Lock the session immediately when quickshell starts. locked: true - onLockedChanged: { - if (!locked) Qt.quit(); - } - WlSessionLockSurface { - // You probably want to replace this with an image. - color: "#303030" - - // For your own sanity you should probably keep this - // while working on the lockscreen. - Button { - text: "Help! I misconfigured my lockscreen!" - onClicked: lock.locked = false - } - - Lockscreen { + LockSurface { anchors.fill: parent - context: authContext + context: lockContext } } } - } diff --git a/lockscreen/test.qml b/lockscreen/test.qml index 2917665..22dddb9 100644 --- a/lockscreen/test.qml +++ b/lockscreen/test.qml @@ -2,17 +2,24 @@ import QtQuick import Quickshell ShellRoot { - AuthContext { - id: authContext - onUnlocked: Qt.quit() + LockContext { + id: lockContext + onUnlocked: Qt.quit(); } FloatingWindow { - color: "#303030" - - Lockscreen { + LockSurface { anchors.fill: parent - context: authContext + context: lockContext + } + } + + // exit the example if the window closes + Connections { + target: Quickshell + + function onLastWindowClosed() { + Qt.quit(); } } }