17

I would like to know how can I ask X11 which windows has the focus. And if for any reason my own application (that may be visible or not) got the focus I want be able to let the former windows get the focus again.

For instance, my application is running with many others (e.g. firefox, gvim, nautilus, ...)

Suppose that at first firefox has focus and that the user clicked on my app which now has the focus. I want that my application put the focus on firefox again.

Does anyone knows how to achieve this? Books recommendations would be very nice.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Plicatibu
  • 1,692
  • 2
  • 19
  • 20

4 Answers4

23

Take a look at the _NET_ACTIVE_WINDOW value of the root window which is set by most modern window managers:

xprop -root _NET_ACTIVE_WINDOW

This value can, of course, be obtained using Xlib library calls.

blueyed
  • 27,102
  • 4
  • 75
  • 71
Marten
  • 1,136
  • 1
  • 8
  • 15
12

You probably want the XGetInputFocus call.

Window focused;
int revert_to;

XGetInputFocus(dpy, &focused, &revert_to);

In this snippet, focused will be the window with current input focus, getting keyboard events and mouse button presses.

This will work even if the window manager does not set the _NET_ACTIVE_WINDOW property on the root window, as specified by EWMH. A few window managers, such as dwm and my 9wm, don't set this.

Neale Pickett
  • 196
  • 1
  • 4
  • 6
    He also asked "how to change it", `XSetInputFocus` can do that, for example: `XSetInputFocus(display, window_to_focus, RevertToNone, CurrentTime);` – Sam Watkins Nov 19 '16 at 04:14
10

I recommend an application called XDoTool. It supports quite a lot of queries, controls, and even hooks.

> xdotool getwindowfocus               # 29360135
> xdotool getwindowfocus getwindowpid  # 12988
> xdotool getwindowfocus getwindowname # tilda
> xdotool getwindowfocus behave '%@' blur getmouselocation
#      or focus, mouse-enter, etc.
x:514 y:317 screen:0 window:56623121
x:271 y:26 screen:0 window:56623121
...

Commands like behave accept a callback, which can be built-in like getmouselocation or external like exec notify-send 'focused window', exec zsh myscript.zsh, etc., however you want to use it.

Edit - you can focus using xdotool windowfocus [options] [window], as in xdotool search --class firefox windowfocus. In my case this causes errors because Firefox shows up as a couple dozen 'windows', but all have the same PID; it works given the right ID. Hopefully that's a start.

Edit 2 - the 'window ID' is the decimal representation of the window pointer, e.g. from xprop:

> xprop -root _NET_ACTIVE_WINDOW
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x1c00007, 0x0
> xdotool getwindowfocus
29360135
> printf '%d\n' '0x1c00007'
29360135
John P
  • 1,463
  • 3
  • 19
  • 39
  • 1
    Thank you for this answer! My use-case is scripting, and `xdotool` is exactly what I needed <3 – Esteis Aug 06 '19 at 16:40
7

Use this XQueryTree to find the currently active, or top-most window.

Here is a function, when given a display, it will find the current window in focus:

static Window
GetCurrWindow(d)
Display *d;
{
Window foo;
Window win;
int bar;

    do{
    (void) XQueryPointer(d, DefaultRootWindow(d), &foo, &win,
        &bar, &bar, &bar, &bar, &bar);
    } while(win <= 0);


#ifdef VROOT
    {
    int n;
    Window *wins;
    XWindowAttributes xwa;

    (void) fputs("=xwa=", stdout);

    /* do{  */
        XQueryTree(d, win, &foo, &foo, &wins, &n);
    /* } while(wins <= 0); */
    bar=0;
    while(--n >= 0) {
        XGetWindowAttributes(d, wins[n], &xwa);
        if( (xwa.width * xwa.height) > bar) {
        win = wins[n];
        bar = xwa.width * xwa.height;
        }
        n--;
    }
    XFree(wins);
    }
#endif
    return(win);
}

http://tronche.com/gui/x/xlib/window-information/XQueryTree.html

I found the source:

http://examples.oreilly.com/networksa/tools/xsnoop.c

Good Luck

Aiden Bell
  • 28,212
  • 4
  • 75
  • 119
  • 1
    Aiden, thank you a lot. This code will help me. I've tried it and it reports which window is under the mouse pointer even if it this window doesn't have focus. I want to know the window that actually has focus. Is there a way my app can register itself as a listener to be informed about it? Or is there a function that can give this information without the need to use mouse position ? Thanks again. – Plicatibu Jun 22 '09 at 16:54
  • @Marcio - It may well be worth checking out the xprop.c source file of the xprop package regarding what functions in libx11 it uses to obtain that information :) – Aiden Bell Jun 22 '09 at 19:20
  • 1
    I saw xprop.c ans xsnoop.c. I belive that I'll be able to adapt that code to use with XSetInputFocus and get the behaviour I want. Best Regards. – Plicatibu Jun 22 '09 at 21:06