No Description

ohnonot 175e341bc7 fixed string disappearing when starting with - 6 months ago
config 29c2f01bc6 More robustness. Use unclutter _or_ hhpc 6 months ago
helperscripts 1fac69271f different method of determining term size 6 months ago
screenshots f11ec18c20 new screencast 6 months ago
.gitignore ade4e9f792 almost perfect 2 years ago 27ae2eba70 small improvements 6 months ago
marquee1 175e341bc7 fixed string disappearing when starting with - 6 months ago
termss 1fac69271f different method of determining term size 6 months ago


A terminal screensaver to replace xscreensaver & Co.
Written in bash.


  • the termss wrapper script: It will open a fullscreen terminal window on top of everything (urxvt is a hard dependency because it has the options to make this work as desired) and execute a command given as an argument, inside that terminal. Then it starts listening to events, and will kill everything as soon as you wiggle your mouse pointer or hit a key. Just like any screensaver. No screen locking.
  • a script (marquee1) designed to run inside that window. It shows configurable command output (by default in awesome toilet fonts) in random colors and position, waits, clears the screen and starts again. It's possible to have some sort of animation ("teletype effect"), and it can be made to sprinkle the screen with stars. Enable the options in marquee1.conf.


The Xorg server has a screensaver built in; its settings can be queried via xset.
Some programs have the capability to catch the Xorg server's signal that it's time, and activate a custom screensaver or any other command - in our case termss.

xss is one such program, and it is the one I'm using. See "The scripts" below for examples.

xss-lock is another, and so is xautolock (this link for FreeBSD's Freshports; look under "Master Sites" to find sources).

Essentially these three programs do the same thing: They provide a mechanism to start an external application when the X server says "no user activity, time to start the screensaver".


Both scripts look for its config file which can be put in $XDG_CONFIG_HOME/termss/.
Two example config files with default options can be found in the config subfolder of this repository.


The termss script

  • Xorg
  • bash
  • urxvt terminal emulator
  • xdotool
  • xrandr, possibly part of xorg-xrandr
  • xinput, possibly part of xorg-xinput
  • sed
  • a writeable $TMPDIR (defaults to /tmp)


  • highly recommended: hhpc or unclutter to hide the pointer
  • (for insecure ungrabbing & pointer hiding) setxkbmap, possibly part of xorg-setxkbmap
  • (for the screencast option) imagemagick and gifsicle


See man urxvt on how to formulate a font string for urxvt's "-fn" option, to be supplied as font="..." in termss.conf.

The termss script needs to detect the width & height of one monospaced cell, i.e. the space any character uses.
There is automatic detection but it is tricky: it flashes a 1x1 sized terminal for just as long as it takes to determine its actual size.
If this creates undesired side effects or simply doesn't work you can define charwidth and charheight in termss.conf. To disable automatic detection completely override both these variables.

The marquee1 script

  • ncurses to provide tput
  • shuf and od (both coreutils)
  • grep


  • pv to slow down output (teletype effect)
  • toilet to create banners - highly recommended!
  • mpi-panel for media player info (also from here)

The scripts

It isn't hard to imagine all the programs one can run in fullscreen to make for a nice screensaver, but this repository uses a terminal emulator.

One could also run pipes for example, or asciiquarium or termsaver...

You will need a command like this in your autostart:

xss /path/to/termss /path/to/marquee1 &
# or
xss /path/to/termss asciiquarium &
# or
xss /path/to/termss sh -c 'cmatrix|lolcat'
# or
xss /path/to/termss sh -c 'tput civis; termsaver matrix'
# etc.


If you use dunst as your notification daemon, termss will pause dunst while the screensaver is active. If you have dunst in your $PATH, and it is not running, it will be started first.


There's not enough quality control. Set it up carefully.
But once it works, it works well enough. Stable, one could say.

There are some situations where the mouse pointer cannot be hidden because some application grabbed it, so it should be ungrabbed first. However, that needs to be enabled first because it is potentially less secure. You can set insecure=1 inside the script, which uses an alternative method that is good enough for most cases, and ungrabbing stays disabled. But you should know that this option then stays enabled for the remainder of that X session.