mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-23 03:25:19 -04:00
fdbbcafb6c
- 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
123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
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)
|
|
}
|