我试过这个:
xprop -id $(gedit & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar而不是我想要做的,然后点击gedit窗口- MY_VAR1没有出现在那里。
所以我想也许我应该睡在里面..。我试过:
xprop -id $(gedit & sleep 5 & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar等了5秒,试了一下,点击了新的窗口。还是什么都没有
谢谢
发布于 2018-11-05 19:45:33
正如杰夫所指出的,PID和window ID是不同的东西,在那里并不总是一种简单的映射方式 --一些进程没有窗口,一些进程共享一个窗口,而另一些进程仍然有很多窗口(至少在X级别上是这样的,即使您只看到一个窗口)。
启动gedit时,我有一个可见窗口,但有3个名称或类"gedit“的离散anonymous (xwininfo -root -tree -all),其中一个是窗口管理器窗口(我使用fvwm2,您的窗口可能不同),其中一个是”客户端领导“,还有多达20个其他匿名的”窗口“,这些窗口实际上是用户界面的一部分(取决于gedit版本、选项卡数和GTK+)。
为了部分解决这个协调问题,您可以使用属性_NET_WM_PID和WM_CLIENT_LEADER,这些属性应该保存拥有进程的PID,以及有多个窗口的领导者ID (虽然后者确实用于会话管理,但在这里可能会有所帮助)。现在,_NET_WM_PID可能存在一些问题,它要求进程和窗口管理器的行为必须正确,但一般来说,在现代桌面上,这应该是可靠的(除了一些老的程序,比如rxvt)。考虑到环境变量之类的属性,应该将其设置为PID,但是没有什么可以强制这样做,尽管一些WMs在这方面比其他WMs更主动。
通常,对于这种类型的问题,您会编写一个简短的脚本,它将枚举gedit的窗口,在循环中查询_NET_WM_PID属性,以获取刚刚启动的进程的PID,然后设置该属性。然而,一切都会对你不利:
xprop缺乏输出所查询窗口的ID的能力。gedit打开的内容更改窗口名称,xprop不支持通配符/模式,并且不会按窗口类匹配xwininfo和xprop都只输出匹配的第一个窗口(例如,由-name输出),而不是全部输出,两者都不便于解析输出。gedit作为单个进程运行,因此,如果启动第二个gedit,该进程一与主进程进行联系就会退出。但是,在最近的版本中,您可以使用gedit -s运行独立的进程/窗口。这就是像xdotool、xwit和wmctl这样的实用程序存在的原因;-)不幸的是,这些工具中没有任何一个是在没有帮助的情况下做到这一点的。
如果您运行的是独立的实例,这将起到很好的作用,就像shell脚本一样,因此可以理解(并且支持文件名参数):
#!/bin/bash
gedit -s "$@" &
_pid=$!
_wid=$(xdotool search --sync --onlyvisible --pid $_pid)
xprop -f MY_VAR1 8s -set MY_VAR1 MyCustomVar -id $_wid
# xprop -id $_wid MY_VAR1 ## for testing这使用xdotool进行繁重的提升,在“同步”模式下,为窗口提供启动和设置属性的时间,并使用gedit -s,使该过程是独立的和长期存在的,而不仅仅是将其交给现有的实例,然后消失(留下xdotool在周围徘徊)。
或者一个等价的单线:
gedit -s & xdotool search --sync --onlyvisible --pid $! |
xargs -r xprop -f MY_VAR1 8s -set MY_VAR1 MyCustomVar -id注意到:
xdotool可以按PID进行搜索,也可以按名称设置一些属性,但不能按需要设置任意属性名称。xprop的搜索和输出选项很差xdotool输出十进制窗口IDs,xprop接受十进制或十六进制。如果没有xdotool,您可以这样做,但最终可能会出现复杂的混乱,需要列出系统上的每个窗口,然后依次处理每个窗口。我试过了,它太丑了,不能贴在这里:-)
对于另一种方法:标准的GTK+客户机允许您通过命令行选项设置属性,即使应用程序没有记录它们(gedit --help-gtk)。遗憾的是,不是任意属性,但您可以将"Class“设置为任意字符串。由于该类是一个多值属性,因此每个窗口仍然具有"gedit“类(因此,如果选择这种方式,设置/资源仍然适用于它,但它可以防止应用"Gedit”设置,尽管这也是一个优势)。
$ gedit --class MyCustomVar
$ xprop -notype -name gedit WM_CLASS _NET_WM_PID
WM_CLASS = "gedit", "MyCustomVar"
_NET_WM_PID = 1517
WM_NAME = "gedit"还有几种用于窗口/进程映射的其他选项(在/proc/PID/environ中查询WINDOWID,尽管这只适用于由遵守该约定的终端仿真器启动的进程;也可能是写一个gedit插件 ),但两者都没有吸引力。还请参阅https://stackoverflow.com/questions/151407/how-to-get-an-x11-window-from-a-process-id --其中一个更有趣的答案是,有一个LD_PRELOAD哈克包XCreateWindow()的链接,还有几个其他的API函数来设置任意属性。
https://unix.stackexchange.com/questions/479788
复制相似问题