获取linux中打开的应用程序窗口的数量

时间:2023-01-21 11:50:10

I want to detect how many instances of a specific application, managed by the window manager, are opened. At the moment, I have this:

我想检测由窗口管理器管理的特定应用程序的实例数量。目前,我有这个:

#!/bin/bash
# wmctrl required

pids=$(pidof $1)
IFS=' ' read -a pid_arr <<< "$pids"
matches=0
for pid in "${pid_arr[@]}"
do
    matching_lines=$(wmctrl -l -p | egrep -c "^.+\b.+\b$pid\b")
    matches=$((matches + $matching_lines))
done
echo $matches

Say I have firefox open three times and I pass firefox as an argument, the function will only return the right number if there were no "sub-windows" (e.g. preference windows) opened. Otherwise, the function will count these windows too.

假设我有三次打开firefox并且我将firefox作为参数传递,如果没有打开“子窗口”(例如首选项窗口),该函数将只返回正确的数字。否则,该函数也将计算这些窗口。

I want to get the number of windows without the "sub-windows".

我想获得没有“子窗口”的窗口数量。

P.S.: Made some changes. To count the number of windows without their dialog-windows, this is my current solution:

P.S。:做了一些改变。要计算没有对话窗口的窗口数,这是我目前的解决方案:

#!/bin/bash

pids=$(pidof $1)
IFS=' ' read -r -a pid_arr <<< "$pids"
matches=0
for pid in "${pid_arr[@]}"
do
    ids=$(wmctrl -l -p | awk '$3=='$pid'{printf $1" "}')
    IFS=' ' read -r -a id_arr <<< "$ids"
    for id in "${id_arr[@]}"
    do
        if ! xprop -id "$id" |
            egrep -q '(WM_TRANSIENT_FOR|_NET_WM_WINDOW_TYPE_DIALOG)'
        then
            ((matches++))
        fi
    done
done
echo $matches

But in the case of firefox, the script cannot distinguish between the browser window and its preference window because none of them is a dialog window.

但是在firefox的情况下,脚本无法区分浏览器窗口及其首选项窗口,因为它们都不是对话框窗口。

The above script is sufficient for me, because I use it to figure out how many windows (without dialog windows) of xfce4-appfinder are open. For xfce4-appfinder the script works, because its preference window can easily be recognized as a dialog window. In firefox the preference window can even be opened standalone by calling firefox -preferences. To recognize windows like this as some kind of "sub-window" is maybe impossible.

上面的脚本对我来说已经足够了,因为我用它来弄清楚xfce4-appfinder有多少个窗口(没有对话窗口)。对于xfce4-appfinder,脚本可以正常工作,因为它的首选项窗口可以很容易地被识别为对话框窗口。在firefox中,甚至可以通过调用firefox -preferences独立打开首选项窗口。将这样的窗口识别为某种“子窗口”可能是不可能的。

Here are my results of xprop and xwininfo for both the browser and preference window of firefox:

以下是我对firefox的浏览器和首选项窗口的xprop和xwininfo的结果:

xwininfo (browser):

xwininfo(浏览器):

xwininfo: Window id: 0x1c0007f "bash - Get number of opened application windows in linux - Stack Overflow - Mozilla Firefox"

  Root window id: 0xa1 (the root window) (has no name)
  Parent window id: 0x1400048 (has no name)
     1 child:
     0x1c00080 (has no name): ()  1x1+-1+-1  +1+37

  Absolute upper-left X:  2
  Absolute upper-left Y:  38
  Relative upper-left X:  0
  Relative upper-left Y:  14
  Width: 956
  Height: 511
  Depth: 24
  Visual: 0x20
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x22 (installed)
  Bit Gravity State: NorthWestGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +2+38  -962+38  -962-531  +2-531
  -geometry 956x511+0+22

  Bit gravity: NorthWestGravity
  Window gravity: NorthWestGravity
  Backing-store hint: NotUseful
  Backing-planes to be preserved: 0xffffffff
  Backing pixel: 0
  Save-unders: No

  Someone wants these events:
      KeyPress
      KeyRelease
      ButtonPress
      ButtonRelease
      EnterWindow
      LeaveWindow
      PointerMotion
      Exposure
      VisibilityChange
      StructureNotify
      FocusChange
      PropertyChange
  Do not propagate these events:
  Override redirection?: No

  Window manager hints:
      Client accepts input or input focus: Yes
      Initial state is Normal State
      Displayed on desktop 0
      Window type:
          Normal
      Process id: 792 on host T530

  Normal window size hints:
      Program supplied minimum size: 300 by 71
      Program supplied maximum size: 32767 by 32767
      Program supplied window gravity: NorthWestGravity
  No zoom window size hints defined

  No window shape defined
  No border shape defined

