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

Multiple issues with foreign windows from QWindow::fromWinId() and QWidget::createWindowContainer()

    XMLWordPrintable

Details

    Description

      Hello,

      I've encountered many issues with foreign windows. Rather than open many tickets, I've listed them all here, especially since I can't tell if any of them have the same root cause.

      I mainly tested foreign windows from Notepad.exe (Windows) and GEdit (Linux) through QWindow and QWidget classes. I briefly tried other programs too, with the same results as far as I could tell.

      TEST CODE
      The report below is split into 3 parts. Uncomment the code related to each part to proceed.

      #include "windows.h"
      #include <QApplication>
      #include <QWindow>
      #include <QWidget>
      #include <QDebug>
      #include <QTimer>
      
      int main(int argc, char *argv[])
      {
          // Windows: Find HWND by window title
          WId id = (WId)FindWindow(NULL, L"Untitled - Notepad");
          if (!id)
              return -1;
      
          // Linux: Find Window ID by running xwininfo externally before compiling this test
          //WId id = 0x4600085
      
          QApplication a(argc, argv);
          QTimer t;
          t.start(2500);
      
          // Part 1
          QWindow* window = QWindow::fromWinId(id);
          window->show();
          window->requestActivate();
          QObject::connect(&t, &QTimer::timeout, [=]
          {
              qDebug() << "=== Inner QWindow ===";
              qDebug() << "Geometry:" << window->geometry();
              qDebug() << "Active?:" << window->isActive();
              qDebug() << "Flags:" << window->flags();
          });
      
      /*
          // Part 2
          QWidget* widget = QWidget::createWindowContainer(window);
          widget->show();
          QObject::connect(&t, &QTimer::timeout, [=]
          {
              qDebug() << "=== Outer QWidget ===";
              qDebug() << "Geometry:" << widget->geometry();
              qDebug() << "Active?" << widget->isActiveWindow();
              qDebug() << "Flags:" << widget->windowFlags();
          });
      */
      
          QObject::connect(&t, &QTimer::timeout, [=]
          {
              qDebug("\n");
      
      /*
              // Part 3
              // Release the window after a few iterations
              static int i = 0;
              if (i++ == 3)
              {
                  window->setParent(nullptr);
                  window->setFlags(window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
              }
      */
          });
      
          return a.exec();
      }
      

      ISSUES
      Part 1: Using a QWindow interface

      • Incorrect geometry reported
        • (Win) window->geometry() always returns the initial geometry (from the point when window->show() was called). Moving/resizing the window does not alter the result of subsequent calls to window->geometry().
        • (Linux) window->geometry() always returns QRect(0, 0, 0x0). Moving/resizing the window has no effect.
      • Incorrect "Active" status reported
        • (Win & Linux) window->isActive() always returns false, even when the window is active. window->requestActivate() has no effect.

      Part 2: Embedding in a QWidget
      This step seems to fix the problems in Part 1, but reveals new problems.

      • Lost key/mouse input
        • (Win) The embedded window stops receiving key press and mouse wheel events (although mouse click events are still fine).
      • Quirks with initial geometry
        • (Win & Linux) The window is forcibly resized to 640x480, even if the original window was not resizable. (The built-in calculator app in Windows, calc.exe, is non-resizable)
        • (Win & Linux) Initially, the inner window is not aligned properly with the outer widget. Resizing the outer widget fixes the alignment. Moving it has no effect.

      Part 3: Releasing an embedded window
      http://qt-project.org/doc/qt-5/qwidget.html#createWindowContainer says that QWindow::setParent() can release the window, but it doesn't quite work.

      • Released but broken
        • (Win) The window is released but remains borderless (as if Qt::FramelessWindowHint was set).
          • However, window->flags() only returns 0x1|0x20 (i.e. Qt::ForeignWindow).
          • Explicitly applying Qt::WindowTitleHint etc. has no effect.

      Attachments

        Issue Links

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

          Activity

            People

              kleint Friedemann Kleint
              jksh Sze Howe Koh
              Votes:
              10 Vote for this issue
              Watchers:
              20 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes