0

I'm creating a multi-window application (cross-platform (X11, macOS, Windows), unspecified window manager), where each window corresponds to a document. When creating a new document (and thus window), the window manager should be free to put the window wherever it finds suitable. However, if the user manually moves the window to some location, this location should be saved along with the document (so on re-opening the document, it will be at exactly the place it was last saved).

The (initial) window size is fixed.

In order to find out the current position, I can either use wm geometry or winfo geometry, which both return slightly different results (the former with decoration (like border and menu), the latter without). As I understand it, I need the result of wm geometry if I would like to restore the position of the window.

However, when I create an initial window and resize it, winfo geometry returns the correct position (but without the decoration), whereas wm geometry does not.

# hide the default window
wm withdraw .

toplevel .my
wm geometry .my 200x100

# the following prints "1x1+0+0" for both geometries
puts "[wm geometry .my] [winfo geometry .my]"

raise .my
# this prints something like "200x100+0+0 200x100+860+542"
puts "[wm geometry .my] [winfo geometry .my]"

If I manually move the window and then call [wm geometry .my] again, it now correctly reports whatever position the window is at.

So my question is:

Is there a way to get the window position (as set by the window manager) after I resized the window using wm geometry ${w}x${h}?

Alternatively, is there a way to find out (from the window itself) whether the user has moved it to some other place? (so I can save the position as "undefined, let the WM do their thing"). Ideally, such a solution would handle the case where the user to manually moved the window to the +0+0 position differently from the case where the window was not moved at all.

I'm especially interested in getting this information without having to bind to the <<Configure>> (or some other) event, in order to detect whether the user touched the window.

sidenote: setting the window dimensions

I know that I can set the window dimensions with both wm geometry ${w}x${h} and when creating the window with toplevel .wm -width $w -height $h. When doing the latter, wm geometry returns the correct window position, but what are there any other differences between the two?

umläute
  • 28,885
  • 9
  • 68
  • 122
  • 1
    I don't think there is. The problem is that the window manager has extreme freedom in how it can go about decorating a window. All you can really find safely and specify are the coordinates for the main window of a `toplevel` and you've already got those. – Donal Fellows Apr 21 '21 at 10:28

1 Answers1

0

I think a more extensive use of winfo is what you need: https://www.tcl.tk/man/tcl8.6/TkCmd/winfo.htm

set _x [winfo rootx .my]

The command above returns the X coord of the upper-left corner

winfo rooty .my

Same as before, returns the Y coord of the upper-left corner

winfo width .my

winfo height .my

Same for these self-explaining commands.

You can save in real time the position and size of any window, to restore later on re-open.

  • 1
    afaiut, the `rootx`, `rooty`, `width` and `height` sub-commands of `winfo` will report *exactly* the same as the `geometry` subcommand (with different formatting). as such, this ignores any window decorations (menubars, borders) and is not really usable for restoring the exact position. – umläute Apr 21 '21 at 07:07