mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-22 19:15:24 -04:00
fix(greeter): avoid pinning auto-login session commands
- Store a desktop session identity instead of relying on raw Exec commands - Resolve the current session desktop file when auto-login launches - Preserve legacy memory compatibility while ignoring stale lastSessionExec - Add regression coverage for stale /nix/store session paths - Autologin users should rerun the process
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package greeter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func sessionDesktopIDFromPath(path string) string {
|
||||
id := strings.TrimSpace(path)
|
||||
if id == "" {
|
||||
return ""
|
||||
}
|
||||
if strings.ContainsAny(id, "/\\") {
|
||||
id = filepath.Base(id)
|
||||
}
|
||||
if id == "" {
|
||||
return ""
|
||||
}
|
||||
if !strings.HasSuffix(id, ".desktop") {
|
||||
id += ".desktop"
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func sessionDesktopIDFromMemory(mem greeterAutoLoginMemory) string {
|
||||
if id := sessionDesktopIDFromPath(mem.LastSessionDesktopID); id != "" {
|
||||
return id
|
||||
}
|
||||
return sessionDesktopIDFromPath(mem.LastSessionID)
|
||||
}
|
||||
|
||||
func sessionDesktopDirs() []string {
|
||||
seen := make(map[string]bool)
|
||||
dirs := make([]string, 0, 8)
|
||||
|
||||
addBase := func(base string) {
|
||||
base = strings.TrimSpace(base)
|
||||
if base == "" {
|
||||
return
|
||||
}
|
||||
for _, sub := range []string{"wayland-sessions", "xsessions"} {
|
||||
dir := filepath.Join(base, sub)
|
||||
if seen[dir] {
|
||||
continue
|
||||
}
|
||||
seen[dir] = true
|
||||
dirs = append(dirs, dir)
|
||||
}
|
||||
}
|
||||
|
||||
if dataHome := os.Getenv("XDG_DATA_HOME"); dataHome != "" {
|
||||
addBase(dataHome)
|
||||
} else if home, err := os.UserHomeDir(); err == nil && home != "" {
|
||||
addBase(filepath.Join(home, ".local", "share"))
|
||||
}
|
||||
|
||||
if dataDirs := os.Getenv("XDG_DATA_DIRS"); dataDirs != "" {
|
||||
for _, dir := range strings.Split(dataDirs, ":") {
|
||||
addBase(dir)
|
||||
}
|
||||
} else {
|
||||
addBase("/usr/local/share")
|
||||
addBase("/usr/share")
|
||||
}
|
||||
|
||||
return dirs
|
||||
}
|
||||
|
||||
func ResolveSessionExec(sessionID string) (string, error) {
|
||||
return resolveSessionExecInDirs(sessionID, sessionDesktopDirs())
|
||||
}
|
||||
|
||||
func resolveSessionExecInDirs(sessionID string, dirs []string) (string, error) {
|
||||
id := sessionDesktopIDFromPath(sessionID)
|
||||
if id == "" {
|
||||
return "", fmt.Errorf("session id is empty")
|
||||
}
|
||||
|
||||
for _, dir := range dirs {
|
||||
path := filepath.Join(dir, id)
|
||||
execLine, err := execFromDesktopFile(path)
|
||||
if err == nil {
|
||||
return execLine, nil
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("session desktop file %q was not found", id)
|
||||
}
|
||||
|
||||
func LaunchSessionByID(sessionID string) error {
|
||||
execLine, err := ResolveSessionExec(sessionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
execLine = strings.TrimSpace(stripDesktopExecCodes(execLine))
|
||||
if execLine == "" {
|
||||
return fmt.Errorf("session %q has an empty Exec command", sessionID)
|
||||
}
|
||||
|
||||
env := append(os.Environ(), "XDG_SESSION_TYPE=wayland")
|
||||
return syscall.Exec("/bin/sh", []string{"sh", "-c", "exec " + execLine}, env)
|
||||
}
|
||||
|
||||
func LaunchSessionFromMemory(cacheDir, homeDir string) error {
|
||||
enabled, _, sessionID, err := resolveGreeterAutoLoginState(cacheDir, homeDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !enabled {
|
||||
return fmt.Errorf("greeter auto-login is disabled")
|
||||
}
|
||||
if sessionID == "" {
|
||||
return fmt.Errorf("greeter auto-login has no remembered session")
|
||||
}
|
||||
return LaunchSessionByID(sessionID)
|
||||
}
|
||||
Reference in New Issue
Block a user