sxot - Simple X screenshOT
sxot is an extremely simple screenshotting tool for X11 designed with the unix
philosophy in mind. This means that by itself sxot doesn’t do much - it
simply takes a screenshot and outputs a binary ppm file to stdout. sxot is
meant to be used in conjunction with other tools in order to be useful in
practice.
Usage
sxot supports only the following options:
-c, --cursoradds the cursor to the screenshot.-g, --geom <x,y,w,h[ wid]>which tellssxotto capture the specified rectangle instead of screenshotting the entire screen. May optionally include a trailing window id.-f, --forceoverwrites the output file if it already exists.-w, --window <WID>to capture a specific window.-B, --keep-borderto capture the window border as well when using-w.
Some example usage:
- Taking a full screen screenshot and saving it to
out.ppm:
$ sxot > out.ppm
- Screenshoting a selected area with
selx:
$ sxot -g $(selx) > out.ppm
- Screenshoting with a 5 seconds delay with
sleepand saving it with a file-name that has date and time information withdate:
$ sleep 5 && sxot > $(date '+%F_%T').ppm
- Screenshoting with a 2 seconds delay after selection with
slop:
$ sxot --geom $(slop -f "%x,%y,%w,%h"; sleep 2;) > out.ppm
- Saving a png screenshot using
ffmpeg:
$ sxot | ffmpeg -i - out.png
Or using ImageMagick:
$ sxot | convert - out.png
- Copying an optimized png screenshot to clipboard,
using
optipng-pipeandxclip:
$ sxot | optipng-pipe | xclip -selection clipboard -target image/png
- Screenshoting a specific monitor via
selx:
$ sxot -g $(selx -m 0) > monitor0.ppm
Output formats
sxot only supports ppm format. Instead of trying to support complicated
compressed formats and doing a mediocre job, sxot leaves this task to more
specialized tools such as optipng.
Some recommended formats and tools:
- I suggest using png with
optipng-pipefor best compatibility and reasonably low file-sizes:
$ sxot | optipng-pipe > out.png
- If smaller file-sizes are desired, then I can suggest using lossless webp with
cwebp. Keep in mind that some compatibility is lost since older software might not support webp. Convenientlycwebpaccepts stdin if the file is named “-”, although this feature is undocumented.
$ sxot | cwebp -quiet -lossless -z 8 -mt -o out.webp -- -
- For lossy compression,
cjpegliis very impressive:
$ sxot | cjpegli /dev/stdin out.jpg -d 0.9 -p 0
The cwebp tool comes with libwebp, and cjpegli is developed alongside the
official jpeg-xl library. However, you distro may package these tools
separately.
jxl also seems promising in terms of lossless compression.
But compatibility isn’t that great as of now (party due to
google killing it in chromium).
Dependencies
-
Build Dependencies:
- C11 compiler
- POSIX 2001 compatible C standard library.
- Necessary library headers (on some distros you need to install
*-devpackages to get header files)
-
Runtime Dependencies:
- X11 server (with true color enabled)
- Xlib
- Xfixes
- libXcomposite (Optional, see the Window capture section)
Building
- Simple release build:
$ cc -o sxot sxot.c -O3 -s -l X11 -l Xfixes
The above command should also work with gcc, clang or any other C compiler
that has a POSIX compatible cli interface.
- Debug build with
gcc(also works withclang):
$ gcc -o sxot sxot.c -std=c11 -Wall -Wextra -Wpedantic -Wshadow \
-g3 -D DEBUG -O0 -fsanitize=address,undefined -l X11 -l Xfixes
- If you’re editing the code, you may optionally run some static analysis:
$ make -f etc/analyze.mk
Installing
Simply copy the binary over to your $PATH:
# install -Dm755 sxot /usr/local/bin/sxot
Optionally install the manpage:
# install -Dm644 sxot.1 /usr/local/share/man/man1/sxot.1
A zsh completion script is also available for zsh users under etc/zsh-completion:
# install -Dm644 etc/zsh-completion/_sxot /usr/local/share/zsh/site-functions/_sxot
Window capture
It may seem odd to include -w flag to capture window when tools like selx
are already capable of selecting a window and reporting it’s geometry. However
there are two cases where simply reporting the window geometry isn’t sufficient:
- When parts of the window is off-screen. In this case we will not be able to capture the off-screen parts from the root window, since they are off-screen.
- When a window is being obscured by another window. In this case capturing geometry on the root window will capture the overlapping window instead of only capturing the window that was actually selected.
By using a window id we can capture the window directly instead of the root window which solves both the issues above. Note that both of these cases require a compositor to be running in order to work.
If you have XComposite dynamic library installed then case 1 can sometimes work without a compositor, but it’s not reliable.
The -g flag also optionally accepts a trailing window id, this avoids having
to use two different invocation, one for capturing window (-w) and another
selection (-g), the following command will work in both cases:
$ sxot -g "$(selx -f "%S" -B)"
Worth noting that the command substitution must be wrapped in double quotes
"$(...)", otherwise the shell will split the output.
The -B flag to selx is to capture the window border, leave it out if you
don’t want it.