198 lines
7.0 KiB
Markdown
198 lines
7.0 KiB
Markdown
# latchd
|
|
|
|
a display manager that runs in your terminal. lets you pick a desktop environment and log in — supports tty, x11, and wayland.
|
|
|
|
## what problem does this solve
|
|
|
|
Most display managers are graphical. that means you need x11 or wayland running before you can even log in. latchd runs in a plain linux terminal (like tty2), so you can log in first, then start your desktop. it's lightweight, looks decent, and doesn't drag in a full graphics stack just to show a login screen.
|
|
|
|
## how it works
|
|
|
|
latchd takes over a virtual terminal (tty2 by default) and draws a login screen using ansi escape codes, powered by [bubbletea](https://github.com/charmbracelet/bubbletea). you type your username and password, pick a session from the switcher, and hit enter.
|
|
|
|
The actual authentication happens through pam (pluggable authentication modules). Once you're authenticated, latchd forks a child process that opens the pam session, sets up your environment, spawns your desktop or window manager, and does utmp accounting so tools like `who` and `loginctl` can see you're logged in.
|
|
|
|
For x11 sessions it handles the whole setup — xauthority cookies, sigusr1 handshake with the x server, timing out if xorg fails to start. for wayland it just runs your compositor script. for tty it drops you into your shell.
|
|
|
|
While the login screen is up, it renders a conway's game of life simulation as the background at 30fps, using unicode half-block characters for a pixelated look.
|
|
|
|
## what you get
|
|
|
|
- Session switcher with left/right arrows and dot indicators
|
|
- username and password fields
|
|
- Status line for errors and info
|
|
- power controls (f1 shutdown, f2 reboot by default — configurable)
|
|
- caps lock indicator
|
|
- shake animation on wrong password
|
|
- spring animation on switcher transitions
|
|
- faillock integration — shows remaining attempts, detects lockouts
|
|
- Admin override (ctrl+u) to unlock a locked-out account
|
|
- configurable color theming via toml
|
|
- variable substitution in config (`$varname`)
|
|
- Preview mode for testing inside an existing session
|
|
|
|
## Known Issues
|
|
|
|
This project is a work in progress. here's what you should know:
|
|
|
|
- **no tests**. at all. no unit tests, no integration tests. if you hit a bug, you'll find it the hard way.
|
|
- **Session spawning is a bit rough**. it uses `ForkExec` to re-launch itself as a child process, which means the pam session lifecycle isn't as clean as the original fork-then-exec model. this can cause pam modules that track session leaders to get confused.
|
|
- **a handful of open bugs** — edge cases in the switcher, occasional terminal state corruption on abrupt exits, and the automata background can flicker when the terminal resizes rapidly.
|
|
- **not all config options are fully wired**. things like `SwitcherConfig.ShowNeighbours`, various color options, and input field styling fields exist in the config struct but may not all be hooked up to the rendering yet.
|
|
|
|
## installing
|
|
|
|
### from source
|
|
|
|
you need go 1.22 or later and `libpam-dev` (or your distro's equivalent).
|
|
|
|
```bash
|
|
# clone and build
|
|
cd src
|
|
go build -ldflags="-s -w" -o latchd .
|
|
sudo cp latchd /usr/bin/
|
|
|
|
# set up config and session directories
|
|
sudo mkdir -p /etc/latchd/wms /etc/latchd/wayland /var/log /var/cache
|
|
sudo cp ../extra/config.toml /etc/latchd/config.toml
|
|
sudo cp ../extra/xsetup.sh /etc/latchd/xsetup.sh
|
|
sudo cp ../extra/lemurs.pam /etc/pam.d/latchd
|
|
sudo cp ../extra/lemurs.service /etc/systemd/system/latchd.service
|
|
|
|
# enable the service
|
|
sudo systemctl enable latchd
|
|
```
|
|
|
|
you can also use the makefile:
|
|
|
|
```bash
|
|
make build # compile to build/latchd
|
|
sudo make install # install to /usr/bin and set up systemd
|
|
make run-preview # test the login screen in your current terminal
|
|
```
|
|
|
|
### arch
|
|
|
|
```bash
|
|
pacman -S latchd
|
|
systemctl enable latchd
|
|
```
|
|
|
|
## command line
|
|
|
|
```
|
|
latchd [options]
|
|
|
|
-c, --config <file> config path (default: /etc/latchd/config.toml)
|
|
-v, --variables <file> variables path
|
|
--tty <n> override the tty number to run on
|
|
--preview run inside an existing session for testing
|
|
--no-log disable all logging
|
|
--show-config print the parsed config and exit
|
|
-V, --version print version and exit
|
|
--xsessions <dir> override xsessions path
|
|
--wlsessions <dir> override wayland-sessions path
|
|
--initial-path <path> override initial PATH value
|
|
```
|
|
|
|
## adding sessions
|
|
|
|
drop executable scripts into the right folder and they show up in the switcher.
|
|
|
|
**x11** — put your xinitrc scripts in `/etc/latchd/wms/`:
|
|
|
|
```bash
|
|
# /etc/latchd/wms/bspwm
|
|
#!/bin/sh
|
|
sxhkd &
|
|
exec bspwm
|
|
```
|
|
|
|
```bash
|
|
chmod +x /etc/latchd/wms/bspwm
|
|
```
|
|
|
|
**wayland** — same thing in `/etc/latchd/wayland/`:
|
|
|
|
```bash
|
|
# /etc/latchd/wayland/sway
|
|
#!/bin/sh
|
|
exec sway
|
|
```
|
|
|
|
latchd also reads freedesktop `.desktop` files from `/usr/share/xsessions` and `/usr/share/wayland-sessions` automatically.
|
|
|
|
tty sessions are added automatically if no other environments are found, or you can force one with `include_tty_shell = true` in the config.
|
|
|
|
## configuring
|
|
|
|
the config lives at `/etc/latchd/config.toml`. all options are documented inline in the file. you can also use a `variables.toml` file with `$VAR` syntax:
|
|
|
|
```toml
|
|
# /etc/latchd/variables.toml
|
|
accent = "orange"
|
|
```
|
|
|
|
```toml
|
|
# /etc/latchd/config.toml
|
|
[password_field.style]
|
|
title_color_focused = "$accent"
|
|
border_color_focused = "$accent"
|
|
```
|
|
|
|
## debugging
|
|
|
|
three log files:
|
|
|
|
- `/var/log/latchd.log` — main latchd events
|
|
- `/var/log/latchd.client.log` — stdout/stderr of your session
|
|
- `/var/log/latchd.xorg.log` — x server output (64mb cap)
|
|
|
|
run `latchd --show-config` to verify your configuration. run `latchd --preview` to test the login screen without leaving your current session.
|
|
|
|
## keybindings
|
|
|
|
standard shell-style bindings in text fields:
|
|
|
|
| key | what it does |
|
|
|---|---|
|
|
| ctrl+a | start of line |
|
|
| ctrl+e | end of line |
|
|
| ctrl+l or ctrl+u | clear field |
|
|
| ctrl+d | delete forward |
|
|
| ctrl+h | backspace |
|
|
| ctrl+b/f | left/right |
|
|
| ctrl+p/n | up/down (previous/next field) |
|
|
| tab, shift+tab | next/prev field |
|
|
| left/right | switch session (in switcher mode) |
|
|
| f1, f2 | power controls |
|
|
| ctrl+u | admin unlock (when account is locked) |
|
|
|
|
## source layout
|
|
|
|
```
|
|
src/
|
|
├── main.go entry point, cli, vt switching, session forking
|
|
├── auth/
|
|
│ ├── pam.go cgo pam bindings (locks goroutine to os thread)
|
|
│ ├── faillock.go faillock tally detection and reset
|
|
│ └── utmpx.go user accounting records
|
|
├── config/
|
|
│ └── config.go toml parsing, variable substitution, defaults
|
|
├── session/
|
|
│ ├── env.go xdg and environment variable setup
|
|
│ ├── exec.go process spawning, privilege dropping, log limits
|
|
│ ├── scan.go session discovery and .desktop parsing
|
|
│ ├── x11.go xorg setup, xauth, sigusr1 handshake
|
|
│ └── wayland.go wayland placeholder
|
|
├── login/
|
|
│ └── login.go login form ui, state machine, animations, rendering
|
|
└── tui/
|
|
└── bg/
|
|
└── automata.go conway's game of life background
|
|
```
|
|
|
|
## license
|
|
|
|
MIT or Apache-2.0
|