如何使用 xprop 设置自定义属性并在一行中打开该程序?

mas*_*007 3 linux x11

我试过这个:

xprop -id $(gedit & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar
Run Code Online (Sandbox Code Playgroud)

比我尝试 xprop 并单击 gedit 窗口 - MY_VAR1 不在那里。

所以我想也许我应该把睡眠放在那里......我试过:

xprop -id $(gedit & sleep 5 & echo $!) -f MY_VAR1 8s -set MY_VAR1 MyCustomVar
Run Code Online (Sandbox Code Playgroud)

等了 5 秒钟并尝试了 xprop 并单击了新窗口.. 仍然没有

谢谢

mr.*_*tic 7

正如杰夫所指出的,PID 和窗口 ID是不同的东西,并不总是有一种简单的方法可以将它们映射到另一个——有些进程没有窗口,有些进程共享一个窗口,而另一些进程仍然有很多窗口(至少他们有)在X级,即使你只看到一个窗口)。

当我开始gedit我有一个可见的窗口,但3分立的X Windows( xwininfo -root -tree -all)与名称或类别“的gedit”,其中之一是一个窗口管理器窗口(我用FVWM2,你可能不同),并且其中一个是“客户端领导者”,以及多达 20 个其他匿名“窗口”,它们实际上是用户界面的一部分(取决于gedit版本、选项卡数量和 GTK+)。

为了部分解决协调问题,您可以使用属性_NET_WM_PIDWM_CLIENT_LEADER,这些应该保存拥有进程的 PID 和有多个窗口的领导者 ID(虽然后者实际上是用于会话管理,但在这里可能会有所帮助)。现在,可能存在一些问题_NET_WM_PID,它要求进程和窗口管理器正确运行,但总的来说,在现代桌面上,这应该是可靠的(除了一些旧程序,如rxvt)。想想像环境变量这样的属性,它应该设置为 PID,但没有强制执行这一点,尽管我相信有些 WM 比其他 WM 更主动。

通常,对于这种类型的问题,您会编写一个简短的脚本来枚举 的窗口gedit_NET_WM_PID在循环中查询属性以获取您刚刚启动的进程的 PID,然后设置该属性。然而,一切都会对你不利

  • 没有包含窗口 ID 的 X 属性
  • xprop 奇怪的是无法输出您查询的窗口的 ID
  • 窗口名称的变化取决于什么gedit打开,xprop不支持通配符/模式,并且不会被窗口类匹配
  • 双方xwininfoxprop只输出第一窗口匹配(例如,通过-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
Run Code Online (Sandbox Code Playgroud)

这用于xdotool完成繁重的工作,在“同步”模式下为窗口时间启动和设置属性,gedit -s因此该过程是独立且长期存在的,而不仅仅是移交给现有实例然后消失(留下xdotool闲逛)。

或等效的单线:

gedit -s & xdotool search --sync --onlyvisible --pid $! | 
   xargs -r xprop -f MY_VAR1 8s -set MY_VAR1 MyCustomVar -id
Run Code Online (Sandbox Code Playgroud)

注意:

  • xdotool 可以通过PID搜索,也可以设置按名称一些属性,但也可以根据需要不设置任意属性名称
  • xprop 搜索和输出选项很差
  • xdotool输出小数窗口的ID,xprop接受十进制或十六进制
  • 没有太多的错误处理

可以在没有 的情况下执行此操作xdotool,但您最终可能会遇到一个令人费解的混乱,需要列出系统上的每个窗口并依次处理每个窗口。我试过了,贴在这里太难看了:-)

对于替代方法:标准 GTK+ 客户端允许您通过命令行选项设置属性,即使应用程序没有记录它们 ( gedit --help-gtk)。遗憾的是不是任意属性,但您可以将“类”设置为任意字符串。由于该类是一个多值属性,每个窗口仍将具有“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"
Run Code Online (Sandbox Code Playgroud)

窗口/进程映射还有其他几个选项(搜索/proc/PID/environfor WINDOWID,尽管这仅适用于由遵守该约定的终端模拟器启动的进程;或者可能编写一个gedit插件),但两者都没有吸引力。另请参阅/sf/ask/10598521/ - 更有趣的答案之一有一个链接,用于LD_PRELOAD包装XCreateWindow()和一些其他 API 函数来设置任意属性。