2

I have used the answer to How do I find the window dimensions and position accurately including decorations? in my bash scripts, and had good success with my Silentcast application on Xfce, but now that others are using it, they are finding some problems in Ubuntu 14.04, Unity. Here is one problem caused by the output of:

xwininfo -id $(xdotool getactivewindow)

Showing:

Relative upper-left X:  0  
Relative upper-left Y:  0

Which I use to calculate the width of the borders and the height of the titlebar. They should not be 0.

Does anyone know how to get the width of the window borders and the height of the titlebar in Unity for Ubuntu 14.04.

Or, how to directly get the full window dimensions?

I have filed a bug against xorg for the xwininfo package https://bugs.freedesktop.org/show_bug.cgi?id=84348

I have also found out information about creating your own theme in Unity under Ubuntu 14.04: https://wiki.ubuntu.com/Unity/Theming

It seems like the answer is in that theming page somewhere, but I don't understand it yet especially since I don't use Ubuntu or Unity.

2 Answers2

3

I also asked this question on stackoverflow and got a good answer that I marked as the correct one and upvoted: https://stackoverflow.com/a/26060527/1707904

This applies also to compiz. There are a couple of ways you can get these informations in some ways:

wnckprop --xid=$(xdotool getactivewindow)

Otherwise, you can just mix the Absolute value you get from xwininfo together with the size of the decorations that are accessible using:

xprop _NET_FRAME_EXTENTS -id $(xdotool getactivewindow)

For your information, if you want to get the full frame size, including the input area around the window, you can use xwininfo -frame

After experimentation, I understand better what the "input area" refers to in Ubuntu. Since the border default size is 0, there's a 10px area around the window where you can grab the window for resizing. It may have other purposes, but the input area basically acts like an invisible 10px border. So, Absolute from xwininfo gives the interior window while xwininfo -frame gives the entire window including title-bar and an additional 10px all around (if the input area is 10px). The xprop... gives just the size of the decorations, not including the input area. So all 3 commands are needed to get a full picture of the geometry of a window.

Here is the code I ended up using (it ignores the invisible input area):

eval $(xwininfo -id "$aw" |
      sed -n -e "s/^ \+Absolute upper-left X: \+\([0-9]\+\).*/x=\1/p" \
             -e "s/^ \+Absolute upper-left Y: \+\([0-9]\+\).*/y=\1/p" \
             -e "s/^ \+Width: \+\([0-9]\+\).*/w=\1/p" \
             -e "s/^ \+Height: \+\([0-9]\+\).*/h=\1/p" )
if [ "$entire" = true ]
then
    extents=$(xprop _NET_FRAME_EXTENTS -id "$aw" | grep "NET_FRAME_EXTENTS" | cut -d '=' -f 2 | tr -d ' ')
    bl=$(echo $extents | cut -d ',' -f 1) # width of left border
    br=$(echo $extents | cut -d ',' -f 2) # width of right border
    t=$(echo $extents | cut -d ',' -f 3)  # height of title bar
    bb=$(echo $extents | cut -d ',' -f 4) # height of bottom border

    let x=$x-$bl
    let y=$y-$t
    let w=$w+$bl+$br
    let h=$h+$t+$bb
fi
0

Below a somewhat more elaborated code, also working with _GTK_FRAME_EXTENTS

#!/bin/bash
# get window coordinates and width and height
# inspired by:
# https://unix.stackexchange.com/questions/14159/how-do-i-find-the-window-dimensions-and-position-accurately-including-decoration
window=$(xwininfo |  awk '/xwininfo: Window id:/{print $4}')
entire=true
set - $(xwininfo -id "$window" | awk '
   /Absolute upper-left X:/{ print $4 } \
   /Absolute upper-left Y:/{ print $4 } \
   /Width:/ { print $2 } \
   /Height:/{ print $2}')
x="$1"
y="$2"
w="$3"
h="$4"
if [ "$entire" = true ]; then
   set - $( xprop -id "$window" | awk ' BEGIN { set=0 } \
   /_..._FRAME_EXTENTS/{ print $1,$3,$4,$5,$6; set=1} \
   END { if (!set) print "none" }' | sed 's/(.*)//;s/,//g')
   prop="$1"
   if [ "$prop" != none ]; then
      bl="$2"
      br="$3"
      t="$4"
      bb="$5"
      case "$prop" in
     *NET*)
        (( x=x-bl    ))
        (( y=y-t     ))
        (( w=w+bl+br ))
        (( h=h+t+bb  ))
        ;;
     *GTK*)
        (( x=x+bl    ))
        (( y=y+t     ))
        (( w=w-bl-br ))
        (( h=h-t-bb  ))
        ;;
      esac
   fi
fi
echo "window: $window"
echo "property: $prop"
echo $x $y $w $h
  • (1) How thoroughly have you tested this?  I believe that if [ "$s"!=none ] needs to be if [ "$s" != none ].  (2) eval is dangerous; try to avoid it.  (Yes, I realize that part of your code is copied from Colin Keenan’s answer.)  (3) If you’re copying part of somebody else’s answer, you should say so, explicitly.  (4) It would be better to quote all references to shell variables.  (5) What is tempfile?  (6) As long as you’re using $(…), you might as well use it consistently. – G-Man Says 'Reinstate Monica' Feb 18 '19 at 04:25
  • Thanks for your review! I was so glad I found something I could use for my xsnow program, I did not test the script enough. I replaced it with something that is somewhat better, I guess. – Willem Vermin Jun 09 '19 at 12:22