Firstly: Aaron, thanks for the clarification!

Secondly: Testcase & Results:

The testcase investigates the following things:
If Qt reacts correctly in case a screen is (dis)connected:
  -QDesktopWidget::screenCountChanged is connected to a slot updating "the 
info labels" (see below)
  -an event-filter is installed on QApplication::desktop() to monitor and log 
resize-events.

"The info labels" display:
  -QDesktopWidget::availableGeometry for screen containing the mouse pointer
  -QDesktopWidget::screenGeometry for screen containing the mouse pointer
  -QDesktopWidget::screenGeometry for the default screen
  -QDesktopWidget::geometry

Results:

QDesktopWidget::availableGeometry & QDesktopWidget::screenGeometry are correct 
- KWin is not to blame :)
QDesktopWidget::geometry is wrong, which can also be seen in the filtered 
QResizeEvents:
connect 2nd screen:    QResizeEvent from 1920x1080 -> 3840x1080
disconnect 2nd screen: QResizeEvent from 3840x1080 -> 3840x1080  !!!

So this seems to be a bug in Qt, I'll file a bug-report there. Maybe other 
users can compile and run the testcase and see if they can confirm the 
behaviour I noticed.

The question is whether a workaround in KDialog::screenRect replacing 
QDesktopWidget::geometry is in order. I think it won't do any harm to use 
QDesktopWidget::screenGeometry(-1) instead - any objections/suggestions?

Cheers,

Thomas

#include <QtGui/QApplication>
#include <QWidget>
#include <QDesktopWidget>
#include <QLabel>
#include <QGridLayout>
#include <QPushButton>
#include <QResizeEvent>
#include <QListWidget>
#include <QListWidgetItem>

/* .pro
*QT       += core gui
*
*TARGET = qdw-test
*TEMPLATE = app
*
*
*SOURCES += main.cpp
*/


/* Test app for QApplicationWidget:
  *
  * Displays:
  *    QDesktopWidget::screenGeometry for screen containing mouse pointer
  *    QDesktopWidget::availableGeometry for screen containing mouse pointer
  *    QDesktopWidget::geometry
  * all of the above are also filled from a slot connected to
  * QDesktopWidget::screenCountChanged
  * Hitting "update" also updates the three labels for the values above
  *
  * Installs eventFilter on QApplication::desktop to spy on resizeEvents and logs
  * both the old and new size for each event.
  *
  * Result (for Qt4.8 beta1): availableGeometry and screenGeometry are correct,
  * geometry is wrong. This can also be seen in the filtered resizeEvents:
  *   connect 2nd screen     => resizeEvent: 1920x1080 -> 3840x1080   <- correct
  *   disconnect 2nd screen  => resizeEvent: 3840x1080 -> 3840x1080   <- INCORRECT!!!
  */

class Widget : public QWidget{
   Q_OBJECT
public:
    Widget():QWidget(0)
    {
        QGridLayout* mainLayout=new QGridLayout(this);

        //yes, I'm lazy enough to use a macro to save a dozen loc
#define ADD_LABEL_ROW(a) do{\
            QLabel* l=new QLabel(#a ":");\
            l->setAlignment(Qt::AlignVCenter|Qt::AlignRight);\
            mainLayout->addWidget(l,mainLayout->rowCount(),0);\
            label_##a=new QLabel;\
            mainLayout->addWidget(label_##a,mainLayout->rowCount()-1,1);\
        }while(0)

        ADD_LABEL_ROW(Screens);
        ADD_LABEL_ROW(AvailableGeometry);
        ADD_LABEL_ROW(ScreenGeometry);
        ADD_LABEL_ROW(Geometry);
#undef ADD_LABEL_ROW

        resizeEventLog=new QListWidget;
        mainLayout->addWidget(resizeEventLog,mainLayout->rowCount(),0,1,2);

        QPushButton* b=new QPushButton("Update");
        mainLayout->addWidget(b,mainLayout->rowCount(),0,1,2);
        connect(b,SIGNAL(clicked()),this,SLOT(fillInfo()));

        fillInfo();

        connect(QApplication::desktop(),SIGNAL(screenCountChanged(int)),this,SLOT(fillInfo()));
        QApplication::desktop()->installEventFilter(this);
    }

    bool eventFilter(QObject *, QEvent *e){
        if(e->type()==QEvent::Resize){
            QResizeEvent* re=static_cast<QResizeEvent*>(e);
            QListWidgetItem* item=new QListWidgetItem(resizeEventLog);
            item->setText(QString("OldSize: %1x%2  NewSize: %3x%4")
                          .arg(re->oldSize().width())
                          .arg(re->oldSize().height())
                          .arg(re->size().width())
                          .arg(re->size().height())
                          );
            resizeEventLog->addItem(item);
        }
        return false;
    }

public slots:
    void fillInfo(){
        QDesktopWidget* dw=QApplication::desktop();
        label_Screens->setNum(dw->screenCount());
        label_AvailableGeometry->setText(rectString(dw->availableGeometry(QCursor::pos())));
        label_ScreenGeometry->setText(rectString(dw->screenGeometry(QCursor::pos())));
        label_Geometry->setText(rectString(dw->geometry()));
    }

private:
    static QString rectString(const QRect& rect){
        QString ret=QString("(%1,%2   %3x%4)")
                .arg(rect.x())
                .arg(rect.y())
                .arg(rect.width())
                .arg(rect.height())
                ;
        return ret;
    }

    QLabel* label_Screens;
    QLabel* label_AvailableGeometry;
    QLabel* label_ScreenGeometry;
    QLabel* label_Geometry;
    QListWidget* resizeEventLog;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

#include "main.moc"

Reply via email to