1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-03 20:32:07 -04:00

fix(lock/greeter): sync auth files with master

This commit is contained in:
purian23
2026-03-26 11:37:17 -04:00
parent 799773c62b
commit 519a8357a1
8 changed files with 71 additions and 42 deletions

View File

@@ -1,7 +1,5 @@
import QtQuick
import Quickshell
import Quickshell.Services.Greetd
import qs.Common
import qs.Modules.Greetd
Scope {

View File

@@ -225,7 +225,13 @@ Item {
}
StyledText {
text: root.errorCount > 0 ? I18n.tr("%1 issue(s) found", "greeter doctor page error count").arg(root.errorCount) : I18n.tr("All checks passed", "greeter doctor page success")
text: {
if (root.errorCount === 0)
return I18n.tr("All checks passed", "greeter doctor page success");
return root.errorCount === 1
? I18n.tr("%1 issue found", "greeter doctor page error count").arg(root.errorCount)
: I18n.tr("%1 issues found", "greeter doctor page error count").arg(root.errorCount);
}
font.pixelSize: Theme.fontSizeMedium
color: root.errorCount > 0 ? Theme.error : Theme.surfaceVariantText
}

View File

@@ -230,19 +230,19 @@ Item {
function currentAuthMessage() {
if (GreeterState.pamState === "error")
return "Authentication error - try again";
return I18n.tr("Authentication error - try again");
if (GreeterState.pamState === "max")
return "Too many failed attempts - account may be locked";
return I18n.tr("Too many failed attempts - account may be locked");
if (GreeterState.pamState === "fail") {
if (passwordAttemptLimitHint > 0) {
const attempt = Math.max(1, Math.min(passwordFailureCount, passwordAttemptLimitHint));
const remaining = Math.max(passwordAttemptLimitHint - attempt, 0);
if (remaining > 0) {
return "Incorrect password - attempt " + attempt + " of " + passwordAttemptLimitHint + " (lockout may follow)";
return I18n.tr("Incorrect password - attempt %1 of %2 (lockout may follow)").arg(attempt).arg(passwordAttemptLimitHint);
}
return "Incorrect password - next failures may trigger account lockout";
return I18n.tr("Incorrect password - next failures may trigger account lockout");
}
return "Incorrect password";
return I18n.tr("Incorrect password");
}
return "";
}
@@ -767,7 +767,7 @@ Item {
property string fullTimeStr: {
const format = GreetdSettings.getEffectiveTimeFormat();
return systemClock.date.toLocaleTimeString(Qt.locale(), format);
return systemClock.date.toLocaleTimeString(I18n.locale(), format);
}
property var timeParts: fullTimeStr.split(':')
property string hours: timeParts[0] || ""
@@ -876,7 +876,7 @@ Item {
anchors.top: clockContainer.bottom
anchors.topMargin: 4
text: {
return systemClock.date.toLocaleDateString(Qt.locale(), GreetdSettings.getEffectiveLockDateFormat());
return systemClock.date.toLocaleDateString(I18n.locale(), GreetdSettings.getEffectiveLockDateFormat());
}
font.pixelSize: Theme.fontSizeXLarge
color: "white"
@@ -1012,15 +1012,15 @@ Item {
anchors.verticalCenter: parent.verticalCenter
text: {
if (GreeterState.unlocking) {
return "Logging in...";
return I18n.tr("Logging in...");
}
if (Greetd.state !== GreetdState.Inactive && !awaitingExternalAuth && !pendingPasswordResponse) {
return "Authenticating...";
return I18n.tr("Authenticating...");
}
if (GreeterState.showPasswordInput) {
return "Password...";
return I18n.tr("Password...");
}
return "Username...";
return I18n.tr("Username...");
}
color: (GreeterState.unlocking || (Greetd.state !== GreetdState.Inactive && !awaitingExternalAuth && !pendingPasswordResponse)) ? Theme.primary : Theme.outline
font.pixelSize: Theme.fontSizeMedium

View File

@@ -6,7 +6,7 @@ A greeter for [greetd](https://github.com/kennylevinsen/greetd) that follows the
- **Multi user**: Login with any system user
- **dms sync**: Sync settings with dms for consistent styling between shell and greeter
- **Multiple compositors**: Supports niri, Hyprland, Sway, or mangowc.
- **Multiple compositors**: The `dms-greeter` wrapper supports niri, Hyprland, sway, scroll, miracle-wm, labwc, and mangowc.
- **Custom PAM**: Supports custom PAM configuration in `/etc/pam.d/greetd`
- **Session Memory**: Remembers last selected session and user
- Can be disabled via `settings.json` keys: `greeterRememberLastSession` and `greeterRememberLastUser`
@@ -152,8 +152,8 @@ sudo chmod +x /usr/local/bin/dms-greeter
5. Create greeter cache directory with proper permissions:
```bash
sudo mkdir -p /var/cache/dms-greeter
sudo chown greeter:greeter /var/cache/dms-greeter
sudo chmod 750 /var/cache/dms-greeter
sudo chown <greeter-user>:<greeter-group> /var/cache/dms-greeter
sudo chmod 2770 /var/cache/dms-greeter
```
6. Edit or create `/etc/greetd/config.toml`:
@@ -163,7 +163,7 @@ vt = 1
[default_session]
user = "greeter"
# Change compositor to sway, hyprland, or mangowc if preferred
# Change compositor to another wrapper-supported compositor if preferred
command = "/usr/local/bin/dms-greeter --command niri"
```
@@ -238,9 +238,12 @@ DMS_RUN_GREETER=1 qs -p /path/to/dms
#### Compositor
You can configure compositor specific settings such as outputs/displays the same as you would in niri or Hyprland.
For current wrapper-based installs, the `dms-greeter` wrapper supports niri, hyprland, sway, scroll, miracle-wm, labwc, and mangowc.
Simply edit `/etc/greetd/dms-niri.kdl` or `/etc/greetd/dms-hypr.conf` to change compositor settings for the greeter
Only niri currently has a generated greeter config path managed by `dms greeter sync`.
- niri: `dms greeter sync` writes the generated greeter config to `/etc/greetd/niri/config.kdl`. Add local manual tweaks in `/etc/greetd/niri_overrides.kdl`.
- Other wrapper-supported compositors use the wrapper-generated config by default. If you need a custom compositor config, add `-C /path/to/config` to the `dms-greeter` command in `/etc/greetd/config.toml`.
#### Personalization
@@ -271,4 +274,4 @@ sudo ln -sf ~/.cache/DankMaterialShell/dms-colors.json /var/cache/dms-greeter/co
**Advanced:** You can override the configuration path with the `DMS_GREET_CFG_DIR` environment variable or the `--cache-dir` flag when using `dms-greeter`. The default is `/var/cache/dms-greeter`.
The cache directory should be owned by `greeter:greeter` with `770` permissions.
The cache directory should be owned by `<greeter-user>:<greeter-group>` with `2770` permissions. If the greeter user is not available yet, DMS falls back to `root:<greeter-group>`.

View File

@@ -214,18 +214,6 @@ export XDG_STATE_HOME="$CACHE_DIR/.local/state"
export XDG_DATA_HOME="$CACHE_DIR/.local/share"
export XDG_CACHE_HOME="$CACHE_DIR/.cache"
# Propagate correct XDG dirs into the systemd user session so socket-activated
# services (e.g. wireplumber) don't inherit HOME=/ from /etc/passwd.
if command -v systemctl >/dev/null 2>&1; then
systemctl --user set-environment \
HOME="$CACHE_DIR" \
XDG_STATE_HOME="$CACHE_DIR/.local/state" \
XDG_DATA_HOME="$CACHE_DIR/.local/share" \
XDG_CACHE_HOME="$CACHE_DIR/.cache" 2>/dev/null || true
if systemctl --user is-active --quiet wireplumber.service 2>/dev/null; then
systemctl --user restart wireplumber.service 2>/dev/null || true
fi
fi
# Keep greeter VT clean by default; callers can override via env or --debug.
if [[ -z "${RUST_LOG:-}" ]]; then

View File

@@ -365,9 +365,9 @@ Item {
visible: SettingsData.lockScreenShowDate
text: {
if (SettingsData.lockDateFormat && SettingsData.lockDateFormat.length > 0) {
return systemClock.date.toLocaleDateString(Qt.locale(), SettingsData.lockDateFormat);
return systemClock.date.toLocaleDateString(I18n.locale(), SettingsData.lockDateFormat);
}
return systemClock.date.toLocaleDateString(Qt.locale(), Locale.LongFormat);
return systemClock.date.toLocaleDateString(I18n.locale(), Locale.LongFormat);
}
font.pixelSize: Theme.fontSizeXLarge
color: "white"
@@ -719,14 +719,24 @@ Item {
anchors.centerIn: parent
name: {
if (pam.u2fPending)
return "passkey";
if (pam.fprint.tries >= SettingsData.maxFprintTries)
return "fingerprint_off";
if (pam.fprint.active)
return "fingerprint";
if (pam.u2f.active)
return "passkey";
return "lock";
}
size: 20
color: pam.fprint.tries >= SettingsData.maxFprintTries ? Theme.error : (passwordField.activeFocus ? Theme.primary : Theme.surfaceVariantText)
color: {
if (pam.fprint.tries >= SettingsData.maxFprintTries)
return Theme.error;
if (pam.u2fState !== "")
return Theme.tertiary;
return passwordField.activeFocus ? Theme.primary : Theme.surfaceVariantText;
}
opacity: pam.passwd.active ? 0 : 1
Behavior on opacity {
@@ -792,6 +802,11 @@ Item {
}
if (event.key === Qt.Key_Escape) {
if (pam.u2fPending) {
pam.cancelU2fPending();
event.accepted = true;
return;
}
clear();
}
@@ -856,6 +871,11 @@ Item {
if (root.unlocking) {
return "Unlocking...";
}
if (pam.u2fPending) {
if (pam.u2fState === "insert")
return "Insert your security key...";
return "Touch your security key...";
}
if (pam.passwd.active) {
return "Authenticating...";
}
@@ -930,7 +950,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
iconName: "keyboard"
buttonSize: 32
visible: !demoMode && !pam.passwd.active && !root.unlocking
visible: !demoMode && !pam.passwd.active && !root.unlocking && !pam.u2fPending
enabled: visible
onClicked: {
if (keyboardController.isKeyboardActive) {
@@ -1031,7 +1051,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
iconName: "keyboard_return"
buttonSize: 36
visible: (demoMode || (!pam.passwd.active && !root.unlocking))
visible: (demoMode || (!pam.passwd.active && !root.unlocking && !pam.u2fPending))
enabled: !demoMode
onClicked: {
if (!demoMode && !root.unlocking && !pam.u2fPending) {
@@ -1637,6 +1657,14 @@ Item {
root.passwordBuffer = "";
}
}
onU2fPendingChanged: {
if (u2fPending) {
passwordField.text = "";
root.passwordBuffer = "";
if (keyboardController.isKeyboardActive)
keyboardController.hide();
}
}
}
Connections {

View File

@@ -14,9 +14,12 @@ Scope {
readonly property alias passwd: passwd
readonly property alias fprint: fprint
readonly property alias u2f: u2f
property string lockMessage
property string state
property string fprintState
property string u2fState
property bool u2fPending: false
property string buffer
signal flashMsg
@@ -127,9 +130,8 @@ Scope {
onCompleted: res => {
if (res === PamResult.Success) {
if (!root.unlockInProgress) {
root.unlockInProgress = true;
fprint.abort();
root.unlockRequested();
root.proceedAfterPrimaryAuth();
}
return;
}
@@ -192,9 +194,8 @@ Scope {
if (res === PamResult.Success) {
if (!root.unlockInProgress) {
root.unlockInProgress = true;
passwd.abort();
root.unlockRequested();
root.proceedAfterPrimaryAuth();
}
return;
}
@@ -356,6 +357,8 @@ Scope {
SettingsData.refreshAuthAvailability();
root.state = "";
root.fprintState = "";
root.u2fState = "";
root.u2fPending = false;
root.lockMessage = "";
root.resetAuthFlows();
fprint.checkAvail();

View File

@@ -0,0 +1,3 @@
#%PAM-1.0
auth required pam_u2f.so cue nouserok timeout=10