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

[REG 5.8->5.9] mapToGlobal not working within an embedded widget like QWinWidget (QtWinMigrate)

    XMLWordPrintable

Details

    Description

      I'm using QtWinMigrate within an MFC application. Since QT 5.9, all floating widgets (menu, popup, ...) have bad location: they are all stuck on top left of the screen whatever the position of the window is.

      It is reproducible with the samples from QtWinMigrate.

      I have identified that it's coming from this commit: https://github.com/qt/qtbase/commit/2ac50ac15621e303adbf6c35cbc2456f7ae5dd2f

      The function QWindowsWindow::isEmbedded() is no longer recursive. Actually, QWinWidget from QtWinMigrate has the embedded flag. So prior to QT 5.9, for all its child widgets isEmbedded() returned true, which is not the case anymore. And this affect the mapToGlobal function.

      Let's take a look at QWindow::mapToGlobal() function:

      if (d->platformWindow
        && (d->platformWindow->isForeignWindow() || d->platformWindow->isEmbedded())) {
        return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this);
      }
      return pos + d->globalPosition();

      Prior to QT 5.9, for all children widgets, it goes inside the if statement. Now it's only working for the top widget QWinWidget. For the children it goes inside globalPosition().

      The problem is that QWindowPrivate::globalPosition() never test the embedded flag so the returned point is expressed in coordinates relative to the top widget and not absolute to the screen (this transformation is done inside QWindowsGeometryHint::mapToGlobal -> ClientToScreen).

      The solution I see is to modify the condition inside QWindowPrivate::globalPosition() to take in account the embedded flag:

      if (pw && (pw->isForeignWindow() || pw->isEmbedded())) {
          // Use mapToGlobal() for foreign windows and embedded widgets like QWinWidget
          offset += p->mapToGlobal(QPoint(0, 0));
          break;
      }

      This fix worked for me and it makes sense since it's the same condition as in QWindow::mapToGlobal.

      Attachments

        1. QTBUG-67211.zip
          750 kB
          Mario Rössel
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            vestbo Tor Arne Vestbø
            tony.riviere Tony Riviere
            Votes:
            7 Vote for this issue
            Watchers:
            12 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes