wm-launch provides a shared library for use with LD_PRELOAD
and a
command-line tool to set IDs on newly created X11 windows. It is intended to be
used by a window manager to uniquely identify clients it launches.
-
Fedora (copr)
dnf copr enable jcrd/wm-launch dnf install wm-launch
-
Arch Linux (AUR)
git clone https://aur.archlinux.org/wm-launch.git cd wm-launch makepkg -si
LD_PRELOAD
can be specified along with WM_LAUNCH_ID
in the
environment of a command:
LD_PRELOAD=/usr/lib/wm-launch/wm-launch-preload.so WM_LAUNCH_ID=id1 xterm
The window created by xterm
will have the property WM_LAUNCH_ID
:
$ xprop WM_LAUNCH_ID
> WM_LAUNCH_ID(UTF8_STRING) = "id1"
A command-line tool is provided for convenience and for interacting with window factories:
usage: wm-launch [options] WM_LAUNCH_ID COMMAND...
options:
-h Show help message
-s Launch with systemd-run
-j Launch with firejail
-f FACTORY Launch via a window factory
-w DIR Launch workspace from DIR
-v Show version
wm-launch can be used to:
- reliably assign clients to window manager desktops/workspaces so that even slow-to-spawn windows appear where intended
- identify separate instances of the same application to be managed differently, focused via keybindings, etc.
- launch or focus a single instance of an application
A window factory is an X11 client responsible for creating the windows of new clients. It can be either implicit or explicit, the key difference being that implicit factories create their own window.
An implicit factory is an X11 client that reuses a single instance to create
additional windows each time it's launched, e.g. qutebrowser
, kitty -1
.
To correctly set the WM_LAUNCH_ID
of an implicit factory, always run it via
wm-launch
with the same argument to the -f
flag:
wm-launch -f qute id2 qutebrowser
An explicit window factory is a daemon that creates windows based on a client's
request, e.g. emacsd
and emacsclient
, urxvtd
and urxvtc
.
To correctly set the WM_LAUNCH_ID
of an explicit factory, run the daemon with
LD_PRELOAD
and WM_LAUNCH_FACTORY
:
LD_PRELOAD=/usr/lib/wm-launch/wm-launch-preload.so WM_LAUNCH_FACTORY=emacs emacsd
Then launch with wm-launch -f emacs id3 emacsclient
.
wm-launchd must be running to handle window factories. Enable the systemd
service to run when the graphical-session.target
is reached:
systemctl --user enable wm-launchd
With the -w
flag, wm-launch
can initiate the startup of multiple clients
based on a .workspace
file. The programs therein are expected to be
launched by the running window manager, which must implement the
com.github.jcrd.wm_launch.WindowManager
DBus interface.
A .workspace
file contains one program per line to run.
If preceded by a @
, the program will be interpreted as one defined by the
window manager, otherwise the window manager should execute it directly.
For example, given:
@terminal
xterm
@terminal
should be defined by the window manager. This is useful when
additional context is necessary, such as running with a factory,
systemd-run
, etc.
xterm
should be executed directly by the window manager.
A window manager must implement the com.github.jcrd.wm_launch.WindowManager
interface under the path /com/github/jcrd/wm_launch/WindowManager
at the
well-known name com.github.jcrd.wm_launch
.
This interface must define the NewWorkspace
method, which takes three arguments:
- The workspace name as a string
- The workspace working directory as a string
- An array of strings representing clients to launch
It returns nothing.
A client can be launched with systemd-run
by running it via wm-launch
using
the -s
flag. This will run the command in a user scope with
systemd-run --user --scope
.
A client can be launched with firejail
by running it via wm-launch
using the -j
flag. This sets the required
environment variables in the sandbox created by firejail.
- Be aware of environment variable inheritance. This becomes a problem when
launching a client from a terminal created by a factory, i.e.
WM_LAUNCH_FACTORY
is present in its environment. The new client will inherit this variable and expect the given factory to exist. This scenario can be avoided by launching the client withwm-launch -f ""
.
- Integration with Awesome WM is provided by awesome-launch.
- libxcb
- libx11
- perl
- go
Build with make
.
Install with make install
.
Tests have additional dependencies:
- xvfb
Run tests locally with make test
or use make test-podman
to run them in a
supplantr/wm-launch container
which includes all dependencies.
Note: firejail cannot run in containers. It must be tested locally.
wm-launch is licensed under the GNU General Public License v3.0 or later (see LICENSE).
wm-launch-preload.c is based on ld-preload-xcreatewindow-net-wm-pid.