xwininfo (preferences):

xwininfo(首选项):

xwininfo: Window id: 0x1c046ef "Firefox Preferences"

  Root window id: 0xa1 (the root window) (has no name)
  Parent window id: 0x1400060 (has no name)
     1 child:
     0x1c046f0 (has no name): ()  1x1+-1+-1  +961+37

  Absolute upper-left X:  962
  Absolute upper-left Y:  38
  Relative upper-left X:  0
  Relative upper-left Y:  14
  Width: 956
  Height: 1040
  Depth: 24
  Visual: 0x20
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x22 (installed)
  Bit Gravity State: NorthWestGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no0x1c00001
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +962+38  -2+38  -2-2  +962-2
  -geometry 956x1040-0-0

  Bit gravity: NorthWestGravity
  Window gravity: NorthWestGravity
  Backing-store hint: NotUseful
  Backing-planes to be preserved: 0xffffffff
  Backing pixel: 0
  Save-unders: No

  Someone wants these events:
      KeyPress
      KeyRelease
      ButtonPress
      ButtonRelease
      EnterWindow
      LeaveWindow
      PointerMotion
      Exposure
      VisibilityChange
      StructureNotify
      FocusChange
      PropertyChange
  Do not propagate these events:
  Override redirection?: No

  Window manager hints:
      Client accepts input or input focus: Yes
      Initial state is Normal State
      Displayed on desktop 0
      Window type:
          Normal
      Process id: 792 on host T530

  Normal window size hints:
      Program supplied location: 0, 0
      Program supplied minimum size: 604 by 594
      Program supplied maximum size: 32767 by 32767
      Program supplied window gravity: NorthWestGravity
  No zoom window size hints defined

  No window shape defined
  No border shape defined

xprop (browser):

xprop(浏览器):

_DESKTOP(CARDINAL) = 0
WM_STATE(WM_STATE):
        window state: Normal
        icon window: 0x0
WM_HINTS(WM_HINTS):
        Client accepts input or input focus: True
        Initial state is Normal State.
        bitmap id # to use for icon: 0x1c00082
        bitmap id # of mask for icon: 0x1c00083
        window id # of group leader: 0x1c00001
_NET_STARTUP_ID(UTF8_STRING) = "xfce4-appfinder/|usr|lib|firefox|firefox/756-0-T530_TIME21351"
WM_WINDOW_ROLE(STRING) = "browser"
XdndAware(ATOM) = BITMAP
_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 29360257
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
_NET_WM_USER_TIME(CARDINAL) = 1758669
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x1c00080
WM_CLIENT_LEADER(WINDOW): window id # 0x1c00001
_NET_WM_PID(CARDINAL) = 792
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLIENT_MACHINE(STRING) = "T530"
WM_NORMAL_HINTS(WM_SIZE_HINTS):
        program specified minimum size: 300 by 71
        program specified maximum size: 32767 by 32767
        window gravity: NorthWest
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_CLASS(STRING) = "Navigator", "Firefox"
WM_ICON_NAME(STRING) = "bash - Get number of opened application windows in linux - Stack Overflow - Mozilla Firefox"
_NET_WM_ICON_NAME(UTF8_STRING) = "bash - Get number of opened application windows in linux - Stack Overflow - Mozilla Firefox"
WM_NAME(STRING) = "bash - Get number of opened application windows in linux - Stack Overflow - Mozilla Firefox"
_NET_WM_NAME(UTF8_STRING) = "bash - Get number of opened application windows in linux - Stack Overflow - Mozilla Firefox"

