如何使用X11 lib获取当前窗口的PID?
我尝试检查窗口及其父项的_NET_WM_PID
属性,但始终未设置。
答案 0 :(得分:2)
由于X11团队做出的架构决策,它无法可靠地完成。例如,创建窗口的进程甚至可能与X11服务器不在同一台机器上(并且谁知道它运行的机器的OS是否具有PID的概念?);除此之外,还没有真正的所有权和#34;在X11中,因为任何程序都可以对任何窗口执行任何操作。
答案 1 :(得分:1)
没有好办法获得X11窗口的PID;并且如果它不会立即有用,因为该过程不能保证在同一台机器上,甚至可能无法从您的过程运行的机器上解析。
旧的xhost
机制实际上已经从现代使用中消失了,但这个概念非常活跃。 ssh -X
非常有用,您可能需要处理这样一个事实:您的流程和目标流程都在ssh -X
的不同实例下运行,可能位于不同的用户之下。这没有留下解决目标的路径。
但是,如果你因为需要杀死这个过程来到这里,那么你很幸运。通过在目标窗口上调用XKilLClient
,可以从X11会话(在默认处理程序中终止它)转储该进程。
int XKillClient(Display *display, XID resource);
第一个参数是您与X服务器的连接。第二个参数是您想要消失的进程的任何窗口(或任何其他资源)。有关详细信息,请参阅man 3 XKillClient
。
在阅读评论后,我觉得我不得不指出_NET_WM_PID
完全不可靠。此时我的桌面上有一个窗口_NET_WM_PID
报告1.这听起来像是一个可怕的XY问题。用于检索属性的C API函数是XGetWindowProperty
,您可以调用它来获取窗口标题等内容。
答案 2 :(得分:0)
最后,我弄明白我做错了什么。 代码改编自ARBTT:
getParent :: Display -> Window -> IO Window
getParent dpy w = do
(_, parent, _) <- queryTree dpy w `catchIOError` const (return (0,0,[]))
return parent
followTreeUntil :: Display -> (Window -> IO Bool) -> Window -> IO Window
followTreeUntil dpy cond = go
where go w = do
match <- cond w
if match
then return w
else
do p <- getParent dpy w
if p == 0 then return w
else go p
getFocusedWindowPID :: Display -> IO String
getFocusedWindowPID d = do
(w, _) <- getInputFocus d
wt <- followTreeUntil d (hasCorrectPID d) w
getWindowPID d wt
getWindowPID :: Display -> Window -> IO String
getWindowPID d w = do
nWP <- internAtom d "_NET_WM_PID" False
pid' <- getWindowProperty32 d nWP w
let pid = case pid' of
Just [pid''] -> show pid''
_ -> ""
return pid
hasCorrectPID :: Display -> Window -> IO Bool
hasCorrectPID d w = do
pid <- getWindowPID d w
return $ pid /= ""
printPIDs :: IO ()
printPIDs = do
d <- openDisplay ""
pid <- getFocusedWindowPID d
print pid
closeDisplay d
threadDelay 1000000
printPIDs
这将每秒显示一次聚焦窗口的PID。