X11 lib - 如何获取当前window的PID?
X11 lib - How to obtain PID of the current window?
如何使用X11 lib获取当前window的PID?
我尝试检查 window 及其父项的 _NET_WM_PID
属性,但它始终未设置。
由于 X11 团队做出的架构决策,它无法可靠地完成。例如,创建 window 的进程甚至可能与 X11 服务器不在同一台机器上(谁知道 运行 所在机器的 OS 是否有概念PID的?);除此之外,X11 中并没有真正的 "ownership" 概念,因为任何程序都可以对任何 window.
做任何事情
X11 的 PID 没有很好的获取方式window;如果有它也不会立即有用,因为不能保证该进程在同一台机器上,甚至可能无法从您的进程 运行 所在的机器上解析。
旧的 xhost
机制实际上已从现代用法中消失,但这个概念非常活跃。 ssh -X
被大量使用,您可能不得不处理这样一个事实,即您的进程和目标进程在 ssh -X
的不同实例下都是 运行,可能在不同的用户下。这没有留下解决目标的路径。
但是,如果您是因为需要终止进程而来到这里,那么您(有点)走运了。通过在目标 window.
上调用 XKilLClient
,可以从 X11 session(在默认处理程序中终止它)转储该进程
int XKillClient(Display *display, XID resource);
第一个参数是您与 X 服务器的连接。第二个参数是您想要离开的进程的任何 window(或任何其他资源)。有关详细信息,请参阅 man 3 XKillClient
。
看完评论,觉得有必要指出_NET_WM_PID
完全不靠谱。此时我的桌面上有一个 window,_NET_WM_PID
报告 1。这现在听起来像是一个可怕的 XY 问题。检索 属性 的 C API 函数是 XGetWindowProperty
,您可以调用它来获取诸如 window 标题之类的东西。
最后,我弄清楚了我做错了什么。
代码改编自 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
这将每秒显示一次焦点 window 的 PID。
如何使用X11 lib获取当前window的PID?
我尝试检查 window 及其父项的 _NET_WM_PID
属性,但它始终未设置。
由于 X11 团队做出的架构决策,它无法可靠地完成。例如,创建 window 的进程甚至可能与 X11 服务器不在同一台机器上(谁知道 运行 所在机器的 OS 是否有概念PID的?);除此之外,X11 中并没有真正的 "ownership" 概念,因为任何程序都可以对任何 window.
做任何事情X11 的 PID 没有很好的获取方式window;如果有它也不会立即有用,因为不能保证该进程在同一台机器上,甚至可能无法从您的进程 运行 所在的机器上解析。
旧的 xhost
机制实际上已从现代用法中消失,但这个概念非常活跃。 ssh -X
被大量使用,您可能不得不处理这样一个事实,即您的进程和目标进程在 ssh -X
的不同实例下都是 运行,可能在不同的用户下。这没有留下解决目标的路径。
但是,如果您是因为需要终止进程而来到这里,那么您(有点)走运了。通过在目标 window.
上调用XKilLClient
,可以从 X11 session(在默认处理程序中终止它)转储该进程
int XKillClient(Display *display, XID resource);
第一个参数是您与 X 服务器的连接。第二个参数是您想要离开的进程的任何 window(或任何其他资源)。有关详细信息,请参阅 man 3 XKillClient
。
看完评论,觉得有必要指出_NET_WM_PID
完全不靠谱。此时我的桌面上有一个 window,_NET_WM_PID
报告 1。这现在听起来像是一个可怕的 XY 问题。检索 属性 的 C API 函数是 XGetWindowProperty
,您可以调用它来获取诸如 window 标题之类的东西。
最后,我弄清楚了我做错了什么。 代码改编自 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
这将每秒显示一次焦点 window 的 PID。