From 9070903512fcb35d008fd1038d6e7fa59a48b450 Mon Sep 17 00:00:00 2001 From: bbedward Date: Thu, 19 Mar 2026 20:02:46 -0400 Subject: [PATCH] cleanup settings tabs --- quickshell/Common/settings/Processes.qml | 4 - .../Modals/Settings/SettingsContent.qml | 15 - .../Modals/Settings/SettingsSidebar.qml | 6 - quickshell/Modules/Settings/GreeterTab.qml | 784 ------------------ quickshell/Modules/Settings/LockScreenTab.qml | 91 -- .../translations/settings_search_index.json | 79 +- 6 files changed, 57 insertions(+), 922 deletions(-) delete mode 100644 quickshell/Modules/Settings/GreeterTab.qml diff --git a/quickshell/Common/settings/Processes.qml b/quickshell/Common/settings/Processes.qml index a69d8e11..a80cf18c 100644 --- a/quickshell/Common/settings/Processes.qml +++ b/quickshell/Common/settings/Processes.qml @@ -57,10 +57,6 @@ Singleton { qtToolsDetectionProcess.running = true; } - function detectFprintd() { - fprintdDetectionProcess.running = true; - } - function detectAuthCapabilities() { if (!settingsRoot) return; diff --git a/quickshell/Modals/Settings/SettingsContent.qml b/quickshell/Modals/Settings/SettingsContent.qml index ddfc1293..107e0534 100644 --- a/quickshell/Modals/Settings/SettingsContent.qml +++ b/quickshell/Modals/Settings/SettingsContent.qml @@ -241,21 +241,6 @@ FocusScope { } } - Loader { - id: greeterLoader - anchors.fill: parent - active: root.currentIndex === 31 - visible: active - focus: active - - sourceComponent: GreeterTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - Loader { id: pluginsLoader anchors.fill: parent diff --git a/quickshell/Modals/Settings/SettingsSidebar.qml b/quickshell/Modals/Settings/SettingsSidebar.qml index 52854091..1b93b531 100644 --- a/quickshell/Modals/Settings/SettingsSidebar.qml +++ b/quickshell/Modals/Settings/SettingsSidebar.qml @@ -281,12 +281,6 @@ Rectangle { "icon": "lock", "tabIndex": 11 }, - { - "id": "greeter", - "text": I18n.tr("Greeter"), - "icon": "login", - "tabIndex": 31 - }, { "id": "power_sleep", "text": I18n.tr("Power & Sleep"), diff --git a/quickshell/Modules/Settings/GreeterTab.qml b/quickshell/Modules/Settings/GreeterTab.qml deleted file mode 100644 index c4cc84c0..00000000 --- a/quickshell/Modules/Settings/GreeterTab.qml +++ /dev/null @@ -1,784 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Layouts -import Quickshell -import Quickshell.Io -import qs.Common -import qs.Modals.Common -import qs.Modals.FileBrowser -import qs.Services -import qs.Widgets -import qs.Modules.Settings.Widgets - -Item { - id: root - - readonly property bool greeterFprintToggleAvailable: SettingsData.greeterFingerprintCanEnable || SettingsData.greeterEnableFprint - readonly property bool greeterU2fToggleAvailable: SettingsData.greeterU2fCanEnable || SettingsData.greeterEnableU2f - - function greeterFingerprintDescription() { - const source = SettingsData.greeterFingerprintSource; - const reason = SettingsData.greeterFingerprintReason; - - if (source === "pam") { - switch (reason) { - case "configured_externally": - return SettingsData.greeterEnableFprint ? I18n.tr("Enabled. PAM already provides fingerprint auth.") : I18n.tr("PAM already provides fingerprint auth. Enable this to show it at login."); - case "missing_enrollment": - return SettingsData.greeterEnableFprint ? I18n.tr("Enabled. PAM provides fingerprint auth, but no prints are enrolled yet.") : I18n.tr("PAM provides fingerprint auth, but no prints are enrolled yet."); - case "missing_reader": - return I18n.tr("PAM provides fingerprint auth, but no reader was detected."); - default: - return I18n.tr("PAM provides fingerprint auth, but availability could not be confirmed."); - } - } - - switch (reason) { - case "ready": - return SettingsData.greeterEnableFprint ? I18n.tr("Run Sync to apply. Fingerprint-only login may not unlock GNOME Keyring.") : I18n.tr("Only affects DMS-managed PAM. If greetd already includes pam_fprintd, fingerprint stays enabled."); - case "missing_enrollment": - if (SettingsData.greeterEnableFprint) - return I18n.tr("Enabled, but no prints are enrolled yet. Enroll fingerprints and run Sync."); - return I18n.tr("Fingerprint reader detected, but no prints are enrolled yet. You can enable this now and run Sync later."); - case "missing_reader": - return SettingsData.greeterEnableFprint ? I18n.tr("Enabled, but no fingerprint reader was detected.") : I18n.tr("No fingerprint reader detected."); - case "missing_pam_support": - return I18n.tr("Not available — install fprintd and pam_fprintd, or configure greetd PAM."); - default: - return SettingsData.greeterEnableFprint ? I18n.tr("Enabled, but fingerprint availability could not be confirmed.") : I18n.tr("Fingerprint availability could not be confirmed."); - } - } - - function greeterU2fDescription() { - const source = SettingsData.greeterU2fSource; - const reason = SettingsData.greeterU2fReason; - - if (source === "pam") { - return SettingsData.greeterEnableU2f ? I18n.tr("Enabled. PAM already provides security-key auth.") : I18n.tr("PAM already provides security-key auth. Enable this to show it at login."); - } - - switch (reason) { - case "ready": - return SettingsData.greeterEnableU2f ? I18n.tr("Run Sync to apply.") : I18n.tr("Available."); - case "missing_key_registration": - if (SettingsData.greeterEnableU2f) - return I18n.tr("Enabled, but no registered security key was found yet. Register a key and run Sync."); - return I18n.tr("Security-key support was detected, but no registered key was found yet. You can enable this now and register one later."); - case "missing_pam_support": - return I18n.tr("Not available — install or configure pam_u2f, or configure greetd PAM."); - default: - return SettingsData.greeterEnableU2f ? I18n.tr("Enabled, but security-key availability could not be confirmed.") : I18n.tr("Security-key availability could not be confirmed."); - } - } - - function refreshAuthDetection() { - SettingsData.refreshAuthAvailability(); - } - - onVisibleChanged: { - if (visible) - refreshAuthDetection(); - } - - ConfirmModal { - id: greeterActionConfirm - } - - FileBrowserModal { - id: greeterWallpaperBrowserModal - browserTitle: I18n.tr("Select greeter background image") - browserIcon: "wallpaper" - browserType: "wallpaper" - showHiddenFiles: true - fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp", "*.jxl", "*.avif", "*.heif"] - onFileSelected: path => { - SettingsData.set("greeterWallpaperPath", path); - close(); - } - } - - property string greeterStatusText: "" - property bool greeterStatusRunning: false - property bool greeterSyncRunning: false - property bool greeterInstallActionRunning: false - property string greeterStatusStdout: "" - property string greeterStatusStderr: "" - property string greeterSyncStdout: "" - property string greeterSyncStderr: "" - property string greeterSudoProbeStderr: "" - property string greeterTerminalFallbackStderr: "" - property bool greeterTerminalFallbackFromPrecheck: false - property var cachedFontFamilies: [] - property bool fontsEnumerated: false - property bool greeterBinaryExists: false - property bool greeterEnabled: false - readonly property bool greeterInstalled: greeterBinaryExists || greeterEnabled - - readonly property string greeterActionLabel: { - if (!root.greeterInstalled) - return I18n.tr("Install"); - if (!root.greeterEnabled) - return I18n.tr("Activate"); - return I18n.tr("Uninstall"); - } - readonly property string greeterActionIcon: { - if (!root.greeterInstalled) - return "download"; - if (!root.greeterEnabled) - return "login"; - return "delete"; - } - readonly property var greeterActionCommand: { - if (!root.greeterInstalled) - return ["dms", "greeter", "install", "--terminal"]; - if (!root.greeterEnabled) - return ["dms", "greeter", "enable", "--terminal"]; - return ["dms", "greeter", "uninstall", "--terminal", "--yes"]; - } - property string greeterPendingAction: "" - - function checkGreeterInstallState() { - greetdEnabledCheckProcess.running = true; - greeterBinaryCheckProcess.running = true; - } - - function runGreeterStatus() { - greeterStatusText = ""; - greeterStatusStdout = ""; - greeterStatusStderr = ""; - greeterStatusRunning = true; - greeterStatusProcess.running = true; - } - - function runGreeterInstallAction() { - root.greeterPendingAction = !root.greeterInstalled ? "install" : !root.greeterEnabled ? "activate" : "uninstall"; - greeterStatusText = I18n.tr("Opening terminal: ") + root.greeterActionLabel + "…"; - greeterInstallActionRunning = true; - greeterInstallActionProcess.running = true; - } - - function promptGreeterActionConfirm() { - var title, message, confirmText; - if (!root.greeterInstalled) { - title = I18n.tr("Install Greeter", "greeter action confirmation"); - message = I18n.tr("Install the DMS greeter? A terminal will open for sudo authentication."); - confirmText = I18n.tr("Install"); - } else if (!root.greeterEnabled) { - title = I18n.tr("Activate Greeter", "greeter action confirmation"); - message = I18n.tr("Activate the DMS greeter? A terminal will open for sudo authentication. Run Sync after activation to apply your settings."); - confirmText = I18n.tr("Activate"); - } else { - title = I18n.tr("Uninstall Greeter", "greeter action confirmation"); - message = I18n.tr("Uninstall the DMS greeter? This will remove configuration and restore your previous display manager. A terminal will open for sudo authentication."); - confirmText = I18n.tr("Uninstall"); - } - greeterActionConfirm.showWithOptions({ - "title": title, - "message": message, - "confirmText": confirmText, - "cancelText": I18n.tr("Cancel"), - "confirmColor": Theme.primary, - "onConfirm": () => root.runGreeterInstallAction(), - "onCancel": () => {} - }); - } - - function runGreeterSync() { - greeterSyncStdout = ""; - greeterSyncStderr = ""; - greeterSudoProbeStderr = ""; - greeterTerminalFallbackStderr = ""; - greeterTerminalFallbackFromPrecheck = false; - greeterStatusText = I18n.tr("Checking whether sudo authentication is needed…"); - greeterSyncRunning = true; - greeterSudoProbeProcess.running = true; - } - - function launchGreeterSyncTerminalFallback(fromPrecheck, statusText) { - greeterTerminalFallbackFromPrecheck = fromPrecheck; - if (statusText && statusText !== "") - greeterStatusText = statusText; - greeterTerminalFallbackStderr = ""; - greeterTerminalFallbackProcess.running = true; - } - - function enumerateFonts() { - if (fontsEnumerated) - return; - var fonts = []; - var availableFonts = Qt.fontFamilies(); - for (var i = 0; i < availableFonts.length; i++) { - var fontName = availableFonts[i]; - if (fontName.startsWith(".")) - continue; - fonts.push(fontName); - } - fonts.sort(); - fonts.unshift("Default"); - cachedFontFamilies = fonts; - fontsEnumerated = true; - } - - Component.onCompleted: { - refreshAuthDetection(); - Qt.callLater(enumerateFonts); - Qt.callLater(checkGreeterInstallState); - } - - Process { - id: greetdEnabledCheckProcess - command: ["systemctl", "is-enabled", "greetd"] - running: false - - stdout: StdioCollector { - onStreamFinished: root.greeterEnabled = text.trim() === "enabled" - } - } - - Process { - id: greeterBinaryCheckProcess - command: ["sh", "-c", "test -f /usr/bin/dms-greeter || test -f /usr/local/bin/dms-greeter"] - running: false - - onExited: exitCode => { - root.greeterBinaryExists = (exitCode === 0); - } - } - - Process { - id: greeterStatusProcess - command: ["dms", "greeter", "status"] - running: false - - stdout: StdioCollector { - onStreamFinished: { - root.greeterStatusStdout = text || ""; - } - } - - stderr: StdioCollector { - onStreamFinished: root.greeterStatusStderr = text || "" - } - - onExited: exitCode => { - root.greeterStatusRunning = false; - const out = (root.greeterStatusStdout || "").trim(); - const err = (root.greeterStatusStderr || "").trim(); - if (exitCode === 0) { - root.greeterStatusText = out !== "" ? out : I18n.tr("No status output."); - if (err !== "") - root.greeterStatusText = root.greeterStatusText + "\n\nstderr:\n" + err; - return; - } - var failure = I18n.tr("Failed to run 'dms greeter status'. Ensure DMS is installed and dms is in PATH.", "greeter status error") + " (exit " + exitCode + ")"; - if (out !== "") - failure = failure + "\n\n" + out; - if (err !== "") - failure = failure + "\n\nstderr:\n" + err; - root.greeterStatusText = failure; - } - } - - Process { - id: greeterSyncProcess - command: ["dms", "greeter", "sync", "--yes"] - running: false - - stdout: StdioCollector { - onStreamFinished: root.greeterSyncStdout = text || "" - } - - stderr: StdioCollector { - onStreamFinished: root.greeterSyncStderr = text || "" - } - - onExited: exitCode => { - root.greeterSyncRunning = false; - const out = (root.greeterSyncStdout || "").trim(); - const err = (root.greeterSyncStderr || "").trim(); - if (exitCode === 0) { - var success = I18n.tr("Sync completed successfully."); - if (out !== "") - success = success + "\n\n" + out; - if (err !== "") - success = success + "\n\nstderr:\n" + err; - root.greeterStatusText = success; - } else { - var failure = I18n.tr("Sync failed in background mode. Trying terminal mode so you can authenticate interactively.") + " (exit " + exitCode + ")"; - if (out !== "") - failure = failure + "\n\n" + out; - if (err !== "") - failure = failure + "\n\nstderr:\n" + err; - root.greeterStatusText = failure; - root.launchGreeterSyncTerminalFallback(false, ""); - } - root.checkGreeterInstallState(); - } - } - - Process { - id: greeterSudoProbeProcess - command: ["sudo", "-n", "true"] - running: false - - stderr: StdioCollector { - onStreamFinished: root.greeterSudoProbeStderr = text || "" - } - - onExited: exitCode => { - const err = (root.greeterSudoProbeStderr || "").trim(); - if (exitCode === 0) { - root.greeterStatusText = I18n.tr("Running greeter sync…"); - greeterSyncProcess.running = true; - return; - } - - var authNeeded = I18n.tr("Sync needs sudo authentication. Opening terminal so you can use password or fingerprint."); - if (err !== "") - authNeeded = authNeeded + "\n\n" + err; - root.launchGreeterSyncTerminalFallback(true, authNeeded); - } - } - - Process { - id: greeterTerminalFallbackProcess - command: ["dms", "greeter", "sync", "--terminal", "--yes"] - running: false - - stderr: StdioCollector { - onStreamFinished: root.greeterTerminalFallbackStderr = text || "" - } - - onExited: exitCode => { - root.greeterSyncRunning = false; - if (exitCode === 0) { - var launched = root.greeterTerminalFallbackFromPrecheck ? I18n.tr("Terminal opened. Complete sync authentication there; it will close automatically when done.") : I18n.tr("Terminal fallback opened. Complete sync there; it will close automatically when done."); - root.greeterStatusText = root.greeterStatusText ? root.greeterStatusText + "\n\n" + launched : launched; - return; - } - var fallback = I18n.tr("Terminal fallback failed. Install one of the supported terminal emulators or run 'dms greeter sync' manually.") + " (exit " + exitCode + ")"; - const err = (root.greeterTerminalFallbackStderr || "").trim(); - if (err !== "") - fallback = fallback + "\n\nstderr:\n" + err; - root.greeterStatusText = root.greeterStatusText ? root.greeterStatusText + "\n\n" + fallback : fallback; - } - } - - Process { - id: greeterInstallActionProcess - command: root.greeterActionCommand - running: false - - onExited: exitCode => { - root.greeterInstallActionRunning = false; - const pending = root.greeterPendingAction; - root.greeterPendingAction = ""; - if (exitCode === 0) { - if (pending === "install") - root.greeterStatusText = I18n.tr("Install complete. Greeter has been installed."); - else if (pending === "activate") - root.greeterStatusText = I18n.tr("Greeter activated. greetd is now enabled."); - else - root.greeterStatusText = I18n.tr("Uninstall complete. Greeter has been removed."); - } else { - root.greeterStatusText = I18n.tr("Action failed or terminal was closed.") + " (exit " + exitCode + ")"; - } - root.checkGreeterInstallState(); - } - } - - readonly property var _lockDateFormatPresets: [ - { - format: "", - label: I18n.tr("System Default", "date format option") - }, - { - format: "ddd d", - label: I18n.tr("Day Date", "date format option") - }, - { - format: "ddd MMM d", - label: I18n.tr("Day Month Date", "date format option") - }, - { - format: "MMM d", - label: I18n.tr("Month Date", "date format option") - }, - { - format: "M/d", - label: I18n.tr("Numeric (M/D)", "date format option") - }, - { - format: "d/M", - label: I18n.tr("Numeric (D/M)", "date format option") - }, - { - format: "ddd d MMM yyyy", - label: I18n.tr("Full with Year", "date format option") - }, - { - format: "yyyy-MM-dd", - label: I18n.tr("ISO Date", "date format option") - }, - { - format: "dddd, MMMM d", - label: I18n.tr("Full Day & Month", "date format option") - } - ] - readonly property var _wallpaperFillModes: ["Stretch", "Fit", "Fill", "Tile", "TileVertically", "TileHorizontally", "Pad"] - - DankFlickable { - anchors.fill: parent - clip: true - contentHeight: mainColumn.height + Theme.spacingXL - contentWidth: width - - Column { - id: mainColumn - topPadding: 4 - width: Math.min(550, parent.width - Theme.spacingL * 2) - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingXL - - SettingsCard { - width: parent.width - iconName: "info" - title: I18n.tr("Greeter Status") - settingKey: "greeterStatus" - - StyledText { - text: I18n.tr("Check sync status on demand. Sync copies your theme, settings, PAM config, and wallpaper to the login screen in one step. Must run Sync to apply changes.") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - wrapMode: Text.Wrap - } - - Item { - width: 1 - height: Theme.spacingS - } - - Rectangle { - width: parent.width - height: Math.min(180, statusTextArea.implicitHeight + Theme.spacingM * 2) - radius: Theme.cornerRadius - color: Theme.surfaceContainerHighest - - StyledText { - id: statusTextArea - anchors.fill: parent - anchors.margins: Theme.spacingM - text: root.greeterStatusRunning ? I18n.tr("Checking…", "greeter status loading") : (root.greeterStatusText || I18n.tr("Click Refresh to check status.", "greeter status placeholder")) - font.pixelSize: Theme.fontSizeSmall - font.family: "monospace" - color: root.greeterStatusRunning ? Theme.surfaceVariantText : Theme.surfaceText - wrapMode: Text.Wrap - verticalAlignment: Text.AlignTop - } - } - - Item { - width: 1 - height: Theme.spacingM - } - - RowLayout { - width: parent.width - spacing: Theme.spacingS - - DankButton { - text: root.greeterActionLabel - iconName: root.greeterActionIcon - horizontalPadding: Theme.spacingL - onClicked: root.promptGreeterActionConfirm() - enabled: !root.greeterInstallActionRunning && !root.greeterSyncRunning - } - - Item { - Layout.fillWidth: true - } - - DankButton { - text: I18n.tr("Refresh") - iconName: "refresh" - horizontalPadding: Theme.spacingL - onClicked: root.runGreeterStatus() - enabled: !root.greeterStatusRunning - } - - DankButton { - text: I18n.tr("Sync") - iconName: "sync" - horizontalPadding: Theme.spacingL - onClicked: root.runGreeterSync() - enabled: root.greeterInstalled && !root.greeterSyncRunning && !root.greeterInstallActionRunning - } - } - } - - SettingsCard { - width: parent.width - iconName: "fingerprint" - title: I18n.tr("Login Authentication") - settingKey: "greeterAuth" - - StyledText { - text: I18n.tr("Enable fingerprint or security key for DMS Greeter. Run Sync to apply and configure PAM.") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - wrapMode: Text.Wrap - } - - SettingsToggleRow { - settingKey: "greeterEnableFprint" - tags: ["greeter", "fingerprint", "fprintd", "login", "auth"] - text: I18n.tr("Enable fingerprint at login") - description: root.greeterFingerprintDescription() - descriptionColor: (SettingsData.greeterFingerprintReason === "ready" || SettingsData.greeterFingerprintReason === "configured_externally") ? Theme.surfaceVariantText : Theme.warning - checked: SettingsData.greeterEnableFprint - enabled: root.greeterFprintToggleAvailable - onToggled: checked => SettingsData.set("greeterEnableFprint", checked) - } - - SettingsToggleRow { - settingKey: "greeterEnableU2f" - tags: ["greeter", "u2f", "security", "key", "login", "auth"] - text: I18n.tr("Enable security key at login") - description: root.greeterU2fDescription() - descriptionColor: (SettingsData.greeterU2fReason === "ready" || SettingsData.greeterU2fReason === "configured_externally") ? Theme.surfaceVariantText : Theme.warning - checked: SettingsData.greeterEnableU2f - enabled: root.greeterU2fToggleAvailable - onToggled: checked => SettingsData.set("greeterEnableU2f", checked) - } - } - - SettingsCard { - width: parent.width - iconName: "palette" - title: I18n.tr("Greeter Appearance") - settingKey: "greeterAppearance" - - StyledText { - text: I18n.tr("Font") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - topPadding: Theme.spacingM - } - - SettingsDropdownRow { - settingKey: "greeterFontFamily" - tags: ["greeter", "font", "typography"] - text: I18n.tr("Greeter font") - description: I18n.tr("Font used on the login screen") - options: root.fontsEnumerated ? root.cachedFontFamilies : ["Default"] - currentValue: (!SettingsData.greeterFontFamily || SettingsData.greeterFontFamily === "" || SettingsData.greeterFontFamily === Theme.defaultFontFamily) ? "Default" : (SettingsData.greeterFontFamily || "Default") - enableFuzzySearch: true - popupWidthOffset: 100 - maxPopupHeight: 400 - onValueChanged: value => { - if (value === "Default") - SettingsData.set("greeterFontFamily", ""); - else - SettingsData.set("greeterFontFamily", value); - } - } - - StyledText { - text: I18n.tr("Time format") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - topPadding: Theme.spacingM - } - - SettingsToggleRow { - settingKey: "greeterUse24Hour" - tags: ["greeter", "time", "24hour"] - text: I18n.tr("24-hour clock") - description: I18n.tr("Greeter only — does not affect main clock") - checked: SettingsData.greeterUse24HourClock - onToggled: checked => SettingsData.set("greeterUse24HourClock", checked) - } - - SettingsToggleRow { - settingKey: "greeterShowSeconds" - tags: ["greeter", "time", "seconds"] - text: I18n.tr("Show seconds") - checked: SettingsData.greeterShowSeconds - onToggled: checked => SettingsData.set("greeterShowSeconds", checked) - } - - SettingsToggleRow { - settingKey: "greeterPadHours" - tags: ["greeter", "time", "12hour"] - text: I18n.tr("Pad hours (02:00 vs 2:00)") - visible: !SettingsData.greeterUse24HourClock - checked: SettingsData.greeterPadHours12Hour - onToggled: checked => SettingsData.set("greeterPadHours12Hour", checked) - } - - StyledText { - text: I18n.tr("Date format on greeter") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - topPadding: Theme.spacingM - } - - SettingsDropdownRow { - settingKey: "greeterLockDateFormat" - tags: ["greeter", "date", "format"] - text: I18n.tr("Date format") - description: I18n.tr("Greeter only — format for the date on the login screen") - options: root._lockDateFormatPresets.map(p => p.label) - currentValue: { - var current = (SettingsData.greeterLockDateFormat !== undefined && SettingsData.greeterLockDateFormat !== "") ? SettingsData.greeterLockDateFormat : SettingsData.lockDateFormat || ""; - var match = root._lockDateFormatPresets.find(p => p.format === current); - return match ? match.label : (current ? I18n.tr("Custom: ") + current : root._lockDateFormatPresets[0].label); - } - onValueChanged: value => { - var preset = root._lockDateFormatPresets.find(p => p.label === value); - SettingsData.set("greeterLockDateFormat", preset ? preset.format : ""); - } - } - - StyledText { - text: I18n.tr("Background") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - topPadding: Theme.spacingM - } - - StyledText { - text: I18n.tr("Use a custom image for the login screen, or leave empty to use your desktop wallpaper.") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - wrapMode: Text.Wrap - } - - Row { - width: parent.width - spacing: Theme.spacingS - - DankTextField { - id: greeterWallpaperPathField - width: parent.width - browseGreeterWallpaperButton.width - Theme.spacingS - placeholderText: I18n.tr("Use desktop wallpaper") - text: SettingsData.greeterWallpaperPath - backgroundColor: Theme.surfaceContainerHighest - onTextChanged: { - if (text !== SettingsData.greeterWallpaperPath) - SettingsData.set("greeterWallpaperPath", text); - } - } - - DankButton { - id: browseGreeterWallpaperButton - text: I18n.tr("Browse") - horizontalPadding: Theme.spacingL - onClicked: greeterWallpaperBrowserModal.open() - } - } - - SettingsDropdownRow { - settingKey: "greeterWallpaperFillMode" - tags: ["greeter", "wallpaper", "background", "fill"] - text: I18n.tr("Wallpaper fill mode") - description: I18n.tr("How the background image is scaled") - options: root._wallpaperFillModes.map(m => I18n.tr(m, "wallpaper fill mode")) - currentValue: { - var mode = (SettingsData.greeterWallpaperFillMode && SettingsData.greeterWallpaperFillMode !== "") ? SettingsData.greeterWallpaperFillMode : (SettingsData.wallpaperFillMode || "Fill"); - var idx = root._wallpaperFillModes.indexOf(mode); - return idx >= 0 ? I18n.tr(root._wallpaperFillModes[idx], "wallpaper fill mode") : I18n.tr("Fill", "wallpaper fill mode"); - } - onValueChanged: value => { - var idx = root._wallpaperFillModes.map(m => I18n.tr(m, "wallpaper fill mode")).indexOf(value); - if (idx >= 0) - SettingsData.set("greeterWallpaperFillMode", root._wallpaperFillModes[idx]); - } - } - - StyledText { - text: I18n.tr("Layout and module positions on the greeter are synced from your shell (e.g. bar config). Run Sync to apply.") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - wrapMode: Text.Wrap - topPadding: Theme.spacingS - } - } - - SettingsCard { - width: parent.width - iconName: "history" - title: I18n.tr("Greeter Behavior") - settingKey: "greeterBehavior" - - StyledText { - text: I18n.tr("Convenience options for the login screen. Sync to apply.") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - wrapMode: Text.Wrap - } - - SettingsToggleRow { - settingKey: "greeterRememberLastSession" - tags: ["greeter", "session", "remember", "login"] - text: I18n.tr("Remember last session") - description: I18n.tr("Pre-select the last used session on the greeter") - checked: SettingsData.greeterRememberLastSession - onToggled: checked => SettingsData.set("greeterRememberLastSession", checked) - } - - SettingsToggleRow { - settingKey: "greeterRememberLastUser" - tags: ["greeter", "user", "remember", "login", "username"] - text: I18n.tr("Remember last user") - description: I18n.tr("Pre-fill the last successful username on the greeter") - checked: SettingsData.greeterRememberLastUser - onToggled: checked => SettingsData.set("greeterRememberLastUser", checked) - } - } - - SettingsCard { - width: parent.width - iconName: "extension" - title: I18n.tr("Dependencies & documentation") - settingKey: "greeterDeps" - - StyledText { - text: I18n.tr("DMS greeter needs: greetd, dms-greeter. Fingerprint: fprintd, pam_fprintd. Security keys: pam_u2f. Add your user to the greeter group. Sync checks sudo first and opens a terminal when interactive authentication is required.") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - wrapMode: Text.Wrap - } - - StyledText { - text: I18n.tr("Installation and PAM setup: see the ") + "DankGreeter docs " + I18n.tr("or run ") + "'dms greeter install'." - textFormat: Text.RichText - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - linkColor: Theme.primary - width: parent.width - wrapMode: Text.Wrap - onLinkActivated: url => Qt.openUrlExternally(url) - - MouseArea { - anchors.fill: parent - cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor - acceptedButtons: Qt.NoButton - propagateComposedEvents: true - } - } - } - } - } -} diff --git a/quickshell/Modules/Settings/LockScreenTab.qml b/quickshell/Modules/Settings/LockScreenTab.qml index 6e16a969..51c54313 100644 --- a/quickshell/Modules/Settings/LockScreenTab.qml +++ b/quickshell/Modules/Settings/LockScreenTab.qml @@ -53,16 +53,6 @@ Item { refreshAuthDetection(); } - FileBrowserModal { - id: videoBrowserModal - browserTitle: I18n.tr("Select Video or Folder") - browserIcon: "movie" - browserType: "video" - showHiddenFiles: false - fileExtensions: ["*.mp4", "*.mkv", "*.webm", "*.mov", "*.avi", "*.m4v"] - onFileSelected: path => SettingsData.set("lockScreenVideoPath", path) - } - DankFlickable { anchors.fill: parent clip: true @@ -251,87 +241,6 @@ Item { } } - SettingsCard { - width: parent.width - iconName: "movie" - title: I18n.tr("Video Screensaver") - settingKey: "videoScreensaver" - - StyledText { - visible: !MultimediaService.available - text: I18n.tr("QtMultimedia is not available - video screensaver requires qt multimedia services") - font.pixelSize: Theme.fontSizeSmall - color: Theme.warning - width: parent.width - wrapMode: Text.WordWrap - } - - SettingsToggleRow { - settingKey: "lockScreenVideoEnabled" - tags: ["lock", "screen", "video", "screensaver", "animation", "movie"] - text: I18n.tr("Enable Video Screensaver") - description: I18n.tr("Play a video when the screen locks.") - enabled: MultimediaService.available - checked: SettingsData.lockScreenVideoEnabled - onToggled: checked => SettingsData.set("lockScreenVideoEnabled", checked) - } - - Column { - width: parent.width - spacing: Theme.spacingXS - visible: SettingsData.lockScreenVideoEnabled && MultimediaService.available - - StyledText { - text: I18n.tr("Video Path") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: I18n.tr("Path to a video file or folder containing videos") - font.pixelSize: Theme.fontSizeSmall - color: Theme.outlineVariant - wrapMode: Text.WordWrap - width: parent.width - } - - Row { - width: parent.width - spacing: Theme.spacingS - - DankTextField { - id: videoPathField - width: parent.width - browseVideoButton.width - Theme.spacingS - placeholderText: I18n.tr("/path/to/videos") - text: SettingsData.lockScreenVideoPath - backgroundColor: Theme.surfaceContainerHighest - onTextChanged: { - if (text !== SettingsData.lockScreenVideoPath) { - SettingsData.set("lockScreenVideoPath", text); - } - } - } - - DankButton { - id: browseVideoButton - text: I18n.tr("Browse") - onClicked: videoBrowserModal.open() - } - } - } - - SettingsToggleRow { - settingKey: "lockScreenVideoCycling" - tags: ["lock", "screen", "video", "screensaver", "cycling", "random", "shuffle"] - text: I18n.tr("Automatic Cycling") - description: I18n.tr("Pick a different random video each time from the same folder") - visible: SettingsData.lockScreenVideoEnabled && MultimediaService.available - enabled: MultimediaService.available - checked: SettingsData.lockScreenVideoCycling - onToggled: checked => SettingsData.set("lockScreenVideoCycling", checked) - } - } - SettingsCard { width: parent.width iconName: "monitor" diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index 62a5a349..4cadf991 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -2484,23 +2484,6 @@ "theme" ] }, - { - "section": "matugenTemplateZed", - "label": "Zed", - "tabIndex": 10, - "category": "Theme & Colors", - "keywords": [ - "appearance", - "colors", - "look", - "matugen", - "scheme", - "style", - "template", - "theme", - "zed" - ] - }, { "section": "matugenTemplateFirefox", "label": "Firefox", @@ -3535,6 +3518,23 @@ ], "description": "Rounded corners for windows (decoration.rounding)" }, + { + "section": "matugenTemplateZed", + "label": "Zed", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "colors", + "look", + "matugen", + "scheme", + "style", + "template", + "theme", + "zed" + ] + }, { "section": "matugenTemplateDgop", "label": "dgop", @@ -3775,18 +3775,14 @@ "authentication", "biometric", "enable", - "enrolled", "fingerprint", "fprint", "lock", - "lockscreen", "login", "password", - "reader", "screen", "security" - ], - "description": "Use fingerprint reader for lock screen authentication (requires enrolled fingerprints)" + ] }, { "section": "loginctlLockIntegration", @@ -3811,6 +3807,26 @@ ], "description": "Bind lock screen to dbus signals from loginctl. Disable if using an external lock screen" }, + { + "section": "enableU2f", + "label": "Enable security key authentication", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "authentication", + "enable", + "fido", + "hardware", + "key", + "lock", + "login", + "password", + "screen", + "security", + "u2f", + "yubikey" + ] + }, { "section": "lockDisplay", "label": "Lock Screen Display", @@ -3982,6 +3998,25 @@ ], "description": "Turn off all displays immediately when the lock screen activates" }, + { + "section": "u2fMode", + "label": "Security key mode", + "tabIndex": 11, + "category": "Lock Screen", + "keywords": [ + "factor", + "key", + "lock", + "login", + "mode", + "password", + "screen", + "second", + "security", + "u2f", + "yubikey" + ] + }, { "section": "lockScreenShowMediaPlayer", "label": "Show Media Player",