如何知道哪个窗口有焦点以及如何更改它?

时间:2022-12-06 15:58:23

I would like to know how can I ask X11 which windows has 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 to get focus again.

我想知道如何向X11询问哪些窗口有焦点。如果由于任何原因我自己的应用程序(可能是可见的或不可见)获得焦点,我希望能够让以前的窗口再次获得焦点。

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

例如,我的应用程序与许多其他应用程序一起运行(例如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 focus on firefox again.

假设首先firefox具有焦点,并且用户点击我现在具有焦点的应用程序。我希望我的应用程序再次关注firefox。

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

有谁知道如何实现这一目标?书籍推荐非常好。

Thanks a lot.

非常感谢。

4 个解决方案

#1


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

使用此XQueryTree查找当前活动或最顶层的窗口。

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

#2


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

看一下大多数现代窗口管理器设置的根窗口的_NET_ACTIVE_WINDOW值:

xprop -root _NET_ACTIVE_WINDOW

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

当然,可以使用Xlib库调用获取此值。

#3


You probably want the XGetInputFocus call.

您可能想要XGetInputFocus调用。

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.

即使窗口管理器未在根窗口上设置_NET_ACTIVE_WINDOW属性(由EWMH指定),这也将起作用。一些窗口管理器,例如dwm和我的9wm,没有设置它。

#4


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

我推荐一个名为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
...

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.

像behave这样的命令接受一个回调,它可以像getmouselocation一样内置,也可以像exec notify-send'focus window',exec zsh myscript.zsh等那样内置,但是你想要使用它。

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.

编辑 - 你可以使用xdotool windowfocus [options] [window]进行聚焦,就像在xdotool中搜索--class firefox windowfocus一样。在我的情况下,这会导致错误,因为Firefox显示为几十个“窗口”,但都具有相同的PID;它的工作原理是正确的ID。希望这是一个开始。

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

编辑2 - '窗口ID'是窗口指针的十进制表示,例如,来自xprop:

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

#1


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

使用此XQueryTree查找当前活动或最顶层的窗口。

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

#2


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

看一下大多数现代窗口管理器设置的根窗口的_NET_ACTIVE_WINDOW值:

xprop -root _NET_ACTIVE_WINDOW

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

当然,可以使用Xlib库调用获取此值。

#3


You probably want the XGetInputFocus call.

您可能想要XGetInputFocus调用。

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.

即使窗口管理器未在根窗口上设置_NET_ACTIVE_WINDOW属性(由EWMH指定),这也将起作用。一些窗口管理器,例如dwm和我的9wm,没有设置它。

#4


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

我推荐一个名为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
...

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.

像behave这样的命令接受一个回调,它可以像getmouselocation一样内置,也可以像exec notify-send'focus window',exec zsh myscript.zsh等那样内置,但是你想要使用它。

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.

编辑 - 你可以使用xdotool windowfocus [options] [window]进行聚焦,就像在xdotool中搜索--class firefox windowfocus一样。在我的情况下,这会导致错误,因为Firefox显示为几十个“窗口”,但都具有相同的PID;它的工作原理是正确的ID。希望这是一个开始。

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

编辑2 - '窗口ID'是窗口指针的十进制表示,例如,来自xprop:

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