Using QOpenGLWidget in a window with a custom title bar causes a black rectangle on some machines

Viewed 98

The goal is to have an app on Windows using QMainWindow with a custom-drawn title bar and containing a QOpenGLWidget.

Using Qt::CustomizeWindowHint to make the title bar drawable was ruled out because of the issue described in QTBUG-47543 - a thick white frame along the top of the window:

screen-shot

So, falling back to platform-specific Win32 WM_NCCALCSIZE instead...

main.cpp:

#include <QApplication>
#include <QMainWindow>
#include <QOpenGLFunctions>
#include <QOpenGLWidget>
#include <windowsx.h>

class MyGLWidget : public QOpenGLWidget {
    Q_OBJECT
protected:
    void initializeGL() override { QOpenGLContext::currentContext()->functions()->glClearColor(1.0f, 0.0f, 1.0f, 1.0f); }
};


class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow() { setCentralWidget(new MyGLWidget); }
protected:
    bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override
    {
        MSG* msg = reinterpret_cast<MSG*>(message);
        switch (msg->message) {
            case WM_NCCALCSIZE: {
                NCCALCSIZE_PARAMS* params = (NCCALCSIZE_PARAMS*)(msg->lParam);
                params->rgrc[0].right -= 8;  // Sizes hard-coded for brevity
                params->rgrc[0].left += 8;
                params->rgrc[0].bottom -= 8;
                *result = 0;
                return true;
            }
            // case WM_NCHITTEST omitted for brevity
        }
        return false;
    }
};

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    MainWindow window;
    window.show();
    return app.exec();
}

#include "main.moc"

TitleBar.pro:

QT += core gui openglwidgets widgets
SOURCES += main.cpp

On most machines, this gives the desired result:

screen-shot

The problem that's happening on a few machines is that a completely black rectangle is showing in the area where the standard title bar would normally be:

screen-shot

Replace the QOpenGLWidget with a regular QWidget and it looks correct on all machines.

Remove MainWindow::nativeEvent() and set Qt::CustomizeWindowHint on the window instead and the black rectangle problem goes away, but the above-mentioned thick white frame issue occurs instead.

Why would the black rectangle problem only happen on some machines and not others? (See Edit, below.)

Is there a way to use Qt::CustomizeWindowHint that avoids the white frame issue, without overriding nativeEvent()?

If not, is there a way to handle WM_NCCALCSIZE that works well with QOpenGLWidget on all machines?

Tests were done using Qt v6.2.0 on Windows 10 v21H1.


Edit:

The black rectangle goes away if QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL) is called at the top of main(), implying that the problem is specific to certain OpenGL drivers.

0 Answers
Related