diff options
| author | Nippy <nippy@rp1.hu> | 2026-05-09 13:33:09 +0200 |
|---|---|---|
| committer | Nippy <nippy@rp1.hu> | 2026-05-09 13:33:09 +0200 |
| commit | a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5 (patch) | |
| tree | 1a8769217f84bfe9d6216fafaadaf8cdd876d457 /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd | |
| parent | 34b9c34f982b2596cfa9e368a2d7f74e9a17477c (diff) | |
| download | RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.tar.gz RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.zip | |
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd')
12 files changed, 0 insertions, 3065 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdEnv.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdEnv.js deleted file mode 100644 index fcce181..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdEnv.js +++ /dev/null @@ -1,20 +0,0 @@ -.pragma library - -function readBoolOverride(envReader, names, fallbackValue) { - for (let i = 0; i < names.length; i++) { - const name = names[i]; - const raw = envReader(name); - if (raw === undefined || raw === null || raw === "") - continue; - - const normalized = String(raw).trim().toLowerCase(); - if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") - return true; - if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") - return false; - - console.warn("Invalid boolean override for", name + ":", raw, "- trying next override/fallback"); - } - - return fallbackValue; -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdMemory.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdMemory.qml deleted file mode 100644 index da949d3..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdMemory.qml +++ /dev/null @@ -1,128 +0,0 @@ -pragma Singleton -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell -import Quickshell.Io -import "GreetdEnv.js" as GreetdEnv - -Singleton { - id: root - - readonly property string greetCfgDir: Quickshell.env("DMS_GREET_CFG_DIR") || "/var/cache/dms-greeter" - readonly property string sessionConfigPath: greetCfgDir + "/session.json" - readonly property string memoryFile: greetCfgDir + "/.local/state/memory.json" - readonly property bool rememberLastSession: GreetdEnv.readBoolOverride(Quickshell.env, ["DMS_GREET_REMEMBER_LAST_SESSION", "DMS_SAVE_SESSION"], true) - readonly property bool rememberLastUser: GreetdEnv.readBoolOverride(Quickshell.env, ["DMS_GREET_REMEMBER_LAST_USER", "DMS_SAVE_USERNAME"], true) - - property string lastSessionId: "" - property string lastSuccessfulUser: "" - property bool memoryReady: false - property bool isLightMode: false - property bool nightModeEnabled: false - - Component.onCompleted: { - loadMemory(); - loadSessionConfig(); - } - - function loadMemory() { - parseMemory(memoryFileView.text()); - } - - function loadSessionConfig() { - parseSessionConfig(sessionConfigFileView.text()); - } - - function parseSessionConfig(content) { - try { - if (content && content.trim()) { - const config = JSON.parse(content); - isLightMode = config.isLightMode !== undefined ? config.isLightMode : false; - nightModeEnabled = config.nightModeEnabled !== undefined ? config.nightModeEnabled : false; - } - } catch (e) { - console.warn("Failed to parse greeter session config:", e); - } - } - - function parseMemory(content) { - try { - if (!content || !content.trim()) - return; - const memory = JSON.parse(content); - lastSessionId = rememberLastSession ? (memory.lastSessionId || "") : ""; - lastSuccessfulUser = rememberLastUser ? (memory.lastSuccessfulUser || "") : ""; - if (!rememberLastSession || !rememberLastUser) - saveMemory(); - } catch (e) { - console.warn("Failed to parse greetd memory:", e); - } - } - - function saveMemory() { - let memory = {}; - if (rememberLastSession && lastSessionId) - memory.lastSessionId = lastSessionId; - if (rememberLastUser && lastSuccessfulUser) - memory.lastSuccessfulUser = lastSuccessfulUser; - memoryFileView.setText(JSON.stringify(memory, null, 2)); - } - - function setLastSessionId(id) { - if (!rememberLastSession) { - if (lastSessionId !== "") { - lastSessionId = ""; - saveMemory(); - } - return; - } - lastSessionId = id || ""; - saveMemory(); - } - - function setLastSuccessfulUser(username) { - if (!rememberLastUser) { - if (lastSuccessfulUser !== "") { - lastSuccessfulUser = ""; - saveMemory(); - } - return; - } - lastSuccessfulUser = username || ""; - saveMemory(); - } - - FileView { - id: memoryFileView - path: root.memoryFile - blockLoading: false - blockWrites: false - atomicWrites: true - watchChanges: false - printErrors: false - onLoaded: { - parseMemory(memoryFileView.text()); - root.memoryReady = true; - } - onLoadFailed: { - root.memoryReady = true; - } - } - - FileView { - id: sessionConfigFileView - path: root.sessionConfigPath - blockLoading: false - blockWrites: true - atomicWrites: false - watchChanges: false - printErrors: true - onLoaded: { - parseSessionConfig(sessionConfigFileView.text()); - } - onLoadFailed: error => { - console.warn("Could not load greeter session config from", root.sessionConfigPath, "error:", error); - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdSettings.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdSettings.qml deleted file mode 100644 index e1f670c..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreetdSettings.qml +++ /dev/null @@ -1,199 +0,0 @@ -pragma Singleton -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell -import Quickshell.Io -import qs.Common -import "GreetdEnv.js" as GreetdEnv - -Singleton { - id: root - - readonly property string configPath: { - const greetCfgDir = Quickshell.env("DMS_GREET_CFG_DIR") || "/var/cache/dms-greeter"; - return greetCfgDir + "/settings.json"; - } - - readonly property string _greeterCacheDir: { - const i = root.configPath.lastIndexOf("/"); - return i >= 0 ? root.configPath.substring(0, i) : ""; - } - readonly property string greeterWallpaperOverridePath: root._greeterCacheDir ? (root._greeterCacheDir + "/greeter_wallpaper_override.jpg") : "" - - property string currentThemeName: "purple" - property bool settingsLoaded: false - property string customThemeFile: "" - property var registryThemeVariants: ({}) - property string matugenScheme: "scheme-tonal-spot" - property bool use24HourClock: true - property bool showSeconds: false - property bool padHours12Hour: false - property bool greeterUse24HourClock: true - property bool greeterShowSeconds: false - property bool greeterPadHours12Hour: false - property string greeterLockDateFormat: "" - property string greeterFontFamily: "" - property string greeterWallpaperFillMode: "" - property bool useFahrenheit: false - property bool nightModeEnabled: false - property string weatherLocation: "New York, NY" - property string weatherCoordinates: "40.7128,-74.0060" - property bool useAutoLocation: false - property bool weatherEnabled: true - property string iconTheme: "System Default" - property bool useOSLogo: false - property string osLogoColorOverride: "" - property real osLogoBrightness: 0.5 - property real osLogoContrast: 1 - property string fontFamily: "Inter Variable" - property string monoFontFamily: "Fira Code" - property int fontWeight: Font.Normal - property real fontScale: 1.0 - property real cornerRadius: 12 - property string widgetBackgroundColor: "sch" - property string lockDateFormat: "" - property bool lockScreenShowPowerActions: true - property bool lockScreenShowProfileImage: true - property bool rememberLastSession: true - property bool rememberLastUser: true - property bool greeterEnableFprint: false - property bool greeterEnableU2f: false - property string greeterWallpaperPath: "" - property bool powerActionConfirm: true - property real powerActionHoldDuration: 0.5 - property var powerMenuActions: ["reboot", "logout", "poweroff", "lock", "suspend", "restart"] - property string powerMenuDefaultAction: "logout" - property bool powerMenuGridLayout: false - property var screenPreferences: ({}) - property int animationSpeed: 2 - property string wallpaperFillMode: "Fill" - - function parseSettings(content) { - try { - let settings = {}; - if (content && content.trim()) { - settings = JSON.parse(content); - } - - const envRememberLastSession = GreetdEnv.readBoolOverride(Quickshell.env, ["DMS_GREET_REMEMBER_LAST_SESSION", "DMS_SAVE_SESSION"], undefined); - const envRememberLastUser = GreetdEnv.readBoolOverride(Quickshell.env, ["DMS_GREET_REMEMBER_LAST_USER", "DMS_SAVE_USERNAME"], undefined); - - currentThemeName = settings.currentThemeName !== undefined ? settings.currentThemeName : "purple"; - customThemeFile = settings.customThemeFile !== undefined ? settings.customThemeFile : ""; - registryThemeVariants = settings.registryThemeVariants !== undefined ? - settings.registryThemeVariants : ({}); - matugenScheme = settings.matugenScheme !== undefined ? settings.matugenScheme : "scheme-tonal-spot"; - use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true; - showSeconds = settings.showSeconds !== undefined ? settings.showSeconds : false; - padHours12Hour = settings.padHours12Hour !== undefined ? settings.padHours12Hour : false; - greeterUse24HourClock = settings.greeterUse24HourClock !== undefined ? settings.greeterUse24HourClock : use24HourClock; - greeterShowSeconds = settings.greeterShowSeconds !== undefined ? settings.greeterShowSeconds : showSeconds; - greeterPadHours12Hour = settings.greeterPadHours12Hour !== undefined ? settings.greeterPadHours12Hour : padHours12Hour; - greeterLockDateFormat = settings.greeterLockDateFormat !== undefined ? settings.greeterLockDateFormat : ""; - greeterFontFamily = settings.greeterFontFamily !== undefined ? settings.greeterFontFamily : ""; - greeterWallpaperFillMode = settings.greeterWallpaperFillMode !== undefined ? settings.greeterWallpaperFillMode : ""; - useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false; - nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false; - weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY"; - weatherCoordinates = settings.weatherCoordinates !== undefined ? settings.weatherCoordinates : "40.7128,-74.0060"; - useAutoLocation = settings.useAutoLocation !== undefined ? settings.useAutoLocation : false; - weatherEnabled = settings.weatherEnabled !== undefined ? settings.weatherEnabled : true; - iconTheme = settings.iconTheme !== undefined ? settings.iconTheme : "System Default"; - useOSLogo = settings.useOSLogo !== undefined ? settings.useOSLogo : false; - osLogoColorOverride = settings.osLogoColorOverride !== undefined ? settings.osLogoColorOverride : ""; - osLogoBrightness = settings.osLogoBrightness !== undefined ? settings.osLogoBrightness : 0.5; - osLogoContrast = settings.osLogoContrast !== undefined ? settings.osLogoContrast : 1; - fontFamily = settings.fontFamily !== undefined ? settings.fontFamily : Theme.defaultFontFamily; - monoFontFamily = settings.monoFontFamily !== undefined ? settings.monoFontFamily : Theme.defaultMonoFontFamily; - fontWeight = settings.fontWeight !== undefined ? settings.fontWeight : Font.Normal; - fontScale = settings.fontScale !== undefined ? settings.fontScale : 1.0; - cornerRadius = settings.cornerRadius !== undefined ? settings.cornerRadius : 12; - widgetBackgroundColor = settings.widgetBackgroundColor !== undefined ? settings.widgetBackgroundColor : "sch"; - lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : ""; - lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true; - lockScreenShowProfileImage = settings.lockScreenShowProfileImage !== undefined ? settings.lockScreenShowProfileImage : true; - if (envRememberLastSession !== undefined) { - rememberLastSession = envRememberLastSession; - } else { - rememberLastSession = settings.greeterRememberLastSession !== undefined ? settings.greeterRememberLastSession : settings.rememberLastSession !== undefined ? settings.rememberLastSession : true; - } - if (envRememberLastUser !== undefined) { - rememberLastUser = envRememberLastUser; - } else { - rememberLastUser = settings.greeterRememberLastUser !== undefined ? settings.greeterRememberLastUser : settings.rememberLastUser !== undefined ? settings.rememberLastUser : true; - } - greeterEnableFprint = settings.greeterEnableFprint !== undefined ? settings.greeterEnableFprint : false; - greeterEnableU2f = settings.greeterEnableU2f !== undefined ? settings.greeterEnableU2f : false; - greeterWallpaperPath = settings.greeterWallpaperPath !== undefined ? settings.greeterWallpaperPath : ""; - powerActionConfirm = settings.powerActionConfirm !== undefined ? settings.powerActionConfirm : true; - powerActionHoldDuration = settings.powerActionHoldDuration !== undefined ? settings.powerActionHoldDuration : 0.5; - powerMenuActions = settings.powerMenuActions !== undefined ? settings.powerMenuActions : ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]; - powerMenuDefaultAction = settings.powerMenuDefaultAction !== undefined ? settings.powerMenuDefaultAction : "logout"; - powerMenuGridLayout = settings.powerMenuGridLayout !== undefined ? settings.powerMenuGridLayout : false; - screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({}); - animationSpeed = settings.animationSpeed !== undefined ? settings.animationSpeed : 2; - wallpaperFillMode = settings.wallpaperFillMode !== undefined ? settings.wallpaperFillMode : "Fill"; - - if (typeof Theme !== "undefined") { - if (currentThemeName === "custom" && customThemeFile) { - Theme.loadCustomThemeFromFile(customThemeFile); - } - Theme.applyGreeterTheme(currentThemeName); - } - } catch (e) { - console.warn("Failed to parse greetd settings:", e); - } finally { - settingsLoaded = true; - } - } - - function getEffectiveTimeFormat() { - const use24 = greeterUse24HourClock; - const secs = greeterShowSeconds; - const pad = greeterPadHours12Hour; - if (use24) - return secs ? "hh:mm:ss" : "hh:mm"; - if (pad) - return secs ? "hh:mm:ss AP" : "hh:mm AP"; - return secs ? "h:mm:ss AP" : "h:mm AP"; - } - - function getEffectiveLockDateFormat() { - const fmt = (greeterLockDateFormat !== undefined && greeterLockDateFormat !== "") ? greeterLockDateFormat : lockDateFormat; - return fmt && fmt.length > 0 ? fmt : Locale.LongFormat; - } - - function getEffectiveWallpaperFillMode() { - return (greeterWallpaperFillMode && greeterWallpaperFillMode !== "") ? greeterWallpaperFillMode : wallpaperFillMode; - } - - function getEffectiveFontFamily() { - return (greeterFontFamily && greeterFontFamily !== "") ? greeterFontFamily : fontFamily; - } - - function getFilteredScreens(componentId) { - const prefs = screenPreferences && screenPreferences[componentId] || ["all"]; - if (prefs.includes("all")) { - return Quickshell.screens; - } - return Quickshell.screens.filter(screen => prefs.includes(screen.name)); - } - - FileView { - id: settingsFile - path: root.configPath - blockLoading: false - blockWrites: true - atomicWrites: false - watchChanges: false - printErrors: true - onLoaded: { - parseSettings(settingsFile.text()); - } - onLoadFailed: error => { - console.warn("Failed to load greetd settings:", error); - root.parseSettings(""); - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterContent.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterContent.qml deleted file mode 100644 index fa82315..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterContent.qml +++ /dev/null @@ -1,1908 +0,0 @@ -import QtCore -import QtQuick -import QtQuick.Effects -import QtQuick.Layouts -import Qt.labs.folderlistmodel -import Quickshell -import Quickshell.Hyprland -import Quickshell.Io -import Quickshell.Services.Greetd -import qs.Common -import qs.Services -import qs.Widgets -import qs.Modules.Lock - -Item { - id: root - - function encodeFileUrl(path) { - if (!path) - return ""; - return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/'); - } - - readonly property string xdgDataDirs: Quickshell.env("XDG_DATA_DIRS") - property string screenName: "" - property string hyprlandCurrentLayout: "" - property string hyprlandKeyboard: "" - property int hyprlandLayoutCount: 0 - property bool isPrimaryScreen: !Quickshell.screens?.length || screenName === Quickshell.screens[0]?.name - - signal launchRequested - - property bool weatherInitialized: false - property bool awaitingExternalAuth: false - property bool pendingPasswordResponse: false - property bool passwordSubmitRequested: false - property bool cancelingExternalAuthForPassword: false - property int defaultAuthTimeoutMs: 10000 - property int externalAuthTimeoutMs: 30000 - property int memoryFlushDelayMs: 120 - property string pendingLaunchCommand: "" - property var pendingLaunchEnv: [] - property int passwordFailureCount: 0 - property int passwordAttemptLimitHint: 0 - property string authFeedbackMessage: "" - property string greetdPamText: "" - property string systemAuthPamText: "" - property string commonAuthPamText: "" - property string passwordAuthPamText: "" - property string systemLoginPamText: "" - property string systemLocalLoginPamText: "" - property string commonAuthPcPamText: "" - property string loginPamText: "" - property string faillockConfigText: "" - property bool greeterWallpaperOverrideExists: false - property string externalAuthAutoStartedForUser: "" - property int passwordSessionTransitionRetryCount: 0 - property int maxPasswordSessionTransitionRetries: 2 - property bool fprintdProbeComplete: false - property bool fprintdHasDevice: false - // Falls back to PAM-only detection until the fprintd D-Bus probe completes. - readonly property bool greeterPamHasFprint: greeterPamStackHasModule("pam_fprintd") && (!fprintdProbeComplete || fprintdHasDevice) - readonly property bool greeterPamHasU2f: greeterPamStackHasModule("pam_u2f") - readonly property bool greeterExternalAuthAvailable: (greeterPamHasFprint && GreetdSettings.greeterEnableFprint) || (greeterPamHasU2f && GreetdSettings.greeterEnableU2f) - readonly property bool greeterPamHasExternalAuth: greeterPamHasFprint || greeterPamHasU2f - - function initWeatherService() { - if (weatherInitialized) - return; - if (!GreetdSettings.settingsLoaded) - return; - if (!GreetdSettings.weatherEnabled) - return; - weatherInitialized = true; - WeatherService.addRef(); - WeatherService.forceRefresh(); - } - - function stripPamComment(line) { - if (!line) - return ""; - const trimmed = line.trim(); - if (!trimmed || trimmed.startsWith("//")) - return ""; - const hashIdx = trimmed.indexOf("//"); - if (hashIdx >= 0) - return trimmed.substring(0, hashIdx).trim(); - return trimmed; - } - - function pamModuleEnabled(pamText, moduleName) { - if (!pamText || !moduleName) - return false; - const lines = pamText.split(/\r?\n/); - for (let i = 0; i < lines.length; i++) { - const line = stripPamComment(lines[i]); - if (!line) - continue; - if (line.includes(moduleName)) - return true; - } - return false; - } - - function pamTextIncludesFile(pamText, filename) { - if (!pamText || !filename) - return false; - const lines = pamText.split(/\r?\n/); - for (let i = 0; i < lines.length; i++) { - const line = stripPamComment(lines[i]); - if (!line) - continue; - if (line.includes(filename) && (line.includes("include") || line.includes("substack") || line.startsWith("@include"))) - return true; - } - return false; - } - - function greeterPamStackHasModule(moduleName) { - if (pamModuleEnabled(greetdPamText, moduleName)) - return true; - const includedPamStacks = [ - ["system-auth", systemAuthPamText], - ["common-auth", commonAuthPamText], - ["password-auth", passwordAuthPamText], - ["system-login", systemLoginPamText], - ["system-local-login", systemLocalLoginPamText], - ["common-auth-pc", commonAuthPcPamText], - ["login", loginPamText] - ]; - for (let i = 0; i < includedPamStacks.length; i++) { - const stack = includedPamStacks[i]; - if (pamTextIncludesFile(greetdPamText, stack[0]) && pamModuleEnabled(stack[1], moduleName)) - return true; - } - return false; - } - - function usesPamLockoutPolicy(pamText) { - if (!pamText) - return false; - const lines = pamText.split(/\r?\n/); - for (let i = 0; i < lines.length; i++) { - const line = stripPamComment(lines[i]); - if (!line) - continue; - if (line.includes("pam_faillock.so") || line.includes("pam_tally2.so") || line.includes("pam_tally.so")) - return true; - } - return false; - } - - function parsePamLineDenyValue(pamText) { - if (!pamText) - return -1; - const lines = pamText.split(/\r?\n/); - for (let i = 0; i < lines.length; i++) { - const line = stripPamComment(lines[i]); - if (!line) - continue; - if (!line.includes("pam_faillock.so") && !line.includes("pam_tally2.so") && !line.includes("pam_tally.so")) - continue; - const denyMatch = line.match(/\bdeny\s*=\s*(\d+)\b/i); - if (!denyMatch) - continue; - const parsed = parseInt(denyMatch[1], 10); - if (!isNaN(parsed)) - return parsed; - } - return -1; - } - - function parseFaillockDenyValue(configText) { - if (!configText) - return -1; - const lines = configText.split(/\r?\n/); - for (let i = 0; i < lines.length; i++) { - const line = stripPamComment(lines[i]); - if (!line) - continue; - const denyMatch = line.match(/^deny\s*=\s*(\d+)\s*$/i); - if (!denyMatch) - continue; - const parsed = parseInt(denyMatch[1], 10); - if (!isNaN(parsed)) - return parsed; - } - return -1; - } - - function refreshPasswordAttemptPolicyHint() { - const pamSources = [greetdPamText, systemAuthPamText, commonAuthPamText, passwordAuthPamText, systemLoginPamText, systemLocalLoginPamText, commonAuthPcPamText, loginPamText]; - let lockoutConfigured = false; - let denyFromPam = -1; - for (let i = 0; i < pamSources.length; i++) { - const source = pamSources[i]; - if (!source) - continue; - if (usesPamLockoutPolicy(source)) - lockoutConfigured = true; - const denyValue = parsePamLineDenyValue(source); - if (denyValue >= 0 && (denyFromPam < 0 || denyValue < denyFromPam)) - denyFromPam = denyValue; - } - - if (!lockoutConfigured) { - passwordAttemptLimitHint = 0; - return; - } - - const denyFromConfig = parseFaillockDenyValue(faillockConfigText); - if (denyFromConfig >= 0) { - passwordAttemptLimitHint = denyFromConfig; - return; - } - - if (denyFromPam >= 0) { - passwordAttemptLimitHint = denyFromPam; - return; - } - - // pam_faillock default deny value when no explicit config is set. - passwordAttemptLimitHint = 3; - } - - function isLikelyLockoutMessage(message) { - const lower = (message || "").toLowerCase(); - return lower.includes("account is locked") || lower.includes("too many") || lower.includes("maximum number of") || lower.includes("auth_err"); - } - - function currentAuthMessage() { - if (GreeterState.pamState === "error") - return I18n.tr("Authentication error - try again"); - if (GreeterState.pamState === "max") - 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 I18n.tr("Incorrect password - attempt %1 of %2 (lockout may follow)").arg(attempt).arg(passwordAttemptLimitHint); - } - return I18n.tr("Incorrect password - next failures may trigger account lockout"); - } - return I18n.tr("Incorrect password"); - } - return ""; - } - - function clearAuthFeedback() { - GreeterState.pamState = ""; - authFeedbackMessage = ""; - } - - function resetPasswordSessionTransition(clearSubmitRequest) { - cancelingExternalAuthForPassword = false; - passwordSessionTransitionRetryCount = 0; - if (clearSubmitRequest) - passwordSubmitRequested = false; - } - - Connections { - target: GreetdSettings - function onSettingsLoadedChanged() { - if (GreetdSettings.settingsLoaded) { - initWeatherService(); - if (isPrimaryScreen) { - applyLastSuccessfulUser(); - finalizeSessionSelection(); - } - } - } - - function onRememberLastUserChanged() { - if (!isPrimaryScreen) - return; - if (!GreetdSettings.rememberLastUser && GreetdMemory.lastSuccessfulUser) { - GreetdMemory.setLastSuccessfulUser(""); - } - applyLastSuccessfulUser(); - } - - function onRememberLastSessionChanged() { - if (!isPrimaryScreen) - return; - if (!GreetdSettings.rememberLastSession && GreetdMemory.lastSessionId) { - GreetdMemory.setLastSessionId(""); - } - finalizeSessionSelection(); - } - } - - FileView { - id: greetdPamWatcher - path: "/etc/pam.d/greetd" - printErrors: false - onLoaded: { - root.greetdPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.greetdPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: systemAuthPamWatcher - path: "/etc/pam.d/system-auth" - printErrors: false - onLoaded: { - root.systemAuthPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.systemAuthPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: commonAuthPamWatcher - path: "/etc/pam.d/common-auth" - printErrors: false - onLoaded: { - root.commonAuthPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.commonAuthPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: passwordAuthPamWatcher - path: "/etc/pam.d/password-auth" - printErrors: false - onLoaded: { - root.passwordAuthPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.passwordAuthPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: systemLoginPamWatcher - path: "/etc/pam.d/system-login" - printErrors: false - onLoaded: { - root.systemLoginPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.systemLoginPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: systemLocalLoginPamWatcher - path: "/etc/pam.d/system-local-login" - printErrors: false - onLoaded: { - root.systemLocalLoginPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.systemLocalLoginPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: commonAuthPcPamWatcher - path: "/etc/pam.d/common-auth-pc" - printErrors: false - onLoaded: { - root.commonAuthPcPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.commonAuthPcPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: loginPamWatcher - path: "/etc/pam.d/login" - printErrors: false - onLoaded: { - root.loginPamText = text(); - root.refreshPasswordAttemptPolicyHint(); - root.maybeAutoStartExternalAuth(); - } - onLoadFailed: { - root.loginPamText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - FileView { - id: faillockConfigWatcher - path: "/etc/security/faillock.conf" - printErrors: false - onLoaded: { - root.faillockConfigText = text(); - root.refreshPasswordAttemptPolicyHint(); - } - onLoadFailed: { - root.faillockConfigText = ""; - root.refreshPasswordAttemptPolicyHint(); - } - } - - Component.onCompleted: { - initWeatherService(); - refreshPasswordAttemptPolicyHint(); - - if (isPrimaryScreen) - applyLastSuccessfulUser(); - - if (CompositorService.isHyprland) - updateHyprlandLayout(); - - fprintdDeviceProbe.running = true; - } - - function applyLastSuccessfulUser() { - if (!GreetdSettings.settingsLoaded || !GreetdSettings.rememberLastUser) - return; - const lastUser = GreetdMemory.lastSuccessfulUser; - if (lastUser && !GreeterState.showPasswordInput && !GreeterState.username) { - GreeterState.username = lastUser; - GreeterState.usernameInput = lastUser; - GreeterState.showPasswordInput = true; - PortalService.getGreeterUserProfileImage(lastUser); - maybeAutoStartExternalAuth(); - } - } - - function submitUsername(rawValue) { - const user = (rawValue || "").trim(); - if (!user) - return; - if (GreeterState.username !== user) { - passwordFailureCount = 0; - clearAuthFeedback(); - externalAuthAutoStartedForUser = ""; - } - GreeterState.username = user; - GreeterState.showPasswordInput = true; - PortalService.getGreeterUserProfileImage(user); - GreeterState.passwordBuffer = ""; - pendingPasswordResponse = false; - resetPasswordSessionTransition(true); - maybeAutoStartExternalAuth(); - } - - function submitBufferedPassword() { - pendingPasswordResponse = false; - resetPasswordSessionTransition(true); - awaitingExternalAuth = false; - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.restart(); - // Some PAM stacks expect an explicit empty response to advance U2F/fprint or fail normally. - Greetd.respond(GreeterState.passwordBuffer || ""); - GreeterState.passwordBuffer = ""; - inputField.text = ""; - return true; - } - - function requestPasswordSessionTransition() { - const hasPasswordBuffer = GreeterState.passwordBuffer && GreeterState.passwordBuffer.length > 0; - if (!passwordSubmitRequested && !hasPasswordBuffer) - return; - if (cancelingExternalAuthForPassword) - return; - if (passwordSessionTransitionRetryCount >= maxPasswordSessionTransitionRetries) { - pendingPasswordResponse = false; - awaitingExternalAuth = false; - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.stop(); - resetPasswordSessionTransition(true); - GreeterState.pamState = "error"; - authFeedbackMessage = currentAuthMessage(); - placeholderDelay.restart(); - Greetd.cancelSession(); - return; - } - cancelingExternalAuthForPassword = true; - passwordSessionTransitionRetryCount = passwordSessionTransitionRetryCount + 1; - awaitingExternalAuth = false; - pendingPasswordResponse = false; - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.stop(); - Greetd.cancelSession(); - } - - function startAuthSession(submitPassword) { - submitPassword = submitPassword === true; - if (!GreeterState.showPasswordInput || !GreeterState.username) - return; - if (GreeterState.unlocking) - return; - const hasPasswordBuffer = GreeterState.passwordBuffer && GreeterState.passwordBuffer.length > 0; - if (Greetd.state !== GreetdState.Inactive) { - if (pendingPasswordResponse && submitPassword) - submitBufferedPassword(); - else if (submitPassword) - passwordSubmitRequested = true; - return; - } - if (cancelingExternalAuthForPassword) { - if (submitPassword) - passwordSubmitRequested = true; - return; - } - if (!submitPassword && !hasPasswordBuffer && !root.greeterExternalAuthAvailable) - return; - pendingPasswordResponse = false; - passwordSubmitRequested = submitPassword; - awaitingExternalAuth = !submitPassword && !hasPasswordBuffer && root.greeterExternalAuthAvailable; - // Use greeterExternalAuthAvailable so systems with pam_fprintd but no hardware don't incur the 30 s wait. - const waitingOnPamExternalBeforePassword = submitPassword && root.greeterExternalAuthAvailable; - authTimeout.interval = (awaitingExternalAuth || waitingOnPamExternalBeforePassword) ? externalAuthTimeoutMs : defaultAuthTimeoutMs; - authTimeout.restart(); - Greetd.createSession(GreeterState.username); - } - - function maybeAutoStartExternalAuth() { - if (!GreeterState.showPasswordInput || !GreeterState.username) - return; - if (!root.greeterExternalAuthAvailable) - return; - if (GreeterState.unlocking || Greetd.state !== GreetdState.Inactive) - return; - if (passwordSubmitRequested || cancelingExternalAuthForPassword) - return; - if (GreeterState.passwordBuffer && GreeterState.passwordBuffer.length > 0) - return; - if (externalAuthAutoStartedForUser === GreeterState.username) - return; - - externalAuthAutoStartedForUser = GreeterState.username; - startAuthSession(false); - } - - function isExternalAuthPrompt(message, responseRequired) { - // Non-response PAM messages commonly represent waiting states (fprint/U2F/token touch). - return !responseRequired; - } - - Component.onDestruction: { - if (weatherInitialized) - WeatherService.removeRef(); - } - - function updateHyprlandLayout() { - if (CompositorService.isHyprland) { - hyprlandLayoutProcess.running = true; - } - } - - Process { - id: hyprlandLayoutProcess - running: false - command: ["hyprctl", "-j", "devices"] - stdout: StdioCollector { - onStreamFinished: { - try { - const data = JSON.parse(text); - const mainKeyboard = data.keyboards.find(kb => kb.main === true); - if (!mainKeyboard) { - hyprlandCurrentLayout = ""; - hyprlandLayoutCount = 0; - return; - } - hyprlandKeyboard = mainKeyboard.name; - if (mainKeyboard.active_keymap) { - const parts = mainKeyboard.active_keymap.split(" "); - hyprlandCurrentLayout = parts[0].substring(0, 2).toUpperCase(); - } else { - hyprlandCurrentLayout = ""; - } - hyprlandLayoutCount = mainKeyboard.layout ? mainKeyboard.layout.split(",").length : 0; - } catch (e) { - hyprlandCurrentLayout = ""; - hyprlandLayoutCount = 0; - } - } - } - } - - // Probe fprintd D-Bus for physically enrolled scanners to eliminate PAM stack false-positives. - Process { - id: fprintdDeviceProbe - running: false - // sh wrapper: emits PROBE_UNAVAILABLE if gdbus is absent or fprintd unreachable, - // keeping the PAM-only fallback active in those cases. - command: ["sh", "-c", - "command -v gdbus >/dev/null 2>&1 || { echo PROBE_UNAVAILABLE; exit 0; }; " + - "gdbus call --system " + - "--dest net.reactivated.Fprint " + - "--object-path /net/reactivated/Fprint/Manager " + - "--method net.reactivated.Fprint.Manager.GetDevices 2>/dev/null " + - "|| echo PROBE_UNAVAILABLE"] - stdout: StdioCollector { - onStreamFinished: { - if (text.includes("PROBE_UNAVAILABLE")) - return; // PAM-only fallback stays active - root.fprintdHasDevice = text.includes("objectpath"); - root.fprintdProbeComplete = true; - root.maybeAutoStartExternalAuth(); - } - } - onExited: function(exitCode, exitStatus) { - if (!root.fprintdProbeComplete) - root.maybeAutoStartExternalAuth(); // PAM-only fallback stays active - } - } - - Connections { - target: CompositorService.isHyprland ? Hyprland : null - enabled: CompositorService.isHyprland - - function onRawEvent(event) { - if (event.name === "activelayout") - updateHyprlandLayout(); - } - } - - Connections { - target: GreetdMemory - enabled: isPrimaryScreen - function onLastSuccessfulUserChanged() { - applyLastSuccessfulUser(); - } - function onMemoryReadyChanged() { - finalizeSessionSelection(); - } - } - - Connections { - target: GreeterState - function onUsernameChanged() { - if (GreeterState.username) { - PortalService.getGreeterUserProfileImage(GreeterState.username); - } - } - } - - FileView { - id: greeterWallpaperOverrideFile - path: GreetdSettings.greeterWallpaperOverridePath - printErrors: false - watchChanges: true - onLoaded: root.greeterWallpaperOverrideExists = true - onLoadFailed: root.greeterWallpaperOverrideExists = false - } - - Connections { - target: GreetdSettings - function onGreeterWallpaperOverridePathChanged() { - if (!GreetdSettings.greeterWallpaperOverridePath) { - root.greeterWallpaperOverrideExists = false; - return; - } - greeterWallpaperOverrideFile.reload(); - } - function onGreeterWallpaperPathChanged() { - if (!GreetdSettings.greeterWallpaperPath) { - root.greeterWallpaperOverrideExists = false; - return; - } - greeterWallpaperOverrideFile.reload(); - } - } - - DankBackdrop { - anchors.fill: parent - screenName: root.screenName - visible: { - if (GreetdSettings.greeterWallpaperPath !== "" && root.greeterWallpaperOverrideExists) - return false; - var _ = SessionData.perMonitorWallpaper; - var __ = SessionData.monitorWallpapers; - var currentWallpaper = SessionData.getMonitorWallpaper(screenName); - return !currentWallpaper || currentWallpaper === "" || (currentWallpaper && currentWallpaper.startsWith("#")); - } - } - - Image { - id: wallpaperBackground - - anchors.fill: parent - source: { - if (GreetdSettings.greeterWallpaperPath !== "" && root.greeterWallpaperOverrideExists) - return encodeFileUrl(GreetdSettings.greeterWallpaperOverridePath); - var _ = SessionData.perMonitorWallpaper; - var __ = SessionData.monitorWallpapers; - var currentWallpaper = SessionData.getMonitorWallpaper(screenName); - return (currentWallpaper && !currentWallpaper.startsWith("#")) ? encodeFileUrl(currentWallpaper) : ""; - } - fillMode: Theme.getFillMode(GreetdSettings.getEffectiveWallpaperFillMode()) - smooth: true - asynchronous: false - cache: true - visible: source !== "" - layer.enabled: true - - layer.effect: MultiEffect { - autoPaddingEnabled: false - blurEnabled: true - blur: 0.8 - blurMax: 32 - blurMultiplier: 1 - } - - Behavior on opacity { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.standardEasing - } - } - } - - Rectangle { - anchors.fill: parent - color: "black" - opacity: 0.4 - } - - SystemClock { - id: systemClock - precision: SystemClock.Seconds - } - - Rectangle { - anchors.fill: parent - color: "transparent" - - Item { - id: clockContainer - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.verticalCenter - anchors.bottomMargin: 60 - width: parent.width - height: clockText.implicitHeight - - Row { - id: clockText - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - spacing: 0 - - property string fullTimeStr: { - const format = GreetdSettings.getEffectiveTimeFormat(); - return systemClock.date.toLocaleTimeString(I18n.locale(), format); - } - property var timeParts: fullTimeStr.split(':') - property string hours: timeParts[0] || "" - property string minutes: timeParts[1] || "" - property string secondsWithAmPm: timeParts.length > 2 ? timeParts[2] : "" - property string seconds: secondsWithAmPm.replace(/\s*(AM|PM|am|pm)$/i, '') - property string ampm: { - const match = fullTimeStr.match(/\s*(AM|PM|am|pm)$/i); - return match ? match[0].trim() : ""; - } - property bool hasSeconds: timeParts.length > 2 - - StyledText { - width: 75 - text: clockText.hours.length > 1 ? clockText.hours[0] : "" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - horizontalAlignment: Text.AlignHCenter - } - - StyledText { - width: 75 - text: clockText.hours.length > 1 ? clockText.hours[1] : clockText.hours.length > 0 ? clockText.hours[0] : "" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - horizontalAlignment: Text.AlignHCenter - } - - StyledText { - text: ":" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - } - - StyledText { - width: 75 - text: clockText.minutes.length > 0 ? clockText.minutes[0] : "" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - horizontalAlignment: Text.AlignHCenter - } - - StyledText { - width: 75 - text: clockText.minutes.length > 1 ? clockText.minutes[1] : "" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - horizontalAlignment: Text.AlignHCenter - } - - StyledText { - text: clockText.hasSeconds ? ":" : "" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - visible: clockText.hasSeconds - } - - StyledText { - width: 75 - text: clockText.hasSeconds && clockText.seconds.length > 0 ? clockText.seconds[0] : "" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - horizontalAlignment: Text.AlignHCenter - visible: clockText.hasSeconds - } - - StyledText { - width: 75 - text: clockText.hasSeconds && clockText.seconds.length > 1 ? clockText.seconds[1] : "" - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - horizontalAlignment: Text.AlignHCenter - visible: clockText.hasSeconds - } - - StyledText { - width: 20 - text: " " - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - visible: clockText.ampm !== "" - } - - StyledText { - text: clockText.ampm - font.pixelSize: 120 - font.weight: Font.Light - color: "white" - visible: clockText.ampm !== "" - } - } - } - - StyledText { - id: dateText - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: clockContainer.bottom - anchors.topMargin: 4 - text: { - return systemClock.date.toLocaleDateString(I18n.locale(), GreetdSettings.getEffectiveLockDateFormat()); - } - font.pixelSize: Theme.fontSizeXLarge - color: "white" - opacity: 0.9 - } - - Item { - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: dateText.bottom - anchors.topMargin: Theme.spacingL - width: 380 - height: 140 - - ColumnLayout { - anchors.fill: parent - spacing: Theme.spacingM - - RowLayout { - spacing: Theme.spacingL - Layout.fillWidth: true - - DankCircularImage { - Layout.preferredWidth: 60 - Layout.preferredHeight: 60 - imageSource: { - if (PortalService.profileImage === "") - return ""; - if (PortalService.profileImage.startsWith("/")) - return encodeFileUrl(PortalService.profileImage); - return PortalService.profileImage; - } - fallbackIcon: "person" - visible: GreetdSettings.lockScreenShowProfileImage - } - - Rectangle { - property bool showPassword: false - - Layout.fillWidth: true - Layout.preferredHeight: 60 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9) - border.color: inputField.activeFocus ? Theme.primary : Qt.rgba(1, 1, 1, 0.3) - border.width: inputField.activeFocus ? 2 : 1 - - DankIcon { - id: lockIcon - - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - name: GreeterState.showPasswordInput ? "lock" : "person" - size: 20 - color: inputField.activeFocus ? Theme.primary : Theme.surfaceVariantText - } - - TextInput { - id: inputField - - property bool syncingFromState: false - - anchors.fill: parent - anchors.leftMargin: lockIcon.width + Theme.spacingM * 2 - anchors.rightMargin: { - let margin = Theme.spacingM; - if (GreeterState.showPasswordInput && revealButton.visible) { - margin += revealButton.width; - } - if (externalAuthButton.visible) { - margin += externalAuthButton.width; - } - if (virtualKeyboardButton.visible) { - margin += virtualKeyboardButton.width; - } - if (enterButton.visible) { - margin += enterButton.width + 2; - } - return margin; - } - opacity: 0 - focus: true - echoMode: GreeterState.showPasswordInput ? (parent.showPassword ? TextInput.Normal : TextInput.Password) : TextInput.Normal - onTextChanged: { - if (syncingFromState) - return; - if (GreeterState.showPasswordInput) { - GreeterState.passwordBuffer = text; - if (!text || text.length === 0) - root.passwordSubmitRequested = false; - } else { - GreeterState.usernameInput = text; - } - } - onAccepted: { - if (GreeterState.showPasswordInput) { - root.startAuthSession(true); - } else { - if (text.trim()) { - root.submitUsername(text); - syncingFromState = true; - text = ""; - syncingFromState = false; - } - } - } - - Component.onCompleted: { - syncingFromState = true; - text = GreeterState.showPasswordInput ? GreeterState.passwordBuffer : GreeterState.usernameInput; - syncingFromState = false; - if (isPrimaryScreen && !powerMenu.isVisible) - forceActiveFocus(); - } - onVisibleChanged: { - if (visible && isPrimaryScreen && !powerMenu.isVisible) - forceActiveFocus(); - } - } - - KeyboardController { - id: keyboard_controller - target: inputField - rootObject: root - } - - StyledText { - id: placeholder - - anchors.left: lockIcon.right - anchors.leftMargin: Theme.spacingM - anchors.right: (GreeterState.showPasswordInput && revealButton.visible ? revealButton.left : (externalAuthButton.visible ? externalAuthButton.left : (virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : parent.right)))) - anchors.rightMargin: 2 - anchors.verticalCenter: parent.verticalCenter - text: { - if (GreeterState.unlocking) { - return I18n.tr("Logging in..."); - } - if (Greetd.state !== GreetdState.Inactive && !awaitingExternalAuth && !pendingPasswordResponse) { - return I18n.tr("Authenticating..."); - } - if (GreeterState.showPasswordInput) { - return I18n.tr("Password..."); - } - return I18n.tr("Username..."); - } - color: (GreeterState.unlocking || (Greetd.state !== GreetdState.Inactive && !awaitingExternalAuth && !pendingPasswordResponse)) ? Theme.primary : Theme.outline - font.pixelSize: Theme.fontSizeMedium - opacity: (GreeterState.showPasswordInput ? GreeterState.passwordBuffer.length === 0 : GreeterState.usernameInput.length === 0) ? 1 : 0 - - Behavior on opacity { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.standardEasing - } - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - - StyledText { - anchors.left: lockIcon.right - anchors.leftMargin: Theme.spacingM - anchors.right: (GreeterState.showPasswordInput && revealButton.visible ? revealButton.left : (externalAuthButton.visible ? externalAuthButton.left : (virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : parent.right)))) - anchors.rightMargin: 2 - anchors.verticalCenter: parent.verticalCenter - text: { - if (GreeterState.showPasswordInput) { - if (parent.showPassword) { - return GreeterState.passwordBuffer; - } - return "•".repeat(GreeterState.passwordBuffer.length); - } - return GreeterState.usernameInput; - } - color: Theme.surfaceText - font.pixelSize: (GreeterState.showPasswordInput && !parent.showPassword) ? Theme.fontSizeLarge : Theme.fontSizeMedium - opacity: (GreeterState.showPasswordInput ? GreeterState.passwordBuffer.length > 0 : GreeterState.usernameInput.length > 0) ? 1 : 0 - clip: true - elide: Text.ElideNone - horizontalAlignment: implicitWidth > width ? Text.AlignRight : Text.AlignLeft - - Behavior on opacity { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.standardEasing - } - } - } - - DankActionButton { - id: revealButton - - anchors.right: externalAuthButton.visible ? externalAuthButton.left : (virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : parent.right)) - anchors.rightMargin: 0 - anchors.verticalCenter: parent.verticalCenter - iconName: parent.showPassword ? "visibility_off" : "visibility" - buttonSize: 32 - visible: GreeterState.showPasswordInput && GreeterState.passwordBuffer.length > 0 && (Greetd.state === GreetdState.Inactive || awaitingExternalAuth || pendingPasswordResponse) && !GreeterState.unlocking - enabled: visible - onClicked: parent.showPassword = !parent.showPassword - } - DankActionButton { - id: externalAuthButton - - anchors.right: virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : parent.right) - anchors.rightMargin: 0 - anchors.verticalCenter: parent.verticalCenter - iconName: root.greeterPamHasFprint ? "fingerprint" : "key" - buttonSize: 32 - visible: GreeterState.showPasswordInput && root.greeterExternalAuthAvailable && GreeterState.passwordBuffer.length === 0 && (Greetd.state === GreetdState.Inactive || awaitingExternalAuth || pendingPasswordResponse) && !GreeterState.unlocking - enabled: visible - onClicked: root.startAuthSession(false) - } - DankActionButton { - id: virtualKeyboardButton - - anchors.right: enterButton.visible ? enterButton.left : parent.right - anchors.rightMargin: enterButton.visible ? 0 : Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - iconName: "keyboard" - buttonSize: 32 - visible: (Greetd.state === GreetdState.Inactive || awaitingExternalAuth || pendingPasswordResponse) && !GreeterState.unlocking - enabled: visible - onClicked: { - if (keyboard_controller.isKeyboardActive) { - keyboard_controller.hide(); - } else { - keyboard_controller.show(); - } - } - } - - DankActionButton { - id: enterButton - - anchors.right: parent.right - anchors.rightMargin: 2 - anchors.verticalCenter: parent.verticalCenter - iconName: "keyboard_return" - buttonSize: 36 - visible: (Greetd.state === GreetdState.Inactive || awaitingExternalAuth || pendingPasswordResponse) && !GreeterState.unlocking - enabled: true - onClicked: { - if (GreeterState.showPasswordInput) { - root.startAuthSession(true); - } else { - if (inputField.text.trim()) { - root.submitUsername(inputField.text); - inputField.text = ""; - } - } - } - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - - Behavior on border.color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - - StyledText { - Layout.fillWidth: true - Layout.preferredHeight: 38 - Layout.topMargin: -Theme.spacingS - Layout.bottomMargin: -Theme.spacingS - text: root.authFeedbackMessage - color: Theme.error - font.pixelSize: Theme.fontSizeSmall - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - maximumLineCount: 2 - opacity: root.authFeedbackMessage !== "" ? 1 : 0 - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - - Rectangle { - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: 0 - Layout.preferredWidth: switchUserRow.width + Theme.spacingL * 2 - Layout.preferredHeight: 40 - radius: Theme.cornerRadius - color: Theme.surfaceContainer - opacity: GreeterState.showPasswordInput ? 1 : 0 - enabled: GreeterState.showPasswordInput - - Behavior on opacity { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.standardEasing - } - } - - Row { - id: switchUserRow - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: "people" - size: Theme.iconSize - 4 - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Switch User") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - StateLayer { - stateColor: Theme.primary - cornerRadius: parent.radius - enabled: !GreeterState.unlocking && Greetd.state === GreetdState.Inactive && GreeterState.showPasswordInput - onClicked: { - GreeterState.reset(); - root.externalAuthAutoStartedForUser = ""; - inputField.text = ""; - PortalService.profileImage = ""; - } - } - } - } - } - - Row { - anchors.top: parent.top - anchors.right: parent.right - anchors.margins: Theme.spacingXL - spacing: Theme.spacingL - - Item { - width: keyboardLayoutRow.width - height: keyboardLayoutRow.height - anchors.verticalCenter: parent.verticalCenter - visible: { - if (CompositorService.isNiri) { - return NiriService.keyboardLayoutNames.length > 1; - } else if (CompositorService.isHyprland) { - return hyprlandLayoutCount > 1; - } - return false; - } - - Row { - id: keyboardLayoutRow - spacing: 4 - - Item { - width: Theme.iconSize - height: Theme.iconSize - - DankIcon { - name: "keyboard" - size: Theme.iconSize - color: "white" - anchors.centerIn: parent - } - } - - Item { - width: childrenRect.width - height: Theme.iconSize - - StyledText { - text: { - if (CompositorService.isNiri) { - const layout = NiriService.getCurrentKeyboardLayoutName(); - if (!layout) - return ""; - const parts = layout.split(" "); - if (parts.length > 0) { - return parts[0].substring(0, 2).toUpperCase(); - } - return layout.substring(0, 2).toUpperCase(); - } else if (CompositorService.isHyprland) { - return hyprlandCurrentLayout; - } - return ""; - } - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Light - color: "white" - anchors.verticalCenter: parent.verticalCenter - } - } - } - - MouseArea { - id: keyboardLayoutArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - if (CompositorService.isNiri) { - NiriService.cycleKeyboardLayout(); - } else if (CompositorService.isHyprland) { - Quickshell.execDetached(["hyprctl", "switchxkblayout", hyprlandKeyboard, "next"]); - updateHyprlandLayout(); - } - } - } - } - - Rectangle { - width: 1 - height: 24 - color: Qt.rgba(255, 255, 255, 0.2) - anchors.verticalCenter: parent.verticalCenter - visible: { - const keyboardVisible = (CompositorService.isNiri && NiriService.keyboardLayoutNames.length > 1) || (CompositorService.isHyprland && hyprlandLayoutCount > 1); - return keyboardVisible && GreetdSettings.weatherEnabled && WeatherService.weather.available; - } - } - - Row { - spacing: 6 - visible: GreetdSettings.weatherEnabled && WeatherService.weather.available - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - name: WeatherService.getWeatherIcon(WeatherService.weather.wCode) - size: Theme.iconSize - color: "white" - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: (GreetdSettings.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp) + "°" - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Light - color: "white" - anchors.verticalCenter: parent.verticalCenter - } - } - - Rectangle { - width: 1 - height: 24 - color: Qt.rgba(255, 255, 255, 0.2) - anchors.verticalCenter: parent.verticalCenter - visible: GreetdSettings.weatherEnabled && WeatherService.weather.available && (NetworkService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio) || BatteryService.batteryAvailable) - } - - Row { - spacing: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - visible: NetworkService.networkStatus !== "disconnected" || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio) - - DankIcon { - name: NetworkService.networkStatus === "ethernet" ? "lan" : NetworkService.wifiSignalIcon - size: Theme.iconSize - 2 - color: NetworkService.networkStatus !== "disconnected" ? "white" : Qt.rgba(255, 255, 255, 0.5) - anchors.verticalCenter: parent.verticalCenter - visible: NetworkService.networkStatus !== "disconnected" - } - - DankIcon { - name: "bluetooth" - size: Theme.iconSize - 2 - color: "white" - anchors.verticalCenter: parent.verticalCenter - visible: BluetoothService.available && BluetoothService.enabled - } - - DankIcon { - name: { - if (!AudioService.sink?.audio) { - return "volume_up"; - } - if (AudioService.sink.audio.muted) - return "volume_off"; - if (AudioService.sink.audio.volume === 0) - return "volume_mute"; - if (AudioService.sink.audio.volume * 100 < 33) { - return "volume_down"; - } - return "volume_up"; - } - size: Theme.iconSize - 2 - color: (AudioService.sink && AudioService.sink.audio && (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0)) ? Qt.rgba(255, 255, 255, 0.5) : "white" - anchors.verticalCenter: parent.verticalCenter - visible: AudioService.sink && AudioService.sink.audio - } - } - - Rectangle { - width: 1 - height: 24 - color: Qt.rgba(255, 255, 255, 0.2) - anchors.verticalCenter: parent.verticalCenter - visible: BatteryService.batteryAvailable && (NetworkService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio)) - } - - Row { - spacing: 4 - visible: BatteryService.batteryAvailable - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - name: { - if (BatteryService.isCharging) { - if (BatteryService.batteryLevel >= 90) { - return "battery_charging_full"; - } - - if (BatteryService.batteryLevel >= 80) { - return "battery_charging_90"; - } - - if (BatteryService.batteryLevel >= 60) { - return "battery_charging_80"; - } - - if (BatteryService.batteryLevel >= 50) { - return "battery_charging_60"; - } - - if (BatteryService.batteryLevel >= 30) { - return "battery_charging_50"; - } - - if (BatteryService.batteryLevel >= 20) { - return "battery_charging_30"; - } - - return "battery_charging_20"; - } - if (BatteryService.isPluggedIn) { - if (BatteryService.batteryLevel >= 90) { - return "battery_charging_full"; - } - - if (BatteryService.batteryLevel >= 80) { - return "battery_charging_90"; - } - - if (BatteryService.batteryLevel >= 60) { - return "battery_charging_80"; - } - - if (BatteryService.batteryLevel >= 50) { - return "battery_charging_60"; - } - - if (BatteryService.batteryLevel >= 30) { - return "battery_charging_50"; - } - - if (BatteryService.batteryLevel >= 20) { - return "battery_charging_30"; - } - - return "battery_charging_20"; - } - if (BatteryService.batteryLevel >= 95) { - return "battery_full"; - } - - if (BatteryService.batteryLevel >= 85) { - return "battery_6_bar"; - } - - if (BatteryService.batteryLevel >= 70) { - return "battery_5_bar"; - } - - if (BatteryService.batteryLevel >= 55) { - return "battery_4_bar"; - } - - if (BatteryService.batteryLevel >= 40) { - return "battery_3_bar"; - } - - if (BatteryService.batteryLevel >= 25) { - return "battery_2_bar"; - } - - return "battery_1_bar"; - } - size: Theme.iconSize - color: { - if (BatteryService.isLowBattery && !BatteryService.isCharging) { - return Theme.error; - } - - if (BatteryService.isCharging || BatteryService.isPluggedIn) { - return Theme.primary; - } - - return "white"; - } - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: BatteryService.batteryLevel + "%" - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Light - color: "white" - anchors.verticalCenter: parent.verticalCenter - } - } - } - - DankActionButton { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.margins: Theme.spacingXL - visible: GreetdSettings.lockScreenShowPowerActions - iconName: "power_settings_new" - iconColor: Theme.error - buttonSize: 40 - onClicked: powerMenu.show() - } - - Item { - anchors.bottom: parent.bottom - anchors.right: parent.right - anchors.margins: Theme.spacingXL - width: Math.max(200, currentSessionMetrics.width + 80) - height: 60 - - StyledTextMetrics { - id: currentSessionMetrics - text: root.currentSessionName - } - - property real longestSessionWidth: { - let maxWidth = 0; - for (var i = 0; i < sessionMetricsRepeater.count; i++) { - const item = sessionMetricsRepeater.itemAt(i); - if (item && item.width > maxWidth) { - maxWidth = item.width; - } - } - return maxWidth; - } - - Repeater { - id: sessionMetricsRepeater - model: GreeterState.sessionList - delegate: StyledTextMetrics { - text: modelData - } - } - - DankDropdown { - id: sessionDropdown - anchors.fill: parent - text: "" - description: "" - currentValue: root.currentSessionName - options: GreeterState.sessionList - enableFuzzySearch: GreeterState.sessionList.length > 5 - popupWidthOffset: 0 - popupWidth: Math.max(250, parent.longestSessionWidth + 100) - openUpwards: true - alignPopupRight: true - onValueChanged: value => { - const idx = GreeterState.sessionList.indexOf(value); - if (idx < 0) - return; - GreeterState.currentSessionIndex = idx; - GreeterState.selectedSession = GreeterState.sessionExecs[idx]; - GreeterState.selectedSessionPath = GreeterState.sessionPaths[idx]; - } - } - } - } - - property string currentSessionName: GreeterState.sessionList[GreeterState.currentSessionIndex] || "" - - function finalizeSessionSelection() { - if (GreeterState.sessionList.length === 0) - return; - if (!GreetdMemory.memoryReady) - return; - if (!GreetdSettings.settingsLoaded) - return; - - const savedSession = GreetdSettings.rememberLastSession ? GreetdMemory.lastSessionId : ""; - if (savedSession && GreetdSettings.rememberLastSession) { - for (var i = 0; i < GreeterState.sessionPaths.length; i++) { - if (GreeterState.sessionPaths[i] === savedSession) { - GreeterState.currentSessionIndex = i; - GreeterState.selectedSession = GreeterState.sessionExecs[i] || ""; - GreeterState.selectedSessionPath = GreeterState.sessionPaths[i]; - return; - } - } - } - - GreeterState.currentSessionIndex = 0; - GreeterState.selectedSession = GreeterState.sessionExecs[0] || ""; - GreeterState.selectedSessionPath = GreeterState.sessionPaths[0] || ""; - } - - property var sessionDirs: { - const homeDir = Quickshell.env("HOME") || ""; - const dirs = ["/usr/share/wayland-sessions", "/usr/share/xsessions", "/usr/local/share/wayland-sessions", "/usr/local/share/xsessions"]; - - if (homeDir) { - dirs.push(homeDir + "/.local/share/wayland-sessions"); - dirs.push(homeDir + "/.local/share/xsessions"); - } - - if (xdgDataDirs) { - xdgDataDirs.split(":").forEach(dir => { - if (dir) { - dirs.push(dir + "/wayland-sessions"); - dirs.push(dir + "/xsessions"); - } - }); - } - return dirs; - } - - property var _pendingFiles: ({}) - property int _pendingCount: 0 - - function _addSession(path, name, exec) { - if (!name || !exec || GreeterState.sessionList.includes(name)) - return; - GreeterState.sessionList = GreeterState.sessionList.concat([name]); - GreeterState.sessionExecs = GreeterState.sessionExecs.concat([exec]); - GreeterState.sessionPaths = GreeterState.sessionPaths.concat([path]); - } - - function _parseDesktopFile(content, path) { - let name = ""; - let exec = ""; - const lines = content.split("\n"); - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; - if (!name && line.startsWith("Name=")) - name = line.substring(5).trim(); - else if (!exec && line.startsWith("Exec=")) - exec = line.substring(5).trim(); - if (name && exec) - break; - } - _addSession(path, name, exec); - } - - function _loadDesktopFile(filePath) { - if (_pendingFiles[filePath]) - return; - _pendingFiles[filePath] = true; - _pendingCount++; - - const loader = desktopFileLoader.createObject(root, { - "filePath": filePath - }); - } - - function _onFileLoaded(filePath) { - _pendingCount--; - if (_pendingCount === 0) - Qt.callLater(finalizeSessionSelection); - } - - Component { - id: desktopFileLoader - - FileView { - id: fv - property string filePath: "" - path: filePath - - onLoaded: { - root._parseDesktopFile(text(), filePath); - root._onFileLoaded(filePath); - fv.destroy(); - } - - onLoadFailed: { - root._onFileLoaded(filePath); - fv.destroy(); - } - } - } - - Repeater { - model: isPrimaryScreen ? sessionDirs : [] - - Item { - required property string modelData - - FolderListModel { - folder: encodeFileUrl(modelData) - nameFilters: ["*.desktop"] - showDirs: false - showDotAndDotDot: false - - onStatusChanged: { - if (status !== FolderListModel.Ready) - return; - for (let i = 0; i < count; i++) { - let fp = get(i, "filePath"); - if (fp.startsWith("file://")) - fp = fp.substring(7); - root._loadDesktopFile(fp); - } - } - } - } - } - - Connections { - target: Greetd - enabled: isPrimaryScreen - - function onAuthMessage(message, error, responseRequired, echoResponse) { - if (responseRequired) { - cancelingExternalAuthForPassword = false; - passwordSessionTransitionRetryCount = 0; - awaitingExternalAuth = false; - pendingPasswordResponse = true; - const hasPasswordBuffer = GreeterState.passwordBuffer && GreeterState.passwordBuffer.length > 0; - if (!passwordSubmitRequested && hasPasswordBuffer) - passwordSubmitRequested = true; - if (passwordSubmitRequested && !root.submitBufferedPassword()) - passwordSubmitRequested = false; - if (passwordSubmitRequested || hasPasswordBuffer) { - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.restart(); - } else { - authTimeout.stop(); - } - return; - } - pendingPasswordResponse = false; - const externalPrompt = root.isExternalAuthPrompt(message, responseRequired); - if (!passwordSubmitRequested) - awaitingExternalAuth = root.greeterExternalAuthAvailable && externalPrompt; - if (awaitingExternalAuth || (passwordSubmitRequested && externalPrompt && root.greeterPamHasExternalAuth)) - authTimeout.interval = externalAuthTimeoutMs; - else - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.restart(); - Greetd.respond(""); - } - - function onStateChanged() { - if (Greetd.state === GreetdState.Inactive) { - const resumePasswordSubmit = cancelingExternalAuthForPassword && passwordSubmitRequested; - awaitingExternalAuth = false; - pendingPasswordResponse = false; - cancelingExternalAuthForPassword = false; - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.stop(); - if (resumePasswordSubmit) { - Qt.callLater(function() { - root.startAuthSession(true); - }); - return; - } - resetPasswordSessionTransition(true); - } - } - - function onReadyToLaunch() { - awaitingExternalAuth = false; - pendingPasswordResponse = false; - resetPasswordSessionTransition(true); - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.stop(); - passwordFailureCount = 0; - clearAuthFeedback(); - const sessionCmd = GreeterState.selectedSession || GreeterState.sessionExecs[GreeterState.currentSessionIndex]; - const sessionPath = GreeterState.selectedSessionPath || GreeterState.sessionPaths[GreeterState.currentSessionIndex]; - if (!sessionCmd) { - GreeterState.pamState = "error"; - authFeedbackMessage = currentAuthMessage(); - placeholderDelay.restart(); - return; - } - - GreeterState.unlocking = true; - launchTimeout.restart(); - if (GreetdSettings.rememberLastSession) { - GreetdMemory.setLastSessionId(sessionPath); - } else if (GreetdMemory.lastSessionId) { - GreetdMemory.setLastSessionId(""); - } - if (GreetdSettings.rememberLastUser) { - GreetdMemory.setLastSuccessfulUser(GreeterState.username); - } else if (GreetdMemory.lastSuccessfulUser) { - GreetdMemory.setLastSuccessfulUser(""); - } - pendingLaunchCommand = sessionCmd; - pendingLaunchEnv = ["XDG_SESSION_TYPE=wayland"]; - memoryFlushTimer.restart(); - } - - function onAuthFailure(message) { - awaitingExternalAuth = false; - pendingPasswordResponse = false; - resetPasswordSessionTransition(true); - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.stop(); - launchTimeout.stop(); - GreeterState.unlocking = false; - if (isLikelyLockoutMessage(message)) { - GreeterState.pamState = "max"; - } else { - GreeterState.pamState = "fail"; - passwordFailureCount = passwordFailureCount + 1; - } - authFeedbackMessage = currentAuthMessage(); - GreeterState.passwordBuffer = ""; - inputField.text = ""; - placeholderDelay.restart(); - Greetd.cancelSession(); - } - - function onError(error) { - awaitingExternalAuth = false; - pendingPasswordResponse = false; - resetPasswordSessionTransition(true); - authTimeout.interval = defaultAuthTimeoutMs; - authTimeout.stop(); - launchTimeout.stop(); - GreeterState.unlocking = false; - GreeterState.pamState = "error"; - authFeedbackMessage = currentAuthMessage(); - GreeterState.passwordBuffer = ""; - inputField.text = ""; - placeholderDelay.restart(); - Greetd.cancelSession(); - } - } - - Timer { - id: memoryFlushTimer - interval: memoryFlushDelayMs - onTriggered: { - if (!pendingLaunchCommand) - return; - const sessionCommand = pendingLaunchCommand; - const launchEnv = pendingLaunchEnv; - pendingLaunchCommand = ""; - pendingLaunchEnv = []; - Greetd.launch(sessionCommand.split(" "), launchEnv); - } - } - - Timer { - id: authTimeout - interval: defaultAuthTimeoutMs - onTriggered: { - if (GreeterState.unlocking || Greetd.state === GreetdState.Inactive) - return; - awaitingExternalAuth = false; - pendingPasswordResponse = false; - resetPasswordSessionTransition(true); - authTimeout.interval = defaultAuthTimeoutMs; - GreeterState.pamState = "error"; - authFeedbackMessage = currentAuthMessage(); - GreeterState.passwordBuffer = ""; - inputField.text = ""; - placeholderDelay.restart(); - Greetd.cancelSession(); - } - } - - Timer { - id: launchTimeout - interval: 8000 - onTriggered: { - if (!GreeterState.unlocking) - return; - pendingPasswordResponse = false; - resetPasswordSessionTransition(true); - GreeterState.unlocking = false; - GreeterState.pamState = "error"; - authFeedbackMessage = currentAuthMessage(); - placeholderDelay.restart(); - Greetd.cancelSession(); - } - } - - Timer { - id: placeholderDelay - interval: 4000 - onTriggered: clearAuthFeedback() - } - - LockPowerMenu { - id: powerMenu - showLogout: false - powerActionConfirmOverride: GreetdSettings.powerActionConfirm - powerActionHoldDurationOverride: GreetdSettings.powerActionHoldDuration - powerMenuActionsOverride: GreetdSettings.powerMenuActions - powerMenuDefaultActionOverride: GreetdSettings.powerMenuDefaultAction - powerMenuGridLayoutOverride: GreetdSettings.powerMenuGridLayout - requiredActions: ["poweroff"] - onClosed: { - if (isPrimaryScreen && inputField && inputField.forceActiveFocus) { - Qt.callLater(() => inputField.forceActiveFocus()); - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterState.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterState.qml deleted file mode 100644 index ac57de7..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterState.qml +++ /dev/null @@ -1,30 +0,0 @@ -pragma Singleton -pragma ComponentBehavior: Bound -import QtQuick -import Quickshell - -Singleton { - id: root - - property string passwordBuffer: "" - property string username: "" - property string usernameInput: "" - property bool showPasswordInput: false - property string selectedSession: "" - property string selectedSessionPath: "" - property string pamState: "" - property bool unlocking: false - - property var sessionList: [] - property var sessionExecs: [] - property var sessionPaths: [] - property int currentSessionIndex: 0 - - function reset() { - showPasswordInput = false; - username = ""; - usernameInput = ""; - passwordBuffer = ""; - pamState = ""; - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterSurface.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterSurface.qml deleted file mode 100644 index a8af5df..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/GreeterSurface.qml +++ /dev/null @@ -1,34 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell -import Quickshell.Wayland -import Quickshell.Services.Greetd -import qs.Common - -Variants { - model: Quickshell.screens - - PanelWindow { - id: root - - property var modelData - - screen: modelData - anchors { - left: true - right: true - top: true - bottom: true - } - exclusionMode: ExclusionMode.Normal - WlrLayershell.layer: WlrLayer.Overlay - WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive - color: "transparent" - - GreeterContent { - anchors.fill: parent - screenName: root.screen?.name ?? "" - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/README.md b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/README.md deleted file mode 100644 index 4ac5a77..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/README.md +++ /dev/null @@ -1,277 +0,0 @@ -# Dank (dms) Greeter - -A greeter for [greetd](https://github.com/kennylevinsen/greetd) that follows the aesthetics of the dms lock screen. - -## Features - -- **Multi user**: Login with any system user -- **dms sync**: Sync settings with dms for consistent styling between shell and greeter -- **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` - -## Installation - -### Arch Linux - -Arch linux users can install [greetd-dms-greeter-git](https://aur.archlinux.org/packages/greetd-dms-greeter-git) from the AUR. - -```bash -paru -S greetd-dms-greeter-git -# Or with yay -yay -S greetd-dms-greeter-git -``` - -### Debian / openSUSE - -Official packages are available from the [DankLinux OBS repository](https://software.opensuse.org/download/package?package=dms-greeter&project=home%3AAvengeMedia%3Adanklinux). Add the repo for your distribution and install: - -```bash -# Debian 13 -sudo apt install dms-greeter # after adding the repo - -# openSUSE Tumbleweed -zypper install dms-greeter # after adding the repo -``` - -See the [Installation guide](https://danklinux.com/docs/dankgreeter/installation) for full repository setup. - -If you previously installed manually, remove legacy files first: - -```bash -sudo rm -f /usr/local/bin/dms-greeter -sudo rm -rf /etc/xdg/quickshell/dms-greeter -``` - -Then complete setup: - -```bash -dms greeter enable -dms greeter sync -``` - -#### Syncing themes (Optional) - -To sync your wallpaper and theme with the greeter login screen, follow the manual setup below: - -<details> -<summary>Manual theme syncing</summary> - -```bash -# Add yourself to greeter group -sudo usermod -aG greeter <username> - -# Set ACLs to allow greeter to traverse your directories -setfacl -m u:greeter:x ~ ~/.config ~/.local ~/.cache ~/.local/state - -# Set group ownership on config directories -sudo chgrp -R greeter ~/.config/DankMaterialShell -sudo chgrp -R greeter ~/.local/state/DankMaterialShell -sudo chgrp -R greeter ~/.cache/DankMaterialShell -sudo chmod -R g+rX ~/.config/DankMaterialShell ~/.cache/DankMaterialShell ~/.cache/quickshell - -# Create symlinks -sudo ln -sf ~/.config/DankMaterialShell/settings.json /var/cache/dms-greeter/settings.json -sudo ln -sf ~/.local/state/DankMaterialShell/session.json /var/cache/dms-greeter/session.json -sudo ln -sf ~/.cache/DankMaterialShell/dms-colors.json /var/cache/dms-greeter/colors.json - -# Logout and login for group membership to take effect -``` - -</details> - -### Fedora / RHEL / Rocky / Alma - -Install from COPR or build the RPM: - -```bash -# From COPR (when available) -sudo dnf copr enable avenge/dms -sudo dnf install dms-greeter - -# Or build locally -cd /path/to/DankMaterialShell -rpkg local -sudo rpm -ivh x86_64/dms-greeter-*.rpm -``` - -The package automatically: -- Creates the greeter user -- Sets up directories and permissions -- Configures greetd with auto-detected compositor -- Applies SELinux contexts - -Then complete setup: - -```bash -dms greeter enable -dms greeter sync -``` - -#### Syncing themes (Optional) - -Run: - -```bash -dms greeter sync -``` - -Then logout/login to see your wallpaper on the greeter. - -### Automatic - -The easiest thing is to run `dms greeter install` or `dms` for interactive installation. -On Debian/openSUSE, this now prefers the `dms-greeter` package when the OBS repo is configured. - -### Manual (fallback only) - -Use this only if no package is available for your distro. - -1. Install `greetd` (in most distro's standard repositories) and `quickshell` - -2. Create the greeter user (if not already created by greetd): -```bash -sudo groupadd -r greeter -sudo useradd -r -g greeter -d /var/lib/greeter -s /bin/bash -c "System Greeter" greeter -sudo mkdir -p /var/lib/greeter -sudo chown greeter:greeter /var/lib/greeter -``` - -3. Clone the dms project to `/etc/xdg/quickshell/dms-greeter`: -```bash -sudo git clone https://github.com/AvengeMedia/DankMaterialShell.git /etc/xdg/quickshell/dms-greeter -``` - -4. Copy `Modules/Greetd/assets/dms-greeter` to `/usr/local/bin/dms-greeter`: -```bash -sudo cp /etc/xdg/quickshell/dms-greeter/Modules/Greetd/assets/dms-greeter /usr/local/bin/dms-greeter -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-user>:<greeter-group> /var/cache/dms-greeter -sudo chmod 2770 /var/cache/dms-greeter -``` - -6. Edit or create `/etc/greetd/config.toml`: -```toml -[terminal] -vt = 1 - -[default_session] -user = "greeter" -# Change compositor to another wrapper-supported compositor if preferred -command = "/usr/local/bin/dms-greeter --command niri" -``` - -7. Disable existing display manager and enable greetd: -```bash -sudo systemctl disable gdm sddm lightdm -sudo systemctl enable greetd -``` - -8. (Optional) Set up theme syncing using the manual ACL method described in the Configuration → Personalization section below - -#### Legacy installation (deprecated) - -If you prefer the old method with separate shell scripts and config files: -1. Copy `assets/dms-niri.kdl` or `assets/dms-hypr.conf` to `/etc/greetd` -2. Copy `assets/greet-niri.sh` or `assets/greet-hyprland.sh` to `/usr/local/bin/start-dms-greetd.sh` -3. Edit the config file and replace `_DMS_PATH_` with your DMS installation path -4. Configure greetd to use `/usr/local/bin/start-dms-greetd.sh` - -### NixOS - -To install the greeter on NixOS add the repo to your flake inputs as described in the readme. Then somewhere in your NixOS config add this to imports: -```nix -imports = [ - inputs.dank-material-shell.nixosModules.greeter -] -``` - -Enable the greeter with this in your NixOS config: -```nix -programs.dank-material-shell.greeter = { - enable = true; - compositor.name = "niri"; # or set to hyprland - configHome = "/home/user"; # optionally copyies that users DMS settings (and wallpaper if set) to the greeters data directory as root before greeter starts -}; -``` - -## Usage - -### Using dms-greeter wrapper (recommended) - -The `dms-greeter` wrapper simplifies running the greeter with any compositor: - -```bash -dms-greeter --command niri -dms-greeter --command hyprland -dms-greeter --command sway -dms-greeter --command mangowc -dms-greeter --command niri -C /path/to/custom-niri.kdl -dms-greeter --command niri --remember-last-user false --remember-last-session false -``` - -Configure greetd to use it in `/etc/greetd/config.toml`: -```toml -[terminal] -vt = 1 - -[default_session] -user = "greeter" -command = "/usr/bin/dms-greeter --command niri" -``` - -### Manual usage - -To run dms in greeter mode you can also manually set environment variables: - -```bash -DMS_RUN_GREETER=1 qs -p /path/to/dms -``` - -### Configuration - -#### Compositor - -For current wrapper-based installs, the `dms-greeter` wrapper supports niri, hyprland, sway, scroll, miracle-wm, labwc, and mangowc. - -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 - -The greeter can be personalized with wallpapers, themes, weather, clock formats, and more - configured exactly the same as dms. - -**Easiest method:** Run `dms greeter sync` to automatically sync your DMS theme with the greeter. - -**Manual method:** You can manually synchronize configurations if you want greeter settings to always mirror your shell: - -```bash -# Add yourself to the greeter group -sudo usermod -aG greeter $USER - -# Set ACLs to allow greeter user to traverse your home directory -setfacl -m u:greeter:x ~ ~/.config ~/.local ~/.cache ~/.local/state - -# Set group permissions on DMS directories -sudo chgrp -R greeter ~/.config/DankMaterialShell ~/.local/state/DankMaterialShell ~/.cache/quickshell -sudo chmod -R g+rX ~/.config/DankMaterialShell ~/.local/state/DankMaterialShell ~/.cache/quickshell - -# Create symlinks for theme files -sudo ln -sf ~/.config/DankMaterialShell/settings.json /var/cache/dms-greeter/settings.json -sudo ln -sf ~/.local/state/DankMaterialShell/session.json /var/cache/dms-greeter/session.json -sudo ln -sf ~/.cache/DankMaterialShell/dms-colors.json /var/cache/dms-greeter/colors.json - -# Logout and login for group membership to take effect -``` - -**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-user>:<greeter-group>` with `2770` permissions. If the greeter user is not available yet, DMS falls back to `root:<greeter-group>`. diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-greeter b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-greeter deleted file mode 100755 index 5d3419c..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-greeter +++ /dev/null @@ -1,424 +0,0 @@ -#!/bin/bash - -set -e - -COMPOSITOR="" -COMPOSITOR_CONFIG="" -DMS_PATH="dms-greeter" -CACHE_DIR="/var/cache/dms-greeter" -REMEMBER_LAST_SESSION="" -REMEMBER_LAST_USER="" -DEBUG_MODE=0 - -show_help() { - cat << EOF -dms-greeter - DankMaterialShell greeter launcher - -Usage: dms-greeter --command COMPOSITOR [OPTIONS] - -Required: - --command COMPOSITOR Compositor to use (niri, hyprland, sway, scroll, miracle, mango, or labwc) - -Options: - -C, --config PATH Custom compositor config file - -p, --path PATH DMS path (config name or absolute path) - (default: dms-greeter) - --cache-dir PATH Cache directory for greeter data - (default: /var/cache/dms-greeter) - --remember-last-session BOOL - Persist selected session to greeter memory - (BOOL: true/false, default: from settings.json) - --remember-last-user BOOL - Persist last successful username to greeter memory - (BOOL: true/false, default: from settings.json) - --no-save-session Alias for --remember-last-session false - --no-save-username Alias for --remember-last-user false - --debug Enable verbose startup logging to stderr - -h, --help Show this help message - -Examples: - dms-greeter --command niri - dms-greeter --command hyprland -C /etc/greetd/custom-hypr.conf - dms-greeter --command sway -p /home/user/.config/quickshell/custom-dms - dms-greeter --command scroll -p /home/user/.config/quickshell/custom-dms - dms-greeter --command niri --cache-dir /tmp/dmsgreeter - dms-greeter --command niri --no-save-session --no-save-username - dms-greeter --command mango - dms-greeter --command labwc -EOF -} - -require_command() { - local cmd="$1" - if ! command -v "$cmd" >/dev/null 2>&1; then - echo "Error: required command '$cmd' was not found in PATH" >&2 - exit 1 - fi -} - -normalize_bool_flag() { - local flag_name="$1" - local value="$2" - local normalized="${value,,}" - - case "$normalized" in - 1|true|yes|on) - echo "1" - ;; - 0|false|no|off) - echo "0" - ;; - *) - echo "Error: $flag_name must be true/false (or 1/0, yes/no, on/off)" >&2 - exit 1 - ;; - esac -} - -exec_compositor() { - local log_tag="$1" - shift - - if [[ "$DEBUG_MODE" == "1" ]]; then - exec "$@" - fi - - if command -v systemd-cat >/dev/null 2>&1; then - exec "$@" > >(systemd-cat -t "dms-greeter/$log_tag" -p info) 2>&1 - fi - - exec "$@" -} - -while [[ $# -gt 0 ]]; do - case $1 in - --command) - COMPOSITOR="$2" - shift 2 - ;; - -C|--config) - COMPOSITOR_CONFIG="$2" - shift 2 - ;; - -p|--path) - DMS_PATH="$2" - shift 2 - ;; - --cache-dir) - CACHE_DIR="$2" - shift 2 - ;; - --remember-last-session) - REMEMBER_LAST_SESSION="$2" - shift 2 - ;; - --remember-last-user) - REMEMBER_LAST_USER="$2" - shift 2 - ;; - --no-save-session) - REMEMBER_LAST_SESSION="0" - shift - ;; - --no-save-username) - REMEMBER_LAST_USER="0" - shift - ;; - --debug) - DEBUG_MODE=1 - shift - ;; - -h|--help) - show_help - exit 0 - ;; - *) - echo "Unknown option: $1" >&2 - show_help - exit 1 - ;; - esac -done - -if [[ -z "$COMPOSITOR" ]]; then - echo "Error: --command COMPOSITOR is required" >&2 - show_help - exit 1 -fi - -locate_dms_config() { - local config_name="$1" - local search_paths=() - - local config_home="${XDG_CONFIG_HOME:-$HOME/.config}" - search_paths+=("$config_home/quickshell/$config_name") - - search_paths+=("/usr/share/quickshell/$config_name") - - local config_dirs="${XDG_CONFIG_DIRS:-/etc/xdg}" - IFS=':' read -ra dirs <<< "$config_dirs" - for dir in "${dirs[@]}"; do - if [[ -n "$dir" ]]; then - search_paths+=("$dir/quickshell/$config_name") - fi - done - - for path in "${search_paths[@]}"; do - if [[ -f "$path/shell.qml" ]]; then - echo "$path" - return 0 - fi - done - - return 1 -} - -export XDG_SESSION_TYPE=wayland -export QT_QPA_PLATFORM=wayland -export QT_WAYLAND_DISABLE_WINDOWDECORATION=1 -export EGL_PLATFORM=gbm -export DMS_RUN_GREETER=1 - -if [[ ! -d "$CACHE_DIR" ]]; then - echo "Error: cache directory '$CACHE_DIR' does not exist." >&2 - echo " Run 'dms greeter sync' to initialize it, or pass --cache-dir to an existing directory." >&2 - exit 1 -fi - -export DMS_GREET_CFG_DIR="$CACHE_DIR" - -if [[ -n "$REMEMBER_LAST_SESSION" ]]; then - DMS_GREET_REMEMBER_LAST_SESSION=$(normalize_bool_flag "--remember-last-session" "$REMEMBER_LAST_SESSION") - export DMS_GREET_REMEMBER_LAST_SESSION - if [[ "$DMS_GREET_REMEMBER_LAST_SESSION" == "1" ]]; then - DMS_SAVE_SESSION=true - else - DMS_SAVE_SESSION=false - fi - export DMS_SAVE_SESSION -fi - -if [[ -n "$REMEMBER_LAST_USER" ]]; then - DMS_GREET_REMEMBER_LAST_USER=$(normalize_bool_flag "--remember-last-user" "$REMEMBER_LAST_USER") - export DMS_GREET_REMEMBER_LAST_USER - if [[ "$DMS_GREET_REMEMBER_LAST_USER" == "1" ]]; then - DMS_SAVE_USERNAME=true - else - DMS_SAVE_USERNAME=false - fi - export DMS_SAVE_USERNAME -fi - -export HOME="$CACHE_DIR" -export XDG_STATE_HOME="$CACHE_DIR/.local/state" -export XDG_DATA_HOME="$CACHE_DIR/.local/share" -export XDG_CACHE_HOME="$CACHE_DIR/.cache" - - -# Keep greeter VT clean by default; callers can override via env or --debug. -if [[ -z "${RUST_LOG:-}" ]]; then - export RUST_LOG=warn -fi -if [[ -z "${NIRI_LOG:-}" ]]; then - export NIRI_LOG=warn -fi - -if command -v qs >/dev/null 2>&1; then - QS_BIN="qs" -elif command -v quickshell >/dev/null 2>&1; then - QS_BIN="quickshell" -else - echo "Error: neither 'qs' nor 'quickshell' was found in PATH" >&2 - exit 1 -fi - -QS_CMD="$QS_BIN" -if [[ "$DMS_PATH" == /* ]]; then - QS_CMD="$QS_BIN -p $DMS_PATH" -else - RESOLVED_PATH=$(locate_dms_config "$DMS_PATH") - if [[ $? -eq 0 && -n "$RESOLVED_PATH" ]]; then - if [[ "$DEBUG_MODE" == "1" ]]; then - echo "Located DMS config at: $RESOLVED_PATH" >&2 - fi - QS_CMD="$QS_BIN -p $RESOLVED_PATH" - else - echo "Error: Could not find DMS config '$DMS_PATH' (shell.qml) in any valid config path" >&2 - exit 1 - fi -fi - -case "$COMPOSITOR" in - niri) - require_command "niri" - if [[ -z "$COMPOSITOR_CONFIG" ]]; then - TEMP_CONFIG=$(mktemp) - # base/default config - cat > "$TEMP_CONFIG" << NIRI_EOF -hotkey-overlay { - skip-at-startup -} - -environment { - DMS_RUN_GREETER "1" -} - -debug { - keep-max-bpc-unchanged -} - -gestures { - hot-corners { - off - } -} - -layout { - background-color "#000000" -} -NIRI_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - else - TEMP_CONFIG=$(mktemp) - cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG" - fi - # Append includes if override_files exist - OVERRIDE_FILES=( - /usr/share/greetd/niri_overrides.kdl # for building into a system image - /etc/greetd/niri_overrides.kdl # for local overrides - ) - for override_file in "${OVERRIDE_FILES[@]}"; do - if [[ -e "$override_file" ]]; then - # TODO: maybe move to optional=true when Niri Next drops, so we can avoid these checks ;-) - cat >> "$TEMP_CONFIG" << NIRI_EOF - -include "$override_file" -NIRI_EOF - fi - done - # Append spawn command - cat >> "$TEMP_CONFIG" << NIRI_EOF - -spawn-at-startup "sh" "-c" "$QS_CMD; niri msg action quit --skip-confirmation" -NIRI_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - exec_compositor "niri" niri -c "$COMPOSITOR_CONFIG" - ;; - - hyprland) - if ! command -v start-hyprland >/dev/null 2>&1 && ! command -v Hyprland >/dev/null 2>&1; then - echo "Error: neither 'start-hyprland' nor 'Hyprland' was found in PATH" >&2 - exit 1 - fi - if [[ -z "$COMPOSITOR_CONFIG" ]]; then - TEMP_CONFIG=$(mktemp) - cat > "$TEMP_CONFIG" << HYPRLAND_EOF -env = DMS_RUN_GREETER,1 - -misc { - disable_hyprland_logo = true -} - -exec-once = sh -c "$QS_CMD; hyprctl dispatch exit" -HYPRLAND_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - else - TEMP_CONFIG=$(mktemp) - cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG" - cat >> "$TEMP_CONFIG" << HYPRLAND_EOF - -exec-once = sh -c "$QS_CMD; hyprctl dispatch exit" -HYPRLAND_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - fi - if command -v start-hyprland >/dev/null 2>&1; then - exec_compositor "hyprland" start-hyprland -- --config "$COMPOSITOR_CONFIG" - else - exec_compositor "hyprland" Hyprland -c "$COMPOSITOR_CONFIG" - fi - ;; - - sway) - require_command "sway" - if [[ -z "$COMPOSITOR_CONFIG" ]]; then - TEMP_CONFIG=$(mktemp) - cat > "$TEMP_CONFIG" << SWAY_EOF -exec "$QS_CMD; swaymsg exit" -SWAY_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - else - TEMP_CONFIG=$(mktemp) - cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG" - cat >> "$TEMP_CONFIG" << SWAY_EOF - -exec "$QS_CMD; swaymsg exit" -SWAY_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - fi - exec_compositor "sway" sway --unsupported-gpu -c "$COMPOSITOR_CONFIG" - ;; - - scroll) - require_command "scroll" - if [[ -z "$COMPOSITOR_CONFIG" ]]; then - TEMP_CONFIG=$(mktemp) - cat > "$TEMP_CONFIG" << SCROLL_EOF -exec "$QS_CMD; scrollmsg exit" -SCROLL_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - else - TEMP_CONFIG=$(mktemp) - cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG" - cat >> "$TEMP_CONFIG" << SCROLL_EOF - -exec "$QS_CMD; scrollmsg exit" -SCROLL_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - fi - exec_compositor "scroll" scroll -c "$COMPOSITOR_CONFIG" - ;; - - miracle|miracle-wm) - require_command "miracle-wm" - if [[ -z "$COMPOSITOR_CONFIG" ]]; then - TEMP_CONFIG=$(mktemp) - cat > "$TEMP_CONFIG" << MIRACLE_EOF -exec "$QS_CMD; miraclemsg exit" -MIRACLE_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - else - TEMP_CONFIG=$(mktemp) - cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG" - cat >> "$TEMP_CONFIG" << MIRACLE_EOF - -exec "$QS_CMD; miraclemsg exit" -MIRACLE_EOF - COMPOSITOR_CONFIG="$TEMP_CONFIG" - fi - exec_compositor "miracle" miracle-wm -c "$COMPOSITOR_CONFIG" - ;; - - labwc) - require_command "labwc" - if [[ -n "$COMPOSITOR_CONFIG" ]]; then - exec_compositor "labwc" labwc --config "$COMPOSITOR_CONFIG" --session "$QS_CMD" - else - exec_compositor "labwc" labwc --session "$QS_CMD" - fi - ;; - - mango|mangowc) - require_command "mango" - if [[ -n "$COMPOSITOR_CONFIG" ]]; then - exec_compositor "mango" mango -c "$COMPOSITOR_CONFIG" -s "$QS_CMD && mmsg -d quit" - else - exec_compositor "mango" mango -s "$QS_CMD && mmsg -d quit" - fi - ;; - - *) - echo "Error: Unsupported compositor: $COMPOSITOR" >&2 - echo "Supported compositors: niri, hyprland, sway, scroll, miracle, mango, labwc" >&2 - exit 1 - ;; -esac diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-hypr.conf b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-hypr.conf deleted file mode 100644 index 33eefcd..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-hypr.conf +++ /dev/null @@ -1,3 +0,0 @@ -env = DMS_RUN_GREETER,1 - -exec = sh -c "qs -p _DMS_PATH_; hyprctl dispatch exit" diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-niri.kdl b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-niri.kdl deleted file mode 100644 index dfc4703..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/dms-niri.kdl +++ /dev/null @@ -1,23 +0,0 @@ -hotkey-overlay { - skip-at-startup -} - -environment { - DMS_RUN_GREETER "1" -} - -spawn-at-startup "sh" "-c" "qs -p _DMS_PATH_; niri msg action quit --skip-confirmation" - -debug { - keep-max-bpc-unchanged -} - -gestures { - hot-corners { - off - } -} - -layout { - background-color "#000000" -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/greet-hyprland.sh b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/greet-hyprland.sh deleted file mode 100755 index c23b479..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/greet-hyprland.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -export XDG_SESSION_TYPE=wayland -export QT_QPA_PLATFORM=wayland -export QT_WAYLAND_DISABLE_WINDOWDECORATION=1 -export EGL_PLATFORM=gbm -if command -v start-hyprland >/dev/null 2>&1; then - exec start-hyprland -- -c /etc/greetd/dms-hypr.conf -else - exec Hyprland -c /etc/greetd/dms-hypr.conf -fi diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/greet-niri.sh b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/greet-niri.sh deleted file mode 100755 index d31db65..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Greetd/assets/greet-niri.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -export XDG_SESSION_TYPE=wayland -export QT_QPA_PLATFORM=wayland -export QT_WAYLAND_DISABLE_WINDOWDECORATION=1 -export EGL_PLATFORM=gbm - -exec niri -c /etc/greetd/dms-niri.kdl |