From d40b66a8ef98777c69ac293dac9a332f88832c23 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 7 Jan 2015 14:50:41 +0100 Subject: Fix use-after-free bug xcb_image_destroy() calls free on m_xcb_image and then few lines down we access member of m_xcb_image. Swap order of these two actions. Change-Id: I01fb43a066459cce462df6af22161c35cef524eb Task-number: QTBUG-43623 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 0b9717759b..f4382c7b50 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -145,8 +145,6 @@ void QXcbShmImage::destroy() if (segmentSize && m_shm_info.shmaddr) Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg)); - xcb_image_destroy(m_xcb_image); - if (segmentSize) { if (m_shm_info.shmaddr) { shmdt(m_shm_info.shmaddr); @@ -156,6 +154,8 @@ void QXcbShmImage::destroy() } } + xcb_image_destroy(m_xcb_image); + if (m_gc) Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc)); } -- cgit v1.2.3 From e6699afbee77b853773579d29d78a1ade2a4ab2c Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 7 Jan 2015 15:19:07 +0100 Subject: Fix physical DPI and size for rotated screens on X11 Rotated screens would use the unrotated physical geometry, causing the calculated physical DPI to be completely wrong. In RandR, the output does not rotate, so the physical size is always for the unrotated display. The transformation is done on the crtc. http://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt Task-number: QTBUG-43688 Change-Id: Ifde192fcc99a37d0bfd6d57b4cdeac124a054ca3 Reviewed-by: Friedemann Kleint Reviewed-by: Shawn Rutledge Reviewed-by: Uli Schlachter --- src/plugins/platforms/xcb/qxcbscreen.cpp | 22 +++++++++++++++++++++- src/plugins/platforms/xcb/qxcbscreen.h | 1 + 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 8bdedba8ac..73f27c7117 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -53,7 +53,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_screen(scr) , m_crtc(output ? output->crtc : 0) , m_outputName(outputName) - , m_sizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) + , m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) , m_virtualSize(scr->width_in_pixels, scr->height_in_pixels) , m_virtualSizeMillimeters(scr->width_in_millimeters, scr->height_in_millimeters) , m_orientation(Qt::PrimaryOrientation) @@ -71,6 +71,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, updateGeometry(output ? output->timestamp : 0); updateRefreshRate(); + const int dpr = int(devicePixelRatio()); // On VNC, it can be that physical size is unknown while // virtual size is known (probably back-calculated from DPI and resolution) @@ -93,6 +94,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, qDebug(" virtual height.: %lf", m_virtualSizeMillimeters.height()); qDebug(" virtual geom...: %d x %d", m_virtualSize.width(), m_virtualSize.height()); qDebug(" avail virt geom: %d x %d +%d +%d", m_availableGeometry.width(), m_availableGeometry.height(), m_availableGeometry.x(), m_availableGeometry.y()); + qDebug(" orientation....: %d", m_orientation); qDebug(" pixel ratio....: %d", m_devicePixelRatio); qDebug(" depth..........: %d", screen()->root_depth); qDebug(" white pixel....: %x", screen()->white_pixel); @@ -413,6 +415,24 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) if (crtc) { xGeometry = QRect(crtc->x, crtc->y, crtc->width, crtc->height); xAvailableGeometry = xGeometry; + switch (crtc->rotation) { + case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal + m_orientation = Qt::LandscapeOrientation; + m_sizeMillimeters = m_outputSizeMillimeters; + break; + case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left + m_orientation = Qt::PortraitOrientation; + m_sizeMillimeters = m_outputSizeMillimeters.transposed(); + break; + case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted + m_orientation = Qt::InvertedLandscapeOrientation; + m_sizeMillimeters = m_outputSizeMillimeters; + break; + case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right + m_orientation = Qt::InvertedPortraitOrientation; + m_sizeMillimeters = m_outputSizeMillimeters.transposed(); + break; + } free(crtc); } } diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index ca0aee2cc4..b9ee331104 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -111,6 +111,7 @@ private: xcb_screen_t *m_screen; xcb_randr_crtc_t m_crtc; QString m_outputName; + QSizeF m_outputSizeMillimeters; QSizeF m_sizeMillimeters; QRect m_geometry; QRect m_availableGeometry; -- cgit v1.2.3 From 3ba1b989a6c7e22e8f0b92c59c5bbb52cdcab638 Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Fri, 9 Jan 2015 22:20:02 +0100 Subject: xcb: build fix when XCB_USE_XLIB is not defined. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When XCB_USE_XLIB was not defined QXcbXSettings still used XIproto.h. This change removes XIProto.h dependency and leaves QXcbXSettings uninitialized when XCB_USE_XLIB is not defined. QXcbXSettings::initialize() is already used in other parts of code e.g. qxcbcursor.cpp. Change-Id: I48eb82e39c5c091b41e8ec19e742a21d41de2610 Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbxsettings.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp index 13d42832db..a1dadb0e54 100644 --- a/src/plugins/platforms/xcb/qxcbxsettings.cpp +++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp @@ -36,7 +36,9 @@ #include #include +#ifdef XCB_USE_XLIB #include +#endif //XCB_USE_XLIB QT_BEGIN_NAMESPACE /* Implementation of http://standards.freedesktop.org/xsettings-spec/xsettings-0.5.html */ @@ -138,6 +140,7 @@ public: return value + 4 - remainder; } +#ifdef XCB_USE_XLIB void populateSettings(const QByteArray &xSettings) { if (xSettings.length() < 12) @@ -212,6 +215,7 @@ public: } } +#endif //XCB_USE_XLIB QXcbScreen *screen; xcb_window_t x_settings_window; @@ -258,8 +262,10 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen) const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE }; xcb_change_window_attributes(screen->xcb_connection(),d_ptr->x_settings_window,event,event_mask); +#ifdef XCB_USE_XLIB d_ptr->populateSettings(d_ptr->getSettings()); d_ptr->initialized = true; +#endif //XCB_USE_XLIB } QXcbXSettings::~QXcbXSettings() @@ -279,7 +285,9 @@ void QXcbXSettings::handlePropertyNotifyEvent(const xcb_property_notify_event_t Q_D(QXcbXSettings); if (event->window != d->x_settings_window) return; +#ifdef XCB_USE_XLIB d->populateSettings(d->getSettings()); +#endif //XCB_USE_XLIB } void QXcbXSettings::registerCallbackForProperty(const QByteArray &property, QXcbXSettings::PropertyChangeFunc func, void *handle) -- cgit v1.2.3 From 075ae987c48ce732e6a22c1eba71023fa0ea1775 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 7 Jan 2015 15:44:12 +0100 Subject: X11 devicePixelRatio screen mapping fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/plugins/platforms/xcb/qxcbscreen.cpp | 5 ++++- src/plugins/platforms/xcb/qxcbscreen.h | 2 ++ src/plugins/platforms/xcb/qxcbwindow.cpp | 29 +++++++++++++++++++++++++++-- src/plugins/platforms/xcb/qxcbwindow.h | 2 ++ 4 files changed, 35 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 73f27c7117..f8d68c68f0 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -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); diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index b9ee331104..4675b12d9c 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -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; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e1ccc3f086..590e296f61 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -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(screen()); + if (!parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) { + Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) { + if (static_cast(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(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; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 12d20d004d..254421e57d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -154,6 +154,8 @@ public: qreal devicePixelRatio() const; + QPlatformScreen *screenForNativeGeometry(const QRect &newGeometry) const; + public Q_SLOTS: void updateSyncRequestCounter(); -- cgit v1.2.3 From 3f0b8a9f198cd1e0e8ae9150561f93fb1b931b7e Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 8 Jan 2015 13:55:32 +0100 Subject: Multi-screen DPI support for X11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calculate the logical DPI independently per screen, but only when auto dpr is enabled. Using a constant DPI value for all screens, based on the combined geometry is arguably incorrect, but changing this now will cause pixel-size fonts to behave visibly different from point-size fonts when moving the window to a different screen. However, with QT_DEVICE_PIXEL_RATIO=auto, the pixel size fonts are already changing when the devicePixelRatio changes. Without this change, the point-size fonts will *not* adapt, which is a clear bug. Task-number: QTBUG-43713 Change-Id: I3e71618f9d55b7828ccd70b69a7b7ce656c69d65 Reviewed-by: Friedemann Kleint Reviewed-by: Jørgen Lind Reviewed-by: Simon Hausmann Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbscreen.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index f8d68c68f0..6559a0bdba 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -317,8 +317,14 @@ QDpi QXcbScreen::logicalDpi() const if (m_forcedDpi > 0) return QDpi(m_forcedDpi/dpr, m_forcedDpi/dpr); - return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width() / dpr, - Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height() / dpr); + static const bool auto_dpr = qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto"; + if (auto_dpr) { + return QDpi(Q_MM_PER_INCH * m_geometry.width() / m_sizeMillimeters.width(), + Q_MM_PER_INCH * m_geometry.height() / m_sizeMillimeters.height()); + } else { + return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width() / dpr, + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height() / dpr); + } } -- cgit v1.2.3 From c1d08afd31074a2733057ed6620735ef2f4dd8c6 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 12 Jan 2015 10:14:44 +0100 Subject: Fix constantly growing window bug with devicePixelRatio Rectangles need to be mapped differently depending on what they are used for. Expose events need to cover the entire geometry, so they must be rounded up, potentially increasing the size. If we use the same conversion for window geometries, it is possible to end up with a feedback loop if the window reacts to the new size. Task-number: QTBUG-43743 Change-Id: I7881cc77bf2148fed2ae743c4226617a61197434 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbwindow.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 590e296f61..4fd71f1635 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -151,7 +151,7 @@ static inline QRect mapToNative(const QRect &qtRect, int dpr) return QRect(qtRect.x() * dpr, qtRect.y() * dpr, qtRect.width() * dpr, qtRect.height() * dpr); } -// When converting native rects to Qt rects: round top/left towards the origin and +// When mapping expose events to Qt rects: round top/left towards the origin and // bottom/right away from the origin, making sure that we cover the whole widget static inline QPoint dpr_floor(const QPoint &p, int dpr) @@ -164,11 +164,15 @@ static inline QPoint dpr_ceil(const QPoint &p, int dpr) return QPoint((p.x() + dpr - 1) / dpr, (p.y() + dpr - 1) / dpr); } -static inline QRect mapFromNative(const QRect &xRect, int dpr) +static inline QRect mapExposeFromNative(const QRect &xRect, int dpr) { return QRect(dpr_floor(xRect.topLeft(), dpr), dpr_ceil(xRect.bottomRight(), dpr)); } +static inline QRect mapGeometryFromNative(const QRect &xRect, int dpr) +{ + return QRect(xRect.topLeft() / dpr, xRect.bottomRight() / dpr); +} // Returns \c true if we should set WM_TRANSIENT_FOR on \a w static inline bool isTransient(const QWindow *w) @@ -1718,7 +1722,7 @@ public: return false; if (expose->count == 0) m_pending = false; - *m_region |= mapFromNative(QRect(expose->x, expose->y, expose->width, expose->height), m_dpr); + *m_region |= mapExposeFromNative(QRect(expose->x, expose->y, expose->width, expose->height), m_dpr); return true; } @@ -1746,7 +1750,7 @@ void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) { const int dpr = int(devicePixelRatio()); QRect x_rect(event->x, event->y, event->width, event->height); - QRect rect = mapFromNative(x_rect, dpr); + QRect rect = mapExposeFromNative(x_rect, dpr); if (m_exposeRegion.isEmpty()) m_exposeRegion = rect; @@ -1866,7 +1870,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * const int dpr = devicePixelRatio(); const QRect nativeRect = QRect(pos, QSize(event->width, event->height)); - const QRect rect = mapFromNative(nativeRect, dpr); + const QRect rect = mapGeometryFromNative(nativeRect, dpr); QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); @@ -1877,7 +1881,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); int newDpr = devicePixelRatio(); if (newDpr != dpr) { - QRect newRect = mapFromNative(nativeRect, newDpr); + QRect newRect = mapGeometryFromNative(nativeRect, newDpr); QPlatformWindow::setGeometry(newRect); QWindowSystemInterface::handleGeometryChange(window(), newRect); } -- cgit v1.2.3 From a8a00f646b57b5a7ca2cf8603311888ff6ff09f8 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 13 Jan 2015 12:45:28 +0100 Subject: Turn off font hinting when we do high DPI scaling Font hinting depends on the specific pixel size, and ends up very wrong when the painter is scaled. Change-Id: I2007ec7e7ad8d52358d76e88e030ea4df7e91455 Task-number: QTBUG-43809 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 6 +++++- src/plugins/platforms/xcb/qxcbnativeinterface.h | 3 ++- src/plugins/platforms/xcb/qxcbscreen.cpp | 7 +++++++ src/plugins/platforms/xcb/qxcbscreen.h | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 3058b29f2d..31dedd40a2 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -78,7 +78,8 @@ static int resourceType(const QByteArray &key) QByteArrayLiteral("startupid"), QByteArrayLiteral("traywindow"), QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"), QByteArrayLiteral("rootwindow"), - QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled") + QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled"), + QByteArrayLiteral("nofonthinting") }; const QByteArray *end = names + sizeof(names) / sizeof(names[0]); const QByteArray *result = std::find(names, end, key); @@ -283,6 +284,9 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q case GetTimestamp: result = getTimestamp(xcbScreen); break; + case NoFontHinting: + result = xcbScreen->noFontHinting() ? this : 0; //qboolptr... + break; default: break; } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index b667f1a372..330dd008c4 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -67,7 +67,8 @@ public: X11Screen, RootWindow, ScreenSubpixelType, - ScreenAntialiasingEnabled + ScreenAntialiasingEnabled, + NoFontHinting }; QXcbNativeInterface(); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 6559a0bdba..7136455754 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -62,6 +62,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_forcedDpi(-1) , m_devicePixelRatio(1) , m_hintStyle(QFontEngine::HintStyle(-1)) + , m_noFontHinting(false) , m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1)) , m_antialiasingEnabled(-1) , m_xSettings(0) @@ -86,6 +87,12 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, readXResources(); + // disable font hinting when we do UI scaling + static bool dpr_scaling_enabled = (qgetenv("QT_DEVICE_PIXEL_RATIO").toInt() > 1 + || qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto"); + if (dpr_scaling_enabled) + m_noFontHinting = true; + #ifdef Q_XCB_DEBUG qDebug(); qDebug("Screen output %s of xcb screen %d:", m_outputName.toUtf8().constData(), m_number); diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 4675b12d9c..e9ab2edaa0 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -98,6 +98,7 @@ public: void readXResources(); QFontEngine::HintStyle hintStyle() const { return m_hintStyle; } + bool noFontHinting() const { return m_noFontHinting; } QFontEngine::SubpixelAntialiasingType subpixelType() const { return m_subpixelType; } int antialiasingEnabled() const { return m_antialiasingEnabled; } @@ -132,6 +133,7 @@ private: int m_forcedDpi; int m_devicePixelRatio; QFontEngine::HintStyle m_hintStyle; + bool m_noFontHinting; QFontEngine::SubpixelAntialiasingType m_subpixelType; int m_antialiasingEnabled; QXcbXSettings *m_xSettings; -- cgit v1.2.3