14

I need a tool to get the width and height of an arbitrary window.

Ideally, that tool would deduct the size of the Ubuntu's menu bar.

6

From your own answer, I understand you are looking for a convenient GUI tool, so:

Small GUI tool to get both the net size and the real size of a window (dynamically updated)

As explained further below in "Explanation", both wmctrl and xdotool return a slightly incorrect windowsize.

enter image description here

The script (indicator) below will show both the "real" size and the net size of a window in the panel.

The script

#!/usr/bin/env python3
import signal
import gi
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Gtk', '3.0')
import subprocess
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread


def get(cmd):
    try:
        return subprocess.check_output(cmd).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

# ---
# uncomment either one of two the lines below; the first one will let the user
# pick a window *after* the indicator started, the second one will pick the 
# currently active window
# ---

window = get(["xdotool", "selectwindow"])
# window = get(["xdotool", "getactivewindow"])

class Indicator():
    def __init__(self):
        self.app = 'test123'
        iconpath = "unity-display-panel"
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)       
        self.indicator.set_menu(self.create_menu())
        self.indicator.set_label(" ...Starting up", self.app)
        # the thread:
        self.update = Thread(target=self.show_seconds)
        # daemonize the thread to make the indicator stopable
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        menu = Gtk.Menu()
        # separator
        menu_sep = Gtk.SeparatorMenuItem()
        menu.append(menu_sep)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        menu.append(item_quit)
        menu.show_all()
        return menu

    def show_seconds(self):
        sizes1 = None
        while True:
            time.sleep(1)
            sizes2 = self.getsize(window)
            if sizes2 != sizes1:
                GObject.idle_add(
                    self.indicator.set_label,
                    sizes2, self.app,
                    priority=GObject.PRIORITY_DEFAULT
                    )
            sizes1 = sizes2

    def getsize(self, window):
        try:
            nettsize = [int(n) for n in get([
                "xdotool", "getwindowgeometry", window
                ]).splitlines()[-1].split()[-1].split("x")]
        except AttributeError:
            subprocess.Popen(["notify-send", "Missing data", "window "+window+\
                              " does not exist\n(terminating)"])
            self.stop()
        else:
            add = [l for l in get(["xprop", "-id", window]).splitlines() if "FRAME" in l][0].split()
            add = [int(n.replace(",", "")) for n in add[-4:]]
            xadd = add[0]+add[1]; yadd = add[2]+add[3]
            totalsize = [str(s) for s in [nettsize[0]+add[0]+add[1], nettsize[1]+add[2]+add[3]]]
            displ_sizes = ["x".join(geo) for geo in [[str(s) for s in nettsize], totalsize]]
            string = " "+displ_sizes[0]+" / "+displ_sizes[1]
            return string+((25-len(string))*" ")

    def stop(self, *args):
        Gtk.main_quit()

Indicator()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()

How to use

  1. The script needs xdotool to be installed:

    sudo apt-get install xdotool
    
  2. Copy the script into an empty file, save it as getwindowsize.py

  3. Test- run the script from a terminal window by the command:

    python3 /path/to/getwindowsize.py
    
  4. The script picks the focussed window to dynamically show the net windowsize (as in the output of both wmctrl and xdotool) and the real window size, including decorators etc.

    If you close the targeted window, the indicator shows a message:

    enter image description here

  5. If all works fine, add it to a shortcut key: choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:

    python3 /path/to/getwindowsize.py
    

Explanation

The window size, as it is displayed by both wmctrl and xdotool

...is slightly incorrect

You mention:

Ideally, that tool would deduct the size of the Ubuntu's menu bar

The complete story is that both wmctrl -lG and xdotool getwindowgeometry return the size of the window without menu bar, or, as it is explained in this answer:

What's happening is that wmctrl is returning the geometry of the window inside the decorations (i.e. not including the title bar and borders)

How to get the correct, "real" size

To get the information correctly, we can run

xprop -id <window_id> | grep FRAME

This will output like:

_NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 28, 0

Here we get the values we need to add to the window's size, as output from wmctrl and xdotool, to the left, right, top and bottom of the window.

In other words, in this case, if a wmctrl shows a size of 200x100, the real size is 200x128.

Note

As suggested by OP, the user can also pick a window after the indicator was started, by replacing:

window = get(["xdotool", "getactivewindow"])

by:

window = get(["xdotool", "selectwindow"])

