c++qtscreenqt6

setGeometry fails setting top coordinate using Qt6 on OS X


I am creating a method called showLeftAligned to force the geometry of a QDialog to be left aligned on screen, separated by a gap of gap pixels around.

void QXDialog::showLeftAligned(int gap) {
  QGuiApplication::primaryScreen()->availableGeometry();
  setGeometry(s.x() + gap, s.y() + gap, width(), s.height() - 2 * gap);
  QDialog::show();
}

As you can see, I am using the screen availableGeometry to take into account the upper menu bar or/and the lower docker. In my case, docker is hidden but OSX menu is set to be always on.

The problem with this method is that the top y-coordinate of the resulting dialog does not separates gap pixels below the menu bar. Here is the result for a gap of 32 pixels.

showLeftAligned result

Using QGuiApplication::primaryScreen()->geometry() Qt is getting right the logical size of the screen, which is 1440 x 900 @ 60.00Hz. Moving to QGuiApplication::primaryScreen()->geometry() I get 1440 x 875, 25 pixels less due to the upper menu bar.

So, everything seems to be logical here but the top position of the QDialog keeps being wrong.

What am I doing wrong here?


Solution

  • You need to adjust the position with the window frame. See the picture and explanation of the difference between geometry and frame geometry here: https://doc.qt.io/qt-6/application-windows.html#window-geometry Your final code can look like this.

    void QXDialog::showLeftAligned(int gap) {
        show(); // we must call this before measuring the window geometry
        auto s = QGuiApplication::primaryScreen()->availableGeometry();
        s.adjust(gap, gap, -gap, -gap);
        auto rect = geometry();
        auto frameRect = frameGeometry();
        auto topLeftDiff = rect.topLeft() - frameRect.topLeft();
        auto bottomRightDiff = rect.bottomRight() - frameRect.bottomRight();
        s.adjust(topLeftDiff.x(), topLeftDiff.y(), bottomRightDiff.x(), bottomRightDiff.y());
        setGeometry(s);
    }