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

X11: QWidget::windowState() ends up at rest out of sync with reality



    • Bug
    • Resolution: Duplicate
    • P2: Important
    • None
    • 5.13.2
    • QPA: X11/XCB
    • None
    • Linux/X11


      It is possible, with a quick succession of window state changes, for a Qt program to end up in a situation where (QWidget::windowState() & Qt::WindowMinized) == true even though the native window is not minimized. The following sample reproduces the problem with gnome (mutter):

      // Build. g++ -std=c++17 -Wall -Wextra -g -fPIC $(pkg-config --cflags --libs Qt5Core  Qt5Gui Qt5Widgets) -o example example.cc
      #include <iostream>
      #include <QApplication>
      #include <QLabel>
      #include <QTimer>
      int main(int argc, char **argv)
          QApplication app(argc, argv);
          QLabel w(QLatin1String("Hello world"));
          QTimer::singleShot(1000, [&] {
              w.setWindowState(w.windowState() | Qt::WindowMinimized);
          QTimer::singleShot(3000, [&] {
              std::cout << "Window state: " << w.windowState() << std::endl;
          return app.exec();

      The program above shows a window with the text "Hello world". After a second it will minimize and then immediately activate the window causing it to not be minimized again. After three seconds it prints the window state and quits. With gnome/mutter this prints "Window state: 1" (minimized) which is incorrect. It should print "Window state: 0".

      I have also been able to reproduce the problem with metacity, though not as easily or reliably.

      While the example above is synthetic I have observed this problem in a real application.

      The problem is that w.setWindowState(w.windowState() | Qt::WindowMinimized); will update QWidget::windowState() directly and then effect the change via the platform QXcbWindow. QWidget::activateWindow() only affects the change via the platform QxcbWindow and relies on property notify events caused by the window manager updating WM_STATE and _NET_WM_STATE to feed the updated window state back to Qt. The problem is that QXcbWindow::handlePropertyNotifyEvent() ignores the updates because it determines that the new state reported is the same as the last update it reported by comparing it to QXcbWindow::m_lastWindowStateEvent.

      I believe what goes wrong here is that if window state changes happen fast enough the window manager has changed the WM_STATE/_NET_WM_STATE to minimized and back to unminimized before QXcbWindow::handlePropertyNotifyEvent() runs, which means that from QXcbWindow's point of view there is nothing new to report and we never clear the Qt::WindowMinimized bit that was set directly by QWidget::setWindowState().


        Issue Links

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



              liaqi Liang Qi
              ts Thomas Sondergaard
              1 Vote for this issue
              2 Start watching this issue



                Gerrit Reviews

                  There are no open Gerrit changes