xprop (preferences)

xprop(首选项)

_NET_WM_DESKTOP(CARDINAL) = 0
WM_STATE(WM_STATE):
        window state: Normal
        icon window: 0x0
WM_HINTS(WM_HINTS):
        Client accepts input or input focus: True
        Initial state is Normal State.
        bitmap id # to use for icon: 0x1c046f2
        bitmap id # of mask for icon: 0x1c046f3
        window id # of group leader: 0x1c00001
WM_WINDOW_ROLE(STRING) = "Preferences"
XdndAware(ATOM) = BITMAP
_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 29378289
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
_NET_WM_USER_TIME(CARDINAL) = 1456410
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x1c046f0
WM_CLIENT_LEADER(WINDOW): window id # 0x1c00001
_NET_WM_PID(CARDINAL) = 792
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLIENT_MACHINE(STRING) = "T530"
WM_NORMAL_HINTS(WM_SIZE_HINTS):
        program specified location: 0, 0
        program specified minimum size: 604 by 594
        program specified maximum size: 32767 by 32767
        window gravity: NorthWest
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_CLASS(STRING) = "Browser", "Firefox"
WM_ICON_NAME(STRING) = "Firefox Preferences"
_NET_WM_ICON_NAME(UTF8_STRING) = "Firefox Preferences"
WM_NAME(STRING) = "Firefox Preferences"
_NET_WM_NAME(UTF8_STRING) = "Firefox Preferences"

1 个解决方案

#1


1  

I don't know that there's a simple answer to this. You are probably going to need to inspect the windows more closely and weed-out any that aren't what you want.

我不知道有一个简单的答案。您可能需要更仔细地检查窗户,并清除任何不是您想要的东西。

The group leader property on a window might be useful. (Some sub-windows should have this and main windows may not).

窗口上的组长属性可能很有用。 (有些子窗口应该有这个,主窗口可能没有)。

You can also look at the full WM_CLASS and WM_WINDOW_ROLE values which might help you distinguish between window types.

您还可以查看完整的WM_CLASS和WM_WINDOW_ROLE值,这些值可以帮助您区分窗口类型。

The _NET_WM_WINDOW_TYPE, etc. properties are also likely to be helpful in figuring out what "kind" of window you are looking at.

_NET_WM_WINDOW_TYPE等属性也可能有助于确定您正在查看的“类型”窗口。

Play around with xwininfo and xprop on the various windows on your display and you'll see what you can find.

在显示器上的各个窗口中使用xwininfo和xprop,您将看到可以找到的内容。

#1


1  

I don't know that there's a simple answer to this. You are probably going to need to inspect the windows more closely and weed-out any that aren't what you want.

我不知道有一个简单的答案。您可能需要更仔细地检查窗户,并清除任何不是您想要的东西。

The group leader property on a window might be useful. (Some sub-windows should have this and main windows may not).

窗口上的组长属性可能很有用。 (有些子窗口应该有这个,主窗口可能没有)。

You can also look at the full WM_CLASS and WM_WINDOW_ROLE values which might help you distinguish between window types.

您还可以查看完整的WM_CLASS和WM_WINDOW_ROLE值,这些值可以帮助您区分窗口类型。

The _NET_WM_WINDOW_TYPE, etc. properties are also likely to be helpful in figuring out what "kind" of window you are looking at.

_NET_WM_WINDOW_TYPE等属性也可能有助于确定您正在查看的“类型”窗口。

Play around with xwininfo and xprop on the various windows on your display and you'll see what you can find.

在显示器上的各个窗口中使用xwininfo和xprop,您将看到可以找到的内容。