Damir Porobic
Damir Porobic

Reputation: 711

How to get Geometry of currently focused Window on Linux in C++?

Is there a way to get the Geometry of the currently focused window under Linux? I just need the position (x and y) and size (width and height) of what ever Window is currently having focus or being on top of the desktop.

I want to use this information in my QT application to take a screen shot of this window.

Upvotes: 2

Views: 1429

Answers (3)

FarK
FarK

Reputation: 636

You could use libxdo

/**
 * Like xdo_get_focused_window, but return the first ancestor-or-self window *
 * having a property of WM_CLASS. This allows you to get the "real" or
 * top-level-ish window having focus rather than something you may not expect
 * to be the window having focused.
 *
 * @param window_ret Pointer to a window where the currently-focused window
 *   will be stored.
 */
int xdo_get_focused_window_sane(const xdo_t *xdo, Window *window_ret);


/**
 * Get a window's size.
 *
 * @param wid the window to query
 * @param width_ret pointer to unsigned int where the width is stored.
 * @param height_ret pointer to unsigned int where the height is stored.
 */
int xdo_get_window_size(const xdo_t *xdo, Window wid, unsigned int *width_ret,
                        unsigned int *height_ret);

Upvotes: 1

Damir Porobic
Damir Porobic

Reputation: 711

Thanks @Striezel, your feedback pointed me in the right direction. After investigating your solution, I run into this post: Xlib: XGetWindowAttributes always returns 1x1?

Tweaking the answer from @Doug a little bit I've got following, which seems to be working as expected:

Window getToplevelParent(Display* display, Window window)
{
    Window parentWindow;
    Window rootWindow;
    Window* childrenWindows;
    unsigned int numberOfChildren;

    while (1) {
        if (XQueryTree(display, window, &rootWindow, &parentWindow, &childrenWindows,
                       &numberOfChildren) == 0) {
            qCritical("ImageGrabber::getToplevelParent: XQueryTree Error");
            return 0;
        }
        if (childrenWindows) {
            XFree(childrenWindows);
        }
        if (window == rootWindow || parentWindow == rootWindow) {
            return window;
        } else {
            window = parentWindow;
        }
    }
}

QRect ImageGrabber::getActiveWindowRect()
{

    Display* display = XOpenDisplay(NULL);
    Window focusWindow, parentOfFocusedWindow;
    XWindowAttributes attrributes;
    int revert;

    XGetInputFocus(display, &focusWindow, &revert);
    parentOfFocusedWindow = getToplevelParent(display, focusWindow);
    if (!parentOfFocusedWindow) {
        qCritical("ImageGrabber::getActiveWindowRect: Unable to get window, returning screen.");
        return getCurrectScreenRect();
    }

    XGetWindowAttributes(display, parentOfFocusedWindow, &attrributes);
    return QRect(attrributes.x, attrributes.y, attrributes.width, attrributes.height);
} 

Upvotes: 2

Striezel
Striezel

Reputation: 3758

Obviously, the first step to solve that problem would be to determine the windows that is currently in focus. To do that, you might employ Xlib's XGetInputFocus() function. After that, use XGetWindowAttributes() to get the position and the size of the window (and even some more information about the window).

Upvotes: 3

Related Questions