2

I've tried xdotool, xwininfo and xprop, but all of them seem to return the content size of the window, which doesn't include the border width. Are there any command-line tools that can find this border width? And hopefully the tool will work on different EWMH-compatible window managers.

  • Hm, my version of xwininfo does include the border width. Debian/8.6, x11-utils 7.7. The MacOS/Xquartz installation (v2.7.11, xorg-server 1.18.4) shows it as well. – ckujau Dec 18 '16 at 23:56
  • @ckujau It does have a Border Width line and on my system its value is 0. But my windows have a think border so I'm wondering where the 0 comes from. – Cyker Dec 19 '16 at 1:10
  • The visible border of all windows is drawn and managed by the window manager. X windows also have an internal border (which is different from the WM decorations you see), and that's the value returned by the various tools. So you'll have to query your WM somehow to find the border widths(s) of the WM decorations (can be different for different borders), but I don't know if there's a command line tool that does that. – dirkt Dec 19 '16 at 8:04
2

Depending on your window manager, you can use xwininfo -tree -root to list all the window hierarchy, and then work up the tree from your target window to the window framing the window manager has placed around the target.

The following script does this iteratively, running xwininfo -tree only on your target window in order to find the parent window, then repeating the process moving up the tree step by step until the parent is the root (Parent window id: ...(the root window)). It assumes the window which has the root as parent is the wanted frame.

By adding -stats you get easy access to the width and height of the window. For example, in an xterm that is 724 by 1069 pixels, we get a frame of 742 by 1087 pixels:

$ xwininfo -tree -stats -id $WINDOWID 
  Parent window id: 0x8002ff (has no name)
  ...
  Width: 724
  Height: 1069
$ xwininfo -tree -stats -id 0x8002ff
  Parent window id: 0x8002fe (has no name)
  ...
  Width: 724
  Height: 1069
$ xwininfo -tree -stats -id 0x8002fe
  Parent window id: 0xc1 (the root window) (has no name)
  ...
  Width: 742
  Height: 1087

Here's the script, taking a window id number as argument:

#!/bin/bash
# http://unix.stackexchange.com/a/331516/119298
getwh(){
    xwininfo -tree -stats -id "$id" | 
    awk '/Parent window id:/{ parent = ($0~/the root window/)?0:$4; }
        / Width:/  { w = $2 }
        / Height:/ { h = $2 }
        END            { printf "%s %d %d\n",parent,w,h }'
}
id=${1:-${WINDOWID?}}
set -- $(getwh "$id")
w=$2 h=$3
while id=$1
      [ "$id" != 0 ]      
do    set -- $(getwh "$id")
done
let bw=$2-w  bh=$3-h
echo "total border w and h $bw $bh"

It prints total border w and h 18 18, and you need to divide these by 2 to have the border width assuming symmetry. If this is not the case, e.g. with a large title bar, you need to also use the difference in x and y offsets to calculate the top, bottom, left, right individual borders.

  • This answer is really cool. I thought about the question for several hours today and finally came to the same solution. But there is one thing that I'm not sure: Does WM only decorate top-level windows? I want my software to work with all windows that WM manages but I don't know how to identify them. – Cyker Dec 19 '16 at 23:54
  • wmctrl -l should list all the windows, as well as xlsclients -l. Or for each window if you xwininfo -all -id ... you can look for any Window manager hints. – meuh Dec 20 '16 at 11:15
0

a round-about method is dump the content using xwd and then measure the image produced.

xwd -frame | xwdtopnm | head -2

xwdtppnm is from the netpbm package

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.