Files
socktop-swipe/README.md
T
2026-09-09 21:30:23 +00:00

14 KiB

socktop-swipe

A rack-mounted touchscreen swipable display that monitors your servers via socktop and other status tuis.

Terminal dashboards are arranged in a grid. Swipe left and right to move along a row; swipe up and down to move between rows. A group of hosts is one place in that grid: it shows them tiled together first, then each one full-screen as you keep swiping.

The touch panel mounted in the rack, showing four Raspberry Pis tiled together

Built for a 9" panel bolted into a 19" server rack, driven by a low-power x86 box running i3 on X11.

What you're looking at

The photo is a 9" touchscreen in a 19" rack, showing four Raspberry Pis at once via socktop. It is a wall display: no keyboard, no mouse, nothing to log into. It comes back by itself after a power cut and it never blanks.

Everything on it is a terminal program. socktop-swipe does not draw anything itself — it decides what is on screen and reads your finger.

                          unifly                     -1x0
                       (UniFi network)
                             ↕
   ┌──────────────────────────────┐  ┌──────────────────┐
   │  4 Raspberry Pis             │→ │ 2 more machines  │      row 0
   │  tiled, then each full-screen│  │                  │
   └──────────────────────────────┘  └──────────────────┘
                 0x0                          0x1
                             ↕
                      uptime kuma                      1x0
                     (service status)

Swipe forward through row 0 and you get: all four Pis tiled, then rpi-master full-screen, then each of the others, then on to the next group. Swipe up at any point for the UniFi network view; swipe back down and you are on the exact host you left.

Hardware

Part What was used Status
Display host LattePanda (Atom x5-Z8350, 1.9 GB), Debian 11, i3 on X11 in daily use
Display host Dell Wyse 3040 (Atom x5-Z8350, 2 GB), 8/16 GB eMMC, DP out not yet tried
Panel GeeekPi 9" 1280x720 3U touchscreen, ILITEK USB touch in daily use
Mounting cad/ — 19" rack adapter printed and in the rack

Any Linux box with a USB or DSI touchscreen will do. It is deliberately modest hardware: the whole point is a display that idles at a few watts.

The panel is sold as a 10-inch mini-rack part. cad/ has a pair of side adapters — OpenSCAD source, STLs with tested print settings, and SendCutSend-ready DXFs — that mount it in a standard 19-inch rack, with three keystone jack positions on each side. The geometry has been physically tested.

Install

curl -fsSL https://gt.wittyoneoff.com/jason/socktop-swipe/raw/branch/main/install.sh | sh

It checks everything first and prints the whole cost — packages, toolchain, disk — before changing anything. Then it asks, one thing at a time:

  • which touch device to use (it looks for one and offers it)
  • how to grant access to it: a udev rule for touchscreens only, or the input group
  • whether to install socktop, uptime-kuma-status or unifly
  • whether to stop the screen blanking, sleeping and locking
  • whether to autostart on login
  • whether to log straight in at boot, so it comes back after a power cut

Every answer has a sensible default and nothing is required. Piping into sh leaves no keyboard on standard input, so the script reads your terminal directly; if there is no terminal at all it takes the defaults and says so. --yes skips the questions.

There are no prebuilt binaries yet — it builds from source, so a Rust toolchain is installed if you do not have one.

Measured on the LattePanda (Atom x5-Z8350, 4 cores, 1.9 GB RAM, no swap), with a toolchain already present: 108 seconds, peaking at 1.1 GB of the 1.9 GB and leaving a 103 MB build directory. The 946 KB binary is the only thing installed. Add roughly 1.2 GB and a few minutes if rustup has to be fetched too. The installer checks free space first and tells you if it will not fit.

From a checkout instead
git clone https://gt.wittyoneoff.com/jason/socktop-swipe
cd socktop-swipe
./install.sh

Your first config

The config lives at ~/.config/socktop-swipe/config.yaml. The installer writes a starting point; this section builds one up from nothing.

Check every edit with:

socktop-swipe validate

which resolves the grid, prints the map, and tells you if a program it would run is not actually there.

One group of hosts

touch:
  device: /dev/input/by-id/usb-ILITEK_ILITEK-TOUCH-event-if00
  width: 1280
  height: 720

screens:
  - at: "0x0"
    type: socktop
    socktop_group: [rpi-master, rpi-worker-1, rpi-worker-2, rpi-worker-3]

That is five screens: the four hosts tiled, then each one full-screen.

0x0  tiled  →  rpi-master  →  rpi-worker-1  →  rpi-worker-2  →  rpi-worker-3

Quote the coordinate. Unquoted, YAML reads 0x0 as the hexadecimal number zero. socktop-swipe validate will tell you so if you forget.

Something above it

  - at: "-1x0"
    type: unifly

Row -1 is above row 0. Now swiping up from any of those five screens shows the UniFi TUI, and swiping down returns you to the exact host you were on.

Something below, and more hosts alongside

  - at: "0x1"
    type: socktop
    socktop_group: "orangepi, trixie"
    layout: even-vertical

  - at: "1x0"
    type: uptime-kuma-status
    url: https://status.example.com/status/mine

0x1 sits to the right of 0x0, so you reach it by swiping forward past the last Pi. 1x0 is below.

Full worked example with every option commented: config.example.yaml.

How the grid works

Row increases downward. -1x0 is above 0x0; 1x0 is below it. Column increases rightward. You start at 0x0.

Coordinates are ordering, not slots. Only their sort order matters, so 0x1 and 0x5 are interchangeable. You never have to count how many screens a group produces in order to place something next to it — add a host to a group and nothing else needs renumbering.

