I tried this:
xprop -id $(gedit & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar
Than i tried to xprop and click on the gedit window – MY_VAR1 was not present there.
So i thought maybe i should put sleep in there… i tried:
xprop -id $(gedit & sleep 5 & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar
Waited 5 seconds and tried xprop and clicked on the new window.. still nothing
Thanks
Best Answer
As Jeff noted, PID and Window ID are different things, and there isn't always an easy way to map one to another — some processes have no window, some processes share a window, and others still have many windows (at least they do at the X level, even if you only see a single window).
When I start
gedit
I have one visible window, but 3 discrete X Windows (xwininfo -root -tree -all
) with name or class "gedit", one of which is a window manager window (I use fvwm2, yours may differ), and one of which is the "client leader", along with up to 20 other anonymous "windows" which are really parts of the user interface (depending ongedit
version, number of tabs, and GTK+).To partly solve that coordination problem you can use properties
_NET_WM_PID
andWM_CLIENT_LEADER
, these should hold the PID of the owning process, and leader ID where there are multiple windows (though the latter is really for session management, it might be helpful here). Now, there may some problems with_NET_WM_PID
, it requires that processes and the window manager behave correctly, but in general, on a modern desktop, this should be reliable (with the exception of a few old programs likerxvt
). Think of properties like environment variables, it should be set to the PID, but nothing enforces this, though some WMs are more proactive than others about this I believe.Ordinarily, for this type of problem, you would write a short script that would enumerate the windows for
gedit
, query the_NET_WM_PID
property in a loop for the PID of the process you just started, then set the property. However, everything will conspire against you:xprop
oddly lacks the ability to output the ID of a window that you querygedit
opens,xprop
doesn't support wildcard/patterns, and won't match by window classxwininfo
andxprop
only output the first window that matches (e.g. by-name
) rather than all of them, and neither make it easy to parse the outputgedit
runs by default as a single process, so if you start a secondgedit
that process exits as soon as it has made contact with the main process. However, on recent versions, you can usegedit -s
to run independent processes/windows.This is the reason that utilities like
xdotool
,xwit
andwmctl
exist ;-) Unfortunately, not even any of those do exactly this without help.If you are running standalone instances, this will do the trick, as a shell script so it's understandable (and supports filename arguments):
This uses
xdotool
to do the heavy lifting, in "sync" mode to give the window time to start up and set properties, and withgedit -s
so the process is standalone and long-lived and doesn't just hand over to an existing instance and then disappear (leavingxdotool
hanging around).Or an equivalent one-liner:
Noting:
xdotool
can search by PID, it can also set a few properties by name, but cannot set arbitrary property names as requiredxprop
has poor search and output optionsxdotool
outputs decimal windows IDs,xprop
accepts either decimal or hexYou could do this without
xdotool
, but you'd likely end up with a convoluted mess that needs to list every window on the system and process each one in turn. I tried, it's just too ugly to paste here :-)For an alternative approach: a standard GTK+ client allows you to set properties via command-line options, even if the application doesn't document them (
gedit --help-gtk
). Sadly not arbitrary properties, but you can set the "Class" to any arbitrary string. Since the class is a multi-valued property each window will still have the "gedit" class (so settings/resources will still apply to it, if selected that way, but it can prevent "Gedit" settings being applied, though that can be an advantage too).There are a couple of other options for window/process mapping (ferreting in
/proc/PID/environ
forWINDOWID
, though this only works for processes started by terminal emulator that observes that convention; or possibly write agedit
plugin ) but neither is appealing. See also https://stackoverflow.com/questions/151407/how-to-get-an-x11-window-from-a-process-id - one of the more interesting answers there has a link for anLD_PRELOAD
hack to wrapXCreateWindow()
and a couple of other API functions to set arbitrary properties.