Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency in window frame offsetting #1341

Closed
i3bot opened this issue Aug 10, 2014 · 16 comments · Fixed by #3184
Closed

Inconsistency in window frame offsetting #1341

i3bot opened this issue Aug 10, 2014 · 16 comments · Fixed by #3184
Assignees
Labels
4.8 bug reproducible A bug that has been reviewed and confirmed by a project contributor

Comments

@i3bot
Copy link

i3bot commented Aug 10, 2014

[Originally reported by lolilolicon@…]
(I notice the window frame in i3 is handled inconsistently between the left frame and the top (title bar) frame. For example, in my case, the title bar is 20 pixels in height, so if I run mpv --geometry +0+20 video.mkv, the window frame is placed with its left-top corner at (0, 0); this is because i3 automatically shifts the mpv window 2 pixels (the size of the left frame/border) to the right, but does not automatically shift the mpv window down in the same manner. This results in unexpectedly that mpv --geometry +0+11 will make i3 put the mpv window at the center of the screen, presumably because i3 calculates that the left-top corner of the frame would be at (0, -9) and decides to resort to putting it at the center of the screen.

The discussion above ignores the fact that the win_gravity of the mpv window is actually CenterGravity, not NorthWestGravity, which I think may change the expected resulting frame coordinates. (To be tested in Mutter when I get the chance).

@i3bot
Copy link
Author

i3bot commented Aug 10, 2014

[Original comment by lolilolicon@…]

Ah, forgot to mention that my mpv windows all float!

@i3bot
Copy link
Author

i3bot commented Aug 16, 2014

[Original comment by lolilolicon@…]

A related / interesting thing about the title bar: if you run xwininfo and click on the title bar, it actually gets info for the title bar window! Its. own. window. That's something I didn't expect. Problem is, the coordinates are wrong. I split my workspace into three containers (left, center, right) and then split the left into two (top, bottom), when I click on the title bar of the left-bottom window, I get this from xwininfo:

xwininfo: Please select the window about which you
          would like information by clicking the
          mouse in that window.

xwininfo: Window id: 0x400045 (has no name)

  Absolute upper-left X:  0
  Absolute upper-left Y:  0
  Relative upper-left X:  0
  Relative upper-left Y:  0
  Width: 621
  Height: 611
  Depth: 24
  Visual: 0x20
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x22 (installed)
  Bit Gravity State: ForgetGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: yes
  Corners:  +0+0  -1299+0  -1299-589  +0-589
  -geometry 621x611+0+0

The Absolute upper-left Y is wrong.Relative upper-left Y is also wrong since its parent is the root window. Surely this is a bug?

@i3bot
Copy link
Author

i3bot commented Aug 16, 2014

[Original comment by lolilolicon@…]

Interestingly, if I click on the left-top window title bar, I get the same window 0x400045 and the exact same output from xwininfo as the left-bottom window title bar. Hmm.

@stapelberg
Copy link
Member

Replying to comment 3 by lolilolicon@…:

Interestingly, if I click on the left-top window title bar, I get the same window 0x400045 and the exact same output from xwininfo as the left-bottom window title bar. Hmm.

That’s because you’re clicking into the split container, onto which the window decorations are rendered. Your comment 2 and 3 are all working as intended.

@stapelberg
Copy link
Member

Replying to #1341 by lolilolicon@…:

I notice the window frame in i3 is handled inconsistently between the left frame and the top (title bar) frame. For example, in my case, the title bar is 20 pixels in height, so if I run mpv --geometry +0+20 video.mkv, the window frame is placed with its left-top corner at (0, 0); this is because i3 automatically shifts the mpv window 2 pixels (the size of the left frame/border) to the right, but does not automatically shift the mpv window down in the same manner. This results in unexpectedly that mpv --geometry +0+11 will make i3 put the mpv window at the center of the screen, presumably because i3 calculates that the left-top corner of the frame would be at (0, -9) and decides to resort to putting it at the center of the screen.

Hm. I’m open to convincing here, but I cannot find clear documentation on how window managers should interpret the geometry it gets from actual application window. The closest thing I can find is the X11 protocol documentation, which states:

This request returns the root and current geometry of the drawable.
The depth is the number of bits per pixel for the object. The x, y,
and border-width will always be zero for pixmaps. For a window, the
x and y coordinates specify the upper-left outer corner of the window
relative to its parent’s origin, and the width and height specify
the inside size, not including the border.

So, based on that, i3 is behaving correct with regards to the title bar (but incorrect with regards to the left/right/bottom? borders).

I’m more interested in what toolkits assume, though. Could you come up with sample applications in GTK and Qt that store their geometry and try to restore it on startup?

@i3bot
Copy link
Author

i3bot commented Aug 25, 2014

[Original comment by lolilolicon@…]

Replying to comment 4 @…:

That’s because you’re clicking into the split container, onto which the window decorations are rendered. Your comment 2 and 3 are all working as intended.

I guess that's understandable, but it's a bit counter-intuitive, isn't it?
I wonder how one could find out the height of the title bar?

Replying to comment 5 @…:

Hm. I’m open to convincing here, but I cannot find clear documentation on how window managers should interpret the geometry it gets from actual application window. The closest thing I can find is the X11 protocol documentation, which states:

This request returns the root and current geometry of the drawable.
The depth is the number of bits per pixel for the object. The x, y,
and border-width will always be zero for pixmaps. For a window, the
x and y coordinates specify the upper-left outer corner of the window
relative to its parent’s origin, and the width and height specify
the inside size, not including the border.

So, based on that, i3 is behaving correct with regards to the title bar (but incorrect with regards to the left/right/bottom? borders).

The documentation in your quote is about GetGeometry. I believe you should be looking at CreateWindow. This also concerns win-gravity (issue #1335).

I’m more interested in what toolkits assume, though. Could you come up with sample applications in GTK and Qt that store their geometry and try to restore it on startup?

Nope, I'm not familiar with that kind of behavior. But I think it's enough to use sxiv as an example. Here's basically how sxiv opens its window (window.c function win_open()):

win = XCreateWindow(display, root, x, y, w, h, 0, depth, InputOutput, visual, 0, NULL);
...
XSetWMNormalHints(display, win, &sizehints);

For the purpose of this bug, let's ignore the win_gravity bit and other hints set in sizehints, and treat win_gravity as the default NorthWest. The following discussion depends on this assumption.

I think the question here, is when an application requests the upper-left outer corner of its window to be put at (x,y), where should the window manager place the framed window after it re-parents this window to the "frame window"? Should the upper-left outer corner of the "frame window" be placed at (x,y), or should the upper-left outer corner of the bare application window be placed at (x,y)? I think the former is correct.

This also begs for a clear definition what the "frame window" is in i3. Currently it seems to be the visible frame excluding the title bar, which is counter-intuitive.


Related documentation:

The X11 protocol documentation says,

win-gravity defines how the window should be repositioned if the parent is resized

The "Window Geometry" section in the EWMH spec includes some clarification

When calculating the reference point at the time of initial placement, the Window Manager should take the initial window's size into consideration, as if it was the frame for this window.
The link: http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140146176643024

@stapelberg
Copy link
Member

Replying to comment 6 by lolilolicon@…:

Replying to comment 4 @…:

That’s because you’re clicking into the split container, onto which the window decorations are rendered. Your comment 2 and 3 are all working as intended.

I guess that's understandable, but it's a bit counter-intuitive, isn't it?
I wonder how one could find out the height of the title bar?

I don’t think the actual application should ever be interested in the height of the title bar.

Replying to comment 5 @…:

Hm. I’m open to convincing here, but I cannot find clear documentation on how window managers should interpret the geometry it gets from actual application window. The closest thing I can find is the X11 protocol documentation, which states:

This request returns the root and current geometry of the drawable.
The depth is the number of bits per pixel for the object. The x, y,
and border-width will always be zero for pixmaps. For a window, the
x and y coordinates specify the upper-left outer corner of the window
relative to its parent’s origin, and the width and height specify
the inside size, not including the border.

So, based on that, i3 is behaving correct with regards to the title bar (but incorrect with regards to the left/right/bottom? borders).

The documentation in your quote is about GetGeometry. I believe you should be looking at CreateWindow. This also concerns win-gravity (issue #1335).

The CreateWindow documentation is not any more helpful unfortunately:

The x and y coordinates for the window are relative to the parent’s
origin and specify the position of the upper-left outer corner of
the window (not the origin).

I’m more interested in what toolkits assume, though. Could you come up with sample applications in GTK and Qt that store their geometry and try to restore it on startup?

Nope, I'm not familiar with that kind of behavior. But I think it's enough to use sxiv as an example. Here's basically how sxiv opens its window (window.c function win_open()):

I don’t think it’s enough. Having these examples with the two most popular toolkits would make for a much more convincing case.

I think the question here, is when an application requests the upper-left outer corner of its window to be put at (x,y), where should the window manager place the framed window after it re-parents this window to the "frame window"? Should the upper-left outer corner of the "frame window" be placed at (x,y), or should the upper-left outer corner of the bare application window be placed at (x,y)? I think the former is correct.

I agree with the question, but I’m still not sure about which possibility is correct.

This also begs for a clear definition what the "frame window" is in i3. Currently it seems to be the visible frame excluding the title bar, which is counter-intuitive.

i3 doesn’t really use frame windows in the conventional sense.

The "Window Geometry" section in the EWMH spec includes some clarification

When calculating the reference point at the time of initial placement, the Window Manager should take the initial window's size into consideration, as if it was the frame for this window.

That’s a good bit of information, but I don’t find it very clear :|. I.e., does it mean that when I request a 200x300 px window at (0, 0), should the window manager assume that 200x300 px is widthxheight including the borders? In that case, how would an application open a window that has at least 200x300 px? It cannot know the border width/height beforehand. (In general we want applications to not care about window sizes and just scale, but that’s not the point here.)

Perhaps you could send an email request for clarification on the wm-spec mailing list where these standards are discussed?

@i3bot
Copy link
Author

i3bot commented Aug 25, 2014

[Original comment by lolilolicon@…]

Replying to comment 7 @…:

I don’t think the actual application should ever be interested in the height of the title bar.
Unless the title bar is not included in the frame...
Firstly, applications do care about the window frame, as evidenced by Gimp (see below).
Secondly, since i3 does not support _NET_FRAME_EXTENTS, I'd like xwininfo -frame to get the geometry of the frame window correctly, that is, including the title bar.

Having these examples with the two most popular toolkits would make for a much more convincing case.

OK, Gimp is a very good example.
First, Gimp is able to restore the position for the Toolbox window perfectly in most cases.

BUT there is a slim window in which i3 will force center the Toolbox window when Gimp is restarted. You can reproduce this by moving the Toolbox window so that some but not all of its title bar is off-screen, then restart Gimp.
Assuming you're not using the single-window mode, on exit, the position of the Toolbox window will be recorded in ~/.gimp-2.8/sessionrc, something like this:

(session-info "toplevel"
    (factory-entry "gimp-toolbox-window")
    (position 0 10)
    (size 200 800)
    (open-on-exit)

In i3, the position parameters Gimp calculates are the coordinates of the upper-left corner of the visible frame excluding the title bar, with negative values corrected to 0. See, since the frame Gimp gets does not include the title bar, it's oblivious about the fact that half of the title bar is off-screen and happily records its y coordinate as 10. When Gimp is restarted, this Toolbox window will be force centered.
This gets us back to the definition of the frame window in i3.

So are you convinced we have a bug here now?

@i3bot
Copy link
Author

i3bot commented Aug 26, 2014

[Original comment by lolilolicon@…]

I just want to add that, considering i3's support for tab and cascade layouts for tiled windows, it makes sense the title bar is ignored. So I understand that if anything shall be done to fix this bug for floating windows, the code probably will need to make a special case for floating windows, which is not something anyone wants to do to their own code. At least we have had some discussion here; whatever is to be done is up to you developers' choice :)

@stapelberg
Copy link
Member

(not a full answer, but interesting excerpt from #xcb with psychon (awesome)):

08:40  psychon> sECuRE_: the window gravity field in ICCCM's WM_NORMAL_HINTS
08:41  psychon> sECuRE_: it definitely does specify how the WM should treat geometry from ConfigureRequests with respect to window decoration, I think it also applies to the initial geometry
08:47  sECuRE_> psychon: ah, right, but that only specifies the reference point, not whether the given geometry is to be interpreted as including the decoration or without
08:49  psychon> oh, well, I think the size is always the size just for the window excluding decorations
08:49  psychon> why would something want to specify the size including decorations (except for fullscreen / maximized)?
09:18  sECuRE_> psychon: agreed, that’s what i thought as well
09:19  psychon> fun fact: awesome pretty much doesn't handle this at all

@i3bot
Copy link
Author

i3bot commented Aug 27, 2014

[Original comment by lolilolicon@…]

Replying to comment 10 @…:

(not a full answer, but interesting excerpt from #xcb with psychon (awesome)):

08:40  psychon> sECuRE_: the window gravity field in ICCCM's WM_NORMAL_HINTS
08:41  psychon> sECuRE_: it definitely does specify how the WM should treat geometry from ConfigureRequests with respect to window decoration, I think it also applies to the initial geometry
08:47  sECuRE_> psychon: ah, right, but that only specifies the reference point, not whether the given geometry is to be interpreted as including the decoration or without
08:49  psychon> oh, well, I think the size is always the size just for the window excluding decorations
08:49  psychon> why would something want to specify the size including decorations (except for fullscreen / maximized)?
09:18  sECuRE_> psychon: agreed, that’s what i thought as well
09:19  psychon> fun fact: awesome pretty much doesn't handle this at all

We all agree that the size of the client window should just be as requested by the client. This following quote from the EWMH spec,

When calculating the reference point at the time of initial placement, the Window Manager should take the initial window's size into consideration, as if it was the frame for this window.

its use of the word "size" and general phrasing makes it somewhat confusing. I think what it means by "size" is all of the client window's geometry parameters: x, y, width, height, bw.

At initial placement, the window manager "takes the initial window's size into consideration", i.e. uses the client window's geometry parameters, to calculate the reference point:

  1. According to the second table in that section, a client window with NorthWestGravity will produce a reference point at (x-bw, y-bw).
  2. According to the first table in that section, the reference point of a client window with NorthWestGravity is "the left top corner of the frame window".
  3. As a result, "the left top corner of the frame window" will be placed at (x-bw, y-bw).

Do you agree with this interpretation?

@Airblader
Copy link
Member

@stapelberg I'm a bit lost with the discussion here, but it's a year old now. Is there anything we plan on doing?

@stapelberg
Copy link
Member

I think it would be nice if the problem was addressed, provided it can be addressed without a big amount of complexity (given that we’re talking about floating windows here).

From my reading of the discussion, I think the summary is “i3 places windows somewhere else than where users expect when they start applications with geometries like +0+0”.

orestisfl added a commit to orestisfl/i3 that referenced this issue Mar 17, 2018
This allows the floating container's top left corner to be mapped
outside any output as long as they are contained partially by one. This,
for example, will allow:
mpv --geometry +1+1 video.mp4

For windows mapped to (0, 0) see comment in floating.c:270-273:
/* Some clients (like GIMP’s color picker window) get mapped
 * to (0, 0), so we push them to a reasonable position
 * (centered over their leader) */

 The floating_reassign_ws call is removed since we try to place the new
 floating container in the current output:
 /* Sanity check: Are the coordinates on the appropriate output? If not, we
  * need to change them */

Fixes i3#1341
orestisfl added a commit to orestisfl/i3 that referenced this issue Mar 23, 2018
This allows the floating container's top left corner to be mapped
outside any output as long as they are contained partially by one. This,
for example, will allow:
mpv --geometry +1+1 video.mp4

For windows mapped to (0, 0) see comment in floating.c:270-273:
/* Some clients (like GIMP’s color picker window) get mapped
 * to (0, 0), so we push them to a reasonable position
 * (centered over their leader) */

 The floating_reassign_ws call is removed since we try to place the new
 floating container in the current output:
 /* Sanity check: Are the coordinates on the appropriate output? If not, we
  * need to change them */

Fixes i3#1341
@orestisfl orestisfl added the reproducible A bug that has been reviewed and confirmed by a project contributor label Apr 7, 2018
@LevitatingBusinessMan
Copy link

Has this bug resurfaced? I am facing these issues. I want to map a window at an offset from the top of the screen using gtk3, but I just cannot figure out how.

I think normally this behavior can be modified by the STATIC gravity.1 But gravities are still not supported.2

@stapelberg
Copy link
Member

Please file a new bug with steps to reproduce instead of posting on many-year old bugs.

@LevitatingBusinessMan
Copy link

I opened a new bug report at #5953 with steps to reproduce.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.8 bug reproducible A bug that has been reviewed and confirmed by a project contributor
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants