Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Remember window size before maximization (or Detect if QResizeEvent is maximization)



  • I need to save the position and state of a QWindow to restore it in the next app execution. The problem is that, if the window gets maximized, I would like to remember its size before being maximized so that it gets saved too.

    Currently I'm using the window's size at the moment of it's closing, but if it is maximized by then I end up saving a very big size instead of what I wanted.

    I tried to change the behavior and save the size only if not maximized, but if I move the window, maximize it and then close, next time it gets placed in the old position.

    Then I tried to save the size everytime it gets resized, using its resizeEvent, but the maximizations get dispatched as QResizeEvents as well. As this last attempt was the most promising, I would like to know if I can detect which kind of resizing I got.

    I tried to test with isMaximized, but it always returns true regardless if I'm maximizing or restoring the window...

    Thank you


  • Lifetime Qt Champion

    Hi,

    What kind of window are you saving the geometry from and how are you doing it ?



  • I don't know if this is helpful, but this is how we save and restore the window layout in our QDialog subclass. Perhaps you can find something useful.

    The UserSettings class is a custom class for saving and restoring different values, where Value() returns a default value. Substitute with your own implementation.

    void MyDialog::saveWindowLayout()
    {
      QPoint currentPos  = this->frameGeometry().topLeft();
      QPoint offsetPos   = this->normalGeometry().topLeft();
      QSize  currentSize = this->normalGeometry().size();
    
      if (!currentSize.isValid())
        currentSize = this->sizeHint();
    
      int screen      = QApplication::desktop()->screenNumber(this);
      int windowstate = this->windowState();
    
      UserSettings settings("mydlg"); 
      settings["Screen"]       = screen;
      settings["WindowState"]  = windowstate;
      settings["PosX"]         = currentPos.x();
      settings["PosY"]         = currentPos.y();
      settings["OffsetX"]      = offsetPos.x();
      settings["OffsetY"]      = offsetPos.y();
      settings["Width"]        = currentSize.width();
      settings["Height"]       = currentSize.height();
      settings.save();
    }
    
    void MyDialog::restoreWindowLayout(bool restoresize)
    {
      QSize currentSize = this->size();
      this->setMinimumSize(currentSize);
    
      UserSettings settings("mydlg"); 
    
      const QDesktopWidget *desktop = QApplication::desktop();
      int screen = settings[dlgname]["Screen"].Value(desktop->primaryScreen());
    
      if (screen >= desktop->screenCount())
        screen = desktop->primaryScreen();
    
      // available desktop geometry excluding the taskbar
      const QRect availableGeometry = desktop->availableGeometry(screen);
    
      int w = currentSize.width();
      int h = currentSize.height();
    
      if (restoresize)
      {
        w = qMax(settings["Width"].Value(0),  w);
        h = qMax(settings["Height"].Value(0), h);
      }
    
      // before the dialog is first shown its top left position defaults to (0,0)
      int x        = settings["PosX"].Value(0);
      int y        = settings["PosY"].Value(0);
      int offX     = settings["OffsetX"].Value(0);
      int offY     = settings["OffsetY"].Value(0);
      int defaultX = (availableGeometry.width()  - w) / 2;
      int defaultY = (availableGeometry.height() - h) / 2;
    
      // if this is the first time the dialog is shown there is no saved position
      if (x == offX && y == offY)
      {
        x    = defaultX;
        y    = defaultY;
        offX = defaultX;
        offY = defaultY;
      }
    
      QRect normalGeometry = QRect(offX, offY, w, h);
      QRect frameGeometry  = QRect(x, y, w, h);
    
      // if the dialog is outside the visible area we reset it to its default position
      if (!frameGeometry.intersects(availableGeometry))
      {
        x = defaultX;
        y = defaultY;
      }
    
      int windowstate = settings["WindowState"].Value(-1);
    
      if (windowstate & Qt::WindowMaximized || windowstate & Qt::WindowFullScreen)
      {
        if (!normalGeometry.intersects(availableGeometry))
          normalGeometry.setTopLeft(QPoint(defaultX, defaultY));
    
        this->setGeometry(normalGeometry);
      }
      else
      {
        this->move(x, y);
        this->resize(w, h);
      }
    
      windowstate &= ~Qt::WindowMinimized;
      this->setWindowState(Qt::WindowStates(windowstate));
      this->setWindowModality(Qt::WindowModal);
    }
    


  • @Arthur-Araruna
    You do not say whether you are Windows or Linux (X11), and that may be relevant to your problem.

    I think you should read the accepted solution at https://stackoverflow.com/a/15112363/489865. Also http://doc.qt.io/qt-5/qwidget.html#maximized-prop.

    BTW: Yes, I would expect to have to hook to QResizeEvent and save at each resize/move, doing whatever recognition to make sure I do not save when the resize is because of maximization, however you detect that.



  • @marcbf said in Remember window size before maximization (or Detect if QResizeEvent is maximization):

    int w = currentSize.width();
    int h = currentSize.height();

    if (restoresize)
    {
    w = qMax(settings["Width"].Value(0), w);
    h = qMax(settings["Height"].Value(0), h);
    }

    Man, this is the deal!!! Everything worked perfectly after I fine tuned your code to my context! Thank you very much.

    The trick was really to use normalGeometry and windowState, so these two are the answer to my question.