Skip to content

Instantly share code, notes, and snippets.

@salewski
Last active February 28, 2023 03:26
Show Gist options
  • Save salewski/fa102f5fc09d39676e6aae8f68a1c3ef to your computer and use it in GitHub Desktop.
Save salewski/fa102f5fc09d39676e6aae8f68a1c3ef to your computer and use it in GitHub Desktop.
wmctrl-list-xterms: canned invocation of wmctrl(1) to list details of windows whose WM_CLASS contains "XTerm"
#!/bin/bash -
# SPDX-FileCopyrightText: <text>
# © 2023 Alan D. Salewski <[email protected]>
# </text>
#
# SPDX-License-Identifier: GPL-2.0-or-later
# wmctrl-list-xterms: Canned wrapper around the wmctrl(1) command that invokes
# it with the arguments to list all windows whose WM_CLASS contains "XTerm"
# (e.g., 'xterm.XTerm').
#
# CAVEAT:
# The output interface from this command should NOT be considered stable. The
# current version lists all available information for each window, with one
# line per window. That is, we always provide the '-p' and '-G' options to
# wmctrl. There is no way to disable that behavior. If real-world practice
# proves that to be too annoying, then we'll change the interface.
#
# Note that the '-x' option to wmctrl provides the column on which we match
# the WM_CLASS value, so that will always be present (this tool would not
# work, otherwise).
#
# Usage:
# wmctrl-list-xterms
#
# Example 1:
# ----------
# Use two separate invocations to find and raise a given XTerm.
#
# First, find the window identity of the window in which we are interested:
#
# $ wmctrl-list-xterms | grep 'whatever'
# 0x0220000f 0 13952 722 -3862 2389 1478 xterm.XTerm yourhost string whatever in window name
#
# Assuming you got a single hit with your grep, run the same command again,
# modified to extract just the window identity field in the first field
# ("0x0220000f" in this example), and feed that to wmctrl(1) directly with
# options that request that that specific XTerm be raised. Note that this
# action requires the use of the '-i' option, since we are identifying the
# window we want raised by its numeric identity (rather than by it's title
# name, which is the default):
#
# $ wmctrl -i -a "$(wmctrl-list-xterms | grep 'whatever' | awk '{ print $1 }')"
#
#
# FIXME:
# * For now, the offical source location is just a GitHub "Gist":
# https://gist.github.com/salewski/fa102f5fc09d39676e6aae8f68a1c3ef
#
declare -r prog='wmctrl-list-xterms'
debugging=false
awk_prog="${AWK:-awk}"
wmctrl_prog="${WMCTRL:-wmctrl}"
declare -a needed_external_progs=(
"${awk_prog}"
"${wmctrl_prog}"
)
for ext_tool in "${needed_external_progs[@]}"; do
t_path=$(builtin type -p "${ext_tool}")
if test $? -ne 0; then
printf "${prog} (error): was unable to locate \"%s\" on PATH; bailing out\n" "${ext_tool}" 1>&2
exit 1
fi
if $debugging; then
printf "${prog} (debug): path to external tool \"%s\": %s\n" "${ext_tool}" "${t_path}" 1>&2
fi
done
declare -a my_wmctrl_opts=()
my_wmctrl_opts+=('-l') # The action for wmctrl to perform
# ("list the windows being mapped by the window manager")
my_wmctrl_opts+=('-x') # Include WM_CLASS in the emitted window list
my_wmctrl_opts+=('-p') # Include PIDs in the emitted window list
my_wmctrl_opts+=('-G') # Include window geometry in the emitted window list:
# x-offset, x-off-set, width and height
# Note that with the above arguments, the output emitted by the wmctrl(1)
# program will look something like this:
# ...
# 0x01c0000f 0 13910 8 -2433 2089 290 xterm.XTerm yourhost some window name
# 0x0220000f 0 13952 722 -3862 2389 1478 xterm.XTerm yourhost some other window name
# ...
#
# where the fields (starting from 1) have the following meanings:
#
# 1: The window identity (as a hexidecimal integer)
#
# 2: The desktop number (a -1 is uded to identify a sticky window)
#
# 3: The PID for the window (present because we specified the '-p' opt)
#
# 4,5,6,7: (present because we specified the '-G' opt)
# 4: x-offset
# 5: y-offset
# 6: width
# 7: height
#
# 8: The WM_CLASS (present because we specified the '-x' opt)
#
# 9: The client machine name ("yourhost" in the above example)
#
# 10-n: The window title (may contain spaces, so may be more than one field)
#
"${wmctrl_prog}" "${my_wmctrl_opts[@]}" \
| "${awk_prog}" '$8 ~ "XTerm"'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment