3

[qt 4.8]

To get correct window dimensions including its frame, I do the following (as described e.g. here, see comment from Daniel Hedberg).

mainWindow.move(-50000, -50000);
mainWindow.show();

// do something with the window dimensions

mainWindow.move(0, 0);
mainWindow.show()

This works fine, however, I have a problem with the move(0,0) call: It makes the window always appear at position (0,0), while I would like to have the default behaviour, this is, the application only suggests to the window manager that (0,0) is a good place to position the window, and the WM might decide to shift it if necessary to avoid overlapping. In other words, I would like to switch back to Qt's default behaviour as if there weren't a call to move at all.

How can I do that?

Community
  • 1
  • 1
lemzwerg
  • 772
  • 7
  • 15

2 Answers2

1

One solution is to store Windows original position and use that. For extra safety (in case screen resolution changes), check that entire window still fits on screen and move and even resize if it does not.

A hacky alternative would be to create and open empty, possibly transparent dummy window of the same size and see where it gets positioned. Then move the original there and close the dummy one. Reading your question carefully, I think this would do what you are after.

I don't know of a Qt way to ask Window Manager to reposition the window, so if you really need that, specify the OS etc details.

hyde
  • 60,639
  • 21
  • 115
  • 176
  • Thanks for the answer. However, I can't believe that it is that complicated – at least this is what I hope... I'll eventually check the source code of Qt how a call to `move` influences Qt's default positioning. – lemzwerg Oct 22 '13 at 20:56
  • @lemzwerg It's not necessarily complicated, but it is asking another program (what ever Window Manager or Desktop Environment or whatnot) to do something. I am not aware of a Qt API which would do this directly (which doesn't prove there isn't one...), and in many cases doing it directly might even be impossible (WM does not have API to ask "where would you auto-place a window like this now", other than actually creating a window and seeing where it goes). But looking at Qt sources on new Window creating is a great idea to get to the bottom of this. – hyde Oct 23 '13 at 06:19
  • It is not as complicated as it sounds. Have a look at the function "mapfromGLobal()" - for example: void MainFrame::getPos(QPoint pos) { m_Pos = QPoint(this->mapFromGlobal(pos)); //savepos } void MainFrame::onSomethingChanged() { ui->videoFullScreenPushButton->move( m_Pos ); } – TWE Oct 23 '13 at 09:48
  • @TWE If I understood correctly, the problem is to get the "automatic window placement" for an existing window (same that happens when you open a new Window), not about saving some position. So converting between widget and global coordinates has nothing to do with this. – hyde Oct 23 '13 at 10:17
  • @hyde: Exactly. Maybe my question is an uncommon request, but the above described trick with `move` avoids frame size issues with window managers – they are responsible for the frame, not Qt, and especially on X11 this is an ansynchronous process, AFAIK. – lemzwerg Oct 24 '13 at 07:43
0

Looking into the source code of Qt, I can now partially answer my own question: To convert a call to move into a suggestion for positioning instead of a request, do this:

mainWindow.move(100, 100);
mainWindow.setAttribute(Qt::WA_Moved, false);
mainWindow.show();

I've tested the code under X11 using Qt 4.8.4, and hopefully it works with on other platforms too.

Unfortunately, this doesn't solve the very problem I have, namely to use show to get the (decorated) dimensions of an off-screen window which then gets moved to the screen, calling show again. It seems that the first call to show directly sets platform-specific window manager flags which aren't completely reset and reevaluated in the second call. Actually, I'm going to think that this is a bug in Qt, so I'll report it accordingly.

lemzwerg
  • 772
  • 7
  • 15
  • And my current working solution is (1) create a temporary `mainWindow` within a block (`{ ... }`) to get the dimensions (and which gets destroyed after leaving the block), (2) save the dimensions, and (3) create a second, real `mainWindow` identical to the temporary one that uses the saved dimensions. There might be performance issues for complicated window layouts, but for my small, single window this solution good enough. – lemzwerg Nov 11 '13 at 11:19