将XQueryTree数据中的组关联到窗口

时间:2015-08-10 07:53:42

标签: linux gtk x11

我在所有窗口上运行了XQueryTree,并且从数组顶部的最顶部到数组底部的最底部以z顺序获取它们。

然后,我只过滤了每个XGetWindowAttributes上显示的内容,如果它不是map_state IsVisible,则将其删除

对于每个可见窗口,我检查并获取_NET_WM_PID_NET_WM_NAMExyheightheight + border_width) ,和width(作为width + border_width)。

我的数据就在这个要点上,也在底部:https://gist.github.com/Noitidart/94562d08f243cd7ca7ec

我的设置是两台显示器。这是他们俩的完整画面:

每个显示器上都有一个透明窗口,即显示器的高度和宽度,它们的标题是" nativeshot_canvas"。

通过查看数据,我发现XQueryTree窗口被分成多个条目。我的手动分析告诉我:

  1. " nativeshot_canvas"在左侧监视器上
  2. " nativeshot_canvas"在右侧监视器上

    • UNKNOWN WINDOW 1
    • UNKNOWN WINDOW 2
  3. 右侧监视器上的
  4. 水平菜单栏

  5. 左侧监视器上的水平菜单栏

  6. 右侧监视器上的垂直停靠

  7. 左侧监视器上的垂直停靠

    • UNKNOWN WINDOW 3
  8. " Javascript Application"窗口

  9. "浏览器控制台"窗口
  10. " Mozilla Firefox"带有两个标签的窗口
  11. "桌面"
  12. 数据图表和我的手动分析如下。

    问题

    有没有办法以编程方式识别哪个条目与单个窗口相关?在我的手动分析中,我使用了一些我提出的模式,每个窗口组都以_NET_WM_PID(下面的数据为pid键)或_NET_WM_NAMEtitle开头。关键数据如下)。我不认为这是一个很好的模式,因为我们看到顶部有一个PID,但它们的宽度和高度都是1.

    编辑:仍然坚持如何找到一种保证的方法将这些划分关联到窗口组中。我基本上需要得到所有窗口的所有x,y,宽度和高度,如果有人有任何输入我将是非常好的

    我的代码列出了XQueryTree数据:

                var xqRoot = ostypes.TYPE.Window();
                var xqParent = ostypes.TYPE.Window();
                var xqChildArr = ostypes.TYPE.Window.ptr();
                var nChilds = ostypes.TYPE.unsigned_int();
    
                var gpTypeReturned = ostypes.TYPE.Atom();
                var gpFormatReturned = ostypes.TYPE.int();
                var gpNItemsReturned = ostypes.TYPE.unsigned_long();
                var gpBytesAfterReturn = ostypes.TYPE.unsigned_long();
                var gpItemsArr = ostypes.TYPE.unsigned_char.ptr();
    
                var geoRoot = ostypes.TYPE.Window();
                var geoX = ostypes.TYPE.int();
                var geoY = ostypes.TYPE.int();
                var geoW = ostypes.TYPE.unsigned_int();
                var geoH = ostypes.TYPE.unsigned_int();
                var geoBorderWidth = ostypes.TYPE.unsigned_int();
                var geoDepth = ostypes.TYPE.unsigned_int();
    
                var wAttr = ostypes.TYPE.XWindowAttributes();
    
                var processWin = function(w) {
                    if (aOptions.filterVisible) {
                        var rez_WA = ostypes.API('XGetWindowAttributes')(ostypes.HELPER.cachedXOpenDisplay(), w, wAttr.address());
                        console.info('wAttr.map_state:', wAttr.map_state.toString());
                        if (!cutils.jscEqual(wAttr.map_state, ostypes.CONST.IsViewable)) {
                            return; // continue as this is a hidden window, do not list features, do not dig this window
                        }
                    }
    
                    var thisWin = {};
                    // fetch props on thisWin
    
                    thisWin.hwndXid = parseInt(cutils.jscGetDeepest(w));
    
                    if (aOptions.getPid) {
                        var rez_pid = ostypes.API('XGetWindowProperty')(ostypes.HELPER.cachedXOpenDisplay(), w, ostypes.HELPER.cachedAtom('_NET_WM_PID'), 0, 1, ostypes.CONST.False, ostypes.CONST.XA_CARDINAL, gpTypeReturned.address(), gpFormatReturned.address(), gpNItemsReturned.address(), gpBytesAfterReturn.address(), gpItemsArr.address());
                        if (ostypes.HELPER.getWinProp_ReturnStatus(ostypes.CONST.XA_CARDINAL, gpTypeReturned, gpFormatReturned, gpBytesAfterReturn) == 1) {
                            var jsN = parseInt(cutils.jscGetDeepest(gpNItemsReturned));
                            if (jsN == 0) {
                                thisWin.pid = null; // set to null as this window did not have a pid, but i add the key indicating i tested for it and the window had the proerty
                            } else {
                                //console.info('gpItemsArr:', gpItemsArr.toString(), 'casted:', ctypes.cast(gpItemsArr, ostypes.TYPE.CARD32).toString(), 'casted to single el:', ctypes.cast(gpItemsArr, ostypes.TYPE.CARD32.array(1).ptr).contents.toString()); // "gpItemsArr:" "ctypes.unsigned_char.ptr(ctypes.UInt64("0x7f229409d710"))" "casted:" "ctypes.unsigned_int(2483672848)" "casted to single el:" "ctypes.unsigned_int.array(1)([2212])" // showing that it must be cast and not just to type cuz its single element, but to array of 1 element
                                thisWin.pid = parseInt(cutils.jscGetDeepest(ctypes.cast(gpItemsArr, ostypes.TYPE.CARD32.array(1).ptr).contents[0]));
                            }
                            ostypes.API('XFree')(gpItemsArr);
                        } else {
                            thisWin.pid = undefined; // window didnt even have property
                        }
                    }
    
                    if (aOptions.getTitle) {
                        var rez_title = ostypes.API('XGetWindowProperty')(ostypes.HELPER.cachedXOpenDisplay(), w, ostypes.HELPER.cachedAtom('_NET_WM_NAME'), 0, 256 /* this number times 4 is maximum ctypes.char that can be returned*/, ostypes.CONST.False, ostypes.HELPER.cachedAtom('UTF8_STRING'), gpTypeReturned.address(), gpFormatReturned.address(), gpNItemsReturned.address(), gpBytesAfterReturn.address(), gpItemsArr.address());
                        if (ostypes.HELPER.getWinProp_ReturnStatus(ostypes.HELPER.cachedAtom('UTF8_STRING'), gpTypeReturned, gpFormatReturned, gpBytesAfterReturn) == 1) {
                            var jsN = parseInt(cutils.jscGetDeepest(gpNItemsReturned));
                            if (jsN == 0) {
                                thisWin.title = ''; // window had property but not title
                            } else {
                                thisWin.title = ctypes.cast(gpItemsArr, ostypes.TYPE.char.array(jsN).ptr).contents.readString();
                            }
                            ostypes.API('XFree')(gpItemsArr);
                        } else {
                            thisWin.title = undefined; // window didnt even have property
                        }
                    }
    
                    if (aOptions.getBounds) {
                        if (aOptions.filterVisible) {
                            // then get the info from wAttr as its already available
                            thisWin.left = parseInt(cutils.jscGetDeepest(wAttr.x));
                            thisWin.top = parseInt(cutils.jscGetDeepest(wAttr.y));
    
                            var borderWidth = parseInt(cutils.jscGetDeepest(wAttr.border_width));
                            thisWin.borderWidth = borderWidth;
    
                            thisWin.width = parseInt(cutils.jscGetDeepest(wAttr.width))/* + borderWidth*/;
                            thisWin.height = parseInt(cutils.jscGetDeepest(wAttr.height))/* + borderWidth*/;
    
                            thisWin.right = thisWin.left + thisWin.width;
                            thisWin.bottom = thisWin.top + thisWin.height;
                        } else {
                            var rez_bounds = ostypes.API('XGetGeometry')(ostypes.HELPER.cachedXOpenDisplay(), w, geoRoot.address(), geoX.address(), geoY.address(), geoW.address(), geoH.address(), geoBorderWidth.address(), geoDepth.address());
                            thisWin.left = parseInt(cutils.jscGetDeepest(geoX));
                            thisWin.top = parseInt(cutils.jscGetDeepest(geoY));
    
                            var borderWidth = parseInt(cutils.jscGetDeepest(wAttr.border_width));
                            thisWin.borderWidth = borderWidth;
    
                            thisWin.width = parseInt(cutils.jscGetDeepest(wAttr.width))/* + borderWidth*/;
                            thisWin.height = parseInt(cutils.jscGetDeepest(wAttr.height))/* + borderWidth*/;
    
                            thisWin.right = thisWin.left + thisWin.width;
                            thisWin.bottom = thisWin.top + thisWin.height;
                        }
                    }
    
                    rezWinArr.splice(0, 0, thisWin);
    
                    // dig the win even if it doesnt qualify
                    var rez_XQ = ostypes.API('XQueryTree')(ostypes.HELPER.cachedXOpenDisplay(), w, xqRoot.address(), xqParent.address(), xqChildArr.address(), nChilds.address()); // interesting note about XQueryTree and workspaces: "The problem with this approach is that it will only return windows on the same virtual desktop.  In the case of multiple virtual desktops, windows on other virtual desktops will be ignored." source: http://www.experts-exchange.com/Programming/System/Q_21443252.html
    
                    var jsNC = parseInt(cutils.jscGetDeepest(nChilds));
    
                    if (jsNC > 0) {
                        var jsChildArr = ctypes.cast(xqChildArr, ostypes.TYPE.Window.array(jsNC).ptr).contents;
    
                        // for (var i=jsNC-1; i>-1; i--) {
                        for (var i=0; i<jsNC; i++) {
                            var wChild = jsChildArr[i];
                            processWin(wChild);
                        }
    
                        ostypes.API('XFree')(xqChildArr);
                    }
                }
    
                processWin(ostypes.HELPER.cachedDefaultRootWindow());
    

0 个答案:

没有答案