1

Does QMainWindow.move() bound the position of the mainwindow to the screen?

I'm working on a PyQt5 application that places an unframed window somewhere in the screen, close to the system tray icon that triggers the window's show event.

The logic in the code is not very clever but seems to do the trick:

    systray_icon_pos = self.status_icon.geometry().center()
    self.move(systray_icon_pos.x() - self.width() / 2,
              systray_icon_pos.y())

A user complains that the window appears off screen, while on my desktop, it won't exceed screen boundaries, even if I patch that code to hardcode huge numbers as move parameters. I thought it could be because we're using different desktop environments (I use Mate, he uses Gnome), but while testing, I did observe the behaviour he describes. I just can't reproduce it.

Also, some people on the Internet use move(-50000, -50000) to hide a window temporarily by putting it off-screen (here's an example).

I don't find any explicit mention of this in the docs.

Jérôme
  • 13,328
  • 7
  • 56
  • 106
  • The docs you link to certainly do explicitly mention issues regarding window geometry on linux. See: [X11 Peculiarities](https://doc.qt.io/qt-5/application-windows.html#x11-peculiarities). – ekhumoro Jul 03 '18 at 13:05
  • Thanks @ekhumoro. I saw that already. Not explicit enough for me, I'm afraid. My window has no frame so I don't mind the uncertainties due to the frame around the window being managed by the window manager. – Jérôme Jul 03 '18 at 19:54
  • The part that applies to my case is "Furthermore, a toolkit cannot simply place windows on the screen. All Qt can do is to send certain hints to the window manager. The window manager, a separate process, may either obey, ignore or misunderstand them.". Should I understand there is nothing I can do to place the window in a sensible place? That the `move` method is worthless on X11? – Jérôme Jul 03 '18 at 19:55
  • From my experience, it looks like `move` sometimes bounds the position to the screen, sometimes not, and I don't understand which conditions triggers which behaviour. – Jérôme Jul 03 '18 at 19:57
  • 1
    The vital point is that the geometry is applied ***asynchronously***, so nothing can be reliably known until the window manager has finished all its operations. Your code calls `self.width()` when calculating the position, which may be problematic. Try printing the geometry before and after calling `move()`, and then use a timer with a one second delay to print them all again afterwards. This will probably reveal several discrepancies, which will likely only occur when the window is first shown. (In fact, using a timer with a small delay may provide a solution to your problem). – ekhumoro Jul 03 '18 at 21:15
  • @ekhumoro Just tried that. Didn't see any discrepancy. But I can't reproduce the issue on my setup, so it's not really a surprise. Also, the docs say that the frame/decoration is asynchronous, but my window has no frame, so I'm not sure it is impacted. – Jérôme Jul 03 '18 at 21:45
  • I'm thinking of taking a different approach. 1/ Determine in which corner the systray icon lies. 2/ Move window to that corner using `move(0,0)` or `move(50000000,50000000)`. Obviously, it only works if the position is bounded to the screen (minus the panels). Hence my question. IIUC, Qt only sends a hint and bounding / avoiding panels is up to the window manager. – Jérôme Jul 03 '18 at 21:49

0 Answers0