From the Qt documentation:
On macOS and iOS, applications use high DPI scaling that is an alternative to the traditional DPI scaling. In the traditional approach, the application is presented with an DPI value used to multiply font sizes, layouts, and so on. In the new approach, the operating system provides Qt with a scaling ratio that is used to scale graphics output: allocate larger buffers and set a scaling transform.
The advantage of this approach is that that vector graphics and fonts scale automatically and existing applications tend to work unmodified. For raster content, high-resolution alternative resources are needed, however.
Scaling is implemented for the QtQuick and QtWidgets stacks, as well as general support in QtGui and the Cocoa platform plugin.
The OS scales window, event, and desktop geometry. The Cocoa platform plugin sets the scaling ratio as QWindow::devicePixelRatio() or QScreen::devicePixelRatio(), as well as on the backing store.
For QtWidgets, QPainter picks up devicePixelRatio() from the backing store and interprets it as a scaling ratio.
However, in OpenGL pixels are always device pixels. For example, geometry passed to glViewport() needs to be scaled by devicePixelRatio().
So Qt widgets hide the DPI scaling but OpenGL does not.
To figure out what was going on in Avogadro2 I put in a resizeEvent in the MainWindow and there I could query the size of the total layout, the multiViewWidget, the qopenglwidget and the glViewport each time I resized the mainwindow. The devicePixelRatio for my hardware is 2 (2017 MBP retina displayed on a 4K monitor). For the Avogadro-master code:
Layout - 1356x804 multiView 1099x708 glWidget 1099x708 glViewport 1099x708.
And the molecule fills the display window and picking works. In my test program if the glwidget size and the glViewport size are the same numerically than the image only fills 1/4 of the window. glWidget is in device independent pixels and glViewport is in pixels.
So I changed the glWidget constructor to get the devicePixelRatio and set the value in the camera. I also changed resizeGL to multiply the width and height by the devicePixelRatio and then pass the new values to the render. So now when I resize the mainwindow the values are:
Layout - 1372x817 multiView 1115x720 glWidget 1115x720 glViewport 2230x1440.
And the molecule fills the screen and picking works. So Avogadro2 works either way!
It looks to me that your code takes any size glViewport and maps it full screen to the glWidget. How I don’t know. Qt does have several device independent pixel formats including a QOpenGLPaintDevice - but I don’t think you are using any of them. I am still confused as to how this works. But my code works according to the Qt documentation so I am just going to make a note of this problem until something breaks and move on to figuring out how to do side by side stereo with the new rendering routines.