summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp16
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm25
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm6
-rw-r--r--src/plugins/platforms/ios/quiview_textinput.mm2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp3
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp10
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp29
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp3
-rw-r--r--src/plugins/printsupport/windows/windows.pro2
14 files changed, 111 insertions, 31 deletions
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 3324d9ba49..02fda19d76 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -338,7 +338,7 @@ static JNINativeMethod methods[] = {
QAndroidInputContext::QAndroidInputContext()
- : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0)
+ : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0)
{
QtAndroid::AttachedJNIEnv env;
if (!env.jniEnv)
@@ -532,6 +532,18 @@ void QAndroidInputContext::clear()
m_extractedText.clear();
}
+
+void QAndroidInputContext::setFocusObject(QObject *object)
+{
+ if (object != m_focusObject) {
+ m_focusObject = object;
+ if (!m_composingText.isEmpty())
+ finishComposingText();
+ reset();
+ }
+ QPlatformInputContext::setFocusObject(object);
+}
+
void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodEvent *event)
{
QCoreApplication::sendEvent(receiver, event);
@@ -678,7 +690,7 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{
QVariant textBefore = queryFocusObjectThreadSafe(Qt::ImTextBeforeCursor, QVariant(length));
if (textBefore.isValid()) {
- return textBefore.toString().left(length) + m_composingText;
+ return textBefore.toString().right(length) + m_composingText;
}
//compatibility code for old controls that do not implement the new API
diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index f7b29a855f..3ce141ae15 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
@@ -95,6 +95,7 @@ public:
bool isComposing() const;
void clear();
+ void setFocusObject(QObject *object);
//---------------//
jboolean beginBatchEdit();
@@ -136,6 +137,7 @@ private:
QMetaObject::Connection m_updateCursorPosConnection;
bool m_blockUpdateSelection;
int m_batchEditNestingLevel;
+ QObject *m_focusObject;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 0274ed8201..de6c6585e9 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -134,6 +134,8 @@ public:
void interrupt();
void flush();
+ bool event(QEvent *);
+
friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher);
};
@@ -163,7 +165,6 @@ public:
// The following variables help organizing modal sessions:
QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
bool currentExecIsNSAppRun;
- bool modalSessionOnNSAppRun;
bool nsAppRunCalledByQt;
bool cleanupModalSessionsNeeded;
uint processEventsCalled;
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 495a54cac4..e0ce9f9648 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -734,13 +734,25 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
updateChildrenWorksWhenModal();
currentModalSessionCached = 0;
if (currentExecIsNSAppRun) {
- modalSessionOnNSAppRun = true;
- q->wakeUp();
+ QEvent *e = new QEvent(QEvent::User);
+ qApp->postEvent(q, e, Qt::HighEventPriority);
} else {
q->interrupt();
}
}
+bool QCocoaEventDispatcher::event(QEvent *e)
+{
+ Q_D(QCocoaEventDispatcher);
+
+ if (e->type() == QEvent::User) {
+ d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents);
+ return true;
+ }
+
+ return QObject::event(e);
+}
+
void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
{
Q_Q(QCocoaEventDispatcher);
@@ -777,7 +789,6 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
runLoopTimerRef(0),
blockSendPostedEvents(false),
currentExecIsNSAppRun(false),
- modalSessionOnNSAppRun(false),
nsAppRunCalledByQt(false),
cleanupModalSessionsNeeded(false),
processEventsCalled(0),
@@ -908,14 +919,6 @@ void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info)
// processEvents() was called "manually," ignore this source for now
d->maybeCancelWaitForMoreEvents();
return;
- } else if (d->modalSessionOnNSAppRun) {
- // We're about to spawn the 1st modal session on top of the main runloop.
- // Instead of calling processPostedEvents(), which would need us stop
- // NSApp, we just re-enter processEvents(). This is equivalent to calling
- // QDialog::exec() except that it's done in a non-blocking way.
- d->modalSessionOnNSAppRun = false;
- d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents);
- return;
}
d->processPostedEvents();
d->maybeCancelWaitForMoreEvents();
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index e2572d607a..5d20764c87 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -680,8 +680,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (m_platformWindow->m_activePopupWindow) {
QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow);
QWindowSystemInterface::flushWindowSystemEvents();
+ Qt::WindowType type = m_platformWindow->m_activePopupWindow->type();
m_platformWindow->m_activePopupWindow = 0;
- return;
+ // Consume the mouse event when closing the popup, except for tool tips
+ // were it's expected that the event is processed normally.
+ if (type != Qt::ToolTip)
+ return;
}
if ([self hasMarkedText]) {
NSInputManager* inputManager = [NSInputManager currentInputManager];
diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm
index 28fb23d57b..3f6c6d1256 100644
--- a/src/plugins/platforms/ios/quiview_textinput.mm
+++ b/src/plugins/platforms/ios/quiview_textinput.mm
@@ -473,6 +473,8 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
QCoreApplication::sendEvent(focusObject, &e);
QFont qfont = qvariant_cast<QFont>(e.value(Qt::ImFont));
UIFont *uifont = [UIFont fontWithName:qfont.family().toNSString() size:qfont.pointSize()];
+ if (!uifont)
+ return [NSDictionary dictionary];
return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey];
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 1432dfdcd9..940d75614c 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -1040,7 +1040,11 @@ QWindowsFontDatabase::~QWindowsFontDatabase()
QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
{
- return new QWindowsMultiFontEngine(fontEngine, script);
+ if (script == QChar::Script_Common)
+ return new QWindowsMultiFontEngine(fontEngine, script);
+ // ### as long as fallbacksForFamily() does not take script parameter into account,
+ // prefer QFontEngineMultiQPA's loadEngine() implementation for complex scripts
+ return QPlatformFontDatabase::fontEngineMulti(fontEngine, script);
}
QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
@@ -1619,8 +1623,7 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon
result << QString::fromLatin1("Arial");
}
- if (script == QChar::Script_Common || script == QChar::Script_Han)
- result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
+ result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
<< script << result << m_families.size();
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 51961014d9..734f645e65 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -477,8 +477,7 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF
}
#endif
- if (script == QChar::Script_Common || script == QChar::Script_Han)
- result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
+ result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
<< script << result << m_families;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 2e38f81499..583441f396 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -1020,7 +1020,9 @@ HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
{
QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
+ QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
backPress.setAccepted(false);
+ backRelease.setAccepted(false);
QObject *receiver = m_visibleWindows.isEmpty()
? static_cast<QObject *>(QGuiApplication::instance())
@@ -1028,12 +1030,8 @@ HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs
// If the event is ignored, the app will suspend
QGuiApplication::sendEvent(receiver, &backPress);
- if (backPress.isAccepted()) {
- args->put_Handled(true);
- // If the app accepts the event, send the release for symmetry
- QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
- QGuiApplication::sendEvent(receiver, &backRelease);
- }
+ QGuiApplication::sendEvent(receiver, &backRelease);
+ args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
return S_OK;
}
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index c183deb3b8..f78d3bcc4e 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -449,12 +449,32 @@ bool QGLXContext::m_supportsThreading = true;
// binary search.
static const char *qglx_threadedgl_blacklist_renderer[] = {
"Chromium", // QTBUG-32225 (initialization fails)
- "Mesa DRI Intel(R) Sandybridge Mobile", // QTBUG-34492 (flickering in fullscreen)
0
};
+// This disables threaded rendering on anything using mesa, e.g.
+// - nvidia/nouveau
+// - amd/gallium
+// - intel
+// - some software opengl implementations
+//
+// The client glx vendor string is used to identify those setups as that seems to show the least
+// variance between the bad configurations. It's always "Mesa Project and SGI". There are some
+// configurations which don't use mesa and which can do threaded rendering (amd and nvidia chips
+// with their own proprietary drivers).
+//
+// This, of course, is very broad and disables threaded rendering on a lot of devices which would
+// be able to use it. However, the bugs listed below don't follow any easily recognizable pattern
+// and we should rather be safe.
+//
+// http://cgit.freedesktop.org/xcb/libxcb/commit/?id=be0fe56c3bcad5124dcc6c47a2fad01acd16f71a will
+// fix some of the issues. Basically, the proprietary drivers seem to have a way of working around
+// a fundamental flaw with multithreaded access to xcb, but mesa doesn't. The blacklist should be
+// reevaluated once that patch is released in some version of xcb.
static const char *qglx_threadedgl_blacklist_vendor[] = {
- "nouveau", // QTCREATORBUG-10875 (crash in creator)
+ "Mesa Project and SGI", // QTCREATORBUG-10875 (crash in creator)
+ // QTBUG-34492 (flickering in fullscreen)
+ // QTBUG-38221
0
};
@@ -502,9 +522,9 @@ void QGLXContext::queryDummyContext()
}
}
- if (const char *vendor = (const char *) glGetString(GL_VENDOR)) {
+ if (glxvendor) {
for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) {
- if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) {
+ if (strstr(glxvendor, qglx_threadedgl_blacklist_vendor[i]) != 0) {
m_supportsThreading = false;
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index a994c51c7d..13a0280baf 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -454,6 +454,10 @@ public:
QXcbSystemTrayTracker *systemTrayTracker();
+#ifdef XCB_USE_XINPUT2
+ void handleEnterEvent(const xcb_enter_notify_event_t *);
+#endif
+
private slots:
void processXcbEvents();
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index d80b49ccbb..d7b3c75aee 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -524,6 +524,35 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
}
+void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *)
+{
+#ifdef XCB_USE_XINPUT21
+ QHash<int, ScrollingDevice>::iterator it = m_scrollingDevices.begin();
+ const QHash<int, ScrollingDevice>::iterator end = m_scrollingDevices.end();
+ while (it != end) {
+ ScrollingDevice& scrollingDevice = it.value();
+ int nrDevices = 0;
+ XIDeviceInfo* xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), scrollingDevice.deviceId, &nrDevices);
+ if (nrDevices <= 0) {
+ it = m_scrollingDevices.erase(it);
+ continue;
+ }
+ for (int c = 0; c < xiDeviceInfo->num_classes; ++c) {
+ if (xiDeviceInfo->classes[c]->type == XIValuatorClass) {
+ XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(xiDeviceInfo->classes[c]);
+ const int valuatorAtom = qatom(vci->label);
+ if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
+ scrollingDevice.lastScrollPosition.setX(vci->value);
+ else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
+ scrollingDevice.lastScrollPosition.setY(vci->value);
+ }
+ }
+ XIFreeDeviceInfo(xiDeviceInfo);
+ ++it;
+ }
+#endif
+}
+
void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
{
#ifdef XCB_USE_XINPUT21
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index dbffd577c1..fb9c03b66d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1844,6 +1844,9 @@ public:
void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
{
connection()->setTime(event->time);
+#ifdef XCB_USE_XINPUT2
+ connection()->handleEnterEvent(event);
+#endif
if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB)
|| event->detail == XCB_NOTIFY_DETAIL_VIRTUAL
diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro
index 364e19e68e..3366262ef0 100644
--- a/src/plugins/printsupport/windows/windows.pro
+++ b/src/plugins/printsupport/windows/windows.pro
@@ -21,4 +21,4 @@ HEADERS += \
OTHER_FILES += windows.json
-LIBS += -lwinspool -lcomdlg32
+LIBS += -lwinspool -lcomdlg32 -lgdi32 -luser32