Skip to content

fix getPosition() function in Linux Window implementation#372

Closed
jarrettchisholm wants to merge 3 commits intoSFML:masterfrom
jarrettchisholm:master
Closed

fix getPosition() function in Linux Window implementation#372
jarrettchisholm wants to merge 3 commits intoSFML:masterfrom
jarrettchisholm:master

Conversation

@jarrettchisholm
Copy link
Copy Markdown

Bug described here:
#346

Fixed 2 things from my patch (which was attached to the issue):

  • made tab into 4 spaces
  • put open braces on new line

@LaurentGomila
Copy link
Copy Markdown
Member

There's a bug in your code, root is uninitialized when you first call while (activeWin != root).

Moreover, it would be nice to explain:

  • why XGetWindowAttributes returns wrong results
  • why you need such a loop in your code

I like to understand the code that I add to SFML ;)

@jarrettchisholm
Copy link
Copy Markdown
Author

Hi @LaurentGomila - fair enough.

root is initialized - it is on the stack. Also, it gets set when you pass it to XGetGeometry.

I'm not sure why XGetWindowAttributes is not returning correct results. It honestly seems like it should, but I haven
t been able to get it to work in my debian linux environments

XGetGeometry gives you the x/y coordinates for the drawable (i.e window) relative to the parent drawable (window). We need to loop (until we reach the root window) in order to add up the x/y coordinates of all the relative drawables.

Hopefully I was able to explain that well...

@LaurentGomila
Copy link
Copy Markdown
Member

root is initialized - it is on the stack

And? Even if there's some obscur rule in the C++ standard that specifies that (and I don't think there's one), it's very bad practice to use uninitialized variables. Explicit initialization is always better, even if there's an implicit one.

Also, it gets set when you pass it to XGetGeometry

I know. The line I mention is located before the call to XGetGeometry.

Hopefully I was able to explain that well...

Very well, thank you ;)

@jarrettchisholm
Copy link
Copy Markdown
Author

Hmmm...well, I wanted to enter the loop at least once, which is why I didn't care what root is initialized to in the beginning - I just wanted it to not equal activeWin.

Anyway, I think it's specified in 8.5.9 of the 2003 spec - but I see your point. It's clearer if we just initialize it. The resulting logic should be the same. I'll make the changes and resubmit.

@jarrettchisholm
Copy link
Copy Markdown
Author

Hey @LaurentGomila sorry it took so long, busy with work :S

I initialized the Window objects and tested it locally on Debian 64bit (Testing), and it worked ok.

Let me know if there is anything else you'd like me to change.

Cheers

@ghost ghost assigned LaurentGomila Apr 27, 2013
@MarioLiebisch
Copy link
Copy Markdown
Member

Just tried this fix on Ubuntu (x64 13.04) and it seems to return the position of the top left pixel of the window contents, not the top left border of the window's frame. Is this intentional or did I make some mistake?

sfml-window-getposition

At least on Windows I get the top left pixel of the window's border. How about Mac OS? Can't test it there.

@LaurentGomila
Copy link
Copy Markdown
Member

And don't forget my comment in #346

Wouldn't XTranslateCoordinates do the same thing with just a single line of code?

@docwild
Copy link
Copy Markdown

docwild commented May 11, 2013

Works fine on debian wheezy x64. Does not take into account window decorations but not sure if you'd even want it to.

@MarioLiebisch
Copy link
Copy Markdown
Member

Think that would be the default/expected behavior. At least that's what pretty much any Windows toolkit (Windows Forms, WPF, etc.) do.

@LaurentGomila
Copy link
Copy Markdown
Member

Works fine on debian wheezy x64. Does not take into account window decorations but not sure if you'd even want it to.

No, I want to take decorations in account. It doesn't make sense to ignore them, they are part of the window.

@jarrettchisholm
Copy link
Copy Markdown
Author

Changed implementation to use XTranslateCoordinates.

@MarioLiebisch, I'm able to reproduce this issue. Unfortunately, I'm not able to get the window position that takes into account the border decoration. I also spent some time today trying to get the window decoration dimensions, but I haven't been able to figure out how to get window decoration dimensions reliably (I can get it ok if the window is maximized, otherwise, all bets are off).

As this implementation works for my purposes, I don't think I'm going to dig too much deeper into getting the exact window position.

@MarioLiebisch
Copy link
Copy Markdown
Member

Actually, what do other toolkits (like GTK, wxWidgets, QT, etc.) return when you query the window position? Maybe this should be handled in a platform consistent (rather than cross-platform consistent) way.

@LaurentGomila
Copy link
Copy Markdown
Member

I found useful answers to my questions.

About why XGetGeometry fails:

All of the popular X window managers will reparent your top level windows to add various decorations such as a title bar or resize handles. You should account for this when inquiring about your windows' position and ancestors. For example, XGetGeometry() will report position relative to the window manager window, not relative to the root window, as you might expect. Use XTranslateCoordinates(), as shown in Figure 19, to convert these coordinates to the root window's coordinate space.

http://www.rahul.net/kenton/40errs.html#Error19

About why decorations are ignored in the position:

Some window managers (Compiz?) draw window decoration totally independently from the client window. The client doesn't know and cannot know the size of the decorations (unless it uses some Compiz-specific tricks).

http://stackoverflow.com/questions/8867715/xlib-center-window

So I think we're stuck with this behaviour.

@LaurentGomila
Copy link
Copy Markdown
Member

I see another problem: setPosition (internally XMoveWindow) moves the top-left corner of the window, including decorations. So the setPosition/getPosition pair is inconsistent.

@docwild
Copy link
Copy Markdown

docwild commented May 18, 2013

It is a complicated issue and a solution which will work with one window manager will not neccessarily work with others. I would be more in favour of tracking relative position so a user can know how far a window has moved since instantiation as this isn't a window toolkit you're providing here. The only real concrete positions that are needed are mouse events which will report positions relative only to the drawable part of the window. This way all the low level window stuff can be handled by the window managers and the application stuf is its own island inside that. I can understand that setting window positions is desirable but the specifications have always stated that the WMs are free to ignore these requests so it might be better to just allow users to set hint requests, rather than promising functionality that can not be guaranteed.

@LaurentGomila
Copy link
Copy Markdown
Member

I wrote the fix directly (your code was not exactly how I'd like it to be).

Thanks a lot for your help!

@jarrettchisholm
Copy link
Copy Markdown
Author

Glad I could help! Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants