Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get number of opened application windows in linux

Tags:

linux

bash

x11

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.

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:

#!/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.

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.

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

xwininfo (browser):

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: 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):

_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)

_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"
like image 704
andreas1724 Avatar asked Oct 21 '14 18:10

andreas1724


1 Answers

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.

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

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

like image 160
Etan Reisner Avatar answered Nov 06 '22 13:11

Etan Reisner