summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/kernel.pri8
-rw-r--r--src/gui/kernel/qcursor.cpp18
-rw-r--r--src/gui/kernel/qdnd.cpp8
-rw-r--r--src/gui/kernel/qevent.cpp62
-rw-r--r--src/gui/kernel/qevent.h13
-rw-r--r--src/gui/kernel/qgenericplugin.h2
-rw-r--r--src/gui/kernel/qguiapplication.cpp196
-rw-r--r--src/gui/kernel/qguiapplication.h2
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/gui/kernel/qguivariant.cpp9
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp423
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h514
-rw-r--r--src/gui/kernel/qinputmethod.cpp3
-rw-r--r--src/gui/kernel/qinputmethod.h2
-rw-r--r--src/gui/kernel/qkeymapper_p.h1
-rw-r--r--src/gui/kernel/qkeysequence.cpp82
-rw-r--r--src/gui/kernel/qkeysequence.h15
-rw-r--r--src/gui/kernel/qkeysequence_p.h13
-rw-r--r--src/gui/kernel/qoffscreensurface.h2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp54
-rw-r--r--src/gui/kernel/qopenglcontext.h9
-rw-r--r--src/gui/kernel/qopenglcontext_p.h2
-rw-r--r--src/gui/kernel/qopenglwindow.cpp5
-rw-r--r--src/gui/kernel/qopenglwindow.h4
-rw-r--r--src/gui/kernel/qpaintdevicewindow.cpp6
-rw-r--r--src/gui/kernel/qpaintdevicewindow_p.h11
-rw-r--r--src/gui/kernel/qplatformcursor.cpp2
-rw-r--r--src/gui/kernel/qplatformcursor.h2
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp19
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h25
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp92
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.h4
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory.cpp46
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory_p.h1
-rw-r--r--src/gui/kernel/qplatformintegration.cpp48
-rw-r--r--src/gui/kernel/qplatformintegration.h7
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp7
-rw-r--r--src/gui/kernel/qplatformmenu.h2
-rw-r--r--src/gui/kernel/qplatformscreen.cpp85
-rw-r--r--src/gui/kernel/qplatformscreen.h17
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.h2
-rw-r--r--src/gui/kernel/qplatformtheme.cpp4
-rw-r--r--src/gui/kernel/qplatformtheme.h2
-rw-r--r--src/gui/kernel/qplatformthemefactory.cpp4
-rw-r--r--src/gui/kernel/qplatformwindow.cpp131
-rw-r--r--src/gui/kernel/qplatformwindow.h15
-rw-r--r--src/gui/kernel/qrasterwindow.cpp2
-rw-r--r--src/gui/kernel/qrasterwindow.h2
-rw-r--r--src/gui/kernel/qscreen.cpp85
-rw-r--r--src/gui/kernel/qscreen.h8
-rw-r--r--src/gui/kernel/qscreen_p.h25
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow.cpp17
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow_p.h4
-rw-r--r--src/gui/kernel/qshortcutmap.cpp69
-rw-r--r--src/gui/kernel/qshortcutmap_p.h5
-rw-r--r--src/gui/kernel/qsimpledrag.cpp85
-rw-r--r--src/gui/kernel/qsimpledrag_p.h16
-rw-r--r--src/gui/kernel/qstylehints.cpp18
-rw-r--r--src/gui/kernel/qstylehints.h2
-rw-r--r--src/gui/kernel/qtouchdevice.cpp25
-rw-r--r--src/gui/kernel/qtouchdevice_p.h6
-rw-r--r--src/gui/kernel/qwindow.cpp164
-rw-r--r--src/gui/kernel/qwindow.h13
-rw-r--r--src/gui/kernel/qwindow_p.h3
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp422
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h35
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h30
67 files changed, 2410 insertions, 607 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index af6a417608..73a5a7b6ab 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -75,7 +75,9 @@ HEADERS += \
kernel/qplatformgraphicsbuffer.h \
kernel/qplatformgraphicsbufferhelper.h \
kernel/qinputdevicemanager_p.h \
- kernel/qinputdevicemanager_p_p.h
+ kernel/qinputdevicemanager_p_p.h \
+ kernel/qhighdpiscaling_p.h
+
SOURCES += \
kernel/qgenericpluginfactory.cpp \
@@ -131,7 +133,9 @@ SOURCES += \
kernel/qrasterwindow.cpp \
kernel/qplatformgraphicsbuffer.cpp \
kernel/qplatformgraphicsbufferhelper.cpp \
- kernel/qinputdevicemanager.cpp
+ kernel/qinputdevicemanager.cpp \
+ kernel/qhighdpiscaling.cpp
+
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 6b01952647..c25f3c2665 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -43,6 +43,7 @@
#include <qpa/qplatformcursor.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -177,9 +178,14 @@ QT_BEGIN_NAMESPACE
*/
QPoint QCursor::pos(const QScreen *screen)
{
- if (screen)
- if (const QPlatformCursor *cursor = screen->handle()->cursor())
- return cursor->pos();
+ if (screen) {
+ if (const QPlatformCursor *cursor = screen->handle()->cursor()) {
+ const QPlatformScreen *ps = screen->handle();
+ QPoint nativePos = cursor->pos();
+ ps = ps->screenForPosition(nativePos);
+ return QHighDpi::fromNativePixels(nativePos, ps->screen());
+ }
+ }
return QGuiApplicationPrivate::lastCursorPosition.toPoint();
}
@@ -231,12 +237,12 @@ void QCursor::setPos(QScreen *screen, int x, int y)
{
if (screen) {
if (QPlatformCursor *cursor = screen->handle()->cursor()) {
- const QPoint pos = QPoint(x, y);
+ const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
// Need to check, since some X servers generate null mouse move
// events, causing looping in applications which call setPos() on
// every mouse move event.
- if (pos != cursor->pos())
- cursor->setPos(pos);
+ if (devicePos != cursor->pos())
+ cursor->setPos(devicePos);
}
}
}
diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp
index 3ce8ab95ec..b05da1bfd0 100644
--- a/src/gui/kernel/qdnd.cpp
+++ b/src/gui/kernel/qdnd.cpp
@@ -147,7 +147,9 @@ static QStringList imageReadMimeFormats()
{
QStringList formats;
QList<QByteArray> imageFormats = QImageReader::supportedImageFormats();
- for (int i = 0; i < imageFormats.size(); ++i) {
+ const int numImageFormats = imageFormats.size();
+ formats.reserve(numImageFormats);
+ for (int i = 0; i < numImageFormats; ++i) {
QString format = QLatin1String("image/");
format += QString::fromLatin1(imageFormats.at(i).toLower());
formats.append(format);
@@ -166,7 +168,9 @@ static QStringList imageWriteMimeFormats()
{
QStringList formats;
QList<QByteArray> imageFormats = QImageWriter::supportedImageFormats();
- for (int i = 0; i < imageFormats.size(); ++i) {
+ const int numImageFormats = imageFormats.size();
+ formats.reserve(numImageFormats);
+ for (int i = 0; i < numImageFormats; ++i) {
QString format = QLatin1String("image/");
format += QString::fromLatin1(imageFormats.at(i).toLower());
formats.append(format);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index c231c47576..2ca17692db 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -171,6 +171,8 @@ QInputEvent::~QInputEvent()
\fn ulong QInputEvent::timestamp() const
Returns the window system's timestamp for this event.
+ It will normally be in milliseconds since some arbitrary point
+ in time, such as the time when the system was started.
*/
/*! \fn void QInputEvent::setTimestamp(ulong atimestamp)
@@ -309,6 +311,36 @@ QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, const QPointF &wind
{}
/*!
+ \since 5.6
+
+ Constructs a mouse event object.
+
+ The \a type parameter must be QEvent::MouseButtonPress,
+ QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick,
+ or QEvent::MouseMove.
+
+ The points \a localPos, \a windowPos and \a screenPos specify the
+ mouse cursor's position relative to the receiving widget or item,
+ window, and screen, respectively.
+
+ The \a button that caused the event is given as a value from the
+ \l Qt::MouseButton enum. If the event \a type is \l MouseMove,
+ the appropriate button for this event is Qt::NoButton. \a buttons
+ is the state of all buttons at the time of the event, \a modifiers
+ is the state of all keyboard modifiers.
+
+ The source of the event is specified by \a source.
+
+*/
+QMouseEvent::QMouseEvent(QEvent::Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos,
+ Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source)
+ : QInputEvent(type, modifiers), l(localPos), w(windowPos), s(screenPos), b(button), mouseState(buttons), caps(0)
+{
+ QGuiApplicationPrivate::setMouseEventSource(this, source);
+}
+
+/*!
\internal
*/
QMouseEvent::~QMouseEvent()
@@ -997,8 +1029,10 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
when keys are pressed or released.
A key event contains a special accept flag that indicates whether
- the receiver will handle the key event. This flag is set by default,
- so there is no need to call accept() when acting on a key event.
+ the receiver will handle the key event. This flag is set by default
+ for QEvent::KeyPress and QEvent::KeyRelease, so there is no need to
+ call accept() when acting on a key event. For QEvent::ShortcutOverride
+ the receiver needs to explicitly accept the event to trigger the override.
Calling ignore() on a key event will propagate it to the parent widget.
The event is propagated up the parent widget chain until a widget
accepts it or an event filter consumes it.
@@ -1033,6 +1067,8 @@ QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const
nScanCode(0), nVirtualKey(0), nModifiers(0),
c(count), autor(autorep)
{
+ if (type == QEvent::ShortcutOverride)
+ ignore();
}
/*!
@@ -1060,6 +1096,8 @@ QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers,
nScanCode(nativeScanCode), nVirtualKey(nativeVirtualKey), nModifiers(nativeModifiers),
c(count), autor(autorep)
{
+ if (type == QEvent::ShortcutOverride)
+ ignore();
}
@@ -1987,6 +2025,11 @@ QInputMethodEvent::QInputMethodEvent(const QInputMethodEvent &other)
{
}
+QInputMethodEvent::~QInputMethodEvent()
+{
+ // must be empty until ### Qt 6
+}
+
/*!
Sets the commit string to \a commitString.
@@ -3374,6 +3417,21 @@ QShowEvent::~QShowEvent()
It may be safely ignored.
\note This class is currently supported for OS X only.
+
+ \section1 OS X Example
+
+ In order to trigger the event on OS X, the application must be configured
+ to let the OS know what kind of file(s) it should react on.
+
+ For example, the following \c Info.plist file declares that the application
+ can act as a viewer for files with a PNG extension:
+
+ \snippet qfileopenevent/Info.plist Custom Info.plist
+
+ The following implementation of a QApplication subclass prints the path to
+ the file that was, for example, dropped on the Dock icon of the application.
+
+ \snippet qfileopenevent/main.cpp QApplication subclass
*/
/*!
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index a1f32026ac..b90fce97e0 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -106,6 +106,9 @@ public:
QMouseEvent(Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers);
+ QMouseEvent(Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos,
+ Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source);
~QMouseEvent();
#ifndef QT_NO_INTEGER_EVENT_COORDINATES
@@ -519,7 +522,7 @@ public:
};
class Attribute {
public:
- Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(val) {}
+ Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(qMove(val)) {}
AttributeType type;
int start;
@@ -528,6 +531,8 @@ public:
};
QInputMethodEvent();
QInputMethodEvent(const QString &preeditText, const QList<Attribute> &attributes);
+ ~QInputMethodEvent();
+
void setCommitString(const QString &commitString, int replaceFrom = 0, int replaceLength = 0);
inline const QList<Attribute> &attributes() const { return attrs; }
inline const QString &preeditString() const { return preedit; }
@@ -694,7 +699,7 @@ class Q_GUI_EXPORT QActionEvent : public QEvent
{
QAction *act, *bef;
public:
- QActionEvent(int type, QAction *action, QAction *before = 0);
+ QActionEvent(int type, QAction *action, QAction *before = Q_NULLPTR);
~QActionEvent();
inline QAction *action() const { return act; }
@@ -871,9 +876,9 @@ public:
#endif
explicit QTouchEvent(QEvent::Type eventType,
- QTouchDevice *device = 0,
+ QTouchDevice *device = Q_NULLPTR,
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
- Qt::TouchPointStates touchPointStates = 0,
+ Qt::TouchPointStates touchPointStates = Qt::TouchPointStates(),
const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>());
~QTouchEvent();
diff --git a/src/gui/kernel/qgenericplugin.h b/src/gui/kernel/qgenericplugin.h
index cfab34d081..03c1df7fba 100644
--- a/src/gui/kernel/qgenericplugin.h
+++ b/src/gui/kernel/qgenericplugin.h
@@ -48,7 +48,7 @@ class Q_GUI_EXPORT QGenericPlugin : public QObject
{
Q_OBJECT
public:
- explicit QGenericPlugin(QObject *parent = 0);
+ explicit QGenericPlugin(QObject *parent = Q_NULLPTR);
~QGenericPlugin();
virtual QObject* create(const QString& name, const QString &spec) = 0;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index c2b561aa93..0f015af2b9 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -99,6 +99,9 @@
#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
# include <QtCore/qt_windows.h>
# include <QtCore/QLibraryInfo>
+# if defined(Q_OS_WINPHONE)
+# include <Objbase.h>
+# endif
#endif // Q_OS_WIN && !Q_OS_WINCE
#include <ctype.h>
@@ -124,8 +127,12 @@ Qt::MouseButtons QGuiApplicationPrivate::tabletState = Qt::NoButton;
QWindow *QGuiApplicationPrivate::tabletPressTarget = 0;
QWindow *QGuiApplicationPrivate::currentMouseWindow = 0;
+QString QGuiApplicationPrivate::styleOverride;
+
Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive;
+bool QGuiApplicationPrivate::highDpiScalingUpdated = false;
+
QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0;
@@ -156,7 +163,7 @@ int QGuiApplicationPrivate::mouse_double_click_distance = -1;
QWindow *QGuiApplicationPrivate::currentMousePressWindow = 0;
-static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
+static Qt::LayoutDirection layout_direction = Qt::LayoutDirectionAuto;
static bool force_reverse = false;
QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
@@ -185,9 +192,6 @@ extern void qRegisterGuiVariant();
#ifndef QT_NO_ANIMATION
extern void qRegisterGuiGetInterpolator();
#endif
-extern void qInitBlendFunctions();
-extern void qInitDrawhelperAsm();
-extern void qInitImageConversions();
static bool qt_detectRTLLanguage()
{
@@ -869,7 +873,7 @@ QWindowList QGuiApplication::topLevelWindows()
if (!list.at(i)->parent() && list.at(i)->type() != Qt::Desktop) {
// Top windows of embedded QAxServers do not have QWindow parents,
// but they are not true top level windows, so do not include them.
- const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded(0);
+ const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded();
if (!embedded)
topLevelWindows.prepend(list.at(i));
}
@@ -877,16 +881,6 @@ QWindowList QGuiApplication::topLevelWindows()
return topLevelWindows;
}
-/*!
- Returns the primary (or default) screen of the application, or null if there is none
-
- This will be the screen where QWindows are initially shown, unless otherwise specified.
-
- On some platforms, it may be null when there are actually no screens connected.
- It is not possible to start a new QGuiApplication while there are no screens.
- Applications which were running at the time the primary screen was removed
- will stop rendering graphics until one or more screens are restored.
-*/
QScreen *QGuiApplication::primaryScreen()
{
if (QGuiApplicationPrivate::screen_list.isEmpty())
@@ -908,7 +902,7 @@ QList<QScreen *> QGuiApplication::screens()
This signal is emitted whenever a new screen \a screen has been added to the system.
- \sa screens(), primaryScreen(), screenRemoved()
+ \sa screens(), primaryScreen, screenRemoved()
*/
/*!
@@ -925,6 +919,23 @@ QList<QScreen *> QGuiApplication::screens()
/*!
+ \property QGuiApplication::primaryScreen
+
+ \brief the primary (or default) screen of the application, or null if there is none.
+
+ This will be the screen where QWindows are initially shown, unless otherwise specified.
+
+ On some platforms, it may be null when there are actually no screens connected.
+ It is not possible to start a new QGuiApplication while there are no screens.
+ Applications which were running at the time the primary screen was removed
+ will stop rendering graphics until one or more screens are restored.
+
+ The primaryScreenChanged signal was introduced in Qt 5.6.
+
+ \sa screens()
+*/
+
+/*!
Returns the highest screen device pixel ratio found on
the system. This is the ratio between physical pixels and
device-independent pixels.
@@ -955,16 +966,38 @@ qreal QGuiApplication::devicePixelRatio() const
*/
QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
{
- QList<QScreen *> screens = QGuiApplication::screens();
- QList<QScreen *>::const_iterator screen = screens.constBegin();
- QList<QScreen *>::const_iterator end = screens.constEnd();
+ const QList<QScreen *> screens = QGuiApplication::screens();
+ if (!screens.isEmpty()) {
+ const QList<QScreen *> primaryScreens = screens.first()->virtualSiblings();
+ QScreen *windowScreen = Q_NULLPTR;
+
+ // Find the window on the primary virtual desktop first
+ foreach (QScreen *screen, primaryScreens) {
+ if (screen->geometry().contains(pos)) {
+ windowScreen = screen;
+ break;
+ }
+ }
- while (screen != end) {
- if ((*screen)->geometry().contains(pos))
- return (*screen)->handle()->topLevelAt(pos);
- ++screen;
+ // If the window is not found on primary virtual desktop, find it on all screens
+ // except the first which was for sure in the previous loop. Some other screens
+ // may repeat. Find only when there is more than one virtual desktop.
+ if (!windowScreen && screens.count() != primaryScreens.count()) {
+ for (int i = 1; i < screens.size(); ++i) {
+ QScreen *screen = screens[i];
+ if (screen->geometry().contains(pos)) {
+ windowScreen = screen;
+ break;
+ }
+ }
+ }
+
+ if (windowScreen) {
+ const QPoint devicePosition = QHighDpi::toNativePixels(pos, windowScreen);
+ return windowScreen->handle()->topLevelAt(devicePosition);
+ }
}
- return 0;
+ return Q_NULLPTR;
}
/*!
@@ -1041,6 +1074,13 @@ static void init_platform(const QString &pluginArgument, const QString &platform
return;
}
+ // Many platforms have created QScreens at this point. Finish initializing
+ // QHighDpiScaling to be prepared for early calls to qt_defaultDpi().
+ if (QGuiApplication::primaryScreen()) {
+ QGuiApplicationPrivate::highDpiScalingUpdated = true;
+ QHighDpiScaling::updateHighDpiScaling();
+ }
+
// Create the platform theme:
// 1) Fetch the platform name from the environment if present.
@@ -1117,6 +1157,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
// this flag.
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+
+ QHighDpiScaling::initHighDpiScaling();
+
// Load the platform integration
QString platformPluginPath = QString::fromLocal8Bit(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
@@ -1206,6 +1249,11 @@ void QGuiApplicationPrivate::eventDispatcherReady()
createPlatformIntegration();
platform_integration->initialize();
+
+ // All platforms should have added screens at this point. Finish
+ // QHighDpiScaling initialization if it has not been done so already.
+ if (!QGuiApplicationPrivate::highDpiScalingUpdated)
+ QHighDpiScaling::updateHighDpiScaling();
}
void QGuiApplicationPrivate::init()
@@ -1218,7 +1266,18 @@ void QGuiApplicationPrivate::init()
#ifndef QT_NO_SESSIONMANAGER
QString session_id;
QString session_key;
+# if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ wchar_t guidstr[40];
+ GUID guid;
+ CoCreateGuid(&guid);
+ StringFromGUID2(guid, guidstr, 40);
+ session_id = QString::fromWCharArray(guidstr);
+ CoCreateGuid(&guid);
+ StringFromGUID2(guid, guidstr, 40);
+ session_key = QString::fromWCharArray(guidstr);
+# endif
#endif
+ QString s;
int j = argc ? 1 : 0;
for (int i=1; i<argc; i++) {
if (argv[i] && *argv[i] != '-') {
@@ -1233,7 +1292,6 @@ void QGuiApplicationPrivate::init()
pluginList << argv[i];
} else if (arg == "-reverse") {
force_reverse = true;
- QGuiApplication::setLayoutDirection(Qt::RightToLeft);
#ifdef Q_OS_MAC
} else if (arg.startsWith("-psn_")) {
// eat "-psn_xxxx" on Mac, which is passed when starting an app from Finder.
@@ -1261,9 +1319,16 @@ void QGuiApplicationPrivate::init()
#endif
} else if (arg == "-testability") {
loadTestability = true;
+ } else if (arg.indexOf("-style=", 0) != -1) {
+ s = QString::fromLocal8Bit(arg.right(arg.length() - 7).toLower());
+ } else if (arg == "-style" && i < argc-1) {
+ s = QString::fromLocal8Bit(argv[++i]).toLower();
} else {
argv[j++] = argv[i];
}
+
+ if (!s.isEmpty())
+ styleOverride = s;
}
if (j < argc) {
@@ -1281,13 +1346,6 @@ void QGuiApplicationPrivate::init()
if (platform_integration == 0)
createPlatformIntegration();
- // Set up blend function tables.
- qInitBlendFunctions();
- // Set up which span functions should be used in raster engine...
- qInitDrawhelperAsm();
- // and QImage conversion functions
- qInitImageConversions();
-
initPalette();
QFont::initialize();
@@ -1330,6 +1388,9 @@ void QGuiApplicationPrivate::init()
#endif
#ifndef QT_NO_LIBRARY
+ if (qEnvironmentVariableIntValue("QT_LOAD_TESTABILITY") > 0)
+ loadTestability = true;
+
if (loadTestability) {
QLibrary testLib(QStringLiteral("qttestability"));
if (testLib.load()) {
@@ -1344,7 +1405,12 @@ void QGuiApplicationPrivate::init()
qCritical() << "Library qttestability load failed:" << testLib.errorString();
}
}
+#else
+ Q_UNUSED(loadTestability);
#endif // QT_NO_LIBRARY
+
+ if (layout_direction == Qt::LayoutDirectionAuto || force_reverse)
+ QGuiApplication::setLayoutDirection(qt_detectRTLLanguage() ? Qt::RightToLeft : Qt::LeftToRight);
}
extern void qt_cleanupFontDatabase();
@@ -1693,12 +1759,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
// A mouse event should not change both position and buttons at the same time. Instead we
// should first send a move event followed by a button changed event. Since this is not the case
// with the current event, we split it in two.
- QWindowSystemInterfacePrivate::MouseEvent *mouseButtonEvent = new QWindowSystemInterfacePrivate::MouseEvent(
- e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers);
+ QWindowSystemInterfacePrivate::MouseEvent mouseButtonEvent(
+ e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers, e->source);
if (e->flags & QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic)
- mouseButtonEvent->flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
- QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(mouseButtonEvent);
- stateChange = Qt::NoButton;
+ mouseButtonEvent.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
+ e->buttons = buttons;
+ processMouseEvent(e);
+ processMouseEvent(&mouseButtonEvent);
+ return;
}
QWindow *window = e->window.data();
@@ -1767,17 +1835,23 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!window)
return;
- QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
- ev.setTimestamp(e->timestamp);
- setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
if (!e->synthetic()) {
if (const QScreen *screen = window->screen())
- if (QPlatformCursor *cursor = screen->handle()->cursor())
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+ const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, screen);
+ const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen);
+ QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint,
+ button, buttons, e->modifiers, e->source);
+ ev.setTimestamp(e->timestamp);
cursor->pointerEvent(ev);
+ }
}
#endif
+ QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source);
+ ev.setTimestamp(e->timestamp);
+
if (window->d_func()->blockedByModalWindow) {
// a modal window is blocking this window, don't allow mouse events through
return;
@@ -1789,6 +1863,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
}
QGuiApplication::sendSpontaneousEvent(window, &ev);
+ e->eventAccepted = ev.isAccepted();
if (!e->synthetic() && !ev.isAccepted()
&& !frameStrut
&& qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) {
@@ -1817,7 +1892,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
points << point;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type);
QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
@@ -1828,9 +1903,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!e->window.isNull() || e->nullWindow()) { // QTBUG-36364, check if window closed in response to press
const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
- button, buttons, e->modifiers);
+ button, buttons, e->modifiers, e->source);
dblClickEvent.setTimestamp(e->timestamp);
- setMouseEventSource(&dblClickEvent, e->source);
QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
}
}
@@ -1882,19 +1956,6 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
window = QGuiApplication::focusWindow();
}
-#if !defined(Q_OS_OSX)
- // On OS X the shortcut override is checked earlier, see: QWindowSystemInterface::handleKeyEvent()
- const bool checkShortcut = e->keyType == QEvent::KeyPress && window != 0;
- if (checkShortcut) {
- QKeyEvent override(QEvent::ShortcutOverride, e->key, e->modifiers,
- e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
- e->unicode, e->repeat, e->repeatCount);
- override.setTimestamp(e->timestamp);
- if (QWindowSystemInterface::tryHandleShortcutOverrideEvent(window, &override))
- return;
- }
-#endif // Q_OS_OSX
-
QKeyEvent ev(e->keyType, e->key, e->modifiers,
e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
e->unicode, e->repeat, e->repeatCount);
@@ -1922,6 +1983,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
}
}
#endif
+ e->eventAccepted = ev.isAccepted();
}
void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
@@ -2030,10 +2092,17 @@ void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfa
void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *wse)
{
if (QWindow *window = wse->window.data()) {
- if (QScreen *screen = wse->screen.data())
- window->d_func()->setTopLevelScreen(screen, false /* recreate */);
- else // Fall back to default behavior, and try to find some appropriate screen
- window->setScreen(0);
+ if (window->isTopLevel()) {
+ if (QScreen *screen = wse->screen.data())
+ window->d_func()->setTopLevelScreen(screen, false /* recreate */);
+ else // Fall back to default behavior, and try to find some appropriate screen
+ window->setScreen(0);
+ }
+ // we may have changed scaling, so trigger resize event if needed
+ if (window->handle()) {
+ QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect());
+ processGeometryChangeEvent(&gce);
+ }
}
}
@@ -3201,7 +3270,10 @@ void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
Qt::LayoutDirection QGuiApplication::layoutDirection()
{
- return layout_direction;
+ // layout_direction is only ever Qt::LayoutDirectionAuto if setLayoutDirection
+ // was never called, or called with Qt::LayoutDirectionAuto (which is a no-op).
+ // In that case we return the default LeftToRight.
+ return layout_direction == Qt::LayoutDirectionAuto ? Qt::LeftToRight : layout_direction;
}
/*!
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index c89268d8d4..d995387d66 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -70,6 +70,7 @@ class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(QString platformName READ platformName STORED false)
Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed)
+ Q_PROPERTY(QScreen *primaryScreen READ primaryScreen NOTIFY primaryScreenChanged STORED false)
public:
#ifdef Q_QDOC
@@ -158,6 +159,7 @@ Q_SIGNALS:
void fontDatabaseChanged();
void screenAdded(QScreen *screen);
void screenRemoved(QScreen *screen);
+ void primaryScreenChanged(QScreen *screen);
void lastWindowClosed();
void focusObjectChanged(QObject *focusObject);
void focusWindowChanged(QWindow *focusWindow);
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 0559442049..7c7da9790b 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -202,6 +202,7 @@ public:
static QWindow *currentMouseWindow;
static QWindow *currentMousePressWindow;
static Qt::ApplicationState applicationState;
+ static bool highDpiScalingUpdated;
#ifndef QT_NO_CLIPBOARD
static QClipboard *qt_clipboard;
@@ -219,6 +220,7 @@ public:
static QFont *app_font;
+ static QString styleOverride;
static QStyleHints *styleHints;
static bool obey_desktop_settings;
QInputMethod *inputMethod;
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index ce4a0ec09e..a0769ca671 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -175,7 +175,8 @@ static bool convert(const QVariant::Private *d, int t,
switch (t) {
case QVariant::ByteArray:
if (d->type == QVariant::Color) {
- *static_cast<QByteArray *>(result) = v_cast<QColor>(d)->name().toLatin1();
+ const QColor *c = v_cast<QColor>(d);
+ *static_cast<QByteArray *>(result) = c->name(c->alpha() != 255 ? QColor::HexArgb : QColor::HexRgb).toLatin1();
return true;
}
break;
@@ -190,9 +191,11 @@ static bool convert(const QVariant::Private *d, int t,
case QVariant::Font:
*str = v_cast<QFont>(d)->toString();
return true;
- case QVariant::Color:
- *str = v_cast<QColor>(d)->name();
+ case QVariant::Color: {
+ const QColor *c = v_cast<QColor>(d);
+ *str = c->name(c->alpha() != 255 ? QColor::HexArgb : QColor::HexRgb);
return true;
+ }
default:
break;
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
new file mode 100644
index 0000000000..b0ef2a284f
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhighdpiscaling_p.h"
+#include "qguiapplication.h"
+#include "qscreen.h"
+#include "qplatformintegration.h"
+#include "private/qscreen_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcScaling, "qt.scaling");
+
+#ifndef QT_NO_HIGHDPISCALING
+static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
+static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR";
+static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR";
+static const char screenFactorsEnvVar[] = "QT_SCREEN_SCALE_FACTORS";
+
+static inline qreal initialGlobalScaleFactor()
+{
+
+ qreal result = 1;
+ if (qEnvironmentVariableIsSet(scaleFactorEnvVar)) {
+ bool ok;
+ const qreal f = qgetenv(scaleFactorEnvVar).toDouble(&ok);
+ if (ok && f > 0) {
+ qCDebug(lcScaling) << "Apply " << scaleFactorEnvVar << f;
+ result = f;
+ }
+ } else {
+ if (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar)) {
+ qWarning() << "Warning:" << legacyDevicePixelEnvVar << "is deprecated. Instead use:" << endl
+ << " " << autoScreenEnvVar << "to enable platform plugin controlled per-screen factors." << endl
+ << " " << screenFactorsEnvVar << "to set per-screen factors." << endl
+ << " " << scaleFactorEnvVar << "to set the application global scale factor.";
+
+ int dpr = qEnvironmentVariableIntValue(legacyDevicePixelEnvVar);
+ if (dpr > 0)
+ result = dpr;
+ }
+ }
+ return result;
+}
+
+/*!
+ \class QHighDpiScaling
+ \since 5.6
+ \internal
+ \preliminary
+ \ingroup qpa
+
+ \brief Collection of utility functions for UI scaling.
+
+ QHighDpiScaling implements utility functions for high-dpi scaling for use
+ on operating systems that provide limited support for native scaling. In
+ addition this functionality can be used for simulation and testing purposes.
+
+ The functions support scaling between the device independent coordinate
+ system used by Qt applications and the native coordinate system used by
+ the platform plugins. Intended usage locations are the low level / platform
+ plugin interfacing parts of QtGui, for example the QWindow, QScreen and
+ QWindowSystemInterface implementation.
+
+ There are now up to three active coordinate systems in Qt:
+
+ ---------------------------------------------------
+ | Application Device Independent Pixels | devicePixelRatio
+ | Qt Widgets | =
+ | Qt Gui |
+ |---------------------------------------------------| Qt Scale Factor
+ | Qt Gui QPlatform* Native Pixels | *
+ | Qt platform plugin |
+ |---------------------------------------------------| OS Scale Factor
+ | Display Device Pixels |
+ | (Graphics Buffers) |
+ -----------------------------------------------------
+
+ This is an simplification and shows the main coordinate system. All layers
+ may work with device pixels in specific cases: OpenGL, creating the backing
+ store, and QPixmap management. The "Native Pixels" coordinate system is
+ internal to Qt and should not be exposed to Qt users: Seen from the outside
+ there are only two coordinate systems: device independent pixels and device
+ pixels.
+
+ The devicePixelRatio seen by applications is the product of the Qt scale
+ factor and the OS scale factor. The value of the scale factors may be 1,
+ in which case two or more of the coordinate systems are equivalent. Platforms
+ that (may) have an OS scale factor include OS X, iOS and Wayland.
+
+ Note that the functions in this file do not work with the OS scale factor
+ directly and are limited to converting between device independent and native
+ pixels. The OS scale factor is accunted for by QWindow::devicePixelRatio()
+ and similar functions.
+
+ Configuration Examples:
+
+ 'Classic': Device Independent Pixels = Native Pixels = Device Pixels
+ --------------------------------------------------- devicePixelRatio: 1
+ | Application / Qt Gui 100 x 100 |
+ | | Qt Scale Factor: 1
+ | Qt Platform / OS 100 x 100 |
+ | | OS Scale Factor: 1
+ | Display 100 x 100 |
+ -----------------------------------------------------
+
+ 'Retina Device': Device Independent Pixels = Native Pixels
+ --------------------------------------------------- devicePixelRatio: 2
+ | Application / Qt Gui 100 x 100 |
+ | | Qt Scale Factor: 1
+ | Qt Platform / OS 100 x 100 |
+ |---------------------------------------------------| OS Scale Factor: 2
+ | Display 200 x 200 |
+ -----------------------------------------------------
+
+ '2x Qt Scaling': Native Pixels = Device Pixels
+ --------------------------------------------------- devicePixelRatio: 2
+ | Application / Qt Gui 100 x 100 |
+ |---------------------------------------------------| Qt Scale Factor: 2
+ | Qt Platform / OS 200 x 200 |
+ | | OS Scale Factor: 1
+ | Display 200 x 200 |
+ -----------------------------------------------------
+
+ The Qt Scale Factor is the product of two sub-scale factors, which
+ are independently either set or determined by the platform plugin.
+ Several APIs are offered for this, targeting both developers and
+ end users. All scale factors are of type qreal.
+
+ 1) A global scale factor
+ The QT_SCALE_FACTOR environment variable can be used to set
+ a global scale factor for all windows in the processs. This
+ is useful for testing and debugging (you can simulate any
+ devicePixelRatio without needing access to sepcial hardware),
+ and perhaps also for targeting a specific application to
+ a specific display type (embedded use cases).
+
+ 2) A per-screen scale factors
+ Some platform plugins support providing a per-screen scale
+ factor based on display density information. These platforms
+ include X11, Windows, and Android.
+
+ There are two APIs for enabling or disabling this behavior:
+ - The QT_AUTO_SCREEN_SCALE_FACTOR environment variable.
+ - The AA_EnableHighDpiScaling and AA_DisableHighDpiScaling
+ application attributes
+
+ Enabling either will make QHighDpiScaling call QPlatformScreen::pixelDensity()
+ and use the value provided as the scale factor for the screen in
+ question. Disabling is done on a 'veto' basis where either the
+ environment or the application source can disable. The intended use
+ cases are 'My system is not providing correct display density
+ information' and 'My application needs to work in display pixels',
+ respectively.
+
+ The QT_SCREEN_SCALE_FACTORS environment variable can be used to set the screen
+ scale factors manually.Set this to a semicolon-separated
+ list of scale factors (matching the order of QGuiApplications::screens()),
+ or to a list of name=value pairs (where name matches QScreen::name()).
+
+ Coordinate conversion functions must be used when writing code that passes
+ geometry across the Qt Gui / Platform plugin boundary. The main conversion
+ functions are:
+ T toNativePixels(T, QWindow *)
+ T fromNativePixels(T, QWindow*)
+
+ The following classes in QtGui use native pixels, for the convenience of the
+ plataform plugins:
+ QPlatformWindow
+ QPlatformScreen
+ QWindowSystemInterface (API only - Events are in device independent pixels)
+
+ As a special consideration platform plugin code should be careful about
+ calling QtGui geometry accessor functions:
+ QRect r = window->geometry();
+ Here the returned geometry is in device independent pixels. Add a conversion call:
+ QRect r = QHighDpi::toNativePixels(window->geometry());
+ (Avoiding calling QWindow and instead using the QPlatformWindow geometry
+ might be a better course of action in this case.)
+*/
+
+qreal QHighDpiScaling::m_factor = 1.0;
+bool QHighDpiScaling::m_active = false; //"overall active" - is there any scale factor set.
+bool QHighDpiScaling::m_usePixelDensity = false; // use scale factor from platform plugin
+bool QHighDpiScaling::m_pixelDensityScalingActive = false; // pixel density scale factor > 1
+bool QHighDpiScaling::m_globalScalingActive = false; // global scale factor is active
+bool QHighDpiScaling::m_screenFactorSet = false; // QHighDpiScaling::setScreenFactor has been used
+QDpi QHighDpiScaling::m_logicalDpi = QDpi(-1,-1); // The scaled logical DPI of the primary screen
+
+/*
+ Initializes the QHighDpiScaling global variables. Called before the
+ platform plugin is created.
+*/
+
+static inline bool usePixelDensity()
+{
+ // Determine if we should set a scale factor based on the pixel density
+ // reported by the platform plugin. There are several enablers and several
+ // disablers. A single disable may veto all other enablers.
+ if (QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling))
+ return false;
+ bool screenEnvValueOk;
+ const int screenEnvValue = qEnvironmentVariableIntValue(autoScreenEnvVar, &screenEnvValueOk);
+ if (screenEnvValueOk && screenEnvValue < 1)
+ return false;
+ return QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling)
+ || (screenEnvValueOk && screenEnvValue > 0)
+ || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) && qgetenv(legacyDevicePixelEnvVar).toLower() == "auto");
+}
+
+void QHighDpiScaling::initHighDpiScaling()
+{
+ // Determine if there is a global scale factor set.
+ m_factor = initialGlobalScaleFactor();
+ m_globalScalingActive = !qFuzzyCompare(m_factor, qreal(1));
+
+ m_usePixelDensity = usePixelDensity();
+
+ m_pixelDensityScalingActive = false; //set in updateHighDpiScaling below
+
+ // we update m_active in updateHighDpiScaling, but while we create the
+ // screens, we have to assume that m_usePixelDensity implies scaling
+ m_active = m_globalScalingActive || m_usePixelDensity;
+}
+
+void QHighDpiScaling::updateHighDpiScaling()
+{
+ if (QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling))
+ return;
+
+ if (m_usePixelDensity && !m_pixelDensityScalingActive) {
+ Q_FOREACH (QScreen *screen, QGuiApplication::screens()) {
+ if (!qFuzzyCompare(screenSubfactor(screen->handle()), qreal(1))) {
+ m_pixelDensityScalingActive = true;
+ break;
+ }
+ }
+ }
+ if (qEnvironmentVariableIsSet(screenFactorsEnvVar)) {
+ int i = 0;
+ Q_FOREACH (const QByteArray &spec, qgetenv(screenFactorsEnvVar).split(';')) {
+ QScreen *screen = 0;
+ int equalsPos = spec.lastIndexOf('=');
+ double factor = 0;
+ if (equalsPos > 0) {
+ // support "name=factor"
+ QByteArray name = spec.mid(0, equalsPos);
+ QByteArray f = spec.mid(equalsPos + 1);
+ bool ok;
+ factor = f.toDouble(&ok);
+ if (ok) {
+ Q_FOREACH (QScreen *s, QGuiApplication::screens()) {
+ if (s->name() == QString::fromLocal8Bit(name)) {
+ screen = s;
+ break;
+ }
+ }
+ }
+ } else {
+ // listing screens in order
+ bool ok;
+ factor = spec.toDouble(&ok);
+ if (ok && i < QGuiApplication::screens().count())
+ screen = QGuiApplication::screens().at(i);
+ }
+ if (screen)
+ setScreenFactor(screen, factor);
+ ++i;
+ }
+ }
+ m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
+
+ QPlatformScreen *primaryScreen = QGuiApplication::primaryScreen()->handle();
+ qreal sf = screenSubfactor(primaryScreen);
+ QDpi primaryDpi = primaryScreen->logicalDpi();
+ m_logicalDpi = QDpi(primaryDpi.first / sf, primaryDpi.second / sf);
+}
+
+/*
+ Sets the global scale factor which is applied to all windows.
+*/
+void QHighDpiScaling::setGlobalFactor(qreal factor)
+{
+ if (qFuzzyCompare(factor, m_factor))
+ return;
+ if (!QGuiApplication::allWindows().isEmpty())
+ qWarning("QHighDpiScaling::setFactor: Should only be called when no windows exist.");
+
+ m_globalScalingActive = !qFuzzyCompare(factor, qreal(1));
+ m_factor = m_globalScalingActive ? factor : qreal(1);
+ m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
+ Q_FOREACH (QScreen *screen, QGuiApplication::screens())
+ screen->d_func()->updateHighDpi();
+}
+
+static const char scaleFactorProperty[] = "_q_scaleFactor";
+
+/*
+ Sets a per-screen scale factor.
+*/
+void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+{
+ m_screenFactorSet = true;
+ m_active = true;
+ screen->setProperty(scaleFactorProperty, QVariant(factor));
+
+ // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+ screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
+}
+
+QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) * scaleFactor + topLeft;
+}
+
+QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) / scaleFactor + topLeft;
+}
+
+qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
+{
+ qreal factor = qreal(1.0);
+ if (screen) {
+ if (m_usePixelDensity)
+ factor *= screen->pixelDensity();
+ if (m_screenFactorSet) {
+ QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
+ if (screenFactor.isValid())
+ factor *= screenFactor.toReal();
+ }
+ }
+ return factor;
+}
+
+QDpi QHighDpiScaling::logicalDpi()
+{
+ return m_logicalDpi;
+}
+
+qreal QHighDpiScaling::factor(const QScreen *screen)
+{
+ // Fast path for when scaling in Qt is not used at all.
+ if (!m_active)
+ return qreal(1.0);
+
+ // The effective factor for a given screen is the product of the
+ // screen and global sub-factors
+ qreal factor = m_factor;
+ if (screen)
+ factor *= screenSubfactor(screen->handle());
+ return factor;
+}
+
+qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen)
+{
+ if (!m_active)
+ return qreal(1.0);
+
+ return m_factor * screenSubfactor(platformScreen);
+}
+
+qreal QHighDpiScaling::factor(const QWindow *window)
+{
+ if (!m_active)
+ return qreal(1.0);
+
+ return factor(window ? window->screen() : QGuiApplication::primaryScreen());
+}
+
+QPoint QHighDpiScaling::origin(const QScreen *screen)
+{
+ return screen->geometry().topLeft();
+}
+
+QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
+{
+ return platformScreen->geometry().topLeft();
+}
+
+#endif //QT_NO_HIGHDPISCALING
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
new file mode 100644
index 0000000000..9e33787f53
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -0,0 +1,514 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHIGHDPISCALING_P_H
+#define QHIGHDPISCALING_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qmargins.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtGui/qregion.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qwindow.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcScaling);
+
+class QScreen;
+class QPlatformScreen;
+typedef QPair<qreal, qreal> QDpi;
+
+#ifndef QT_NO_HIGHDPISCALING
+class Q_GUI_EXPORT QHighDpiScaling {
+public:
+ static void initHighDpiScaling();
+ static void updateHighDpiScaling();
+ static void setGlobalFactor(qreal factor);
+ static void setScreenFactor(QScreen *window, qreal factor);
+
+ static bool isActive() { return m_active; }
+ static qreal factor(const QWindow *window);
+ static qreal factor(const QScreen *screen);
+ static qreal factor(const QPlatformScreen *platformScreen);
+ static QPoint origin(const QScreen *screen);
+ static QPoint origin(const QPlatformScreen *platformScreen);
+ static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
+ static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
+ static QDpi logicalDpi();
+
+private:
+ static qreal screenSubfactor(const QPlatformScreen *screen);
+
+ static qreal m_factor;
+ static bool m_active;
+ static bool m_usePixelDensity;
+ static bool m_globalScalingActive;
+ static bool m_pixelDensityScalingActive;
+ static bool m_screenFactorSet;
+ static QDpi m_logicalDpi;
+};
+
+// Coordinate system conversion functions:
+// QHighDpi::fromNativePixels : from physical(screen/backing) to logical pixels
+// QHighDpi::toNativePixels : from logical to physical pixels
+
+namespace QHighDpi {
+
+inline QPointF fromNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin)
+{
+ return (pos - origin) / scaleFactor + origin;
+}
+
+inline QPointF toNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin)
+{
+ return (pos - origin) * scaleFactor + origin;
+}
+
+inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
+{
+ return (pos - origin) / scaleFactor + origin;
+}
+
+inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
+{
+ return (pos - origin) * scaleFactor + origin;
+}
+
+inline QPoint fromNative(const QPoint &pos, qreal scaleFactor)
+{
+ return pos / scaleFactor;
+}
+
+inline QPoint toNative(const QPoint &pos, qreal scaleFactor)
+{
+ return pos * scaleFactor;
+}
+
+inline QSize fromNative(const QSize &size, qreal scaleFactor)
+{
+ return size / scaleFactor; // TODO: should we round up?
+}
+
+inline QSize toNative(const QSize &size, qreal scaleFactor)
+{
+ return size * scaleFactor;
+}
+
+inline QSizeF fromNative(const QSizeF &size, qreal scaleFactor)
+{
+ return size / scaleFactor;
+}
+
+inline QSizeF toNative(const QSizeF &size, qreal scaleFactor)
+{
+ return size * scaleFactor;
+}
+
+inline QRect fromNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
+{
+ return QRect(fromNative(rect.topLeft(), scaleFactor, origin), fromNative(rect.size(), scaleFactor));
+}
+
+inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
+{
+ return QRect(toNative(rect.topLeft(), scaleFactor, origin), toNative(rect.size(), scaleFactor));
+
+}
+
+inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
+{
+ return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin);
+}
+
+inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
+{
+ return QRect(nativeScreenGeometry.topLeft(),
+ fromNative(nativeScreenGeometry.size(), QHighDpiScaling::factor(screen)));
+}
+
+inline QPoint fromNativeLocalPosition(const QPoint &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos / scaleFactor;
+}
+
+inline QPoint toNativeLocalPosition(const QPoint &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos * scaleFactor;
+}
+
+inline QPointF fromNativeLocalPosition(const QPointF &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos / scaleFactor;
+}
+
+inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos * scaleFactor;
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
+ const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
+ const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return fromNativePixels(pixelRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor));
+ }
+}
+
+inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return toNativePixels(pointRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor));
+ }
+}
+
+inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return fromNativePixels(pixelRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
+ }
+}
+
+inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return toNativePixels(pointRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
+ }
+}
+
+inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
+{
+ return pixelSize / QHighDpiScaling::factor(window);
+}
+
+inline QSize toNativePixels(const QSize &pointSize, const QWindow *window)
+{
+ return pointSize * QHighDpiScaling::factor(window);
+}
+
+inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window)
+{
+ return pixelSize / QHighDpiScaling::factor(window);
+}
+
+inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
+{
+ return pointSize * QHighDpiScaling::factor(window);
+}
+
+inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen)
+{
+ return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return fromNativePixels(pixelPoint, window->screen());
+ else
+ return pixelPoint / QHighDpiScaling::factor(window);
+}
+
+inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen)
+{
+ return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return toNativePixels(pointPoint, window->screen());
+ else
+ return pointPoint * QHighDpiScaling::factor(window);
+}
+
+inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen)
+{
+ return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return fromNativePixels(pixelPoint, window->screen());
+ else
+ return pixelPoint / QHighDpiScaling::factor(window);
+}
+
+inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen)
+{
+ return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return toNativePixels(pointPoint, window->screen());
+ else
+ return pointPoint * QHighDpiScaling::factor(window);
+}
+
+inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor,
+ pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor);
+}
+
+inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor,
+ pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor);
+}
+
+inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelRegion;
+
+ qreal scaleFactor = QHighDpiScaling::factor(window);
+ QRegion pointRegion;
+ foreach (const QRect &rect, pixelRegion.rects()) {
+ pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor),
+ fromNative(rect.size(), scaleFactor));
+ }
+ return pointRegion;
+}
+
+inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointRegion;
+
+ qreal scaleFactor = QHighDpiScaling::factor(window);
+ QRegion pixelRegon;
+ foreach (const QRect &rect, pointRegion.rects()) {
+ pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor),
+ toNative(rect.size(), scaleFactor));
+ }
+ return pixelRegon;
+}
+
+// Any T that has operator/()
+template <typename T>
+T fromNativePixels(const T &pixelValue, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValue;
+
+ return pixelValue / QHighDpiScaling::factor(window);
+
+}
+
+ //##### ?????
+template <typename T>
+T fromNativePixels(const T &pixelValue, const QScreen *screen)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValue;
+
+ return pixelValue / QHighDpiScaling::factor(screen);
+
+}
+
+// Any T that has operator*()
+template <typename T>
+T toNativePixels(const T &pointValue, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValue;
+
+ return pointValue * QHighDpiScaling::factor(window);
+}
+
+template <typename T>
+T toNativePixels(const T &pointValue, const QScreen *screen)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValue;
+
+ return pointValue * QHighDpiScaling::factor(screen);
+}
+
+
+// Any QVector<T> where T has operator/()
+template <typename T>
+QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValues;
+
+ QVector<T> pointValues;
+ foreach (const T& pixelValue, pixelValues)
+ pointValues.append(pixelValue / QHighDpiScaling::factor(window));
+ return pointValues;
+}
+
+// Any QVector<T> where T has operator*()
+template <typename T>
+QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValues;
+
+ QVector<T> pixelValues;
+ foreach (const T& pointValue, pointValues)
+ pixelValues.append(pointValue * QHighDpiScaling::factor(window));
+ return pixelValues;
+}
+
+} // namespace QHighDpi
+#else // QT_NO_HIGHDPISCALING
+class Q_GUI_EXPORT QHighDpiScaling {
+public:
+ static inline void initHighDpiScaling() {}
+ static inline void updateHighDpiScaling() {}
+ static inline void setGlobalFactor(qreal) {}
+ static inline void setScreenFactor(QScreen *, qreal) {}
+
+ static inline bool isActive() { return false; }
+ static inline qreal factor(const QWindow *) { return 1.0; }
+ static inline qreal factor(const QScreen *) { return 1.0; }
+ static inline qreal factor(const QPlatformScreen *) { return 1.0; }
+ static inline QPoint origin(const QScreen *) { return QPoint(); }
+ static inline QPoint origin(const QPlatformScreen *) { return QPoint(); }
+ static inline QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
+ static inline QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
+ static inline QDpi logicalDpi() { return QDpi(-1,-1); }
+};
+
+namespace QHighDpi {
+ template <typename T> inline
+ T toNative(const T &value, ...) { return value; }
+ template <typename T> inline
+ T fromNative(const T &value, ...) { return value; }
+
+ template <typename T> inline
+ T fromNativeLocalPosition(const T &value, ...) { return value; }
+ template <typename T> inline
+ T toNativeLocalPosition(const T &value, ...) { return value; }
+
+ template <typename T> inline
+ T fromNativeLocalRegion(const T &value, ...) { return value; }
+ template <typename T> inline
+ T toNativeLocalRegion(const T &value, ...) { return value; }
+
+ template <typename T> inline
+ T fromNativeScreenGeometry(const T &value, ...) { return value; }
+
+ template <typename T, typename U> inline
+ T toNativePixels(const T &value, const U*) {return value;}
+ template <typename T, typename U> inline
+ T fromNativePixels(const T &value, const U*) {return value;}
+}
+#endif // QT_NO_HIGHDPISCALING
+QT_END_NAMESPACE
+
+#endif // QHIGHDPISCALING_P_H
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp
index 8d51be853a..2684c43518 100644
--- a/src/gui/kernel/qinputmethod.cpp
+++ b/src/gui/kernel/qinputmethod.cpp
@@ -147,6 +147,9 @@ QRectF QInputMethod::cursorRectangle() const
/*!
\property QInputMethod::keyboardRectangle
\brief Virtual keyboard's geometry in window coordinates.
+
+ This might be an empty rectangle if it is not possible to know the geometry
+ of the keyboard. This is the case for a floating keyboard on android.
*/
QRectF QInputMethod::keyboardRectangle() const
{
diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h
index 3e801bff3c..d7a7b1db8a 100644
--- a/src/gui/kernel/qinputmethod.h
+++ b/src/gui/kernel/qinputmethod.h
@@ -82,7 +82,7 @@ public:
QLocale locale() const;
Qt::LayoutDirection inputDirection() const;
- static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument);
+ static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument); // ### Qt 6: QVariant by const-ref
public Q_SLOTS:
void show();
diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h
index 20dcbbc139..34003cdf41 100644
--- a/src/gui/kernel/qkeymapper_p.h
+++ b/src/gui/kernel/qkeymapper_p.h
@@ -50,7 +50,6 @@
#include <qlist.h>
#include <qlocale.h>
#include <qevent.h>
-#include <qhash.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 5bf22b9394..881d7cc76a 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -39,6 +39,7 @@
#ifndef QT_NO_SHORTCUT
#include "qdebug.h"
+#include <QtCore/qhashfunctions.h>
#ifndef QT_NO_REGEXP
# include "qregexp.h"
#endif
@@ -290,6 +291,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter
\row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter, Meta+O \li Shift+Enter \li Shift+Enter
\row \li Backspace \li (none) \li Meta+H \li (none) \li (none)
+ \row \li Cancel \li Escape \li Escape, Ctrl+. \li Escape \li Escape
\endtable
Note that, since the key sequences used for the standard shortcuts differ
@@ -751,6 +753,7 @@ static const struct {
\value ZoomIn Zoom in.
\value ZoomOut Zoom out.
\value FullScreen Toggle the window state to/from full screen.
+ \value Cancel Cancel the current operation.
*/
/*!
@@ -818,6 +821,7 @@ QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat form
assign(key, format);
}
+Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs and ctor impl below");
/*!
Constructs a key sequence with up to 4 keys \a k1, \a k2,
\a k3 and \a k4.
@@ -876,26 +880,19 @@ QKeySequence::~QKeySequence()
void QKeySequence::setKey(int key, int index)
{
- Q_ASSERT_X(index >= 0 && index < 4, "QKeySequence::setKey", "index out of range");
+ Q_ASSERT_X(index >= 0 && index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::setKey", "index out of range");
qAtomicDetach(d);
d->key[index] = key;
}
+Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs below");
/*!
Returns the number of keys in the key sequence.
The maximum is 4.
*/
int QKeySequence::count() const
{
- if (!d->key[0])
- return 0;
- if (!d->key[1])
- return 1;
- if (!d->key[2])
- return 2;
- if (!d->key[3])
- return 3;
- return 4;
+ return int(std::distance(d->key, std::find(d->key, d->key + QKeySequencePrivate::MaxKeyCount, 0)));
}
@@ -987,8 +984,8 @@ int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format)
int p = 0, diff = 0;
// Run through the whole string, but stop
- // if we have 4 keys before the end.
- while (keyseq.length() && n < 4) {
+ // if we have MaxKeyCount keys before the end.
+ while (keyseq.length() && n < QKeySequencePrivate::MaxKeyCount) {
// We MUST use something to separate each sequence, and space
// does not cut it, since some of the key names have space
// in them.. (Let's hope no one translate with a comma in it:)
@@ -1022,9 +1019,10 @@ struct QModifKeyName {
int qt_key;
QString name;
};
+Q_DECLARE_TYPEINFO(QModifKeyName, Q_MOVABLE_TYPE);
-Q_GLOBAL_STATIC(QList<QModifKeyName>, globalModifs)
-Q_GLOBAL_STATIC(QList<QModifKeyName>, globalPortableModifs)
+Q_GLOBAL_STATIC(QVector<QModifKeyName>, globalModifs)
+Q_GLOBAL_STATIC(QVector<QModifKeyName>, globalPortableModifs)
/*!
Constructs a single key from the string \a str.
@@ -1040,7 +1038,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
QString accel = str.toLower();
bool nativeText = (format == QKeySequence::NativeText);
- QList<QModifKeyName> *gmodifs;
+ QVector<QModifKeyName> *gmodifs;
if (nativeText) {
gmodifs = globalModifs();
if (gmodifs->isEmpty()) {
@@ -1076,7 +1074,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
if (!gmodifs) return ret;
- QList<QModifKeyName> modifs;
+ QVector<QModifKeyName> modifs;
if (nativeText) {
modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+')))
<< QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").toLower().append(QLatin1Char('+')))
@@ -1100,7 +1098,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
int i = 0;
int lastI = 0;
while ((i = sl.indexOf(QLatin1Char('+'), i + 1)) != -1) {
- const QString sub = sl.mid(lastI, i - lastI + 1);
+ const QStringRef sub = sl.midRef(lastI, i - lastI + 1);
// If we get here the shortcuts contains at least one '+'. We break up
// along the following strategy:
// Meta+Ctrl++ ( "Meta+", "Ctrl+", "+" )
@@ -1366,7 +1364,7 @@ QKeySequence::operator QVariant() const
*/
int QKeySequence::operator[](uint index) const
{
- Q_ASSERT_X(index < 4, "QKeySequence::operator[]", "index out of range");
+ Q_ASSERT_X(index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::operator[]", "index out of range");
return d->key[index];
}
@@ -1409,6 +1407,16 @@ bool QKeySequence::operator==(const QKeySequence &other) const
d->key[3] == other.d->key[3]);
}
+/*!
+ \since 5.6
+
+ Calculates the hash value of \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW
+{
+ return qHashRange(key.d->key, key.d->key + QKeySequencePrivate::MaxKeyCount, seed);
+}
/*!
Provides an arbitrary comparison of this key sequence and
@@ -1424,10 +1432,8 @@ bool QKeySequence::operator==(const QKeySequence &other) const
*/
bool QKeySequence::operator< (const QKeySequence &other) const
{
- for (int i = 0; i < 4; ++i)
- if (d->key[i] != other.d->key[i])
- return d->key[i] < other.d->key[i];
- return false;
+ return std::lexicographical_compare(d->key, d->key + QKeySequencePrivate::MaxKeyCount,
+ other.d->key, other.d->key + QKeySequencePrivate::MaxKeyCount);
}
/*!
@@ -1523,6 +1529,7 @@ QList<QKeySequence> QKeySequence::listFromString(const QString &str, SequenceFor
QList<QKeySequence> result;
QStringList strings = str.split(QLatin1String("; "));
+ result.reserve(strings.count());
foreach (const QString &string, strings) {
result << fromString(string, format);
}
@@ -1565,15 +1572,14 @@ QString QKeySequence::listToString(const QList<QKeySequence> &list, SequenceForm
*/
QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
{
- QList<quint32> list;
- list << keysequence.d->key[0];
-
- if (s.version() >= 5 && keysequence.count() > 1) {
- list << keysequence.d->key[1];
- list << keysequence.d->key[2];
- list << keysequence.d->key[3];
+ Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Forgot to adapt QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence) to new QKeySequence::MaxKeyCount");
+ const bool extended = s.version() >= 5 && keysequence.count() > 1;
+ s << quint32(extended ? 4 : 1) << quint32(keysequence.d->key[0]);
+ if (extended) {
+ s << quint32(keysequence.d->key[1])
+ << quint32(keysequence.d->key[2])
+ << quint32(keysequence.d->key[3]);
}
- s << list;
return s;
}
@@ -1588,11 +1594,19 @@ QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
*/
QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
{
+ const quint32 MaxKeys = QKeySequencePrivate::MaxKeyCount;
+ quint32 c;
+ s >> c;
+ quint32 keys[MaxKeys] = {0};
+ for (uint i = 0; i < qMin(c, MaxKeys); ++i) {
+ if (s.atEnd()) {
+ qWarning("Premature EOF while reading QKeySequence");
+ return s;
+ }
+ s >> keys[i];
+ }
qAtomicDetach(keysequence.d);
- QList<quint32> list;
- s >> list;
- for (int i = 0; i < 4; ++i)
- keysequence.d->key[i] = list.value(i);
+ std::copy(keys, keys + MaxKeys, keysequence.d->key);
return s;
}
diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h
index cd7af5718f..98a611aab5 100644
--- a/src/gui/kernel/qkeysequence.h
+++ b/src/gui/kernel/qkeysequence.h
@@ -43,11 +43,12 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_SHORTCUT
+class QKeySequence;
+
/*****************************************************************************
QKeySequence stream functions
*****************************************************************************/
#ifndef QT_NO_DATASTREAM
-class QKeySequence;
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks);
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &out, QKeySequence &ks);
#endif
@@ -59,6 +60,8 @@ void qt_set_sequence_auto_mnemonic(bool b);
class QVariant;
class QKeySequencePrivate;
+Q_GUI_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QKeySequence &key, uint seed = 0) Q_DECL_NOTHROW;
+
class Q_GUI_EXPORT QKeySequence
{
Q_GADGET
@@ -134,7 +137,8 @@ public:
FullScreen,
Deselect,
DeleteCompleteLine,
- Backspace
+ Backspace,
+ Cancel
};
Q_ENUM(StandardKey)
@@ -177,10 +181,10 @@ public:
int operator[](uint i) const;
QKeySequence &operator=(const QKeySequence &other);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QKeySequence &operator=(QKeySequence &&other)
- { qSwap(d, other.d); return *this; }
+ QKeySequence &operator=(QKeySequence &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QKeySequence &other) { qSwap(d, other.d); }
+ void swap(QKeySequence &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
bool operator==(const QKeySequence &other) const;
inline bool operator!= (const QKeySequence &other) const
{ return !(*this == other); }
@@ -204,6 +208,7 @@ private:
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks);
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &in, QKeySequence &ks);
+ friend Q_GUI_EXPORT uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW;
friend class QShortcutMap;
friend class QShortcut;
diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h
index 97416943d0..3e4c5bae88 100644
--- a/src/gui/kernel/qkeysequence_p.h
+++ b/src/gui/kernel/qkeysequence_p.h
@@ -47,6 +47,8 @@
#include "qkeysequence.h"
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SHORTCUT
@@ -61,20 +63,17 @@ struct Q_AUTOTEST_EXPORT QKeyBinding
class Q_AUTOTEST_EXPORT QKeySequencePrivate
{
public:
- enum { MaxKeyCount = 4 }; // used in QKeySequenceEdit
+ enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit
inline QKeySequencePrivate() : ref(1)
{
- key[0] = key[1] = key[2] = key[3] = 0;
+ std::fill_n(key, uint(MaxKeyCount), 0);
}
inline QKeySequencePrivate(const QKeySequencePrivate &copy) : ref(1)
{
- key[0] = copy.key[0];
- key[1] = copy.key[1];
- key[2] = copy.key[2];
- key[3] = copy.key[3];
+ std::copy(copy.key, copy.key + MaxKeyCount, key);
}
QAtomicInt ref;
- int key[4];
+ int key[MaxKeyCount];
static QString encodeString(int key, QKeySequence::SequenceFormat format);
static int decodeString(const QString &keyStr, QKeySequence::SequenceFormat format);
};
diff --git a/src/gui/kernel/qoffscreensurface.h b/src/gui/kernel/qoffscreensurface.h
index 909a1ef256..17bc8a7d17 100644
--- a/src/gui/kernel/qoffscreensurface.h
+++ b/src/gui/kernel/qoffscreensurface.h
@@ -51,7 +51,7 @@ class Q_GUI_EXPORT QOffscreenSurface : public QObject, public QSurface
public:
- explicit QOffscreenSurface(QScreen *screen = 0);
+ explicit QOffscreenSurface(QScreen *screen = Q_NULLPTR);
virtual ~QOffscreenSurface();
SurfaceType surfaceType() const Q_DECL_OVERRIDE;
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 56a3729a4a..3c033ea39e 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -226,7 +226,7 @@ public:
QOpenGLContext *context;
};
-static QThreadStorage<QGuiGLThreadContext *> qwindow_context_storage;
+Q_GLOBAL_STATIC(QThreadStorage<QGuiGLThreadContext *>, qwindow_context_storage);
static QOpenGLContext *global_share_context = 0;
#ifndef QT_NO_DEBUG
@@ -336,14 +336,14 @@ QOpenGLContext *qt_gl_global_share_context()
*/
QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context)
{
- QGuiGLThreadContext *threadContext = qwindow_context_storage.localData();
+ QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData();
if (!threadContext) {
if (!QThread::currentThread()) {
qWarning("No QTLS available. currentContext won't work");
return 0;
}
threadContext = new QGuiGLThreadContext;
- qwindow_context_storage.setLocalData(threadContext);
+ qwindow_context_storage()->setLocalData(threadContext);
}
QOpenGLContext *previous = threadContext->context;
threadContext->context = context;
@@ -412,8 +412,8 @@ int QOpenGLContextPrivate::maxTextureSize()
*/
QOpenGLContext* QOpenGLContext::currentContext()
{
- QGuiGLThreadContext *threadContext = qwindow_context_storage.localData();
- if(threadContext) {
+ QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData();
+ if (threadContext) {
return threadContext->context;
}
return 0;
@@ -462,8 +462,7 @@ QPlatformOpenGLContext *QOpenGLContext::shareHandle() const
QOpenGLContext::QOpenGLContext(QObject *parent)
: QObject(*new QOpenGLContextPrivate(), parent)
{
- Q_D(QOpenGLContext);
- d->screen = QGuiApplication::primaryScreen();
+ setScreen(QGuiApplication::primaryScreen());
}
/*!
@@ -499,9 +498,20 @@ void QOpenGLContext::setShareContext(QOpenGLContext *shareContext)
void QOpenGLContext::setScreen(QScreen *screen)
{
Q_D(QOpenGLContext);
+ if (d->screen)
+ disconnect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(_q_screenDestroyed(QObject*)));
d->screen = screen;
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
+ if (d->screen)
+ connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(_q_screenDestroyed(QObject*)));
+}
+
+void QOpenGLContextPrivate::_q_screenDestroyed(QObject *object)
+{
+ Q_Q(QOpenGLContext);
+ if (object == static_cast<QObject *>(screen))
+ q->setScreen(0);
}
/*!
@@ -719,6 +729,28 @@ QOpenGLFunctions *QOpenGLContext::functions() const
}
/*!
+ Get the QOpenGLExtraFunctions instance for this context.
+
+ QOpenGLContext offers this as a convenient way to access QOpenGLExtraFunctions
+ without having to manage it manually.
+
+ The context or a sharing context must be current.
+
+ The returned QOpenGLExtraFunctions instance is ready to be used and it
+ does not need initializeOpenGLFunctions() to be called.
+
+ \note QOpenGLExtraFunctions contains functionality that is not guaranteed to
+ be available at runtime. Runtime availability depends on the platform,
+ graphics driver, and the OpenGL version requested by the application.
+
+ \sa QOpenGLFunctions, QOpenGLExtraFunctions
+*/
+QOpenGLExtraFunctions *QOpenGLContext::extraFunctions() const
+{
+ return static_cast<QOpenGLExtraFunctions *>(functions());
+}
+
+/*!
\fn T *QOpenGLContext::versionFunctions() const
\overload versionFunctions()
@@ -1427,11 +1459,11 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
{
QMutexLocker locker(&m_mutex);
- QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
+ const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
m_pendingDeletion.clear();
- QList<QOpenGLSharedResource *>::iterator it = pending.begin();
- QList<QOpenGLSharedResource *>::iterator end = pending.end();
+ QList<QOpenGLSharedResource *>::const_iterator it = pending.begin();
+ QList<QOpenGLSharedResource *>::const_iterator end = pending.end();
while (it != end) {
(*it)->freeResource(ctx);
delete *it;
@@ -1604,4 +1636,6 @@ void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContextGroup *group, QOpenG
m_groups.removeOne(group);
}
+#include "moc_qopenglcontext.cpp"
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h
index a529957ad6..841967a545 100644
--- a/src/gui/kernel/qopenglcontext.h
+++ b/src/gui/kernel/qopenglcontext.h
@@ -54,7 +54,10 @@
#include <QtGui/qopengl.h>
#include <QtGui/qopenglversionfunctions.h>
+#if QT_DEPRECATED_SINCE(5, 5)
#include <QtCore/qhash.h>
+#endif
+#include <QtCore/qhashfunctions.h>
#include <QtCore/qpair.h>
#include <QtCore/qvariant.h>
@@ -63,6 +66,7 @@ QT_BEGIN_NAMESPACE
class QOpenGLContextPrivate;
class QOpenGLContextGroupPrivate;
class QOpenGLFunctions;
+class QOpenGLExtraFunctions;
class QPlatformOpenGLContext;
class QScreen;
@@ -140,7 +144,7 @@ class Q_GUI_EXPORT QOpenGLContext : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QOpenGLContext)
public:
- explicit QOpenGLContext(QObject *parent = 0);
+ explicit QOpenGLContext(QObject *parent = Q_NULLPTR);
~QOpenGLContext();
void setFormat(const QSurfaceFormat &format);
@@ -174,6 +178,7 @@ public:
QPlatformOpenGLContext *shareHandle() const;
QOpenGLFunctions *functions() const;
+ QOpenGLExtraFunctions *extraFunctions() const;
QAbstractOpenGLFunctions *versionFunctions(const QOpenGLVersionProfile &versionProfile = QOpenGLVersionProfile()) const;
@@ -236,6 +241,8 @@ private:
void setTextureFunctions(QOpenGLTextureHelper* textureFuncs);
void destroy();
+
+ Q_PRIVATE_SLOT(d_func(), void _q_screenDestroyed(QObject *object))
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index f9f3ce2c5f..4a746bf12b 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -270,6 +270,8 @@ public:
static QHash<QOpenGLContext *, bool> makeCurrentTracker;
static QMutex makeCurrentTrackerMutex;
#endif
+
+ void _q_screenDestroyed(QObject *object);
};
Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
index b2025faaf1..3a1126d318 100644
--- a/src/gui/kernel/qopenglwindow.cpp
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -664,15 +664,10 @@ int QOpenGLWindow::metric(PaintDeviceMetric metric) const
if (d->paintDevice)
return d->paintDevice->depth();
break;
- case PdmDevicePixelRatio:
- if (d->paintDevice)
- return devicePixelRatio();
- break;
default:
break;
}
return QPaintDeviceWindow::metric(metric);
-
}
/*!
diff --git a/src/gui/kernel/qopenglwindow.h b/src/gui/kernel/qopenglwindow.h
index f274275c3f..0c2b44c1c7 100644
--- a/src/gui/kernel/qopenglwindow.h
+++ b/src/gui/kernel/qopenglwindow.h
@@ -58,8 +58,8 @@ public:
PartialUpdateBlend
};
- explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0);
- explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0);
+ explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = Q_NULLPTR);
+ explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = Q_NULLPTR);
~QOpenGLWindow();
UpdateBehavior updateBehavior() const;
diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp
index ff661d017d..cd894866c3 100644
--- a/src/gui/kernel/qpaintdevicewindow.cpp
+++ b/src/gui/kernel/qpaintdevicewindow.cpp
@@ -155,8 +155,10 @@ int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const
return qRound(screen->physicalDotsPerInchY());
break;
case PdmDevicePixelRatio:
- if (screen)
- return screen->devicePixelRatio();
+ return int(QWindow::devicePixelRatio());
+ break;
+ case PdmDevicePixelRatioScaled:
+ return int(QWindow::devicePixelRatio() * devicePixelRatioFScale());
break;
default:
break;
diff --git a/src/gui/kernel/qpaintdevicewindow_p.h b/src/gui/kernel/qpaintdevicewindow_p.h
index e234906fe0..071f2ee54c 100644
--- a/src/gui/kernel/qpaintdevicewindow_p.h
+++ b/src/gui/kernel/qpaintdevicewindow_p.h
@@ -34,6 +34,17 @@
#ifndef QPAINTDEVICEWINDOW_P_H
#define QPAINTDEVICEWINDOW_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtGui/QPaintDeviceWindow>
#include <QtCore/QCoreApplication>
#include <QtGui/private/qwindow_p.h>
diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp
index 7239ac7ba4..cd43fc42fe 100644
--- a/src/gui/kernel/qplatformcursor.cpp
+++ b/src/gui/kernel/qplatformcursor.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
diff --git a/src/gui/kernel/qplatformcursor.h b/src/gui/kernel/qplatformcursor.h
index 4f4f9cc6ae..8c788fd27b 100644
--- a/src/gui/kernel/qplatformcursor.h
+++ b/src/gui/kernel/qplatformcursor.h
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 3d37088182..f69efe0935 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -36,7 +36,6 @@
#include <QtCore/QVariant>
#include <QtCore/QSharedData>
#include <QtCore/QSettings>
-#include <QtCore/QHash>
#include <QtCore/QUrl>
#include <QtGui/QColor>
@@ -120,6 +119,8 @@ static const int buttonRoleLayouts[2][5][14] =
QPlatformDialogHelper::QPlatformDialogHelper()
{
+ qRegisterMetaType<StandardButton>();
+ qRegisterMetaType<ButtonRole>();
}
QPlatformDialogHelper::~QPlatformDialogHelper()
@@ -423,6 +424,7 @@ public:
QUrl initialDirectory;
QString initiallySelectedNameFilter;
QList<QUrl> initiallySelectedFiles;
+ QStringList supportedSchemes;
};
QFileDialogOptions::QFileDialogOptions() : d(new QFileDialogOptionsPrivate)
@@ -614,6 +616,18 @@ void QFileDialogOptions::setInitiallySelectedFiles(const QList<QUrl> &files)
d->initiallySelectedFiles = files;
}
+// Schemes supported by the application
+void QFileDialogOptions::setSupportedSchemes(const QStringList &schemes)
+{
+ d->supportedSchemes = schemes;
+}
+
+QStringList QFileDialogOptions::supportedSchemes() const
+{
+ return d->supportedSchemes;
+}
+
+// Return true if the URL is supported by the filedialog implementation *and* by the application.
bool QPlatformFileDialogHelper::isSupportedUrl(const QUrl &url) const
{
return url.isLocalFile();
@@ -639,12 +653,13 @@ void QPlatformFileDialogHelper::setOptions(const QSharedPointer<QFileDialogOptio
}
const char *QPlatformFileDialogHelper::filterRegExp =
-"^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
+"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
QStringList QPlatformFileDialogHelper::cleanFilterList(const QString &filter)
{
QRegExp regexp(QString::fromLatin1(filterRegExp));
+ Q_ASSERT(regexp.isValid());
QString f = filter;
int i = regexp.indexIn(f);
if (i >= 0)
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 8b2b9881b7..5b2f4ece77 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -104,6 +104,7 @@ public:
};
Q_DECLARE_FLAGS(StandardButtons, StandardButton)
+ Q_FLAG(StandardButtons)
enum ButtonRole {
// keep this in sync with QDialogButtonBox::ButtonRole and QMessageBox::ButtonRole
@@ -128,6 +129,7 @@ public:
Reverse = 0x40000000,
EOL = InvalidRole
};
+ Q_ENUM(ButtonRole)
enum ButtonLayout {
// keep this in sync with QDialogButtonBox::ButtonLayout and QMessageBox::ButtonLayout
@@ -160,8 +162,14 @@ Q_SIGNALS:
void reject();
};
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QPlatformDialogHelper::StandardButton)
+Q_DECLARE_METATYPE(QPlatformDialogHelper::ButtonRole)
+QT_BEGIN_NAMESPACE
+
class Q_GUI_EXPORT QColorDialogOptions
{
+ Q_GADGET
public:
enum ColorDialogOption {
ShowAlphaChannel = 0x00000001,
@@ -170,6 +178,7 @@ public:
};
Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption)
+ Q_FLAG(ColorDialogOptions)
QColorDialogOptions();
QColorDialogOptions(const QColorDialogOptions &rhs);
@@ -221,6 +230,7 @@ private:
class Q_GUI_EXPORT QFontDialogOptions
{
+ Q_GADGET
public:
enum FontDialogOption {
NoButtons = 0x00000001,
@@ -232,6 +242,7 @@ public:
};
Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
+ Q_FLAG(FontDialogOptions)
QFontDialogOptions();
QFontDialogOptions(const QFontDialogOptions &rhs);
@@ -274,11 +285,19 @@ private:
class Q_GUI_EXPORT QFileDialogOptions
{
+ Q_GADGET
public:
enum ViewMode { Detail, List };
+ Q_ENUM(ViewMode)
+
enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly };
+ Q_ENUM(FileMode)
+
enum AcceptMode { AcceptOpen, AcceptSave };
+ Q_ENUM(AcceptMode)
+
enum DialogLabel { LookIn, FileName, FileType, Accept, Reject, DialogLabelCount };
+ Q_ENUM(DialogLabel)
enum FileDialogOption
{
@@ -292,6 +311,7 @@ public:
DontUseCustomDirectoryIcons = 0x00000080
};
Q_DECLARE_FLAGS(FileDialogOptions, FileDialogOption)
+ Q_FLAG(FileDialogOptions)
QFileDialogOptions();
QFileDialogOptions(const QFileDialogOptions &rhs);
@@ -348,6 +368,9 @@ public:
QList<QUrl> initiallySelectedFiles() const;
void setInitiallySelectedFiles(const QList<QUrl> &);
+ void setSupportedSchemes(const QStringList &schemes);
+ QStringList supportedSchemes() const;
+
private:
QSharedDataPointer<QFileDialogOptionsPrivate> d;
};
@@ -388,9 +411,11 @@ private:
class Q_GUI_EXPORT QMessageDialogOptions
{
+ Q_GADGET
public:
// Keep in sync with QMessageBox::Icon
enum Icon { NoIcon, Information, Warning, Critical, Question };
+ Q_ENUM(Icon)
QMessageDialogOptions();
QMessageDialogOptions(const QMessageDialogOptions &rhs);
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
index 2749b05691..c0c51b8d5e 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
@@ -40,6 +40,14 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -64,23 +72,25 @@ QT_BEGIN_NAMESPACE
bound texture, otherwise returns false.
*/
bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer,
- bool *swizzle,
+ bool *swizzle, bool *premultiplied,
const QRect &rect)
{
if (graphicsBuffer->lock(QPlatformGraphicsBuffer::TextureAccess)) {
if (!graphicsBuffer->bindToTexture(rect)) {
- qWarning() << Q_FUNC_INFO << "Failed to bind graphicsbuffer to texture";
+ qWarning("Failed to bind %sgraphicsbuffer to texture", "");
return false;
}
if (swizzle)
*swizzle = false;
+ if (premultiplied)
+ *premultiplied = false;
} else if (graphicsBuffer->lock(QPlatformGraphicsBuffer::SWReadAccess)) {
- if (!bindSWToTexture(graphicsBuffer, swizzle, rect)) {
- qWarning() << Q_FUNC_INFO << "Failed to bind SW graphcisbuffer to texture";
+ if (!bindSWToTexture(graphicsBuffer, swizzle, premultiplied, rect)) {
+ qWarning("Failed to bind %sgraphicsbuffer to texture", "SW ");
return false;
}
} else {
- qWarning() << Q_FUNC_INFO << "Failed to lock";
+ qWarning("Failed to lock");
return false;
}
return true;
@@ -109,11 +119,12 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer
Returns true on success, otherwise false.
*/
bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer,
- bool *swizzleRandB,
+ bool *swizzleRandB, bool *premultipliedB,
const QRect &subRect)
{
#ifndef QT_NO_OPENGL
- if (!QOpenGLContext::currentContext())
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx)
return false;
if (!(graphicsBuffer->isLocked() & QPlatformGraphicsBuffer::SWReadAccess))
@@ -123,27 +134,70 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
Q_ASSERT(subRect.isEmpty() || QRect(QPoint(0,0), size).contains(subRect));
+ GLenum internalFormat = GL_RGBA;
+ GLuint pixelType = GL_UNSIGNED_BYTE;
+
+ bool needsConversion = false;
bool swizzle = false;
+ bool premultiplied = false;
QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format());
QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat);
if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) {
- image = image.convertToFormat(QImage::Format_RGBA8888);
- } else if (imageformat == QImage::Format_RGB32) {
- swizzle = true;
- } else if (imageformat != QImage::Format_RGBA8888) {
- image = image.convertToFormat(QImage::Format_RGBA8888);
+ needsConversion = true;
+ } else {
+ switch (imageformat) {
+ case QImage::Format_ARGB32_Premultiplied:
+ premultiplied = true;
+ // no break
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ swizzle = true;
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ premultiplied = true;
+ // no break
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ break;
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ premultiplied = true;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ premultiplied = true;
+ swizzle = true;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ default:
+ needsConversion = true;
+ break;
+ }
}
+ if (needsConversion)
+ image = image.convertToFormat(QImage::Format_RGBA8888);
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ QOpenGLFunctions *funcs = ctx->functions();
QRect rect = subRect;
if (rect.isNull() || rect == QRect(QPoint(0,0),size)) {
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0, GL_RGBA, pixelType, image.constBits());
} else {
#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ if (!ctx->isOpenGLES()) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else
@@ -160,16 +214,18 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
// OpenGL instead of copying, since there's no gap between scanlines
if (rect.width() == size.width()) {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()));
} else {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.copy(rect).constBits());
}
}
}
if (swizzleRandB)
*swizzleRandB = swizzle;
+ if (premultipliedB)
+ *premultipliedB = premultiplied;
return true;
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.h b/src/gui/kernel/qplatformgraphicsbufferhelper.h
index ded7810608..cc1a4918cd 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.h
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.h
@@ -39,8 +39,8 @@
QT_BEGIN_NAMESPACE
namespace QPlatformGraphicsBufferHelper {
- bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, const QRect &rect = QRect());
- bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, const QRect &rect = QRect());
+ bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect());
+ bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, bool *premultipliedB = Q_NULLPTR, const QRect &rect = QRect());
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontextfactory.cpp b/src/gui/kernel/qplatforminputcontextfactory.cpp
index a7660e76ae..fedf940dda 100644
--- a/src/gui/kernel/qplatforminputcontextfactory.cpp
+++ b/src/gui/kernel/qplatforminputcontextfactory.cpp
@@ -56,48 +56,34 @@ QStringList QPlatformInputContextFactory::keys()
#endif
}
-QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
+QString QPlatformInputContextFactory::requested()
{
- QStringList paramList = key.split(QLatin1Char(':'));
- const QString platform = paramList.takeFirst().toLower();
-
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
- if (QPlatformInputContext *ret = qLoadPlugin1<QPlatformInputContext, QPlatformInputContextPlugin>(loader(), platform, paramList))
- return ret;
-#endif
- return 0;
+ QByteArray env = qgetenv("QT_IM_MODULE");
+ return env.isNull() ? QString() : QString::fromLocal8Bit(env);
}
-QPlatformInputContext *QPlatformInputContextFactory::create()
+QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
{
- QPlatformInputContext *ic = 0;
-
- QString icString = QString::fromLatin1(qgetenv("QT_IM_MODULE"));
-
- if (icString == QLatin1String("none"))
- return 0;
-
- ic = create(icString);
- if (ic && ic->isValid())
- return ic;
-
- delete ic;
- ic = 0;
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ if (!key.isEmpty()) {
+ QStringList paramList = key.split(QLatin1Char(':'));
+ const QString platform = paramList.takeFirst().toLower();
- QStringList k = keys();
- for (int i = 0; i < k.size(); ++i) {
- if (k.at(i) == icString)
- continue;
- ic = create(k.at(i));
+ QPlatformInputContext *ic = qLoadPlugin1<QPlatformInputContext, QPlatformInputContextPlugin>
+ (loader(), platform, paramList);
if (ic && ic->isValid())
return ic;
+
delete ic;
- ic = 0;
}
-
+#endif
return 0;
}
+QPlatformInputContext *QPlatformInputContextFactory::create()
+{
+ return create(requested());
+}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontextfactory_p.h b/src/gui/kernel/qplatforminputcontextfactory_p.h
index a74c4f5f80..38f4358287 100644
--- a/src/gui/kernel/qplatforminputcontextfactory_p.h
+++ b/src/gui/kernel/qplatforminputcontextfactory_p.h
@@ -56,6 +56,7 @@ class Q_GUI_EXPORT QPlatformInputContextFactory
{
public:
static QStringList keys();
+ static QString requested();
static QPlatformInputContext *create(const QString &key);
static QPlatformInputContext *create();
};
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 4d973d47a5..14633d8b30 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -39,7 +39,6 @@
#include <qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
-#include <qpa/qplatformscreen_p.h>
#include <private/qdnd_p.h>
#include <private/qsimpledrag_p.h>
@@ -209,8 +208,7 @@ QPlatformServices *QPlatformIntegration::services() const
behavior for desktop platforms.
\value ForeignWindows The platform allows creating QWindows which represent
- native windows created by other processes or anyway created by using native
- libraries.
+ native windows created by other processes or by using native libraries.
\value NonFullScreenWindows The platform supports top-level windows which do not
fill the screen. The default implementation returns \c true. Returning false for
@@ -450,13 +448,31 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
{
QScreen *screen = new QScreen(ps);
- ps->d_func()->screen = screen;
+
if (isPrimary) {
QGuiApplicationPrivate::screen_list.prepend(screen);
} else {
QGuiApplicationPrivate::screen_list.append(screen);
}
emit qGuiApp->screenAdded(screen);
+
+ if (isPrimary)
+ emit qGuiApp->primaryScreenChanged(screen);
+}
+
+/*!
+ Just removes the screen, call destroyScreen instead.
+
+ \sa destroyScreen()
+*/
+
+void QPlatformIntegration::removeScreen(QScreen *screen)
+{
+ const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list[0] == screen);
+ QGuiApplicationPrivate::screen_list.removeOne(screen);
+
+ if (wasPrimary && qGuiApp && !QGuiApplicationPrivate::screen_list.isEmpty())
+ emit qGuiApp->primaryScreenChanged(QGuiApplicationPrivate::screen_list[0]);
}
/*!
@@ -469,11 +485,31 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
*/
void QPlatformIntegration::destroyScreen(QPlatformScreen *screen)
{
- QGuiApplicationPrivate::screen_list.removeOne(screen->d_func()->screen);
- delete screen->d_func()->screen;
+ QScreen *qScreen = screen->screen();
+ removeScreen(qScreen);
+ delete qScreen;
delete screen;
}
+/*!
+ Should be called whenever the primary screen changes.
+
+ When the screen specified as primary changes, this method will notify
+ QGuiApplication and emit the QGuiApplication::primaryScreenChanged signal.
+ */
+
+void QPlatformIntegration::setPrimaryScreen(QPlatformScreen *newPrimary)
+{
+ QScreen* newPrimaryScreen = newPrimary->screen();
+ int idx = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
+ Q_ASSERT(idx >= 0);
+ if (idx == 0)
+ return;
+
+ QGuiApplicationPrivate::screen_list.swap(0, idx);
+ emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
+}
+
QStringList QPlatformIntegration::themeNames() const
{
return QStringList();
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 2aa502b3d2..af89a73455 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -91,7 +91,8 @@ public:
SyncState,
RasterGLSurface,
AllGLFunctionsQueryable,
- ApplicationIcon
+ ApplicationIcon,
+ SwitchableWidgetComposition
};
virtual ~QPlatformIntegration() { }
@@ -172,9 +173,13 @@ public:
virtual QOpenGLContext::OpenGLModuleType openGLModuleType();
#endif
virtual void setApplicationIcon(const QIcon &icon) const;
+
+ void removeScreen(QScreen *screen);
+
protected:
void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
void destroyScreen(QPlatformScreen *screen);
+ void setPrimaryScreen(QPlatformScreen *newPrimary);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp
index d58ac3a33f..5a1fb3ca83 100644
--- a/src/gui/kernel/qplatformintegrationfactory.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory.cpp
@@ -72,6 +72,12 @@ QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platfor
}
if (QPlatformIntegration *ret = loadIntegration(loader(), platform, paramList, argc, argv))
return ret;
+#else
+ Q_UNUSED(platform);
+ Q_UNUSED(paramList);
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
+ Q_UNUSED(platformPluginPath);
#endif
return 0;
}
@@ -102,6 +108,7 @@ QStringList QPlatformIntegrationFactory::keys(const QString &platformPluginPath)
list.append(loader()->keyMap().values());
return list;
#else
+ Q_UNUSED(platformPluginPath);
return QStringList();
#endif
}
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 1022d0ed4a..bc0b3a4870 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -63,6 +63,7 @@ public:
// They could be added as public QAction roles if necessary.
CutRole, CopyRole, PasteRole, SelectAllRole,
RoleCount };
+ Q_ENUM(MenuRole)
virtual void setTag(quintptr tag) = 0;
virtual quintptr tag()const = 0;
@@ -91,6 +92,7 @@ class Q_GUI_EXPORT QPlatformMenu : public QObject
Q_OBJECT
public:
enum MenuType { DefaultMenu = 0, EditMenu };
+ Q_ENUM(MenuType)
virtual void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) = 0;
virtual void removeMenuItem(QPlatformMenuItem *menuItem) = 0;
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index edf546799f..8e9767d69e 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -40,6 +40,7 @@
#include <qpa/qplatformintegration.h>
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -55,7 +56,7 @@ QPlatformScreen::~QPlatformScreen()
Q_D(QPlatformScreen);
if (d->screen) {
qWarning("Manually deleting a QPlatformScreen. Call QPlatformIntegration::destroyScreen instead.");
- QGuiApplicationPrivate::screen_list.removeOne(d->screen);
+ QGuiApplicationPrivate::platformIntegration()->removeScreen(d->screen);
delete d->screen;
}
}
@@ -89,7 +90,7 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
QWindowList list = QGuiApplication::topLevelWindows();
for (int i = list.size()-1; i >= 0; --i) {
QWindow *w = list[i];
- if (w->isVisible() && w->geometry().contains(pos))
+ if (w->isVisible() && QHighDpi::toNativePixels(w->geometry(), w).contains(pos))
return w;
}
@@ -97,6 +98,23 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
}
/*!
+ Find the sibling screen corresponding to \a globalPos.
+
+ Returns this screen if no suitable screen is found at the position.
+ */
+const QPlatformScreen *QPlatformScreen::screenForPosition(const QPoint &point) const
+{
+ if (!geometry().contains(point)) {
+ Q_FOREACH (const QPlatformScreen* screen, virtualSiblings()) {
+ if (screen->geometry().contains(point))
+ return screen;
+ }
+ }
+ return this;
+}
+
+
+/*!
Returns a list of all the platform screens that are part of the same
virtual desktop.
@@ -156,11 +174,13 @@ QDpi QPlatformScreen::logicalDpi() const
}
/*!
- Reimplement this function in subclass to return the device pixel
- ratio for the screen. This is the ratio between physical pixels
- and device-independent pixels.
+ Reimplement this function in subclass to return the device pixel ratio
+ for the screen. This is the ratio between physical pixels and the
+ device-independent pixels of the windowing system. The default
+ implementation returns 1.0.
- \sa QPlatformWindow::devicePixelRatio();
+ \sa QPlatformWindow::devicePixelRatio()
+ \sa QPlatformScreen::pixelDensity()
*/
qreal QPlatformScreen::devicePixelRatio() const
{
@@ -168,6 +188,24 @@ qreal QPlatformScreen::devicePixelRatio() const
}
/*!
+ Reimplement this function in subclass to return the pixel density of the
+ screen. This is the scale factor needed to make a low-dpi application
+ usable on this screen. The default implementation returns 1.0.
+
+ Returning something else than 1.0 from this function causes Qt to
+ apply the scale factor to the application's coordinate system.
+ This is different from devicePixelRatio, which reports a scale
+ factor already applied by the windowing system. A platform plugin
+ typically implements one (or none) of these two functions.
+
+ \sa QPlatformWindow::devicePixelRatio()
+*/
+qreal QPlatformScreen::pixelDensity() const
+{
+ return 1.0;
+}
+
+/*!
Reimplement this function in subclass to return the vertical refresh rate
of the screen, in Hz.
@@ -290,8 +328,8 @@ void QPlatformScreen::resizeMaximizedWindows()
// 'screen()' still has the old geometry info while 'this' has the new geometry info
const QRect oldGeometry = screen()->geometry();
const QRect oldAvailableGeometry = screen()->availableGeometry();
- const QRect newGeometry = geometry();
- const QRect newAvailableGeometry = availableGeometry();
+ const QRect newGeometry = deviceIndependentGeometry();
+ const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft());
// make sure maximized and fullscreen windows are updated
for (int i = 0; i < windows.size(); ++i) {
@@ -324,7 +362,7 @@ static int log2(uint i)
int QPlatformScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b)
{
if (a == Qt::PrimaryOrientation || b == Qt::PrimaryOrientation) {
- qWarning() << "Use QScreen version of" << __FUNCTION__ << "when passing Qt::PrimaryOrientation";
+ qWarning("Use QScreen version of %sBetween() when passing Qt::PrimaryOrientation", "angle");
return 0;
}
@@ -346,7 +384,7 @@ int QPlatformScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation
QTransform QPlatformScreen::transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target)
{
if (a == Qt::PrimaryOrientation || b == Qt::PrimaryOrientation) {
- qWarning() << "Use QScreen version of" << __FUNCTION__ << "when passing Qt::PrimaryOrientation";
+ qWarning("Use QScreen version of %sBetween() when passing Qt::PrimaryOrientation", "transform");
return QTransform();
}
@@ -377,7 +415,7 @@ QTransform QPlatformScreen::transformBetween(Qt::ScreenOrientation a, Qt::Screen
QRect QPlatformScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect)
{
if (a == Qt::PrimaryOrientation || b == Qt::PrimaryOrientation) {
- qWarning() << "Use QScreen version of" << __FUNCTION__ << "when passing Qt::PrimaryOrientation";
+ qWarning("Use QScreen version of %sBetween() when passing Qt::PrimaryOrientation", "map");
return rect;
}
@@ -393,6 +431,13 @@ QRect QPlatformScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation
return rect;
}
+QRect QPlatformScreen::deviceIndependentGeometry() const
+{
+ qreal scaleFactor = QHighDpiScaling::factor(this);
+ QRect nativeGeometry = geometry();
+ return QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor));
+}
+
/*!
Returns a hint about this screen's subpixel layout structure.
@@ -420,4 +465,22 @@ QPlatformScreen::SubpixelAntialiasingType QPlatformScreen::subpixelAntialiasingT
return static_cast<QPlatformScreen::SubpixelAntialiasingType>(type);
}
+/*!
+ Returns the current power state.
+
+ The default implementation always returns PowerStateOn.
+*/
+QPlatformScreen::PowerState QPlatformScreen::powerState() const
+{
+ return PowerStateOn;
+}
+
+/*!
+ Sets the power state for this screen.
+*/
+void QPlatformScreen::setPowerState(PowerState state)
+{
+ Q_UNUSED(state);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index 551cb788c9..b32f9cf97c 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -82,6 +82,13 @@ public:
Subpixel_VBGR
};
+ enum PowerState {
+ PowerStateOn,
+ PowerStateStandby,
+ PowerStateSuspend,
+ PowerStateOff
+ };
+
QPlatformScreen();
virtual ~QPlatformScreen();
@@ -96,6 +103,7 @@ public:
virtual QSizeF physicalSize() const;
virtual QDpi logicalDpi() const;
virtual qreal devicePixelRatio() const;
+ virtual qreal pixelDensity() const;
virtual qreal refreshRate() const;
@@ -105,6 +113,7 @@ public:
virtual QWindow *topLevelAt(const QPoint &point) const;
virtual QList<QPlatformScreen *> virtualSiblings() const;
+ const QPlatformScreen *screenForPosition(const QPoint &point) const;
QScreen *screen() const;
@@ -117,10 +126,16 @@ public:
virtual QPlatformCursor *cursor() const;
virtual SubpixelAntialiasingType subpixelAntialiasingTypeHint() const;
+ virtual PowerState powerState() const;
+ virtual void setPowerState(PowerState state);
+
static int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b);
static QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target);
static QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect);
+ // The platform screen's geometry in device independent coordinates
+ QRect deviceIndependentGeometry() const;
+
protected:
void resizeMaximizedWindows();
@@ -129,7 +144,7 @@ protected:
private:
Q_DISABLE_COPY(QPlatformScreen)
- friend class QPlatformIntegration;
+ friend class QScreenPrivate;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h
index 437f5e02b1..6ef2d1538f 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.h
+++ b/src/gui/kernel/qplatformsystemtrayicon.h
@@ -57,8 +57,10 @@ public:
Trigger,
MiddleClick
};
+ Q_ENUM(ActivationReason)
enum MessageIcon { NoIcon, Information, Warning, Critical };
+ Q_ENUM(MessageIcon)
QPlatformSystemTrayIcon();
~QPlatformSystemTrayIcon();
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 36a71fe2da..ce8548f628 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -323,7 +323,9 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
{QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11},
{QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, KB_X11},
- {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac}
+ {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac},
+ {QKeySequence::Cancel, 0, Qt::Key_Escape, KB_All},
+ {QKeySequence::Cancel, 0, Qt::CTRL | Qt::Key_Period, KB_Mac}
};
const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding));
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 69cc2f90af..36fa7a65aa 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -164,6 +164,8 @@ public:
SmallFont,
MiniFont,
FixedFont,
+ GroupBoxTitleFont,
+ TabButtonFont,
NFonts
};
diff --git a/src/gui/kernel/qplatformthemefactory.cpp b/src/gui/kernel/qplatformthemefactory.cpp
index d4902ac163..bcc37dad06 100644
--- a/src/gui/kernel/qplatformthemefactory.cpp
+++ b/src/gui/kernel/qplatformthemefactory.cpp
@@ -63,6 +63,9 @@ QPlatformTheme *QPlatformThemeFactory::create(const QString& key, const QString
}
if (QPlatformTheme *ret = qLoadPlugin1<QPlatformTheme, QPlatformThemePlugin>(loader(), platform, paramList))
return ret;
+#else
+ Q_UNUSED(key);
+ Q_UNUSED(platformPluginPath);
#endif
return 0;
}
@@ -93,6 +96,7 @@ QStringList QPlatformThemeFactory::keys(const QString &platformPluginPath)
list += loader()->keyMap().values();
return list;
#else
+ Q_UNUSED(platformPluginPath);
return QStringList();
#endif
}
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 114fcf8062..aea029b7f5 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -39,8 +39,10 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/qwindow.h>
#include <QtGui/qscreen.h>
+#include <private/qhighdpiscaling_p.h>
#include <private/qwindow_p.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -481,13 +483,27 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &
QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const
{
QPlatformScreen *currentScreen = screen();
- if (!parent() && currentScreen && !currentScreen->geometry().intersects(newGeometry)) {
+ QPlatformScreen *fallback = currentScreen;
+ //QRect::center can return a value outside the rectangle if it's empty
+ const QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center();
+
+ if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) {
Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
- if (screen->geometry().intersects(newGeometry))
+ if (screen->geometry().contains(center))
return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
}
}
- return currentScreen;
+ return fallback;
+}
+
+/*!
+ Returns a size with both dimensions bounded to [0, QWINDOWSIZE_MAX]
+*/
+QSize QPlatformWindow::constrainWindowSize(const QSize &size)
+{
+ return size.expandedTo(QSize(0, 0)).boundedTo(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
}
/*!
@@ -565,7 +581,10 @@ void QPlatformWindow::invalidateSurface()
QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
- QRect rect(initialGeometry);
+ const QScreen *screen = effectiveScreen(w);
+ if (!screen)
+ return initialGeometry;
+ QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
if (rect.width() == 0) {
const int minWidth = w->minimumWidth();
rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
@@ -575,25 +594,23 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
rect.setHeight(minHeight > 0 ? minHeight : defaultHeight);
}
if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
- && w->type() != Qt::Popup) {
- if (const QScreen *screen = effectiveScreen(w)) {
- const QRect availableGeometry = screen->availableGeometry();
- // Center unless the geometry ( + unknown window frame) is too large for the screen).
- if (rect.height() < (availableGeometry.height() * 8) / 9
+ && w->type() != Qt::Popup) {
+ const QRect availableGeometry = screen->availableGeometry();
+ // Center unless the geometry ( + unknown window frame) is too large for the screen).
+ if (rect.height() < (availableGeometry.height() * 8) / 9
&& rect.width() < (availableGeometry.width() * 8) / 9) {
- const QWindow *tp = w->transientParent();
- if (tp) {
- // A transient window should be centered w.r.t. its transient parent.
- rect.moveCenter(tp->geometry().center());
- } else {
- // Center the window on the screen. (Only applicable on platforms
- // which do not provide a better way.)
- rect.moveCenter(availableGeometry.center());
- }
+ const QWindow *tp = w->transientParent();
+ if (tp) {
+ // A transient window should be centered w.r.t. its transient parent.
+ rect.moveCenter(tp->geometry().center());
+ } else {
+ // Center the window on the screen. (Only applicable on platforms
+ // which do not provide a better way.)
+ rect.moveCenter(availableGeometry.center());
}
}
}
- return rect;
+ return QHighDpi::toNativePixels(rect, screen);
}
/*!
@@ -627,6 +644,82 @@ void QPlatformWindow::requestUpdate()
}
/*!
+ Returns the QWindow minimum size.
+*/
+QSize QPlatformWindow::windowMinimumSize() const
+{
+ return constrainWindowSize(QHighDpi::toNativePixels(window()->minimumSize(), window()));
+}
+
+/*!
+ Returns the QWindow maximum size.
+*/
+QSize QPlatformWindow::windowMaximumSize() const
+{
+ return constrainWindowSize(QHighDpi::toNativePixels(window()->maximumSize(), window()));
+}
+
+/*!
+ Returns the QWindow base size.
+*/
+QSize QPlatformWindow::windowBaseSize() const
+{
+ return QHighDpi::toNativePixels(window()->baseSize(), window());
+}
+
+/*!
+ Returns the QWindow size increment.
+*/
+QSize QPlatformWindow::windowSizeIncrement() const
+{
+ QSize increment = window()->sizeIncrement();
+ if (!QHighDpiScaling::isActive())
+ return increment;
+
+ // Normalize the increment. If not set the increment can be
+ // (-1, -1) or (0, 0). Make that (1, 1) which is scalable.
+ if (increment.isEmpty())
+ increment = QSize(1, 1);
+
+ return QHighDpi::toNativePixels(increment, window());
+}
+
+/*!
+ Returns the QWindow geometry.
+*/
+QRect QPlatformWindow::windowGeometry() const
+{
+ return QHighDpi::toNativePixels(window()->geometry(), window());
+}
+
+/*!
+ Returns the QWindow frame geometry.
+*/
+QRect QPlatformWindow::windowFrameGeometry() const
+{
+ return QHighDpi::toNativePixels(window()->frameGeometry(), window());
+}
+
+/*!
+ Returns the closest acceptable geometry for a given geometry before
+ a resize/move event for platforms that support it, for example to
+ implement heightForWidth().
+*/
+
+QRectF QPlatformWindow::closestAcceptableGeometry(const QWindow *qWindow, const QRectF &nativeRect)
+{
+ const QRectF rectF = QHighDpi::fromNativePixels(nativeRect, qWindow);
+ const QRectF correctedGeometryF = qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(rectF);
+ return !correctedGeometryF.isEmpty() && rectF != correctedGeometryF
+ ? QHighDpi::toNativePixels(correctedGeometryF, qWindow) : nativeRect;
+}
+
+QRectF QPlatformWindow::windowClosestAcceptableGeometry(const QRectF &nativeRect) const
+{
+ return QPlatformWindow::closestAcceptableGeometry(window(), nativeRect);
+}
+
+/*!
\class QPlatformWindow
\since 4.8
\internal
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index c7c1efdc58..850e2b4bfe 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -95,7 +95,7 @@ public:
virtual bool isExposed() const;
virtual bool isActive() const;
- virtual bool isEmbedded(const QPlatformWindow *parentWindow) const;
+ virtual bool isEmbedded(const QPlatformWindow *parentWindow = 0) const;
virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const;
@@ -130,9 +130,22 @@ public:
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
virtual void requestUpdate();
+
+ // Window property accessors. Platform plugins should use these
+ // instead of accessing QWindow directly.
+ QSize windowMinimumSize() const;
+ QSize windowMaximumSize() const;
+ QSize windowBaseSize() const;
+ QSize windowSizeIncrement() const;
+ QRect windowGeometry() const;
+ QRect windowFrameGeometry() const;
+ QRectF windowClosestAcceptableGeometry(const QRectF &nativeRect) const;
+ static QRectF closestAcceptableGeometry(const QWindow *w, const QRectF &nativeRect);
+
protected:
static QString formatWindowTitle(const QString &title, const QString &separator);
QPlatformScreen *screenForGeometry(const QRect &newGeometry) const;
+ static QSize constrainWindowSize(const QSize &size);
QScopedPointer<QPlatformWindowPrivate> d_ptr;
private:
diff --git a/src/gui/kernel/qrasterwindow.cpp b/src/gui/kernel/qrasterwindow.cpp
index c04eb71420..fc1739ca0e 100644
--- a/src/gui/kernel/qrasterwindow.cpp
+++ b/src/gui/kernel/qrasterwindow.cpp
@@ -108,8 +108,6 @@ int QRasterWindow::metric(PaintDeviceMetric metric) const
switch (metric) {
case PdmDepth:
return d->backingstore->paintDevice()->depth();
- case PdmDevicePixelRatio:
- return d->backingstore->paintDevice()->devicePixelRatio();
default:
break;
}
diff --git a/src/gui/kernel/qrasterwindow.h b/src/gui/kernel/qrasterwindow.h
index 4912efad37..6db6baa8f5 100644
--- a/src/gui/kernel/qrasterwindow.h
+++ b/src/gui/kernel/qrasterwindow.h
@@ -46,7 +46,7 @@ class Q_GUI_EXPORT QRasterWindow : public QPaintDeviceWindow
Q_DECLARE_PRIVATE(QRasterWindow)
public:
- explicit QRasterWindow(QWindow *parent = 0);
+ explicit QRasterWindow(QWindow *parent = Q_NULLPTR);
protected:
int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 038be09dc7..52e7686439 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -36,7 +36,9 @@
#include "qpixmap.h"
#include "qguiapplication_p.h"
#include <qpa/qplatformscreen.h>
+#include <qpa/qplatformscreen_p.h>
+#include <QtCore/QDebug>
#include <QtCore/private/qobject_p.h>
QT_BEGIN_NAMESPACE
@@ -62,8 +64,33 @@ QT_BEGIN_NAMESPACE
*/
QScreen::QScreen(QPlatformScreen *screen)
- : QObject(*new QScreenPrivate(screen), 0)
+ : QObject(*new QScreenPrivate(), 0)
{
+ Q_D(QScreen);
+ d->setPlatformScreen(screen);
+}
+
+void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
+{
+ Q_Q(QScreen);
+ platformScreen = screen;
+ platformScreen->d_func()->screen = q;
+ orientation = platformScreen->orientation();
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ logicalDpi = platformScreen->logicalDpi();
+ refreshRate = platformScreen->refreshRate();
+ // safeguard ourselves against buggy platform behavior...
+ if (refreshRate < 1.0)
+ refreshRate = 60.0;
+
+ updatePrimaryOrientation();
+
+ filteredOrientation = orientation;
+ if (filteredOrientation == Qt::PrimaryOrientation)
+ filteredOrientation = primaryOrientation;
+
+ updateHighDpi();
}
@@ -89,8 +116,8 @@ QScreen::~QScreen()
bool movingFromVirtualSibling = primaryScreen && primaryScreen->handle()->virtualSiblings().contains(handle());
// Move any leftover windows to the primary screen
- foreach (QWindow *window, QGuiApplication::topLevelWindows()) {
- if (window->screen() != this)
+ foreach (QWindow *window, QGuiApplication::allWindows()) {
+ if (!window->isTopLevel() || window->screen() != this)
continue;
const bool wasVisible = window->isVisible();
@@ -207,6 +234,8 @@ qreal QScreen::physicalDotsPerInch() const
qreal QScreen::logicalDotsPerInchX() const
{
Q_D(const QScreen);
+ if (QHighDpiScaling::isActive())
+ return QHighDpiScaling::logicalDpi().first;
return d->logicalDpi.first;
}
@@ -221,6 +250,8 @@ qreal QScreen::logicalDotsPerInchX() const
qreal QScreen::logicalDotsPerInchY() const
{
Q_D(const QScreen);
+ if (QHighDpiScaling::isActive())
+ return QHighDpiScaling::logicalDpi().second;
return d->logicalDpi.second;
}
@@ -239,7 +270,7 @@ qreal QScreen::logicalDotsPerInchY() const
qreal QScreen::logicalDotsPerInch() const
{
Q_D(const QScreen);
- QDpi dpi = d->logicalDpi;
+ QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi() : d->logicalDpi;
return (dpi.first + dpi.second) * qreal(0.5);
}
@@ -258,7 +289,7 @@ qreal QScreen::logicalDotsPerInch() const
qreal QScreen::devicePixelRatio() const
{
Q_D(const QScreen);
- return d->platformScreen->devicePixelRatio();
+ return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this);
}
/*!
@@ -328,6 +359,7 @@ QList<QScreen *> QScreen::virtualSiblings() const
Q_D(const QScreen);
QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
QList<QScreen *> screens;
+ screens.reserve(platformScreens.count());
foreach (QPlatformScreen *platformScreen, platformScreens)
screens << platformScreen->screen();
return screens;
@@ -589,7 +621,7 @@ bool QScreen::isLandscape(Qt::ScreenOrientation o) const
\fn void QScreen::orientationChanged(Qt::ScreenOrientation orientation)
This signal is emitted when the orientation of the screen
- changes.
+ changes with \a orientation as an argument.
\sa orientation()
*/
@@ -598,7 +630,7 @@ bool QScreen::isLandscape(Qt::ScreenOrientation o) const
\fn void QScreen::primaryOrientationChanged(Qt::ScreenOrientation orientation)
This signal is emitted when the primary orientation of the screen
- changes.
+ changes with \a orientation as an argument.
\sa primaryOrientation()
*/
@@ -648,10 +680,47 @@ QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
{
const QPlatformScreen *platformScreen = handle();
if (!platformScreen) {
- qWarning("%s invoked with handle==0", Q_FUNC_INFO);
+ qWarning("invoked with handle==0");
return QPixmap();
}
return platformScreen->grabWindow(window, x, y, width, height);
}
+#ifndef QT_NO_DEBUG_STREAM
+
+static inline void formatRect(QDebug &debug, const QRect r)
+{
+ debug << r.width() << 'x' << r.height()
+ << forcesign << r.x() << r.y() << noforcesign;
+}
+
+Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QScreen *screen)
+{
+ const QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "QScreen(" << (const void *)screen;
+ if (screen) {
+ debug << ", name=" << screen->name();
+ if (debug.verbosity() > 2) {
+ if (screen == QGuiApplication::primaryScreen())
+ debug << ", primary";
+ debug << ", geometry=";
+ formatRect(debug, screen->geometry());
+ debug << ", available=";
+ formatRect(debug, screen->availableGeometry());
+ debug << ", logical DPI=" << screen->logicalDotsPerInchX()
+ << ',' << screen->logicalDotsPerInchY()
+ << ", physical DPI=" << screen->physicalDotsPerInchX()
+ << ',' << screen->physicalDotsPerInchY()
+ << ", devicePixelRatio=" << screen->devicePixelRatio()
+ << ", orientation=" << screen->orientation()
+ << ", physical size=" << screen->physicalSize().width()
+ << 'x' << screen->physicalSize().height() << "mm";
+ }
+ }
+ debug << ')';
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index 255e735baf..a6018128e2 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -52,6 +52,9 @@ class QScreenPrivate;
class QWindow;
class QRect;
class QPixmap;
+#ifndef QT_NO_DEBUG_STREAM
+class QDebug;
+#endif
class Q_GUI_EXPORT QScreen : public QObject
{
@@ -151,8 +154,13 @@ private:
friend class QGuiApplicationPrivate;
friend class QPlatformIntegration;
friend class QPlatformScreen;
+ friend class QHighDpiScaling;
};
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QScreen *);
+#endif
+
QT_END_NAMESPACE
#endif // QSCREEN_H
diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h
index d341b71932..4492eddd45 100644
--- a/src/gui/kernel/qscreen_p.h
+++ b/src/gui/kernel/qscreen_p.h
@@ -47,6 +47,7 @@
#include <QtGui/qscreen.h>
#include <qpa/qplatformscreen.h>
+#include "qhighdpiscaling_p.h"
#include <QtCore/private/qobject_p.h>
@@ -54,25 +55,19 @@ QT_BEGIN_NAMESPACE
class QScreenPrivate : public QObjectPrivate
{
+ Q_DECLARE_PUBLIC(QScreen)
public:
- QScreenPrivate(QPlatformScreen *screen)
- : platformScreen(screen)
+ QScreenPrivate()
+ : platformScreen(0)
, orientationUpdateMask(0)
{
- orientation = platformScreen->orientation();
- geometry = platformScreen->geometry();
- availableGeometry = platformScreen->availableGeometry();
- logicalDpi = platformScreen->logicalDpi();
- refreshRate = platformScreen->refreshRate();
- // safeguard ourselves against buggy platform behavior...
- if (refreshRate < 1.0)
- refreshRate = 60.0;
-
- updatePrimaryOrientation();
+ }
- filteredOrientation = orientation;
- if (filteredOrientation == Qt::PrimaryOrientation)
- filteredOrientation = primaryOrientation;
+ void setPlatformScreen(QPlatformScreen *screen);
+ void updateHighDpi()
+ {
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
}
void updatePrimaryOrientation();
diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp
index 8f80789fb0..d77b6dc262 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow.cpp
+++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
@@ -35,12 +35,16 @@
#include <QtGui/QPainter>
#include <QtGui/QCursor>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QPalette>
+#include <QtGui/QBitmap>
QT_BEGIN_NAMESPACE
-QShapedPixmapWindow::QShapedPixmapWindow()
- : QWindow(),
- m_backingStore(0)
+QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
+ : QWindow(screen),
+ m_backingStore(0),
+ m_useCompositing(true)
{
QSurfaceFormat format;
format.setAlphaBufferSize(8);
@@ -68,7 +72,10 @@ void QShapedPixmapWindow::render()
{
QPainter p(device);
- p.setCompositionMode(QPainter::CompositionMode_Source);
+ if (m_useCompositing)
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ else
+ p.fillRect(rect, QGuiApplication::palette().base());
p.drawPixmap(0, 0, m_pixmap);
}
@@ -79,6 +86,8 @@ void QShapedPixmapWindow::render()
void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
+ if (!m_useCompositing)
+ setMask(m_pixmap.mask());
}
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h
index fc311cff92..3d7974fa82 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow_p.h
+++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h
@@ -55,11 +55,12 @@ class QShapedPixmapWindow : public QWindow
{
Q_OBJECT
public:
- QShapedPixmapWindow();
+ explicit QShapedPixmapWindow(QScreen *screen = 0);
~QShapedPixmapWindow();
void render();
+ void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot);
@@ -72,6 +73,7 @@ private:
QBackingStore *m_backingStore;
QPixmap m_pixmap;
QPoint m_hotSpot;
+ bool m_useCompositing;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 3e267f2e0b..3941f7233f 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -84,7 +84,7 @@ struct QShortcutEntry
QShortcutMap::ContextMatcher contextMatcher;
};
-#if 0 //ndef QT_NO_DEBUG_STREAM
+#ifdef Dump_QShortcutMap
/*! \internal
QDebug operator<< for easy debug output of the shortcut entries.
*/
@@ -99,7 +99,7 @@ static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se)
<< "), owner(" << se->owner << ')';
return dbg;
}
-#endif // QT_NO_DEBUGSTREAM
+#endif // Dump_QShortcutMap
/* \internal
Private data for QShortcutMap
@@ -309,59 +309,46 @@ QKeySequence::SequenceMatch QShortcutMap::state()
}
/*! \internal
- Uses ShortcutOverride event to see if any widgets want to override
- the event. If not, uses nextState(QKeyEvent) to check for a grabbed
- Shortcut, and dispatchEvent() is found and identical.
+ Uses nextState(QKeyEvent) to check for a grabbed shortcut.
- \note that this function should only be called from QWindowSystemInterface,
- otherwise it will result in duplicate events.
+ If so, it is dispatched using dispatchEvent().
+
+ Returns true if a shortcut handled the event.
\sa nextState, dispatchEvent
*/
-bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
+bool QShortcutMap::tryShortcut(QKeyEvent *e)
{
Q_D(QShortcutMap);
if (e->key() == Qt::Key_unknown)
return false;
- bool wasAccepted = e->isAccepted();
- bool wasSpontaneous = e->spont;
- if (d->currentState == QKeySequence::NoMatch) {
- ushort orgType = e->t;
- e->t = QEvent::ShortcutOverride;
- e->ignore();
- QCoreApplication::sendEvent(o, e);
- e->t = orgType;
- e->spont = wasSpontaneous;
- if (e->isAccepted()) {
- if (!wasAccepted)
- e->ignore();
- return false;
- }
- }
-
- QKeySequence::SequenceMatch result = nextState(e);
- bool stateWasAccepted = e->isAccepted();
- if (wasAccepted)
- e->accept();
- else
- e->ignore();
-
- int identicalMatches = d->identicals.count();
+ QKeySequence::SequenceMatch previousState = state();
- switch(result) {
+ switch (nextState(e)) {
case QKeySequence::NoMatch:
- return stateWasAccepted;
- case QKeySequence::ExactMatch:
+ // In the case of going from a partial match to no match we handled the
+ // event, since we already stated that we did for the partial match. But
+ // in the normal case of directly going to no match we say we didn't.
+ return previousState == QKeySequence::PartialMatch;
+ case QKeySequence::PartialMatch:
+ // For a partial match we don't know yet if we will handle the shortcut
+ // but we need to say we did, so that we get the follow-up key-presses.
+ return true;
+ case QKeySequence::ExactMatch: {
+ // Save number of identical matches before dispatching
+ // to keep QShortcutMap and tryShortcut reentrant.
+ const int identicalMatches = d->identicals.count();
resetState();
dispatchEvent(e);
+ // If there are no identicals we've only found disabled shortcuts, and
+ // shouldn't say that we handled the event.
+ return identicalMatches > 0;
+ }
default:
- break;
+ Q_UNREACHABLE();
}
- // If nextState is QKeySequence::ExactMatch && identicals.count == 0
- // we've only found disabled shortcuts
- return identicalMatches > 0 || result == QKeySequence::PartialMatch;
}
/*! \internal
@@ -396,10 +383,6 @@ QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)
}
}
- // Should we eat this key press?
- if (d->currentState == QKeySequence::PartialMatch
- || (d->currentState == QKeySequence::ExactMatch && d->identicals.count()))
- e->accept();
// Does the new state require us to clean up?
if (result == QKeySequence::NoMatch)
clearSequence(d->currentSequences);
diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/gui/kernel/qshortcutmap_p.h
index 2376d27c78..16542b078a 100644
--- a/src/gui/kernel/qshortcutmap_p.h
+++ b/src/gui/kernel/qshortcutmap_p.h
@@ -75,7 +75,9 @@ public:
int setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key = QKeySequence());
int setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key = QKeySequence());
- bool tryShortcutEvent(QObject *o, QKeyEvent *e);
+ QKeySequence::SequenceMatch state();
+
+ bool tryShortcut(QKeyEvent *e);
bool hasShortcutForKeySequence(const QKeySequence &seq) const;
#ifdef Dump_QShortcutMap
@@ -85,7 +87,6 @@ public:
private:
void resetState();
QKeySequence::SequenceMatch nextState(QKeyEvent *e);
- QKeySequence::SequenceMatch state();
void dispatchEvent(QKeyEvent *e);
QKeySequence::SequenceMatch find(QKeyEvent *e, int ignoredModifiers = 0);
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index b850f53014..9f38c9b78a 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -55,6 +55,7 @@
#include <private/qdnd_p.h>
#include <private/qshapedpixmapdndwindow_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -87,7 +88,7 @@ static QWindow* topLevelAt(const QPoint &pos)
QBasicDrag::QBasicDrag() :
m_restoreCursor(false), m_eventLoop(0),
m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
- m_drag(0), m_drag_icon_window(0)
+ m_drag(0), m_drag_icon_window(0), m_useCompositing(true)
{
}
@@ -106,6 +107,12 @@ void QBasicDrag::disableEventFilter()
qApp->removeEventFilter(this);
}
+
+static inline QPoint getNativeMousePos(QEvent *e, QObject *o)
+{
+ return QHighDpi::toNativePixels(static_cast<QMouseEvent *>(e)->globalPos(), qobject_cast<QWindow*>(o));
+}
+
bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
{
Q_UNUSED(o);
@@ -139,20 +146,22 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
}
case QEvent::MouseMove:
- move(static_cast<QMouseEvent *>(e));
- return true; // Eat all mouse events
-
+ {
+ QPoint nativePosition = getNativeMousePos(e, o);
+ move(nativePosition);
+ return true; // Eat all mouse move events
+ }
case QEvent::MouseButtonRelease:
disableEventFilter();
if (canDrop()) {
- drop(static_cast<QMouseEvent *>(e));
+ QPoint nativePosition = getNativeMousePos(e, o);
+ drop(nativePosition);
} else {
cancel();
}
exitDndEventLoop();
- return true; // Eat all mouse events
-
- case QEvent::MouseButtonPress:
+ QCoreApplication::postEvent(o, new QMouseEvent(*static_cast<QMouseEvent *>(e)));
+ return true; // defer mouse release events until drag event loop has returned
case QEvent::MouseButtonDblClick:
case QEvent::Wheel:
return true;
@@ -194,25 +203,15 @@ void QBasicDrag::restoreCursor()
void QBasicDrag::startDrag()
{
- // ### TODO Check if its really necessary to have m_drag_icon_window
- // when QDrag is used without a pixmap - QDrag::setPixmap()
- if (!m_drag_icon_window)
- m_drag_icon_window = new QShapedPixmapWindow();
-
- m_drag_icon_window->setPixmap(m_drag->pixmap());
- m_drag_icon_window->setHotspot(m_drag->hotSpot());
-
+ QPoint pos;
#ifndef QT_NO_CURSOR
- QPoint pos = QCursor::pos();
+ pos = QCursor::pos();
if (pos.x() == int(qInf())) {
// ### fixme: no mouse pos registered. Get pos from touch...
pos = QPoint();
}
- m_drag_icon_window->updateGeometry(pos);
#endif
-
- m_drag_icon_window->setVisible(true);
-
+ recreateShapedPixmapWindow(Q_NULLPTR, pos);
enableEventFilter();
}
@@ -220,6 +219,20 @@ void QBasicDrag::endDrag()
{
}
+void QBasicDrag::recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos)
+{
+ delete m_drag_icon_window;
+ // ### TODO Check if its really necessary to have m_drag_icon_window
+ // when QDrag is used without a pixmap - QDrag::setPixmap()
+ m_drag_icon_window = new QShapedPixmapWindow(screen);
+
+ m_drag_icon_window->setUseCompositing(m_useCompositing);
+ m_drag_icon_window->setPixmap(m_drag->pixmap());
+ m_drag_icon_window->setHotspot(m_drag->hotSpot());
+ m_drag_icon_window->updateGeometry(pos);
+ m_drag_icon_window->setVisible(true);
+}
+
void QBasicDrag::cancel()
{
disableEventFilter();
@@ -227,13 +240,18 @@ void QBasicDrag::cancel()
m_drag_icon_window->setVisible(false);
}
-void QBasicDrag::move(const QMouseEvent *e)
+/*!
+ Move the drag label to \a globalPos, which is
+ interpreted in device independent coordinates. Typically called from reimplementations of move().
+ */
+
+void QBasicDrag::moveShapedPixmapWindow(const QPoint &globalPos)
{
if (m_drag)
- m_drag_icon_window->updateGeometry(e->globalPos());
+ m_drag_icon_window->updateGeometry(globalPos);
}
-void QBasicDrag::drop(const QMouseEvent *)
+void QBasicDrag::drop(const QPoint &)
{
disableEventFilter();
restoreCursor();
@@ -330,14 +348,15 @@ void QSimpleDrag::cancel()
}
}
-void QSimpleDrag::move(const QMouseEvent *me)
+void QSimpleDrag::move(const QPoint &globalPos)
{
- QBasicDrag::move(me);
- QWindow *window = topLevelAt(me->globalPos());
+ //### not high-DPI aware
+ moveShapedPixmapWindow(globalPos);
+ QWindow *window = topLevelAt(globalPos);
if (!window)
return;
- const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPoint pos = globalPos - window->geometry().topLeft();
const QPlatformDragQtResponse qt_response =
QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions());
@@ -345,14 +364,16 @@ void QSimpleDrag::move(const QMouseEvent *me)
setCanDrop(qt_response.isAccepted());
}
-void QSimpleDrag::drop(const QMouseEvent *me)
+void QSimpleDrag::drop(const QPoint &globalPos)
{
- QBasicDrag::drop(me);
- QWindow *window = topLevelAt(me->globalPos());
+ //### not high-DPI aware
+
+ QBasicDrag::drop(globalPos);
+ QWindow *window = topLevelAt(globalPos);
if (!window)
return;
- const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPoint pos = globalPos - window->geometry().topLeft();
const QPlatformDropQtResponse response =
QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions());
if (response.isAccepted()) {
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 7812f8b863..055136c436 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -58,6 +58,7 @@ class QWindow;
class QEventLoop;
class QDropData;
class QShapedPixmapWindow;
+class QScreen;
class Q_GUI_EXPORT QBasicDrag : public QPlatformDrag, public QObject
{
@@ -73,16 +74,22 @@ protected:
virtual void startDrag();
virtual void cancel();
- virtual void move(const QMouseEvent *me);
- virtual void drop(const QMouseEvent *me);
+ virtual void move(const QPoint &globalPos) = 0;
+ virtual void drop(const QPoint &globalPos) = 0;
virtual void endDrag();
+
+ void moveShapedPixmapWindow(const QPoint &deviceIndependentPosition);
QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; }
+ void recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos);
void updateCursor(Qt::DropAction action);
bool canDrop() const { return m_can_drop; }
void setCanDrop(bool c) { m_can_drop = c; }
+ bool useCompositing() const { return m_useCompositing; }
+ void setUseCompositing(bool on) { m_useCompositing = on; }
+
Qt::DropAction executedDropAction() const { return m_executed_drop_action; }
void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; }
@@ -100,6 +107,7 @@ private:
bool m_can_drop;
QDrag *m_drag;
QShapedPixmapWindow *m_drag_icon_window;
+ bool m_useCompositing;
};
class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
@@ -111,8 +119,8 @@ public:
protected:
virtual void startDrag() Q_DECL_OVERRIDE;
virtual void cancel() Q_DECL_OVERRIDE;
- virtual void move(const QMouseEvent *me) Q_DECL_OVERRIDE;
- virtual void drop(const QMouseEvent *me) Q_DECL_OVERRIDE;
+ virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
+ virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
private:
QWindow *m_current_window;
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 7ff0f9f860..7fc89112e6 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -305,7 +305,7 @@ int QStyleHints::cursorFlashTime() const
\note The platform may still choose to show certain windows non-fullscreen,
such as popups or dialogs. This property only reports the default behavior.
- \sa QWindow::show()
+ \sa QWindow::show(), showIsMaximized()
*/
bool QStyleHints::showIsFullScreen() const
{
@@ -313,6 +313,22 @@ bool QStyleHints::showIsFullScreen() const
}
/*!
+ \property QStyleHints::showIsMaximized
+ \brief \c true if the platform defaults to windows being maximized,
+ otherwise \c false.
+
+ \note The platform may still choose to show certain windows non-maximized,
+ such as popups or dialogs. This property only reports the default behavior.
+
+ \sa QWindow::show(), showIsFullScreen()
+ \since 5.6
+*/
+bool QStyleHints::showIsMaximized() const
+{
+ return hint(QPlatformIntegration::ShowIsMaximized).toBool();
+}
+
+/*!
\property QStyleHints::passwordMaskDelay
\brief the time, in milliseconds, a typed letter is displayed unshrouded
in a text input field in password mode.
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 82eb8a6f7d..c5b8241e07 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -56,6 +56,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay STORED false CONSTANT FINAL)
Q_PROPERTY(bool setFocusOnTouchRelease READ setFocusOnTouchRelease STORED false CONSTANT FINAL)
Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen STORED false CONSTANT FINAL)
+ Q_PROPERTY(bool showIsMaximized READ showIsMaximized STORED false CONSTANT FINAL)
Q_PROPERTY(int startDragDistance READ startDragDistance NOTIFY startDragDistanceChanged FINAL)
Q_PROPERTY(int startDragTime READ startDragTime NOTIFY startDragTimeChanged FINAL)
Q_PROPERTY(int startDragVelocity READ startDragVelocity STORED false CONSTANT FINAL)
@@ -78,6 +79,7 @@ public:
void setCursorFlashTime(int cursorFlashTime);
int cursorFlashTime() const;
bool showIsFullScreen() const;
+ bool showIsMaximized() const;
int passwordMaskDelay() const;
QChar passwordMaskCharacter() const;
qreal fontSmoothingGamma() const;
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index 1a6e9deba8..266b5308a2 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -195,7 +195,7 @@ void QTouchDevice::setName(const QString &name)
d->name = name;
}
-typedef QList<QTouchDevice *> TouchDevices;
+typedef QList<const QTouchDevice *> TouchDevices;
Q_GLOBAL_STATIC(TouchDevices, deviceList)
static QBasicMutex devicesMutex;
@@ -214,26 +214,22 @@ static void cleanupDevicesList()
QList<const QTouchDevice *> QTouchDevice::devices()
{
QMutexLocker lock(&devicesMutex);
- QList<QTouchDevice *> *devList = deviceList();
- QList<const QTouchDevice *> constDevList;
- for (int i = 0, count = devList->count(); i != count; ++i)
- constDevList.append(devList->at(i));
- return constDevList;
+ return *deviceList();
}
/*!
\internal
*/
-bool QTouchDevicePrivate::isRegistered(QTouchDevice *dev)
+bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{
- QMutexLocker lock(&devicesMutex);
+ QMutexLocker locker(&devicesMutex);
return deviceList()->contains(dev);
}
/*!
\internal
*/
-void QTouchDevicePrivate::registerDevice(QTouchDevice *dev)
+void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{
QMutexLocker lock(&devicesMutex);
if (deviceList()->isEmpty())
@@ -241,6 +237,17 @@ void QTouchDevicePrivate::registerDevice(QTouchDevice *dev)
deviceList()->append(dev);
}
+/*!
+ \internal
+ */
+void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
+{
+ QMutexLocker lock(&devicesMutex);
+ bool wasRemoved = deviceList()->removeOne(dev);
+ if (wasRemoved && deviceList()->isEmpty())
+ qRemovePostRoutine(cleanupDevicesList);
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QTouchDevice *device)
{
diff --git a/src/gui/kernel/qtouchdevice_p.h b/src/gui/kernel/qtouchdevice_p.h
index 9c0bcf3414..63b83d33ec 100644
--- a/src/gui/kernel/qtouchdevice_p.h
+++ b/src/gui/kernel/qtouchdevice_p.h
@@ -45,7 +45,6 @@
// We mean it.
//
-#include <QtCore/qobject.h>
#include <QtGui/qtouchdevice.h>
QT_BEGIN_NAMESPACE
@@ -65,8 +64,9 @@ public:
QString name;
int maxTouchPoints;
- static void registerDevice(QTouchDevice *dev);
- static bool isRegistered(QTouchDevice *dev);
+ static void registerDevice(const QTouchDevice *dev);
+ static void unregisterDevice(const QTouchDevice *dev);
+ static bool isRegistered(const QTouchDevice *dev);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 871437efb1..21734f1619 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -47,6 +47,7 @@
#ifndef QT_NO_ACCESSIBILITY
# include "qaccessible.h"
#endif
+#include "qhighdpiscaling_p.h"
#include <private/qevent_p.h>
@@ -368,7 +369,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
{
Q_Q(QWindow);
if (parentWindow) {
- qWarning() << this << Q_FUNC_INFO << '(' << newScreen << "): Attempt to set a screen on a child window.";
+ qWarning() << this << '(' << newScreen << "): Attempt to set a screen on a child window.";
return;
}
if (newScreen != topLevelScreen) {
@@ -388,25 +389,31 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
void QWindowPrivate::create(bool recursive)
{
Q_Q(QWindow);
+ if (platformWindow)
+ return;
+
+ platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
+ Q_ASSERT(platformWindow);
+
if (!platformWindow) {
- platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
- QObjectList childObjects = q->children();
- for (int i = 0; i < childObjects.size(); i ++) {
- QObject *object = childObjects.at(i);
- if (object->isWindowType()) {
- QWindow *window = static_cast<QWindow *>(object);
- if (recursive)
- window->d_func()->create(true);
- if (window->d_func()->platformWindow)
- window->d_func()->platformWindow->setParent(platformWindow);
- }
- }
+ qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
+ return;
+ }
- if (platformWindow) {
- QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
- QGuiApplication::sendEvent(q, &e);
+ QObjectList childObjects = q->children();
+ for (int i = 0; i < childObjects.size(); i ++) {
+ QObject *object = childObjects.at(i);
+ if (object->isWindowType()) {
+ QWindow *window = static_cast<QWindow *>(object);
+ if (recursive)
+ window->d_func()->create(true);
+ if (window->d_func()->platformWindow)
+ window->d_func()->platformWindow->setParent(platformWindow);
}
}
+
+ QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
+ QGuiApplication::sendEvent(q, &e);
}
void QWindowPrivate::clearFocusObject()
@@ -587,8 +594,7 @@ QWindow *QWindow::parent() const
Setting \a parent to be 0 will make the window become a top level window.
If \a parent is a window created by fromWinId(), then the current window
- will be embedded inside \a parent, if the platform supports it. Window
- embedding is currently supported only by the X11 platform plugin.
+ will be embedded inside \a parent, if the platform supports it.
*/
void QWindow::setParent(QWindow *parent)
{
@@ -598,11 +604,13 @@ void QWindow::setParent(QWindow *parent)
QScreen *newScreen = parent ? parent->screen() : screen();
if (d->windowRecreationRequired(newScreen)) {
- qWarning() << this << Q_FUNC_INFO << '(' << parent << "): Cannot change screens (" << screen() << newScreen << ')';
+ qWarning() << this << '(' << parent << "): Cannot change screens (" << screen() << newScreen << ')';
return;
}
QObject::setParent(parent);
+ d->parentWindow = parent;
+
if (parent)
d->disconnectFromScreen();
else
@@ -616,8 +624,6 @@ void QWindow::setParent(QWindow *parent)
}
}
- d->parentWindow = parent;
-
QGuiApplicationPrivate::updateBlockedStatus(this);
}
@@ -1085,13 +1091,13 @@ qreal QWindow::devicePixelRatio() const
{
Q_D(const QWindow);
- // If there is no platform window, do the second best thing and
- // return the app global devicePixelRatio. This is the highest
- // devicePixelRatio found on the system screens, and will be
- // correct for single-display systems (a very common case).
+ // If there is no platform window use the app global devicePixelRatio,
+ // which is the the highest devicePixelRatio found on the system
+ // screens, and will be correct for single-display systems (a very common case).
if (!d->platformWindow)
return qApp->devicePixelRatio();
- return d->platformWindow->devicePixelRatio();
+
+ return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this);
}
/*!
@@ -1154,7 +1160,7 @@ void QWindow::setTransientParent(QWindow *parent)
{
Q_D(QWindow);
if (parent && !parent->isTopLevel()) {
- qWarning() << Q_FUNC_INFO << parent << "must be a top level window.";
+ qWarning() << parent << "must be a top level window.";
return;
}
@@ -1437,7 +1443,13 @@ void QWindow::setGeometry(const QRect &rect)
d->positionPolicy = QWindowPrivate::WindowFrameExclusive;
if (d->platformWindow) {
- d->platformWindow->setGeometry(rect);
+ QRect nativeRect;
+ QScreen *newScreen = d->screenForGeometry(rect);
+ if (newScreen && isTopLevel())
+ nativeRect = QHighDpi::toNativePixels(rect, newScreen);
+ else
+ nativeRect = QHighDpi::toNativePixels(rect, this);
+ d->platformWindow->setGeometry(nativeRect);
} else {
d->geometry = rect;
@@ -1452,6 +1464,30 @@ void QWindow::setGeometry(const QRect &rect)
}
}
+/*
+ This is equivalent to QPlatformWindow::screenForGeometry, but in platform
+ independent coordinates. The duplication is unfortunate, but there is a
+ chicken and egg problem here: we cannot convert to native coordinates
+ before we know which screen we are on.
+*/
+QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry)
+{
+ Q_Q(QWindow);
+ QScreen *currentScreen = q->screen();
+ QScreen *fallback = currentScreen;
+ QPoint center = newGeometry.center();
+ if (!q->parent() && currentScreen && !currentScreen->geometry().contains(center)) {
+ Q_FOREACH (QScreen* screen, currentScreen->virtualSiblings()) {
+ if (screen->geometry().contains(center))
+ return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
+ }
+ }
+ return fallback;
+}
+
+
/*!
Returns the geometry of the window, excluding its window frame.
@@ -1461,7 +1497,7 @@ QRect QWindow::geometry() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->geometry();
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this);
return d->geometry;
}
@@ -1474,7 +1510,7 @@ QMargins QWindow::frameMargins() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->frameMargins();
+ return QHighDpi::fromNativePixels(d->platformWindow->frameMargins(), this);
return QMargins();
}
@@ -1488,7 +1524,7 @@ QRect QWindow::frameGeometry() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins m = frameMargins();
- return d->platformWindow->geometry().adjusted(-m.left(), -m.top(), m.right(), m.bottom());
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this).adjusted(-m.left(), -m.top(), m.right(), m.bottom());
}
return d->geometry;
}
@@ -1505,7 +1541,7 @@ QPoint QWindow::framePosition() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins margins = frameMargins();
- return d->platformWindow->geometry().topLeft() - QPoint(margins.left(), margins.top());
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry().topLeft(), this) - QPoint(margins.left(), margins.top());
}
return d->geometry.topLeft();
}
@@ -1521,7 +1557,7 @@ void QWindow::setFramePosition(const QPoint &point)
d->positionPolicy = QWindowPrivate::WindowFrameInclusive;
d->positionAutomatic = false;
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(point, size()));
+ d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(point, size()), this));
} else {
d->geometry.moveTopLeft(point);
}
@@ -1581,7 +1617,7 @@ void QWindow::resize(const QSize &newSize)
{
Q_D(QWindow);
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(position(), newSize));
+ d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(position(), newSize), this));
} else {
const QSize oldSize = d->geometry.size();
d->geometry.setSize(newSize);
@@ -2261,10 +2297,10 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapToGlobal(pos);
}
- return pos + d_func()->globalPosition();
+ return pos + d->globalPosition();
}
@@ -2281,10 +2317,10 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapFromGlobal(pos);
}
- return pos - d_func()->globalPosition();
+ return pos - d->globalPosition();
}
@@ -2346,9 +2382,16 @@ QWindow *QWindowPrivate::topLevelWindow() const
Given the handle \a id to a native window, this method creates a QWindow
object which can be used to represent the window when invoking methods like
setParent() and setTransientParent().
- This can be used, on platforms which support it, to embed a window inside a
- container or to make a window stick on top of a window created by another
- process.
+
+ This can be used, on platforms which support it, to embed a QWindow inside a
+ native window, or to embed a native window inside a QWindow.
+
+ If foreign windows are not supported, this function returns 0.
+
+ \note The resulting QWindow should not be used to manipulate the underlying
+ native window (besides re-parenting), or to observe state changes of the
+ native window. Any support for these kind of operations is incidental, highly
+ platform dependent and untested.
\sa setParent()
\sa setTransientParent()
@@ -2477,6 +2520,45 @@ void QWindowPrivate::applyCursor()
}
#endif // QT_NO_CURSOR
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QWindow *window)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ if (window) {
+ debug << window->metaObject()->className() << '(' << (const void *)window;
+ if (!window->objectName().isEmpty())
+ debug << ", name=" << window->objectName();
+ if (debug.verbosity() > 2) {
+ const QRect geometry = window->geometry();
+ if (window->isVisible())
+ debug << ", visible";
+ if (window->isExposed())
+ debug << ", exposed";
+ debug << ", state=" << window->windowState()
+ << ", type=" << window->type() << ", flags=" << window->flags()
+ << ", surface type=" << window->surfaceType();
+ if (window->isTopLevel())
+ debug << ", toplevel";
+ debug << ", " << geometry.width() << 'x' << geometry.height()
+ << forcesign << geometry.x() << geometry.y() << noforcesign;
+ const QMargins margins = window->frameMargins();
+ if (!margins.isNull())
+ debug << ", margins=" << margins;
+ debug << ", devicePixelRatio=" << window->devicePixelRatio();
+ if (const QPlatformWindow *platformWindow = window->handle())
+ debug << ", winId=0x" << hex << platformWindow->winId() << dec;
+ if (const QScreen *screen = window->screen())
+ debug << ", on " << screen->name();
+ }
+ debug << ')';
+ } else {
+ debug << "QWindow(0x0)";
+ }
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
#include "moc_qwindow.cpp"
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index f9fe37718c..b29e7aaae7 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -78,6 +78,9 @@ class QBackingStore;
class QScreen;
class QAccessibleInterface;
class QWindowContainer;
+#ifndef QT_NO_DEBUG_STREAM
+class QDebug;
+#endif
class Q_GUI_EXPORT QWindow : public QObject, public QSurface
{
@@ -122,7 +125,7 @@ public:
};
Q_ENUM(Visibility)
- explicit QWindow(QScreen *screen = 0);
+ explicit QWindow(QScreen *screen = Q_NULLPTR);
explicit QWindow(QWindow *parent);
virtual ~QWindow();
@@ -357,16 +360,20 @@ private:
#ifndef Q_QDOC
template <> inline QWindow *qobject_cast<QWindow*>(QObject *o)
{
- if (!o || !o->isWindowType()) return 0;
+ if (!o || !o->isWindowType()) return Q_NULLPTR;
return static_cast<QWindow*>(o);
}
template <> inline const QWindow *qobject_cast<const QWindow*>(const QObject *o)
{
- if (!o || !o->isWindowType()) return 0;
+ if (!o || !o->isWindowType()) return Q_NULLPTR;
return static_cast<const QWindow*>(o);
}
#endif // !Q_QDOC
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QWindow *);
+#endif
+
QT_END_NAMESPACE
#endif // QWINDOW_H
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 4fc63acf28..6880edaada 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -50,6 +50,7 @@
#include <qpa/qplatformwindow.h>
#include <QtCore/private/qobject_p.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE
@@ -136,6 +137,7 @@ public:
void connectToScreen(QScreen *topLevelScreen);
void disconnectFromScreen();
void emitScreenChangedRecursion(QScreen *newScreen);
+ QScreen *screenForGeometry(const QRect &rect);
virtual void clearFocusObject();
virtual QRectF closestAcceptableGeometry(const QRectF &rect) const;
@@ -186,6 +188,7 @@ public:
#endif
bool compositing;
+ QElapsedTimer lastComposeTime;
};
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 850b69d729..d17a1f1d5b 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -40,14 +40,18 @@
#include <qpa/qplatformdrag.h>
#include <qpa/qplatformintegration.h>
#include <qdebug.h>
+#include "qhighdpiscaling_p.h"
+#include <QtCore/qscopedvaluerollback.h>
QT_BEGIN_NAMESPACE
QElapsedTimer QWindowSystemInterfacePrivate::eventTime;
-bool QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = false;
+bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false;
QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed;
QMutex QWindowSystemInterfacePrivate::flushEventMutex;
+QAtomicInt QWindowSystemInterfacePrivate::eventAccepted;
+QWindowSystemEventHandler *QWindowSystemInterfacePrivate::eventHandler;
//------------------------------------------------------------
//
@@ -93,14 +97,14 @@ void QWindowSystemInterface::handleLeaveEvent(QWindow *tlw)
*/
void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local, const QPointF& global)
{
- bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents;
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
if (wasSynchronous)
- setSynchronousWindowsSystemEvents(false);
+ setSynchronousWindowSystemEvents(false);
handleLeaveEvent(leave);
handleEnterEvent(enter, local, global);
if (wasSynchronous) {
flushWindowSystemEvents();
- setSynchronousWindowsSystemEvents(true);
+ setSynchronousWindowSystemEvents(true);
}
}
@@ -138,7 +142,7 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState
*/
void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect)
{
- QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect, oldRect);
+ QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -167,7 +171,7 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const
Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
- new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source);
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -184,167 +188,102 @@ void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timest
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
QWindowSystemInterfacePrivate::FrameStrutMouse,
- local, global, b, mods, source);
+ QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-bool QWindowSystemInterface::tryHandleShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- const QString & text, bool autorep, ushort count)
-{
- unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed();
- return tryHandleShortcutEvent(w, timestamp, k, mods, text, autorep, count);
-}
-
-bool QWindowSystemInterface::tryHandleShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString & text, bool autorep, ushort count)
-{
-#ifndef QT_NO_SHORTCUT
- QGuiApplicationPrivate::modifier_buttons = mods;
-
- if (!w)
- w = QGuiApplication::focusWindow();
- if (!w)
- return false;
-
- QObject *focus = w->focusObject();
- if (!focus)
- focus = w;
-
- QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
- qevent.setTimestamp(timestamp);
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, &qevent);
-#else
- Q_UNUSED(w)
- Q_UNUSED(timestamp)
- Q_UNUSED(k)
- Q_UNUSED(mods)
- Q_UNUSED(text)
- Q_UNUSED(autorep)
- Q_UNUSED(count)
- return false;
-#endif
-}
-
-bool QWindowSystemInterface::tryHandleShortcutOverrideEvent(QWindow *w, QKeyEvent *ev)
-{
-#ifndef QT_NO_SHORTCUT
- Q_ASSERT(ev->type() == QKeyEvent::ShortcutOverride);
- QGuiApplicationPrivate::modifier_buttons = ev->modifiers();
-
- QObject *focus = w->focusObject();
- if (!focus)
- focus = w;
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, ev);
-#else
- Q_UNUSED(w)
- Q_UNUSED(ev)
- return false;
-#endif
-}
-
-// used by QTestLib to directly send shortcuts to objects
-bool QWindowSystemInterface::tryHandleShortcutEventToObject(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString &text, bool autorep, ushort count)
+bool QWindowSystemInterface::handleShortcutEvent(QWindow *window, ulong timestamp, int keyCode, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode,
+ quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text, bool autorepeat, ushort count)
{
#ifndef QT_NO_SHORTCUT
- QGuiApplicationPrivate::modifier_buttons = mods;
-
- QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
- qevent.setTimestamp(timestamp);
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(o, &qevent);
-#else
- Q_UNUSED(w)
- Q_UNUSED(timestamp)
- Q_UNUSED(k)
- Q_UNUSED(mods)
- Q_UNUSED(text)
- Q_UNUSED(autorep)
- Q_UNUSED(count)
- return false;
-#endif
-}
-
-bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString &text, bool autorep, ushort count)
-{
- unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed();
- return tryHandleExtendedShortcutEvent(w, timestamp, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
-}
-
-bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString &text, bool autorep, ushort count)
-{
-#ifndef QT_NO_SHORTCUT
- QGuiApplicationPrivate::modifier_buttons = mods;
+ if (!window)
+ window = QGuiApplication::focusWindow();
+
+ QShortcutMap &shortcutMap = QGuiApplicationPrivate::instance()->shortcutMap;
+ if (shortcutMap.state() == QKeySequence::NoMatch) {
+ // Check if the shortcut is overridden by some object in the event delivery path (typically the focus object).
+ // If so, we should not look up the shortcut in the shortcut map, but instead deliver the event as a regular
+ // key event, so that the target that accepted the shortcut override event can handle it. Note that we only
+ // do this if the shortcut map hasn't found a partial shortcut match yet. If it has, the shortcut can not be
+ // overridden.
+ QWindowSystemInterfacePrivate::KeyEvent *shortcutOverrideEvent = new QWindowSystemInterfacePrivate::KeyEvent(window, timestamp,
+ QEvent::ShortcutOverride, keyCode, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorepeat, count);
+
+ {
+ // FIXME: Template handleWindowSystemEvent to support both sync and async delivery
+ QScopedValueRollback<bool> syncRollback(QWindowSystemInterfacePrivate::synchronousWindowSystemEvents);
+ QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = true;
+
+ if (QWindowSystemInterfacePrivate::handleWindowSystemEvent(shortcutOverrideEvent))
+ return false;
+ }
+ }
- QObject *focus = w->focusObject();
- if (!focus)
- focus = w;
+ // The shortcut event is dispatched as a QShortcutEvent, not a QKeyEvent, but we use
+ // the QKeyEvent as a container for the various properties that the shortcut map needs
+ // to inspect to determine if a shortcut matched the keys that were pressed.
+ QKeyEvent keyEvent(QEvent::ShortcutOverride, keyCode, modifiers, nativeScanCode,
+ nativeVirtualKey, nativeModifiers, text, autorepeat, count);
- QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
- qevent.setTimestamp(timestamp);
- return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, &qevent);
+ return shortcutMap.tryShortcut(&keyEvent);
#else
- Q_UNUSED(w)
+ Q_UNUSED(window)
Q_UNUSED(timestamp)
- Q_UNUSED(k)
- Q_UNUSED(mods)
+ Q_UNUSED(key)
+ Q_UNUSED(modifiers)
Q_UNUSED(nativeScanCode)
Q_UNUSED(nativeVirtualKey)
Q_UNUSED(nativeModifiers)
Q_UNUSED(text)
- Q_UNUSED(autorep)
+ Q_UNUSED(autorepeat)
Q_UNUSED(count)
return false;
#endif
}
-void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
+bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleKeyEvent(w, time, t, k, mods, text, autorep, count);
+ return handleKeyEvent(w, time, t, k, mods, text, autorep, count);
}
-void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
+bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
{
- // This is special handling needed for OS X which eventually will call sendEvent(), on other platforms
- // this might not be safe, e.g., on Android. See: QGuiApplicationPrivate::processKeyEvent() for
- // shortcut overriding on other platforms.
-#if defined(Q_OS_OSX)
- if (t == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, k, mods, text))
- return;
-#endif // Q_OS_OSX
+ if (t == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, timestamp, k, mods, 0, 0, 0, text, autorep, count))
+ return true;
QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text, bool autorep,
- ushort count)
+ ushort count, bool tryShortcutOverride)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
- text, autorep, count);
+ return handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
+ text, autorep, count, tryShortcutOverride);
}
-void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key,
+bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key,
Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text, bool autorep,
ushort count, bool tryShortcutOverride)
{
- Q_UNUSED(tryShortcutOverride)
+ if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw,
+ timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) {
+ return true;
+ }
+
QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers,
nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods) {
@@ -382,14 +321,14 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Simple case: vertical deltas only:
if (angleDelta.y() != 0 && angleDelta.x() == 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
// Simple case: horizontal deltas only:
if (angleDelta.y() == 0 && angleDelta.x() != 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
@@ -397,12 +336,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Both horizontal and vertical deltas: Send two wheel events.
// The first event contains the Qt 5 pixel and angle delta as points,
// and in addition the Qt 4 compatibility vertical angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
// The second event contains null pixel and angle points and the
// Qt 4 compatibility horizontal angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -440,23 +379,60 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e
windowSystemEventQueue.remove(event);
}
-void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
+void QWindowSystemInterfacePrivate::postWindowSystemEvent(WindowSystemEvent *ev)
{
- if (synchronousWindowsSystemEvents) {
- QGuiApplicationPrivate::processWindowSystemEvent(ev);
+ windowSystemEventQueue.append(ev);
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
+ if (dispatcher)
+ dispatcher->wakeUp();
+}
+
+/*!
+ Handles a window system event.
+
+ By default this function posts the event on the window system event queue and
+ wakes the Gui event dispatcher. Qt Gui will then handle the event asynchonously
+ at a later point. The return value is not used in asynchronous mode and will
+ always be true.
+
+ In synchronous mode Qt Gui will process the event immediately. The return value
+ indicates if Qt accepted the event.
+
+ \sa flushWindowSystemEvents(), setSynchronousWindowSystemEvents()
+*/
+bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
+{
+ bool accepted = true;
+ if (synchronousWindowSystemEvents) {
+ if (QThread::currentThread() == QGuiApplication::instance()->thread()) {
+ // Process the event immediately on the current thread and return the accepted state.
+ QGuiApplicationPrivate::processWindowSystemEvent(ev);
+ accepted = ev->eventAccepted;
+ delete ev;
+ } else {
+ // Post the event on the Qt main thread queue and flush the queue.
+ // This will wake up the Gui thread which will process the event.
+ // Return the accepted state for the last event on the queue,
+ // which is the event posted by this function.
+ postWindowSystemEvent(ev);
+ accepted = QWindowSystemInterface::flushWindowSystemEvents();
+ }
} else {
- windowSystemEventQueue.append(ev);
- QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
- if (dispatcher)
- dispatcher->wakeUp();
+ postWindowSystemEvent(ev);
}
+ return accepted;
}
-void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device)
+void QWindowSystemInterface::registerTouchDevice(const QTouchDevice *device)
{
QTouchDevicePrivate::registerDevice(device);
}
+void QWindowSystemInterface::unregisterTouchDevice(const QTouchDevice *device)
+{
+ QTouchDevicePrivate::unregisterDevice(device);
+}
+
void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
@@ -464,12 +440,16 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
handleTouchEvent(w, time, device, points, mods);
}
-QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type)
+QList<QTouchEvent::TouchPoint>
+ QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
+ const QWindow *window,
+ QEvent::Type *type)
{
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates states;
QTouchEvent::TouchPoint p;
+ touchPoints.reserve(points.count());
QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin();
QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd();
while (point != end) {
@@ -479,16 +459,16 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
p.setState(point->state);
const QPointF screenPos = point->area.center();
- p.setScreenPos(screenPos);
- p.setScreenRect(point->area);
+ p.setScreenPos(QHighDpi::fromNativePixels(screenPos, window));
+ p.setScreenRect(QHighDpi::fromNativePixels(point->area, window));
// The local pos and rect are not set, they will be calculated
// when the event gets processed by QGuiApplication.
- p.setNormalizedPos(point->normalPosition);
- p.setVelocity(point->velocity);
+ p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window));
+ p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window));
p.setFlags(point->flags);
- p.setRawScreenPositions(point->rawPositions);
+ p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window));
touchPoints.append(p);
++point;
@@ -506,6 +486,27 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
return touchPoints;
}
+QList<QWindowSystemInterface::TouchPoint>
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
+ const QWindow *window)
+{
+ QList<QWindowSystemInterface::TouchPoint> newList;
+ newList.reserve(pointList.size());
+ foreach (const QTouchEvent::TouchPoint &pt, pointList) {
+ QWindowSystemInterface::TouchPoint p;
+ p.id = pt.id();
+ p.flags = pt.flags();
+ p.normalPosition = QHighDpi::toNativeLocalPosition(pt.normalizedPos(), window);
+ p.area = QHighDpi::toNativePixels(pt.screenRect(), window);
+ p.pressure = pt.pressure();
+ p.state = pt.state();
+ p.velocity = pt.velocity();
+ p.rawPositions = pt.rawScreenPositions();
+ newList.append(p);
+ }
+ return newList;
+}
+
void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTouchDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
@@ -516,7 +517,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo
return;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, tlw, &type);
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods);
@@ -549,14 +550,14 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::
void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry)
{
QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
- new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry);
+ new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft()));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY)
{
QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e =
- new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY);
+ new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); // ### tja
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -575,7 +576,7 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{
- QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
+ QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -584,30 +585,37 @@ void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::Process
Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
- flushWindowSystemEvents(flags);
+ sendWindowSystemEvents(flags);
QWindowSystemInterfacePrivate::eventsFlushed.wakeOne();
}
-void QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
+/*!
+ Make Qt Gui process all events on the event queue immediately. Return the
+ accepted state for the last event on the queue.
+*/
+bool QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
{
const int count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count();
if (!count)
- return;
+ return false;
if (!QGuiApplication::instance()) {
qWarning().nospace()
<< "QWindowSystemInterface::flushWindowSystemEvents() invoked after "
"QGuiApplication destruction, discarding " << count << " events.";
QWindowSystemInterfacePrivate::windowSystemEventQueue.clear();
- return;
+ return false;
}
if (QThread::currentThread() != QGuiApplication::instance()->thread()) {
+ // Post a FlushEvents event which will trigger a call back to
+ // deferredFlushWindowSystemEvents from the Gui thread.
QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
QWindowSystemInterfacePrivate::FlushEventsEvent *e = new QWindowSystemInterfacePrivate::FlushEventsEvent(flags);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ QWindowSystemInterfacePrivate::postWindowSystemEvent(e);
QWindowSystemInterfacePrivate::eventsFlushed.wait(&QWindowSystemInterfacePrivate::flushEventMutex);
} else {
sendWindowSystemEvents(flags);
}
+ return QWindowSystemInterfacePrivate::eventAccepted.load() > 0;
}
bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
@@ -621,17 +629,42 @@ bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFla
QWindowSystemInterfacePrivate::getWindowSystemEvent();
if (!event)
break;
- nevents++;
- QGuiApplicationPrivate::processWindowSystemEvent(event);
+
+ if (QWindowSystemInterfacePrivate::eventHandler) {
+ if (QWindowSystemInterfacePrivate::eventHandler->sendEvent(event))
+ nevents++;
+ } else {
+ nevents++;
+ QGuiApplicationPrivate::processWindowSystemEvent(event);
+ }
+
+ // Record the accepted state for the processed event
+ // (excluding flush events). This state can then be
+ // returned by flushWindowSystemEvents().
+ if (event->type != QWindowSystemInterfacePrivate::FlushEvents)
+ QWindowSystemInterfacePrivate::eventAccepted.store(event->eventAccepted);
+
delete event;
}
return (nevents > 0);
}
-void QWindowSystemInterface::setSynchronousWindowsSystemEvents(bool enable)
+void QWindowSystemInterfacePrivate::installWindowSystemEventHandler(QWindowSystemEventHandler *handler)
+{
+ if (!eventHandler)
+ eventHandler = handler;
+}
+
+void QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(QWindowSystemEventHandler *handler)
+{
+ if (eventHandler == handler)
+ eventHandler = 0;
+}
+
+void QWindowSystemInterface::setSynchronousWindowSystemEvents(bool enable)
{
- QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = enable;
+ QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = enable;
}
int QWindowSystemInterface::windowSystemEventsQueued()
@@ -642,12 +675,12 @@ int QWindowSystemInterface::windowSystemEventsQueued()
#ifndef QT_NO_DRAGANDDROP
QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrag(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrag(w, dropData, QHighDpi::fromNativeLocalPosition(p, w) ,supportedActions);
}
QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrop(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrop(w, dropData, QHighDpi::fromNativeLocalPosition(p, w),supportedActions);
}
#endif // QT_NO_DRAGANDDROP
@@ -681,8 +714,11 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, cons
Qt::KeyboardModifiers modifiers)
{
QWindowSystemInterfacePrivate::TabletEvent *e =
- new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure,
- xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+ new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp,
+ QHighDpi::fromNativeLocalPosition(local, w),
+ QHighDpi::fromNativePixels(global, w),
+ device, pointerType, buttons, pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -807,18 +843,60 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo
}
#endif
-Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) {
- QWindowSystemInterface::handleMouseEvent(w, local, global, b, mods);
+// The following functions are used by testlib, and need to be synchronous to avoid
+// race conditions with plugins delivering native events from secondary threads.
+
+Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp)
+{
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
+ QWindowSystemInterface::handleMouseEvent(w, timestamp, local, global, b, mods);
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
}
Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
{
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
QWindowSystemInterface::handleKeyEvent(w, t, k, mods, text, autorep, count);
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
}
-Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
+Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
{
- return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count);
+#ifndef QT_NO_SHORTCUT
+
+ // FIXME: This method should not allow targeting a specific object, but should
+ // instead forward the event to a window, which then takes care of normal event
+ // propagation. We need to fix a lot of tests before we can refactor this (the
+ // window needs to be exposed and active and have a focus object), so we leave
+ // it as is for now. See QTBUG-48577.
+
+ QGuiApplicationPrivate::modifier_buttons = mods;
+
+ QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
+ qevent.setTimestamp(timestamp);
+
+ QShortcutMap &shortcutMap = QGuiApplicationPrivate::instance()->shortcutMap;
+ if (shortcutMap.state() == QKeySequence::NoMatch) {
+ // Try sending as QKeyEvent::ShortcutOverride first
+ QCoreApplication::sendEvent(o, &qevent);
+ if (qevent.isAccepted())
+ return false;
+ }
+
+ // Then as QShortcutEvent
+ return shortcutMap.tryShortcut(&qevent);
+#else
+ Q_UNUSED(o)
+ Q_UNUSED(timestamp)
+ Q_UNUSED(k)
+ Q_UNUSED(mods)
+ Q_UNUSED(text)
+ Q_UNUSED(autorep)
+ Q_UNUSED(count)
+ return false;
+#endif
}
static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt)
@@ -839,17 +917,31 @@ static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QLi
QList<struct QWindowSystemInterface::TouchPoint> newList;
Q_FOREACH (QTouchEvent::TouchPoint p, pointList)
- {
newList.append(touchPoint(p));
- }
+
return newList;
}
-Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
+Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<QTouchEvent::TouchPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier)
{
+ bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents;
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods);
+ QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
}
+QWindowSystemEventHandler::~QWindowSystemEventHandler()
+{
+ QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(this);
+}
+
+bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
+{
+ QGuiApplicationPrivate::processWindowSystemEvent(e);
+ return true;
+}
+
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 448c5d0893..a27c68649e 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -78,32 +78,18 @@ public:
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
- static bool tryHandleShortcutOverrideEvent(QWindow *w, QKeyEvent *ev);
+ static bool handleShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode,
+ quint32 nativeVirtualKey, quint32 nativeModifiers, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static bool handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static bool handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleShortcutEventToObject(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
-
- static bool tryHandleExtendedShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
- static bool tryHandleExtendedShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- const QString & text = QString(), bool autorep = false, ushort count = 1);
-
- static void handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static void handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
-
- static void handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ static bool handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
- ushort count = 1);
- static void handleExtendedKeyEvent(QWindow *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ ushort count = 1, bool tryShortcutOverride = true);
+ static bool handleExtendedKeyEvent(QWindow *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
@@ -127,7 +113,8 @@ public:
QVector<QPointF> rawPositions; // in screen coordinates
};
- static void registerTouchDevice(QTouchDevice *device);
+ static void registerTouchDevice(const QTouchDevice *device);
+ static void unregisterTouchDevice(const QTouchDevice *device);
static void handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
static void handleTouchEvent(QWindow *w, ulong timestamp, QTouchDevice *device,
@@ -212,8 +199,8 @@ public:
// For event dispatcher implementations
static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
- static void setSynchronousWindowsSystemEvents(bool enable);
- static void flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents);
+ static void setSynchronousWindowSystemEvents(bool enable);
+ static bool flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents);
static void deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
static int windowSystemEventsQueued();
};
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 2ec402a1e9..e48d1e965b 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -51,9 +51,12 @@
#include <QMutex>
#include <QList>
#include <QWaitCondition>
+#include <QAtomicInt>
QT_BEGIN_NAMESPACE
+class QWindowSystemEventHandler;
+
class Q_GUI_EXPORT QWindowSystemInterfacePrivate {
public:
enum EventType {
@@ -99,7 +102,7 @@ public:
};
explicit WindowSystemEvent(EventType t)
- : type(t), flags(0) { }
+ : type(t), flags(0), eventAccepted(true) { }
virtual ~WindowSystemEvent() { }
bool synthetic() const { return flags & Synthetic; }
@@ -107,6 +110,7 @@ public:
EventType type;
int flags;
+ bool eventAccepted;
};
class CloseEvent : public WindowSystemEvent {
@@ -478,15 +482,33 @@ public:
static WindowSystemEvent *getNonUserInputWindowSystemEvent();
static WindowSystemEvent *peekWindowSystemEvent(EventType t);
static void removeWindowSystemEvent(WindowSystemEvent *event);
- static void handleWindowSystemEvent(WindowSystemEvent *ev);
+ static void postWindowSystemEvent(WindowSystemEvent *ev);
+ static bool handleWindowSystemEvent(WindowSystemEvent *ev);
static QElapsedTimer eventTime;
- static bool synchronousWindowsSystemEvents;
+ static bool synchronousWindowSystemEvents;
static QWaitCondition eventsFlushed;
static QMutex flushEventMutex;
+ static QAtomicInt eventAccepted;
+
+ static QList<QTouchEvent::TouchPoint>
+ fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
+ const QWindow *window, QEvent::Type *type = Q_NULLPTR);
+ static QList<QWindowSystemInterface::TouchPoint>
+ toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
+ const QWindow *window);
+
+ static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
+ static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);
+ static QWindowSystemEventHandler *eventHandler;
+};
- static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type);
+class Q_GUI_EXPORT QWindowSystemEventHandler
+{
+public:
+ virtual ~QWindowSystemEventHandler();
+ virtual bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *event);
};
QT_END_NAMESPACE