A group of hosts is one place in the grid. Swiping forward walks its screens — tiled overview, then each host — and only moves on to the next place after the last one. Coming back from the right lands you on that group's last host, not its overview, so the row reads as one continuous strip.

Swiping up or down returns you to where you were. Each row remembers its position. If you glance at the network view and come back, you are on the same host, still zoomed.

Nothing wraps around. Swiping past either end of a row does nothing. On a wall display, wrapping makes it impossible to tell where you are.

If a row has no screen in your current column, you land on the nearest one — 0x3 swiping up with only -1x0 above goes there. That only happens the first time; after that the row remembers.

Monitor types

Every type also accepts command: to replace the generated command outright, and title: to change the label on the pane border.

type: Parameters What it runs
socktop socktop_group (list, or comma-separated string), layout one socktop per host
uptime-kuma-status url uptime-kuma-status against a public Uptime Kuma status page
unifly (none yet) unifly tui
generic command, title anything you like

layout takes any tmux layout name: tiled (the default), even-horizontal, even-vertical, main-horizontal, main-vertical.

  - at: "1x1"
    type: generic
    title: k3s
    command: journalctl -f -u k3s-agent

Configuration reference

Key Default What it does
session socktop-swipe tmux session name
terminal (none) Terminal that run opens the dashboard in. Unset attaches in the current one
indicator false Show position — what is above, where you are, what is below — in the status line
binaries.socktop etc. looked up on PATH Full path to each program. ~/ is expanded
touch.device Always a /dev/input/by-id/ path; eventN numbers change on reboot
touch.width / .height The panel's resolution, not the X screen
touch.grab true Take the panel exclusively so X never sees the touches
touch.threshold 80 Pixels of travel before a drag counts as a swipe
touch.leniency 30 Degrees off-axis tolerated, max 45
touch.fingers [1, 2, 3] Contact counts accepted. The setting most likely to need changing
gestures.forward / .back RL / LR Named by finger motion. Swap to reverse
gestures.up / .down DU / UD

Commands

Command
socktop-swipe run Build the session, open it in a terminal, read the panel. The one thing to autostart
socktop-swipe validate Check the config and print the grid map
socktop-swipe doctor Swipe, and be told what the panel reported
socktop-swipe doctor --list List touch devices — works before any config exists
socktop-swipe forward / back / up / down Move a running instance. For keybindings, or a box with no panel
socktop-swipe build / attach / daemon The pieces of run, separately, for a systemd split

Unattended operation

A wall display has to survive a power cut with nobody in the room.

Never blank. The installer writes an Xorg ServerFlags snippet with all four timeouts at zero, which covers every session including the display manager's greeter and survives reboots, and adds an xset line to the session autostart, because a session can re-enable blanking after X starts. Both are needed. Check with xset q | grep -A1 -E 'Screen Saver|DPMS' — you want timeout: 0, prefer blanking: no, DPMS is Disabled.

Come back by itself. Without autologin, a reboot leaves the panel at a login prompt and nothing starts. The installer offers a lightdm drop-in. It is opt-in and defaults to no, because anyone with physical access to the panel gets that user's session — only do it where the account is nothing but the dashboard. Delete /etc/lightdm/lightdm.conf.d/50-autologin-socktop-swipe.conf to undo it.

Autostart. socktop-swipe run is a single process that builds the session, opens the terminal and reads the panel, so one line in your window manager's autostart is enough. For a systemd user session, packaging/socktop-swipe.service splits it up.

Troubleshooting

Start here:

socktop-swipe doctor

It watches the panel and says what it saw in English — direction, contact count, and why a gesture was ignored.

Swipes are detected but nothing happens

doctor will say saw 2 contact(s), config accepts [1]. Many multipoint panels report two or even three contacts for a physically one-finger swipe. Add them to touch.fingers. This is the single most common problem on new hardware.

Nothing is detected at all

In order: is the device path right (socktop-swipe doctor --list)? Can you read it — is the udev rule installed, or are you in the input group and did you log out and back in? Is the panel plugged in?

Swipes work, but the terminal also reacts — text zooming, panes resizing

X is delivering touch to whatever is on screen as well. touch.grab: true (the default) prevents this by taking the device exclusively. If you have set it to false because you want touch in other applications, tell X to ignore the panel instead:

sudo tee /etc/X11/xorg.conf.d/99-ignore-touch-socktop-swipe.conf >/dev/null <<'EOF'
Section "InputClass"
    Identifier   "ignore touchscreen (socktop-swipe)"
    MatchProduct "ILITEK"
    MatchIsTouchscreen "on"
    Option       "Ignore" "on"
EndSection
EOF

Adjust MatchProduct to your panel, and restart X.

A pane shows [... exited: status 1]

That monitor program stopped. The pane is deliberately kept so the layout does not reshuffle and you can see what happened. Check the path under binaries:, and that the program works when you run it by hand.

The dashboard is on a screen that isn't there

Some boards report an output with no panel behind it, and X will happily put the dashboard on it — everything looks fine over ssh while the real panel shows an empty desktop. See notes/HARDWARE-NOTES.md.

Uninstall

./uninstall.sh                 # binary, config, udev rule, X snippets, autologin
./uninstall.sh --keep-config   # keep your settings

The Rust toolchain, tmux, the monitor programs and your input group membership are left alone; the script prints how to remove each.

Notes

Design decisions and the reasoning behind them are in notes/:

  • DESIGN.md — why tmux, why evdev, why the grid works this way
  • HARDWARE-NOTES.md — panel quirks, phantom outputs, the sudo xset trap
  • V1-BASH.md — the shell implementation this replaced, and how to migrate
  • TODO.md

License

Apache-2.0.