Improve handling of screens in QWidgets.
Historically, the screen number of a QWidget was stored in QTLWExtra::screenIndex which came in via the Q_WS_QWS platform. The variable contained the screen number of the QDesktopScreenWidget and the desired screen number for widget creation (from parent widget or desktop parent widgets) and was not updated according to widget geometry or when the associated QWindow moved to another screen. Storing the screen number is problematic in Qt 5 since it may change when the list of QScreens in QGuiApplication is rearranged. This change renames it to initialScreen and changes its usage to only contain a screen number when a screen is requested by parenting on a desktop widget or reparenting. A value of -1 indicates no screen is requested and the number should be deduced from the geometry. For the usage in QDesktopScreenWidget, add a method to determine the number via index in the list of QDesktopWidget. Task-number: QTBUG-44070 Task-number: QTBUG-44213 Change-Id: I153d19073ad4b0fd14ef3d24caa6d3e76f350e82 Reviewed-by: Andy Shaw <andy.shaw@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
This commit is contained in:
parent
4805714b0f
commit
b3fc5e1ea3
@ -39,6 +39,13 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
int QDesktopScreenWidget::screenNumber() const
|
||||
{
|
||||
const QDesktopWidgetPrivate *desktopWidgetP
|
||||
= static_cast<const QDesktopWidgetPrivate *>(qt_widget_private(QApplication::desktop()));
|
||||
return desktopWidgetP->screens.indexOf(const_cast<QDesktopScreenWidget *>(this));
|
||||
}
|
||||
|
||||
const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const
|
||||
{
|
||||
if (!widget) {
|
||||
@ -79,7 +86,7 @@ void QDesktopWidgetPrivate::_q_updateScreens()
|
||||
|
||||
for (int currentLength = screens.size(); currentLength < targetLength; ++currentLength) {
|
||||
QScreen *qScreen = screenList.at(currentLength);
|
||||
QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget(currentLength);
|
||||
QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget;
|
||||
screenWidget->setGeometry(qScreen->geometry());
|
||||
QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)),
|
||||
q, SLOT(_q_updateScreens()), Qt::QueuedConnection);
|
||||
|
@ -53,12 +53,12 @@ QT_BEGIN_NAMESPACE
|
||||
class QDesktopScreenWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QDesktopScreenWidget(int screenNumber = -1) : QWidget(0, Qt::Desktop)
|
||||
QDesktopScreenWidget() : QWidget(Q_NULLPTR, Qt::Desktop)
|
||||
{
|
||||
setVisible(false);
|
||||
QTLWExtra *topData = d_func()->topData();
|
||||
topData->screenIndex = screenNumber;
|
||||
}
|
||||
|
||||
int screenNumber() const;
|
||||
};
|
||||
|
||||
class QDesktopWidgetPrivate : public QWidgetPrivate {
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "qapplication_p.h"
|
||||
#include "qbrush.h"
|
||||
#include "qcursor.h"
|
||||
#include "qdesktopwidget.h"
|
||||
#include "qdesktopwidget_p.h"
|
||||
#include "qevent.h"
|
||||
#include "qhash.h"
|
||||
#include "qlayout.h"
|
||||
@ -1111,9 +1111,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
|
||||
if (allWidgets)
|
||||
allWidgets->insert(q);
|
||||
|
||||
QWidget *desktopWidget = 0;
|
||||
int targetScreen = -1;
|
||||
if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
|
||||
desktopWidget = parentWidget;
|
||||
const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(parentWidget);
|
||||
targetScreen = sw ? sw->screenNumber() : 0;
|
||||
parentWidget = 0;
|
||||
}
|
||||
|
||||
@ -1133,10 +1134,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
|
||||
xinfo = desktopWidget->d_func()->xinfo;
|
||||
}
|
||||
#endif
|
||||
if (desktopWidget) {
|
||||
const int screen = desktopWidget->d_func()->topData()->screenIndex;
|
||||
if (targetScreen >= 0) {
|
||||
topData()->initialScreenIndex = targetScreen;
|
||||
if (QWindow *window = q->windowHandle())
|
||||
window->setScreen(QGuiApplication::screens().value(screen, 0));
|
||||
window->setScreen(QGuiApplication::screens().value(targetScreen, Q_NULLPTR));
|
||||
}
|
||||
|
||||
data.fstrut_dirty = true;
|
||||
@ -1414,8 +1415,15 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
|
||||
win->setGeometry(q->geometry());
|
||||
else
|
||||
win->resize(q->size());
|
||||
if (win->isTopLevel())
|
||||
win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
|
||||
if (win->isTopLevel()) {
|
||||
int screenNumber = topData()->initialScreenIndex;
|
||||
topData()->initialScreenIndex = -1;
|
||||
if (screenNumber < 0) {
|
||||
screenNumber = q->windowType() != Qt::Desktop
|
||||
? QApplication::desktop()->screenNumber(q) : 0;
|
||||
}
|
||||
win->setScreen(QGuiApplication::screens().value(screenNumber, Q_NULLPTR));
|
||||
}
|
||||
|
||||
QSurfaceFormat format = win->requestedFormat();
|
||||
if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface
|
||||
@ -1715,7 +1723,7 @@ void QWidgetPrivate::createTLExtra()
|
||||
x->embedded = 0;
|
||||
x->window = 0;
|
||||
x->shareContext = 0;
|
||||
x->screenIndex = 0;
|
||||
x->initialScreenIndex = -1;
|
||||
#ifdef Q_WS_MAC
|
||||
x->wasMaximized = false;
|
||||
#endif // Q_WS_MAC
|
||||
@ -10503,9 +10511,8 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
|
||||
if (newparent && newparent->windowType() == Qt::Desktop) {
|
||||
// make sure the widget is created on the same screen as the
|
||||
// programmer specified desktop widget
|
||||
|
||||
// get the desktop's screen number
|
||||
targetScreen = newparent->window()->d_func()->topData()->screenIndex;
|
||||
const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(newparent);
|
||||
targetScreen = sw ? sw->screenNumber() : 0;
|
||||
newparent = 0;
|
||||
}
|
||||
|
||||
@ -10537,7 +10544,7 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
|
||||
f |= Qt::Window;
|
||||
if (targetScreen == -1) {
|
||||
if (parent)
|
||||
targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
|
||||
targetScreen = QApplication::desktop()->screenNumber(q->parentWidget()->window());
|
||||
}
|
||||
}
|
||||
|
||||
@ -10581,12 +10588,11 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
|
||||
|
||||
// move the window to the selected screen
|
||||
if (!newparent && targetScreen != -1) {
|
||||
if (maybeTopData())
|
||||
maybeTopData()->screenIndex = targetScreen;
|
||||
// only if it is already created
|
||||
if (q->testAttribute(Qt::WA_WState_Created)) {
|
||||
if (q->testAttribute(Qt::WA_WState_Created))
|
||||
q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
|
||||
}
|
||||
else
|
||||
topData()->initialScreenIndex = targetScreen;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ struct QTLWExtra {
|
||||
#endif
|
||||
QWidgetWindow *window;
|
||||
QOpenGLContext *shareContext;
|
||||
quint32 screenIndex; // index in qplatformscreenlist
|
||||
int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent.
|
||||
};
|
||||
|
||||
struct QWExtra {
|
||||
|
Loading…
Reference in New Issue
Block a user