在尝试编写涉及 wmctrl 的脚本时(因为 LMDE 2 上的 MATE 不提供与涉及 Compiz 的其他 WM 配置一样多的高级功能,而我在 LMDE 2 上没有),我遇到了识别最新的问题在一组具有相同标题的窗口中创建窗口。
出现这个问题是因为正如这里所述,我无法使用 PID 来识别该窗口。
所以,我想知道我的假设,即窗口 ID 按升序给出(编辑:当然有一些上限)是否成立。
如果是这样,请给我一个简洁的解释(我认为对于任何足够了解的人来说这应该很容易回答)。
密切相关:我也很高兴知道是否wmctrl -l
实际上按升序(十六进制)数字顺序对具有相同标题的窗口进行排序。似乎是这样,但我还没有找到任何关于此的官方记录声明。
答案1
窗口 ID 由 X 服务器给出。窗口管理器没有发言权。
窗口 ID 在高 12 位中对窗口所属的客户端进行编码。低 12 位首先按顺序分配,但如果中间数字空闲,则可以重新使用。因此,比较窗口 ID 并不能可靠地指示最后创建的是哪个窗口。
请注意,即使您可以通过进程 ID 识别窗口,也无助于找到最新的窗口,因为 PID 并不总是随着时间的推移而增加。即使在按顺序分配 PID 的 Unix 变体上(这不是通用的),一旦达到最大值(Linux 上默认低至 32767),它们就会换行。此外,X11客户端可以与服务器运行在不同的机器上,但进程ID仅在一台机器上有意义。
兼容 Freedesktop 的应用程序(包括 Mate Terminal)设置_NET_WM_USER_TIME
财产每当有用户活动时都会显示窗口(对于 Mate 终端,这意味着输入)。您可以通过 查询该属性xprop -id … _NET_WM_USER_TIME
。这告诉您窗口最后一次活动的时间,而不是创建它的时间。
如果您想可靠地识别窗口,一种可能是设置其标题。另一种可能性是设置具有唯一值的环境变量并使用ps
或/proc
定位具有该唯一值的进程。你可以查找打开 X11 窗口的客户端的进程 ID通过其_NET_WM_PID
财产,如果存在,您可以使用xprop
或 进行查询xdotool getwindowpid
。具有该_NET_WM_PID
属性的 Windows 还应该将该属性WM_CLIENT_MACHINE
设置为运行客户端进程的计算机的主机名。这将有助于为每个窗口使用单独的进程。
答案2
我的猜测是,它们就像 PID,按升序分配,除非它们不是:
PID 环绕。
让我们(暂时)假设它们只会上涨。运行很长时间的系统会发生什么? ID会变得太大,或者必须允许ID大小增长,32位、64位、128位……
如果它们必须上升,那么它们可能会耗尽,而大量的系统资源仍然空闲(无法重用,因此最终系统将因 ID 耗尽而死亡)。