문제

X11 세션에서 모든 최상위 데스크탑 창의 목록을 얻으려고합니다. 기본적으로 Window Managers 애플리케이션 전환 UI에 표시된 모든 Windows의 목록을 얻고 싶습니다 (일반적으로 사용자가 Alt+Tab을 누를 때 열린).

나는 전에 X11 프로그래밍을 한 적이 없지만 지금까지는 전체 창 목록을 통해 다음과 같은 모습을 보이는 코드를 열거했습니다.

void CSoftwareInfoLinux::enumerateWindows(Display *display, Window rootWindow)
{
    Window parent;
    Window *children;
    Window *child;
    quint32 nNumChildren;

    XTextProperty wmName;
    XTextProperty wmCommand;

    int status = XGetWMName(display, rootWindow, &wmName);
    if (status && wmName.value && wmName.nitems)
    {
        int i;
        char **list;
        status = XmbTextPropertyToTextList(display, &wmName, &list, &i);
        if (status >= Success && i && *list)
        {
            qDebug() << "Found window with name:" << (char*) *list;
        }

        status = XGetCommand(display, rootWindow, &list, &i);
        if (status >= Success && i && *list)
        {
            qDebug() << "... and Command:" << i << (char*) *list;
        }

        Window tf;
        status = XGetTransientForHint(display, rootWindow, &tf);
        if (status >= Success && tf)
        {
            qDebug() << "TF set!";
        }

        XWMHints *pHints = XGetWMHints(display, rootWindow);
        if (pHints)
        {
            qDebug() << "Flags:" << pHints->flags
                    << "Window group:" << pHints->window_group;
        }
    }

    status = XQueryTree(display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
    if (status == 0)
    {
        // Could not query window tree further, aborting
        return;
    }

    if (nNumChildren == 0)
    {
        // No more children found. Aborting
        return;
    }

    for (int i = 0; i < nNumChildren; i++)
    {
        enumerateWindows(display, children[i]);
    }

    XFree((char*) children);
}

enumerateWindows() 처음에는 루트 창으로 불립니다.

이것은 수백 개의 창문에 대한 정보를 인쇄하는 한 작동합니다. 내가 필요로하는 것은 내가 어떤 속성을 심문 할 수 있는지 알아내는 것입니다. Window 최상위 데스크탑 응용 프로그램 창입니다 (공식 용어가 무엇인지 확실하지 않음).

누구든지 이것에 대해 약간의 빛을 발할 수 있습니까? 내가 찾은 X11 프로그래밍에 대해 찾은 모든 참조 문서는 매우 건조하고 이해하기 어려웠습니다. 아마도 누군가가 더 나은 자원을 가리킬 수 있습니까?

도움이 되었습니까?

해결책

해결책이 있습니다!

글쎄요, 일종의.

Window Manager가 확장 된 창 관리자 힌트 (EWMH)를 사용하는 경우 "_NET_CLIENT_LIST"Atom.이 클라이언트 Windows Window Manager 의이 클라이언트 목록. 자세한 내용은 참조하십시오. 여기.

그러나 이것에 몇 가지 문제가 있습니다. 처음에는 사용중인 창 관리자가 EWMH를 지원해야합니다. Kde와 Gnome은 그렇습니다. 나는 다른 사람들도 그렇게 할 것이라고 확신합니다. 그러나 나는 그렇지 않은 많은 것이 있다고 확신합니다. 또한 KDE에 몇 가지 문제가 있음을 알았습니다. 기본적으로 일부 비 KDE 응용 프로그램은 목록에 포함되지 않습니다. 예를 들어, KDE에서 XCALC를 실행하면이 목록에 표시되지 않습니다.

이 방법에 대해 누군가가 개선을 제공 할 수 있다면 기꺼이들을 것입니다. 참고로 사용중인 코드는 다음과 같습니다.

    Atom a = XInternAtom(m_pDisplay, "_NET_CLIENT_LIST" , true);
    Atom actualType;
    int format;
    unsigned long numItems, bytesAfter;
    unsigned char *data =0;
    int status = XGetWindowProperty(m_pDisplay,
                                rootWindow,
                                a,
                                0L,
                                (~0L),
                                false,
                                AnyPropertyType,
                                &actualType,
                                &format,
                                &numItems,
                                &bytesAfter,
                                &data);

    if (status >= Success && numItems)
    {
        // success - we have data: Format should always be 32:
        Q_ASSERT(format == 32);
        // cast to proper format, and iterate through values:
        quint32 *array = (quint32*) data;
        for (quint32 k = 0; k < numItems; k++)
        {
            // get window Id:
            Window w = (Window) array[k];

            qDebug() << "Scanned client window:" << w;
        }
        XFree(data);
    }

다른 팁

이전 솔루션을 확장하려면 창 이름을 얻으려면 다음과 같습니다.

// get window Id:
Window w = (Window) array[k];

char* name = '\0';
status = XFetchName(display, w, &name);
if (status >= Success)
{
    if (name == NULL)
        printf("Found: %ul  NULL\n", w);
    else
        printf("Found: %ul  %s\n", w, name);
}
XFree(name);

xlib를 사용할 필요가없는 경우 GDK를 사용합니다. gdk_screen_get_window_stack() 그리고 gdk_window_get_window_type() 귀하의 요구에 도움이 될 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top