Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I've been trying to figure out the size of a window for use in a small script. My current technique is using wmctrl -lG to find out the dimensions. However, the problem is this:

The x and y figures it gives are for the top left of the window decorations, while the height and width are for just the content area. This means that if the window decorations add 20px of height and 2px of width, wmctrl will report a window as being 640x480, even if it takes up 660x482 on screen. This is a problem because my script's next step would be to use that area to tell ffmpeg to record the screen. I would like to avoid hardcoding in the size of the window decorations from my current setup.

What would suit is either a method to get the size of the window decorations so I can use them to figure out the position of the 640x480 content area, or a way to get the position of the content area directly, not that of the window decorations.

share|improve this question
1  
I mixed up height and width in the figures for the diagram. – Macha Jun 1 '11 at 16:44
    
Dead image link. – Ciro Santilli 六四事件 法轮功 包卓轩 Aug 13 '14 at 6:41
    
close question but also asks other things: superuser.com/questions/164047/… – Ciro Santilli 六四事件 法轮功 包卓轩 Aug 13 '14 at 6:47
up vote 14 down vote accepted

The following script will give you the top-left screen co-ords and size of the window (without any decoration). . . . xwininfo -id $(xdotool getactivewindow) contains enough information for you.


#!/bin/bash
# Get the coordinates of the active window's
#    top-left corner, and the window's size.
#    This excludes the window decoration.
  unset x y w h
  eval $(xwininfo -id $(xdotool getactivewindow) |
    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" )
  echo -n "$x $y $w $h"
#
share|improve this answer
    
This appears to work because xdotool getactivewindow returns the window id of the window manager frame (which includes decoration) rather than the client window contained inside it. – Adam Spiers Feb 12 '15 at 0:53
    
No, this returns the geometry without the decorations, which is explicitly not what the question asked. If you don't want decorations included , there are easier ways to do that, for example xdotool getactivewindow getwindowgeometry – slinkp Jan 27 at 4:20

The accepted answer explicitly does not include window decoration. For those still looking for how to get the geometry including all decorations, as per this question's title, you can use wmiface as per this other question http://superuser.com/questions/164047/how-to-get-accurate-window-information-dimensions-etc-in-linux-x. Example:

wmiface frameGeometry `wmiface activeWindow`

This returns geometry and position relative to top left like so:

650x437+0+1003

wmiface does not seem to come with all linux distros (I didn't find a package providing it on Mint or Ubuntu) but I was able to install it from the packages here: http://kde-apps.org/content/show.php?content=40425

And it comes with no docs nor even --help, but the README is here:

https://gitorious.org/wmiface/wmiface/source/ea941eeb2076124734f6a3d3079326c826b462d7:README

share|improve this answer
    
Sorry - I regret my upvote for this because the accepted answer does include window decoration as per my comment on it. – Adam Spiers Feb 12 '15 at 0:57
    
I wish that were true, but unfortunately that comment is wrong. They agree about the active window id: $ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772 But they do not agree about geometry, and I can confirm with eg. screenruler that wmiface includes the window decoration and xdotool does not. Try it for yourself. $ wmiface frameGeometry wmiface activeWindow 570x434+870+31 $ xdotool getwindowgeometry xdotool getactivewindow Window 6291772 Position: 878,77 (screen: 0) Geometry: 562x407 – slinkp Jan 27 at 3:30
    
sorry, hope you can puzzle out what i meant there... wish stackoverflow would allow block code samples in comments. – slinkp Jan 27 at 3:33

The accepted answer can be extended to get the entire window:

entire=false
x=0
y=0
w=0
h=0
b=0  # b for border
t=0  # t for title (or top)

# ... find out what user wants then 

eval $(xwininfo -id $(xdotool getactivewindow) |
  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" \
         -e "s/^ \+Relative upper-left X: \+\([0-9]\+\).*/b=\1/p" \
         -e "s/^ \+Relative upper-left Y: \+\([0-9]\+\).*/t=\1/p" )
if [ "$entire" = true ]
then                     # if user wanted entire window, adjust x,y,w and h
    let x=$x-$b
    let y=$y-$t
    let w=$w+2*$b
    let h=$h+$t+$b
fi
echo "$w"x"$h" $x,$y

Although easy, it turns out not to work on Unity in Ubuntu 14.04 because the Relative info is all 0. I asked Get the full window dimensions (including decorations) in Unity and got a good answer. Here is how I used that answer:

aw=$(xdotool getactivewindow)
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

This second method works in both Unity and Xfce, and should work in Gnome too.

share|improve this answer
    
The top approach is wrong even outside Unity on Ubuntu because it assumes the left, right, and bottom borders are all the same width, and there is no guarantee of this. The second approach looks better. – Adam Spiers Feb 12 '15 at 1:09
    
I just checked the second approach - it only needed aw=`xdotool getactivewindow` added up top to avoid hanging on the xwininfo call. This is great to know because i am considering switching to Unity, where i can't get wmiface to run without segfaulting. – slinkp Jan 27 at 3:47
    
@slinkp, thanks for pointing out the missing aw definition. I will edit the answer now to add that line. – Colin Keenan Jan 28 at 4:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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