In the script, either one of these lines can be uncommented.

  • Cheers @Jacob-vlijm, such a good answer! Just two things: 1) I've replaced getactivewindow by selectwindow, so when the script is launched you choose with the cursor the window to get dimensions from. I find this behaviour much more convenient. 2) I've uploaded the code to paste ubuntu, so it's easier to set up: Just download and save as getwindowsize.py – Akronix Dec 24 '16 at 18:00
  • @Akronix Thanks! sounds like a great idea, would you mind if I edit it into the answer? – Jacob Vlijm Dec 24 '16 at 21:17
  • Sure @jacob-vljim. Feel free ;) – Akronix Dec 25 '16 at 22:02
11

You can use wmctrl -lG to get a list of all open windows, in a table with the format:

<window ID> <desktop ID> <x-coordinate> <y-coordinate> <width> <height> <client machine> <window title>

An example output could look like this:

$ wmctrl -lG
0x02a00002  0 -2020 -1180 1920 1080 MyHostName XdndCollectionWindowImp
0x02a00005  0 0    24   61   1056 MyHostName unity-launcher
0x02a00008  0 0    0    1920 24   MyHostName unity-panel
0x02a0000b  0 -1241 -728 1141 628  MyHostName unity-dash
0x02a0000c  0 -420 -300 320  200  MyHostName Hud
0x03a0000a  0 0    0    1920 1080 MyHostName Desktop
0x0400001d  0 61   24   1859 1056 MyHostName application development - A tool to get window dimensions - Ask Ubuntu - Mozilla Firefox
0x04200084  0 61   52   999  745  MyHostName Untitled Document 1 - gedit
9

I found xwininfo -all from https://unix.stackexchange.com/questions/14159/how-do-i-find-the-window-dimensions-and-position-accurately-including-decoration.

It does work but I'm still open to more convenient solutions => a real-time GUI tool.

  • I posted an answer, but didn't notice you've found xwininfo already. Perhaps you would be interested in the script I wrote - it uses xwininfo but with a GUI popup, please see it below. – Sergiy Kolodyazhnyy Dec 18 '16 at 12:58
2

One could try:

xdotool search --name gnome-panel getwindowgeometry

Assuming gnome-panel is ubuntu's toolbar's process name, but who knows.

(may require a sudo apt-get install xdotool)

For an improvised GUI thing that one may want to further improve so to display just the bare essentials:

zenity --text-info --filename=<(xprop)

It will change the pointer to xprop's cross, then you click the window, and it will print xprop's info in a GTK dialog.

2

xwininfo and its advantages

The big problem with wmctrl and xdotool is that those tools need to be installed - they aren't on Ubuntu by default. However, Ubuntu ships with xwininfo. It is a simple tool that provides information about user-selected window.

Simple usage would be to type in xwininfo | awk '/Width/||/Height/' (notice that awk is used for filtering the output) in terminal, and when your cursor changes to x select any GUI window you like and it will display its info. For example:

$ xwininfo | awk '/Width/||/Height/'                
  Width: 602
  Height: 398

So the advantages are:

  • it is simple
  • it is installed by default
  • it's just text - nothing fancy and you can filter and tweak it as necessary

Taking xwininfo one step further - displaying properties of an active window

Of course if you have terminal open 24/7 like I do, xwininfo is all you need. Some users might prefer having a keyboard shortcut. The script below (which is intended to be bound to a keyboard shortcut) allows you to display a graphical popup with information about your currently active window. As can be seen in the screenshot, it displays window title,width and height info.

enter image description here

Under the hood this doesn't do anything particularly spectacular. It uses information from dbus service and xwininfo and puts it into simple popup. The source code is below. Remember, standard scripting rules apply: ensure it has executable permissions with chmod +x and when binding to keyboard shortcut you give full path to the script file as command.

#!/bin/bash 

get_active_window()
{
    qdbus org.ayatana.bamf \
          /org/ayatana/bamf/matcher \
          org.ayatana.bamf.matcher.ActiveWindow
}

get_active_name()
{
    qdbus org.ayatana.bamf $1 \
          org.ayatana.bamf.view.Name
}

main()
{
    active_window=$(get_active_window)
    active_xid=$( awk -F '/' '{print $NF}' <<< "$active_window" )
    echo $active_xid
    active_title=$(get_active_name $active_window)
    dimensions=$(xwininfo -id "$active_xid" | awk '/Width/||/Height/')
    text="$active_title\n""$dimensions"
    zenity --info --text "$text" --width=200 --height=200
}

main $@

Using Unity's top panel indicator for information.

When writing my answer, I've realized that this would be a very useful feature to incorporate into one of my existing projects - the Ayatana Indicator. This indicator allows showing whole range of information about GUI windows. Currently is still under active development. The geometry info feature has been added to the github repository and is on the way into my personal PPA. And of course, it uses xwininfo although in slightly different manner.

enter image description here

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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