Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-40485

Custom window frame behaving incorrectly on OpenGL Qt build

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Not Evaluated
    • 5.4.0
    • 5.2.1, 5.3.1
    • None
    • Qt 5.3.1 for Windows 32-bit (VS 2013, OpenGL, 557 MB)
      Qt 5.3.1 for Windows 32-bit (VS 2013, 559 MB)
      Windows 8.1

    Description

      My task is to create a window for QtQuick with possibility to use it like a common window but with custom frame look (not the default system decoration). I would like to achieve effect similar to Visual Studio window or something like this.

      Code that allows me to achieve that goal is shown below:

      main.cpp
      #include <QtQuick/qquickpainteditem.h>
      #include <qapplication.h>
      #include <qqmlengine.h>
      #include <QtQuick/qquickwindow.h>
      
      class frameLess :
          public QQuickWindow
      {
      public:
          frameLess(QWindow *parent = 0) :QQuickWindow(parent) { }
      
          bool nativeEvent(const QByteArray& eventType, void* message, long* result)
          {
              MSG *msg = static_cast<MSG *>(message);
      
              switch (msg->message)
              {
              case WM_SHOWWINDOW:
                  // after that call Qt considers window as frameless
                  setFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
                  // that call force the Windows to serve users mouse events like in standard window
                  SetWindowLongPtr(msg->hwnd, GWL_STYLE, WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
                  return false;
      
              case WM_NCCALCSIZE:
                  // prevent the Windows from painting the frame
                  *result = 0;
                  return true;
      
              default:
                  break;
              }
      
              return false;
          }
      };
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
      
          qmlRegisterType<frameLess>("fb", 1, 0, "FrameLess");
      
          QQmlEngine engine;
          QQmlComponent *component = new QQmlComponent(&engine);
      
          QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
      
          component->loadUrl(QUrl("qrc:////main.qml"));
      
          if (!component->isReady())
          {
              qWarning("%s", qPrintable(component->errorString()));
              return -1;
          }
      
          QObject *topLevel = component->create();
          QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
      
          QSurfaceFormat surfaceFormat = window->requestedFormat();
          window->setFormat(surfaceFormat);
          window->show();
      
          return app.exec();
      }
      
      main.qml
      import fb 1.0
      import QtQuick 2.2
      import QtQuick.Controls 1.1
      
      FrameLess {
          color:"lightgray"
          Rectangle {
              width: 45
              height: 45
              color: "green"
              anchors {
                  top: parent.top
                  left: parent.left
              }
      
              MouseArea {
                  anchors.fill: parent
                  hoverEnabled: true;
                  onEntered: parent.color="red"
                  onExited: parent.color="green"
              }
          }
      }
      

      As a result, frameless window with green rectangle in the upper left corner should appear. Furthermore, that rectangle should change color to red when hovered by mouse.

      When I'm building that with ANGLE-based Qt build, everything works as expected.

      However, my team is using OpenGL-based Qt build. The problem is that when my code is linked against such version of Qt, painting area is shifted by the size of window frame.

      What is more, only painting area is shifted. For example, mouse hitboxes are in proper place. Because of that hitboxes and scene items coordinates are desynchronized. (the interactive area of MouseArea lies in a different place than the Rectangle it fills)

      I described that problem at page below and they suggested me to report an issue:
      http://stackoverflow.com/questions/24994033/custom-window-frame-behaving-differently-across-qt-builds-angle-vs-opengl

      Attachments

        1. bad.PNG
          bad.PNG
          2 kB
        2. bad_noMouse.png
          bad_noMouse.png
          1 kB
        3. good.png
          good.png
          0.6 kB
        4. qtbug40485_example.zip
          1 kB
        5. bad.PNG
          bad.PNG
          2 kB
        6. max_restore.png
          max_restore.png
          0.4 kB
        7. qtbug40485_example_qtquick.rar
          3 kB
        8. qt_5.4.1_Intel_VGA_debug_log.txt
          3 kB

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              kleint Friedemann Kleint
              srutownik Marek Wawrzos
              Votes:
              0 Vote for this issue
              Watchers:
              18 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes