我试过这个:
xprop -id $(gedit & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar
我尝试 xprop 并单击 gedit 窗口 - MY_VAR1 不存在。
所以我想也许我应该在那里睡觉......我尝试过:
xprop -id $(gedit & sleep 5 & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar
等了 5 秒,尝试了 xprop 并点击了新窗口..仍然没有任何结果
谢谢
答案1
正如 Jeff 指出的那样,PID 和窗口号是不同的东西,并且有将一个映射到另一个并不总是一种简单的方法— 有些进程没有窗口,有些进程共享一个窗口,而其他进程仍然有许多窗口(至少它们在 X 级别上是这样,即使您只看到一个窗口)。
当我开始时,gedit
我有一个可见的窗口,但有 3 个离散的 X Windows ( xwininfo -root -tree -all
),其名称或类为“gedit”,其中之一是窗口管理器窗口(我使用 fvwm2,您的可能不同),其中之一是“客户端” Leader”,以及多达 20 个其他匿名“窗口”,它们实际上是用户界面的一部分(取决于gedit
版本、选项卡数量和 GTK+)。
为了部分解决协调问题,您可以使用属性_NET_WM_PID
和WM_CLIENT_LEADER
,这些应该保存所属进程的 PID,以及有多个窗口的领导者 ID(尽管后者实际上是为了会话管理,这可能对这里有帮助)。现在,可能存在一些问题_NET_WM_PID
,它要求进程和窗口管理器行为正确,但一般来说,在现代桌面上,这应该是可靠的(除了一些旧程序,例如rxvt
)。想想像环境变量这样的属性,它应该被设置为 PID,但没有任何强制执行这一点,尽管我相信一些 WM 比其他 WM 更主动。
通常,对于此类问题,您可以编写一个简短的脚本来枚举 Windows ,在循环中gedit
查询属性以获取刚刚启动的进程的 PID,然后设置该属性。_NET_WM_PID
然而,一切都会密谋反对你:
- 没有包含窗口 ID 的 X 属性
xprop
奇怪的是,它无法输出您查询的窗口的 ID- 窗口名称根据
gedit
打开的内容而变化,xprop
不支持通配符/模式,并且不会按窗口类别匹配 - 两者
xwininfo
且xprop
仅输出匹配(例如 by-name
)的第一个窗口,而不是所有窗口,并且都不易于解析输出 - X“窗口”的数量可以超过可见的窗口扩大 50 倍
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
输出十进制窗口 ID,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
for中进行搜索WINDOWID
,尽管这仅适用于由遵守该约定的终端仿真器启动的进程;或者可能写一个gedit
插件)但两者都没有吸引力。也可以看看https://stackoverflow.com/questions/151407/how-to-get-an-x11-window-from-a-process-id- 更有趣的答案之一有一个LD_PRELOAD
hack 包装的链接XCreateWindow()
和几个其他 API 函数来设置任意属性。