X11 changes for highdpi

Adapt the xcb plugin to work with the new cross-platform
high-DPI scaling.

Fixes for drag and drop is done in a separate change.

Task-number: QTBUG-46615
Change-Id: I29002721169750b9de59edb0f3e9134adabc4855
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
bb10
Paul Olav Tvete 2015-06-22 12:25:33 +02:00
parent fd6821740f
commit ec462b245f
4 changed files with 29 additions and 16 deletions

View File

@ -49,6 +49,7 @@
#include <qdebug.h>
#include <qpainter.h>
#include <qscreen.h>
#include <QtGui/private/qhighdpiscaling_p.h>
#include <qpa/qplatformgraphicsbuffer.h>
#include <algorithm>
@ -365,7 +366,7 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
QSize imageSize = m_image->size();
QRegion clipped = region;
clipped &= QRect(QPoint(), window->size());
clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window));
clipped &= QRect(0, 0, imageSize.width(), imageSize.height()).translated(-offset);
QRect bounds = clipped.boundingRect();

View File

@ -44,6 +44,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <private/qmath_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@ -86,6 +87,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_orientation(Qt::PrimaryOrientation)
, m_refreshRate(60)
, m_forcedDpi(-1)
, m_pixelDensity(1)
, m_hintStyle(QFontEngine::HintStyle(-1))
, m_noFontHinting(false)
, m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1))
@ -302,6 +304,11 @@ QDpi QXcbScreen::logicalDpi() const
return virtualDpi();
}
qreal QXcbScreen::pixelDensity() const
{
return m_pixelDensity;
}
QPlatformCursor *QXcbScreen::cursor() const
{
return m_cursor;
@ -457,6 +464,8 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
}
free(workArea);
qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4);
m_pixelDensity = qRound(dpi/96);
m_geometry = QRect(xGeometry.topLeft(), xGeometry.size());
m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size());
m_availableGeometry = QRect(xAvailableGeometry.topLeft(), xAvailableGeometry.size());

View File

@ -96,6 +96,7 @@ public:
QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; }
QDpi virtualDpi() const;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
qreal pixelDensity() const Q_DECL_OVERRIDE;
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
qreal refreshRate() const Q_DECL_OVERRIDE { return m_refreshRate; }
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_orientation; }
@ -168,6 +169,7 @@ private:
QXcbCursor *m_cursor;
int m_refreshRate;
int m_forcedDpi;
int m_pixelDensity;
QFontEngine::HintStyle m_hintStyle;
bool m_noFontHinting;
QFontEngine::SubpixelAntialiasingType m_subpixelType;

View File

@ -37,6 +37,7 @@
#include <QScreen>
#include <QtGui/QIcon>
#include <QtGui/QRegion>
#include <QtGui/private/qhighdpiscaling_p.h>
#include "qxcbintegration.h"
#include "qxcbconnection.h"
@ -320,7 +321,7 @@ void QXcbWindow::create()
Qt::WindowType type = window()->type();
QXcbScreen *currentScreen = xcbScreen();
QRect rect = window()->geometry();
QRect rect = windowGeometry();
QXcbScreen *platformScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
m_xcbScreen = platformScreen;
@ -363,15 +364,15 @@ void QXcbWindow::create()
if (platformScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
QSize minimumSize = window()->minimumSize();
const QSize minimumSize = windowMinimumSize();
if (rect.width() > 0 || rect.height() > 0) {
rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
rect.setHeight(qBound(1, rect.height(), XCOORD_MAX));
} else if (minimumSize.width() > 0 || minimumSize.height() > 0) {
rect.setSize(minimumSize);
} else {
rect.setWidth(defaultWindowWidth);
rect.setHeight(defaultWindowHeight);
rect.setWidth(QHighDpi::toNativePixels(int(defaultWindowWidth), platformScreen->QPlatformScreen::screen()));
rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen()));
}
xcb_window_t xcb_parent_id = platformScreen->root();
@ -641,11 +642,11 @@ void QXcbWindow::setGeometry(const QRect &rect)
propagateSizeHints();
QXcbScreen *currentScreen = xcbScreen();
QXcbScreen *currentScreen = m_xcbScreen;
QXcbScreen *newScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
if (!newScreen)
newScreen = currentScreen;
newScreen = xcbScreen();
m_xcbScreen = newScreen;
const QRect wmGeometry = windowToWmGeometry(rect);
@ -1260,7 +1261,7 @@ void QXcbWindow::updateMotifWmHintsBeforeMap()
mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
}
if (window()->minimumSize() == window()->maximumSize()) {
if (windowMinimumSize() == windowMaximumSize()) {
// fixed size, remove the resize handle (since mwm/dtwm
// isn't smart enough to do it itself)
mwmhints.flags |= MWM_HINTS_FUNCTIONS;
@ -1556,10 +1557,10 @@ void QXcbWindow::propagateSizeHints()
xcb_size_hints_set_size(&hints, true, xRect.width(), xRect.height());
xcb_size_hints_set_win_gravity(&hints, m_gravity);
QSize minimumSize = window()->minimumSize();
QSize maximumSize = window()->maximumSize();
QSize baseSize = window()->baseSize();
QSize sizeIncrement = window()->sizeIncrement();
QSize minimumSize = windowMinimumSize();
QSize maximumSize = windowMaximumSize();
QSize baseSize = windowBaseSize();
QSize sizeIncrement = windowSizeIncrement();
if (minimumSize.width() > 0 || minimumSize.height() > 0)
xcb_size_hints_set_min_size(&hints,
@ -1951,13 +1952,13 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
}
#ifndef QT_NO_DRAGANDDROP
} else if (event->type == atom(QXcbAtom::XdndEnter)) {
connection()->drag()->handleEnter(window(), event);
connection()->drag()->handleEnter(this, event);
} else if (event->type == atom(QXcbAtom::XdndPosition)) {
connection()->drag()->handlePosition(window(), event);
connection()->drag()->handlePosition(this, event);
} else if (event->type == atom(QXcbAtom::XdndLeave)) {
connection()->drag()->handleLeave(window(), event);
connection()->drag()->handleLeave(this, event);
} else if (event->type == atom(QXcbAtom::XdndDrop)) {
connection()->drag()->handleDrop(window(), event);
connection()->drag()->handleDrop(this, event);
#endif
} else if (event->type == atom(QXcbAtom::_XEMBED)) {
handleXEmbedMessage(event);