Как узнать, какое окно имеет фокус и как его изменить? - PullRequest
11 голосов
/ 18 июня 2009

Я хотел бы знать, как я могу спросить X11, какие окна имеют фокус. И если по какой-либо причине мое собственное приложение (которое может быть видимым или нет) получило фокус, я хочу, чтобы прежние окна снова получили фокус.

Например, мое приложение работает со многими другими (например, firefox, gvim, nautilus, ...)

Предположим, что сначала Firefox имеет фокус и что пользователь щелкнул мое приложение, которое теперь имеет фокус. Я хочу, чтобы мое приложение снова сфокусировалось на Firefox.

Кто-нибудь знает, как этого добиться? Книжные рекомендации были бы очень хорошими.

Большое спасибо.

Ответы [ 4 ]

17 голосов
/ 19 июня 2009

Посмотрите на значение _NET_ACTIVE_WINDOW корневого окна, которое устанавливается большинством современных оконных менеджеров:

xprop -root _NET_ACTIVE_WINDOW

Это значение, конечно, можно получить с помощью вызовов библиотеки Xlib.

9 голосов
/ 06 марта 2015

Вы, вероятно, хотите позвонить XGetInputFocus.

Window focused;
int revert_to;

XGetInputFocus(dpy, &focused, &revert_to);

В этом фрагменте focused будет окном с текущим фокусом ввода, получением событий клавиатуры и нажатий кнопок мыши.

Это будет работать, даже если оконный менеджер не устанавливает свойство _NET_ACTIVE_WINDOW в корневом окне, как указано в EWMH. Некоторые оконные менеджеры, такие как dwm и my 9wm, не устанавливают это.

6 голосов
/ 19 июня 2009

Используйте это XQueryTree , чтобы найти текущее активное или самое верхнее окно.

Вот функция, когда отображается дисплей, она находит текущее окно в фокусе:

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

Я нашел источник:

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

Удачи

2 голосов
/ 02 октября 2018

Я рекомендую приложение под названием XDoTool. Он поддерживает довольно много запросов, элементов управления и даже хуков.

> 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
...

Такие команды, как behave принимают обратный вызов, который может быть встроенным, например getmouselocation, или внешним, например exec notify-send 'focused window', exec zsh myscript.zsh и т. Д., Однако вы хотите использовать его.

Редактировать - вы можете фокусироваться, используя xdotool windowfocus [options] [window], как в xdotool search --class firefox windowfocus. В моем случае это вызывает ошибки, потому что Firefox отображается в виде пары дюжин «окон», но у всех одинаковый PID; это работает с правильным ID. Надеюсь, это начало.

Редактировать 2 - «идентификатор окна» - это десятичное представление указателя окна, например, от xprop :

> xprop -root _NET_ACTIVE_WINDOW
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x1c00007, 0x0
> xdotool getwindowfocus
29360135
> printf '%d\n' '0x1c00007'
29360135
...