X11 devicePixelRatio screen mapping fix
Fix screen detection and window geometry when screens have different displayPixelRatios. We must use the native coordinate system to figure out which screen a window belongs to. Also, when a window moves to a screen with a different devicePixelRatio, we must recalculate the Qt geometry. Task-number: QTBUG-43713 Change-Id: I93063e37354ff88f3c8a13320b76dfb272e43a9c Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>bb10
parent
3ba1b989a6
commit
075ae987c4
|
|
@ -77,8 +77,10 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
|
|||
// virtual size is known (probably back-calculated from DPI and resolution)
|
||||
if (m_sizeMillimeters.isEmpty())
|
||||
m_sizeMillimeters = m_virtualSizeMillimeters;
|
||||
if (m_geometry.isEmpty())
|
||||
if (m_geometry.isEmpty()) {
|
||||
m_geometry = QRect(QPoint(), m_virtualSize/dpr);
|
||||
m_nativeGeometry = QRect(QPoint(), m_virtualSize);
|
||||
}
|
||||
if (m_availableGeometry.isEmpty())
|
||||
m_availableGeometry = m_geometry;
|
||||
|
||||
|
|
@ -461,6 +463,7 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
|
|||
m_devicePixelRatio = qRound(dpi/96);
|
||||
const int dpr = int(devicePixelRatio()); // we may override m_devicePixelRatio
|
||||
m_geometry = QRect(xGeometry.topLeft()/dpr, xGeometry.size()/dpr);
|
||||
m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size());
|
||||
m_availableGeometry = QRect(xAvailableGeometry.topLeft()/dpr, xAvailableGeometry.size()/dpr);
|
||||
|
||||
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public:
|
|||
QWindow *topLevelAt(const QPoint &point) const;
|
||||
|
||||
QRect geometry() const { return m_geometry; }
|
||||
QRect nativeGeometry() const { return m_nativeGeometry; }
|
||||
QRect availableGeometry() const {return m_availableGeometry;}
|
||||
int depth() const { return m_screen->root_depth; }
|
||||
QImage::Format format() const;
|
||||
|
|
@ -114,6 +115,7 @@ private:
|
|||
QSizeF m_outputSizeMillimeters;
|
||||
QSizeF m_sizeMillimeters;
|
||||
QRect m_geometry;
|
||||
QRect m_nativeGeometry;
|
||||
QRect m_availableGeometry;
|
||||
QSize m_virtualSize;
|
||||
QSizeF m_virtualSizeMillimeters;
|
||||
|
|
|
|||
|
|
@ -1831,6 +1831,23 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
|
|||
}
|
||||
}
|
||||
|
||||
// Temporary workaround for bug in QPlatformScreen::screenForNativeGeometry
|
||||
// we need the native geometries to detect our screen, but that's not
|
||||
// available in cross-platform code. Will be fixed properly when highDPI
|
||||
// support is refactored to expose the native coordinate system.
|
||||
|
||||
QPlatformScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const
|
||||
{
|
||||
QXcbScreen *currentScreen = static_cast<QXcbScreen*>(screen());
|
||||
if (!parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) {
|
||||
Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
|
||||
if (static_cast<QXcbScreen*>(screen)->nativeGeometry().intersects(newGeometry))
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
return currentScreen;
|
||||
}
|
||||
|
||||
void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
|
||||
{
|
||||
bool fromSendEvent = (event->response_type & 0x80);
|
||||
|
|
@ -1847,15 +1864,23 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
|
|||
}
|
||||
}
|
||||
|
||||
QRect rect = mapFromNative(QRect(pos, QSize(event->width, event->height)), int(devicePixelRatio()));
|
||||
const int dpr = devicePixelRatio();
|
||||
const QRect nativeRect = QRect(pos, QSize(event->width, event->height));
|
||||
const QRect rect = mapFromNative(nativeRect, dpr);
|
||||
|
||||
QPlatformWindow::setGeometry(rect);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), rect);
|
||||
|
||||
QPlatformScreen *newScreen = screenForGeometry(rect);
|
||||
QPlatformScreen *newScreen = screenForNativeGeometry(nativeRect);
|
||||
if (newScreen != m_screen) {
|
||||
m_screen = static_cast<QXcbScreen*>(newScreen);
|
||||
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
|
||||
int newDpr = devicePixelRatio();
|
||||
if (newDpr != dpr) {
|
||||
QRect newRect = mapFromNative(nativeRect, newDpr);
|
||||
QPlatformWindow::setGeometry(newRect);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), newRect);
|
||||
}
|
||||
}
|
||||
|
||||
m_configureNotifyPending = false;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,8 @@ public:
|
|||
|
||||
qreal devicePixelRatio() const;
|
||||
|
||||
QPlatformScreen *screenForNativeGeometry(const QRect &newGeometry) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void updateSyncRequestCounter();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue