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"