summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qguiapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r--src/gui/kernel/qguiapplication.cpp102
1 files changed, 65 insertions, 37 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 64be8ee3d9..2e0595152b 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>
@@ -867,7 +870,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));
}
@@ -875,16 +878,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())
@@ -906,7 +899,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()
*/
/*!
@@ -923,6 +916,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.
@@ -958,8 +968,10 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
QList<QScreen *>::const_iterator end = screens.constEnd();
while (screen != end) {
- if ((*screen)->geometry().contains(pos))
- return (*screen)->handle()->topLevelAt(pos);
+ if ((*screen)->geometry().contains(pos)) {
+ const QPoint devicePosition = QHighDpi::toNativePixels(pos, *screen);
+ return (*screen)->handle()->topLevelAt(devicePosition);
+ }
++screen;
}
return 0;
@@ -1115,6 +1127,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"));
@@ -1204,6 +1219,10 @@ void QGuiApplicationPrivate::eventDispatcherReady()
createPlatformIntegration();
platform_integration->initialize();
+
+ // Do this here in order to play nice with platforms that add screens only
+ // in initialize().
+ QHighDpiScaling::updateHighDpiScaling();
}
void QGuiApplicationPrivate::init()
@@ -1216,6 +1235,16 @@ 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
int j = argc ? 1 : 0;
for (int i=1; i<argc; i++) {
@@ -1328,6 +1357,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()) {
@@ -1342,6 +1374,8 @@ void QGuiApplicationPrivate::init()
qCritical() << "Library qttestability load failed:" << testLib.errorString();
}
}
+#else
+ Q_UNUSED(loadTestability);
#endif // QT_NO_LIBRARY
}
@@ -1691,12 +1725,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();
@@ -1765,9 +1801,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!window)
return;
- QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
+ QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source);
ev.setTimestamp(e->timestamp);
- setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
if (!e->synthetic()) {
if (const QScreen *screen = window->screen())
@@ -1787,6 +1822,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)) {
@@ -1815,7 +1851,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;
@@ -1826,9 +1862,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);
}
}
@@ -1880,19 +1915,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);
@@ -1920,6 +1942,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
}
}
#endif
+ e->eventAccepted = ev.isAccepted();
}
void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
@@ -2032,6 +2055,11 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
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);
+ }
}
}