rpcd - ratpoison control daemon
This project provides a limited interaction surface for (non-local) users, allowing them to load layouts into the ratpoison window manager as well as enabling them to start/stop a set of previously approved processes.
This allows non-privileged users to run eg. games or view videos on a big screen without having to give them local shell access to start the software.
Additionally, it provides an automation controller to update the display contents based on external factors.
This project consists of several modules
This tool interacts with ratpoison and the underlying Linux system, loading layouts and managing processes. It provides an external API via HTTP, which is detailed in endpoints.txt. Additionally, the automated control feature provides an optional internal API, which is described in detail in a later section.
cli module provides a command line interface (
rpcd-cli), which can be used for automating
To build the daemon, the following prerequisites are needed
- GNU make
- A C compiler
Once those are met, running
make in the root directory should suffice to build all the modules.
Setup & Configuration
To install the web client, copy the directory to a path served by an HTTP daemon and modify the API URL in js/config.js to your setup.
To install the daemon, simply create your configuration file and run the daemon executable on the host running ratpoison (preferrably not as root). The first and only argument to the daemon executable is the configuration file to be used.
To install the command line interface, run
make install within the
The daemon configuration file closely mirrors the standard
ini file format. An example
configuration may be found in daemon/rpcd.conf.
Sub-configuration files can be pulled in while parsing with an
include <file> line.
Lines starting with a semicolon
; are treated as comments and ignored. Inline comments
are not yet supported.
Some section types (
x11) describe named elements. This name is provided
in the section header, separated from the keyword by a space. Names are unique for a specific type,
except for layout names, which are unique per display.
|Section||Option||Default value||Example value||Description||Notes|
||HTTP API host and port|
||Unix domain socket for automation control||Created if missing|
||FIFO for automation control||Created if missing|
||Define an automation variable as well as its default value|
||Automation control script (see below)|
||X11 display identifier to use|
||Layout to apply on reset|
||Store current window-frame mapping|
||Path to a ratpoison
||Read the layout data from a running
||Command to execute including arguments||required|
||Indicates that the command will not open an X window|
||Working directory to execute the command in|
||Command argument variable specification (see below)|
||Command executed to start the window||required|
||Working directory to start the window in|
||Window swap/kill mode (see below)|
Commands may have any number of user-specifiable arguments, which replace the
%Variable placeholders in the command specification.
Argument configuration is specified in command sections by assigning configuration to an option with the same name, ie to configure the
%Var1, you assign the specification to the option
Variables may either be of the type
enum, providing a fixed set of values (separated by space characters) for the user to choose from,
or of the type
string, allowing free-form user entry via a text field. For
enum arguments, variable values exactly match the specified
string arguments, an optional hint may be supplied, which is displayed as an entry hint within the web client.
Placeholders for which no argument configuration is specified are not replaced.
rpcd can be used to update the contents of the managed displays based on an automation script. This feature is optional.
Automated windows are only displayed when a display is not busy with user commands. The windows to be shown can be started and
rpcd automatically, based on the automation script and current variable values.
Automation variables occupy variable space distinct from user command variables. They may be set via the control inputs or the configuration
file. All spawned window processes receive the entire automation variable space in their environment. Variable arguments to
processes also refer to the automated variable space.
Automation variables are required to follow the naming conventions for environment variables, that is the can only consist of the ASCII characters A-z (upper- and lowercase), as well as the digits 0-9 and the underscore (_). Variable names may not start a number, to be able to distinguish them from constants and may not contain spaces.
The automation script, given in an
[automation] section in the control file, consists of line-by-line instructions executed
rpcdis first started
- A child (window or command) terminates
resetAPI endpoint is invoked
- An automated window process maps an X11 window
Changes are only made on displays that are not currently running any user commands.
The automation script may contain the following instructions:
||Apply the default layout on a display if set|
||Activate a layout|
||Assign an automated window to a frame|
||Skip the next
||Terminate automation script execution|
||If condition is not met, skip the next statement|
Conditionals may be negated using the syntax
if not. Valid conditional expressions are
a < b: Expression
anumerically less than
a > b: Expression
anumerically greater than
a = b: Expression
acontains same string as
empty a: Expression
acontains an empty string
Expressions may either be
- Automation variable names
- Numeric constants
- Strings encapsulated in double quotes (")
For each display, the last
layout instruction decides the final layout to be applied, overwriting previous
layout calls. In a similar fashion, later
assign calls overwrite earlier ones referring to the same display/frame combination
Note that cascading conditional statements, while possible, will not work as intended due to the internal implementation of the automation engine.
When assigning a window active on one display to a frame on another display,
rpcd will stop and restart the window
process to execute it on the new display. When defining a window with the
ondemand kill-mode (see below), the process
is terminated as soon as the window is no longer mapped on any display.
External processes may update the automation variable space and trigger a re-evaluation of the automation script by using one of the configured control inputs (Unix domain socket or FIFO).
To update a variable, write or send a
\n-terminated line of the following format:
Variables (for example
%AutoVar) used as parameters are replaced with their value (from the automation variable space) before execution.
Variables reflect the content they had when the window was started, as updates at a later time are not possible.
A method to restart a window on variable change may be implemented in the future.
The following swap/kill modes are supported for windows:
- default (
lazy): The process is started when required, and stopped only when when shutting down or mapping the window to another X server (necessitating an update of the environment).
ondemand: Start the process when the window is mapped, terminate the process when it is unmapped.
keepalive: Start the process on
rpcdstartup (on the default display), stop only when shutting down or switching X servers.
Usage (Web Interface)
To run a command
- Point your browser to the web client
- Select a command to see its options
- Fill the options to your liking
Runto start the command
Stopto kill the program
To change the layout
- Point your browser to the web client
- Select a layout to view it
Applyto activate it on the screen
Usage (Command Line Interface)
The command line interface client for the HTTP API may for example be used for automating interaction with
The module accepts the following parameters:
||Print a short help summary|
||List all commands supported by the server|
||List all layouts supported by the server|
||Load a layout on a display|
||Run a command with arguments, formatted as
||Stop a command|
||Query server status|
||Run a command in fullscreen mode|
||Select a frame to run a command in|
||Print machine-readable JSON output|
||Select the target host (Default:
||Select the API port (Default:
Interaction with the daemon is mostly limited to the HTTP API. It is documented in endpoints.txt and may be accessed either directly or through the provided interfaces.
To generate a layout dump from an existing ratpoison instance for use with
ratpoison -c sfdump and
store the output to a file.
Some of the features may not be immediately obvious or may have interesting background information.
Reloading the daemon configuration
When the daemon receives
SIGHUP, it will try to reload the configuration file it was started with.
When a user command is running, the configuration reload is postponed until the command terminates.
Upon receiving a second
SIGHUP while waiting for command termination, the configuration is force-reloaded,
which will terminate all running commands.
Should the reloaded configuration contain an error,
rpcd will not shut down but respond as if no
configuration would have been read. This implies that the daemon will not respond on any API endpoint.
When sending a
stop command to the API, rpcd first sends SIGTERM to the process group it spawned for the
start command. This should terminate all processes within that group. Should a process misbehave and not
terminate upon receiving SIGTERM, the next
stop command will send SIGKILL to the process.
The fullscreen checkbox (and the fullscreen parameter to the
start endpoint) cause rpcd to execute the
only (take window fullscreen on this screen) before running the command, as well as
undo at termination, rolling back the last layout change.
Commands without windows
Indicating that a command creates no X windows (for example, to implement control commands for another running command) has the following consequences:
- The command will not have a
DISPLAYvariable in its environment
fullscreenparameters are ignored
- This implies that there will be no interaction with
ratpoisonat all for the command
- This implies that there will be no interaction with
- The command will not block the execution of any automation script
In a multihead environment (that is, one where
rpcd manages multiple ratpoison instances on different
X servers), the specific display a command is to be run on needs to be passed. To stay compatible with single-head
deployments, this option may be omitted and the first display defined in the configuration is used.
In the same manner, layouts may still be defined with the old configuration syntax (omitting the display a layout is defined on). The default display will then be used for the layout.
Mapping windows to processes
There is no inherently reliable way for an external process like
rpcd to map X11 window IDs to the processes
that spawned them. This is a known problem, for which the
was created. For child processes (commands and automated windows) supporting this protocol (which is most),
all features work as intended. For processes not supporting it, a "window filter" feature is intended to be implemented
at a later stage. Sadly, some applications refuse to set any identifying information within the window properties.
If a user command is running,
rpcd may assign such a window to the last command started as a last-resort heuristic.
The following features may be broken for such processes:
- Loading a layout while the command is running may hide the window without terminating the command
- Display automation may not run even though there is no window displayed, as the display is still considered busy until the command terminates
- The window may not show up at all (with this not being recognized as a bug in
- Nesting conditionals in the automation configuration will pass the parser, but execution will not be straightforward and may produce unintended side effects due to the internal implementation.
- Special characters and spaces in layout/command names currently cause problems. This may be fixed in the (near) future.
stringarguments allow free-form user supplied data to be passed to spawned commands, presenting a possible security risk if not properly sanitized. Properly checking and sanitizing user input is the responsibility of the called command.
- All programs started by
rpcdshould support the
rpcdto be able to reliably map X11 windows to child processes.