How to get an X11 Window from a Process ID?

后端 未结 8 702
孤街浪徒
孤街浪徒 2020-11-27 11:30

Under Linux, my C++ application is using fork() and execv() to launch multiple instances of OpenOffice so as to view some powerpoint slide shows. This part works.

Ne

8条回答
  •  粉色の甜心
    2020-11-27 12:12

    If you use python, I found a way here, the idea is from BurntSushi

    If you launched the application, then you should know its cmd string, with which you can reduce calls to xprop, you can always loop through all the xids and check if the pid is the same as the pid you want

    import subprocess
    import re
    
    import struct
    import xcffib as xcb
    import xcffib.xproto
    
    def get_property_value(property_reply):
        assert isinstance(property_reply, xcb.xproto.GetPropertyReply)
    
        if property_reply.format == 8:
            if 0 in property_reply.value:
                ret = []
                s = ''
                for o in property_reply.value:
                    if o == 0:
                        ret.append(s)
                        s = ''
                    else:
                        s += chr(o)
            else:
                ret = str(property_reply.value.buf())
    
            return ret
        elif property_reply.format in (16, 32):
            return list(struct.unpack('I' * property_reply.value_len,
                                      property_reply.value.buf()))
    
        return None
    
    def getProperty(connection, ident, propertyName):
    
        propertyType = eval(' xcb.xproto.Atom.%s' % propertyName)
    
        try:
            return connection.core.GetProperty(False, ident, propertyType,
                                            xcb.xproto.GetPropertyType.Any,
                                            0, 2 ** 32 - 1)
        except:
            return None
    
    
    c = xcb.connect()
    root = c.get_setup().roots[0].root
    
    _NET_CLIENT_LIST = c.core.InternAtom(True, len('_NET_CLIENT_LIST'),
                                         '_NET_CLIENT_LIST').reply().atom
    
    
    raw_clientlist = c.core.GetProperty(False, root, _NET_CLIENT_LIST,
                                        xcb.xproto.GetPropertyType.Any,
                                        0, 2 ** 32 - 1).reply()
    
    clientlist = get_property_value(raw_clientlist)
    
    cookies = {}
    
    for ident in clientlist:
        wm_command = getProperty(c, ident, 'WM_COMMAND')
        cookies[ident] = (wm_command)
    
    xids=[]
    
    for ident in cookies:
        cmd = get_property_value(cookies[ident].reply())
        if cmd and spref in cmd:
            xids.append(ident)
    
    for xid in xids:
        pid = subprocess.check_output('xprop -id %s _NET_WM_PID' % xid, shell=True)
        pid = re.search('(?<=\s=\s)\d+', pid).group()
    
        if int(pid) == self.pid:
            print 'found pid:', pid
            break
    
    print 'your xid:', xid
    

提交回复
热议问题