【问题标题】:How to know which window has focus and how to change it?如何知道哪个窗口有焦点以及如何改变它?
【发布时间】:2010-11-04 03:06:40
【问题描述】:

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

例如,我的应用程序与许多其他应用程序一起运行(例如 firefox、gvim、nautilus...)

假设起初 firefox 有焦点,而用户点击了我现在拥有焦点的应用程序。我希望我的应用程序再次关注 Firefox。

有谁知道如何做到这一点?书籍推荐会非常好。

非常感谢。

【问题讨论】:

    标签: x11


    【解决方案1】:

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

    xprop -root _NET_ACTIVE_WINDOW
    

    这个值当然可以使用 Xlib 库调用来获得。

    【讨论】:

      【解决方案2】:

      您可能想要XGetInputFocus 电话。

      Window focused;
      int revert_to;
      
      XGetInputFocus(dpy, &focused, &revert_to);
      

      在这个 sn-p 中,focused 将是当前输入焦点的窗口,获取键盘事件和鼠标按钮按下。

      即使窗口管理器没有在根窗口上设置_NET_ACTIVE_WINDOW 属性(如 EWMH 所指定),这也将起作用。一些窗口管理器,比如 dwm 和 my 9wm,不设置这个。

      【讨论】:

      • 他还问“怎么改”,XSetInputFocus可以做到,例如:XSetInputFocus(display, window_to_focus, RevertToNone, CurrentTime);
      【解决方案3】:

      我推荐一个名为 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,它就可以工作。希望这是一个开始。

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

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

      【讨论】:

      • 感谢您的回答!我的用例是脚本,xdotool 正是我需要的
      【解决方案4】:

      使用此 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

      祝你好运

      【讨论】:

      • 艾登,非常感谢。这段代码会帮助我。我已经尝试过了,它会报告哪个窗口在鼠标指针下方,即使这个窗口没有焦点。我想知道实际具有焦点的窗口。有没有办法我的应用程序可以将自己注册为侦听器以了解它?或者是否有无需使用鼠标位置即可提供此信息的功能?再次感谢。
      • @Marcio - 可能值得查看 xprop 包的 xprop.c 源文件,了解它使用 libx11 中的哪些函数来获取该信息:)
      • 我看到了 xprop.c 和 xsnoop.c。我相信我将能够调整该代码以与 XSetInputFocus 一起使用并获得我想要的行为。最好的问候。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多