10

About wmctrl

With wmctrl (not installed by default), we can get information on windows, their id, their geometry, the pid they belong to etc. We can also move or resize windows with several commands. However, in some respects, its behaviour seems not logical. My question is about moving windows by wmctrl:

Getting information

When I run the command:

wmctrl -lG

I get (a.o.) the following information about the window in the picture(s)below:

0x04200085  0 746  443  468  205  jacob-System-Product-Name Niet-opgeslagen document 1 - gedit

In column 3-5, the geometry information tells us the x/y coordinates and the width/height.

Moving/resizing the window

When I put these coordinates in the wmctrl command to move/resize a window, it should do nothing, since the coordinates are unchanged:

wmctrl -ir 0x04200085 -e 0,746,443,468,205

Deviation

However, the pictures below show the window is moved downwards (28px to be precise). I assumed the reason was that the wmctrl window move command calculated with the working area (screen minus panel height), while the wmctrl -lG command calculated with the total screen size. Then still 4px is unexplained however (the panel is 24px high).

Although the deviation can very well be compensated in scripts, the fact that I don't understand the cause is not satisfying, so the question is:

What is exactly the cause for this deviation?


Moving a window with the exact coordinates in the output of wmctrl -lG should not move the window, but it does

enter image description here

enter image description here

15

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) but is using the larger window position for the move.

(Some command output lines removed : xdotool might not be installed)

$ wmctrl -lG
0x04000040  0 702  23   900  950  KMatrix dave@KMatrix: test – Konsole

$ xdotool getwindowgeometry 0x04000040
Window 67108928
  Position: 702,23 (screen: 0)
  Geometry: 900x950

The next command prompts for the window of interest and returns the parent window which includes all the decorations and varies depending on the window theme in use.

$ xdotool selectwindow
25166060

$ xdotool getwindowgeometry 0x18000ec
Window 25166060
  Position: 700,0 (screen: 0)
  Geometry: 904x977

As you can see, it's a different window; the X position starts 2px to the left (702-2) and the total width is larger by 4px (900+2+2) because the right border is also 2px. Y is higher (above the top border, if any, and the title bar); height is larger because of all of that plus the bottom border.

wmctrl moves the parent window to the desired [X,Y] position of the child window; width and height are applied correctly to the child, as shown in the "before & after" below.

$ wmctrl -lG
0x04000040  0 702  23   900  950  KMatrix dave@KMatrix: test – Konsole

$ xdotool getwindowgeometry 0x18000ec   # (PARENT)
Window 25166060
  Position: 700,0 (screen: 0)
  Geometry: 904x977

$ xdotool getwindowgeometry 0x04000040  # (CHILD)
Window 67108928
  Position: 702,23 (screen: 0)
  Geometry: 900x950

$ wmctrl -ir 0x04000040 -e 0,702,23,900,950   # <----- "MOVE/RESIZE" *****

$ wmctrl -lG
0x04000040  0 704  46   900  950  KMatrix dave@KMatrix: test – Konsole

$ xdotool getwindowgeometry 0x18000ec   # (PARENT)
Window 25166060
  Position: 702,23 (screen: 0)    <----- Desired [X,Y] applied to parent
  Geometry: 904x977

$ xdotool getwindowgeometry 0x04000040  # (CHILD)
Window 67108928
  Position: 704,46 (screen: 0)
  Geometry: 900x950               <----- Desired [W,H] applied to child

Edit: additional info.

Desktop geometry, Viewport & Workarea

$ wmctrl -d    # (KDE)
0  * DG: 1680x1050  VP: 0,0  WA: 0,0 1680x1015  Desktop 1
$ xdotool -v
xdotool version 3.20140217.1

https://github.com/jordansissel/xdotool

Re: @Sneetsher tip in comments

$ xprop | grep FRAME
_KDE_NET_WM_FRAME_STRUT(CARDINAL) = 2, 2, 23, 4
_NET_FRAME_EXTENTS(CARDINAL) = 2, 2, 23, 4
  • This looks like an excellent answer! I'll look into its details tonight. – Jacob Vlijm Jan 30 '15 at 7:53
  • for my understanding, the output of xdotool selectwindow is 25166060, but what is the step to get to 0x18000ec? I tried the conversion from hexadecimal, but that seems not to be it. – Jacob Vlijm Jan 30 '15 at 10:27
  • The output from xdotool getwindowgeometry 0x18000ec returns the decimal window ID of 25166060 (parent). I just input the hex value of 0x18000ec to show that it was not 0x04000040 (the child). By the way, I just re-ran the whole test with easier numbers in the hope that you weren't looking. See previous edit revision if you were in the middle of something. – Daxx Jan 30 '15 at 10:40
  • 2
    @JacobVlijm, xprop seems to show decoration padding: _KDE_NET_WM_FRAME_STRUT(CARDINAL) = 1, 1, 24, 6 and _NET_FRAME_EXTENTS(CARDINAL) = 1, 1, 24, 6. It may help to check. – user.dz Jan 30 '15 at 13:13
  • Is it possible that the xdotool selectwindow command behaves differently on KDE and Unity? The output of the xdotool selectwindow command refers to exactly the same window (-id) and (thus) xdotool getwindowgeometry outputs the same data as wmctrl -lG. The xprop command however, as suggested by @Sneetsher shows _NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 28, 0, which is exactly what I measured manually, and proves the essence of your answer is correct, and it is the perfect answer to my question. I am impressed by your thoroughness. Thanks! – Jacob Vlijm Jan 30 '15 at 17:45
0

I had the same problem and could find a workaround.


Situation

My situation is based on Mate 16.04 with Compiz installed (which activates the gtk window manager)

I am using a script connected to key-bindings to place windows on predefined places. This script fails if I am not using the maximized option.


Analysis

The problem could be turned on and off by turning on and of the window decorations in the settings (compiz).


Workaround

The window decorations can be turned on and off using python for a specific window (using keybindings it is convenient to use the active window).

#!/usr/bin/python
from gtk.gdk import *
import gtk.gdk
import time
import sys

w = gtk.gdk.get_default_root_window().get_screen().get_active_window()
w.set_decorations(0) #use 1 to turn on decorations
window_process_all_updates()
gtk.gdk.flush()

Then you can turn off window decorations, move the window, and turn on window decorations.

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.