diff options
Diffstat (limited to 'src/plugins/platforms')
35 files changed, 239 insertions, 197 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index 309e41bfd6..d4b7f38bf6 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -329,10 +329,7 @@ if (!clazz) { \ GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V"); GET_AND_CHECK_STATIC_METHOD(m_setScrollableMethodID, nodeInfoClass, "setScrollable", "(Z)V"); GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V"); - - if (QtAndroidPrivate::androidSdkVersion() >= 18) { - GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V"); - } + GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V"); return true; } diff --git a/src/plugins/platforms/android/extract-dummy.cpp b/src/plugins/platforms/android/extract-dummy.cpp index d07fbe1ba7..fdce8ec64c 100644 --- a/src/plugins/platforms/android/extract-dummy.cpp +++ b/src/plugins/platforms/android/extract-dummy.cpp @@ -40,16 +40,6 @@ #include <jni.h> #include <extract.h> -extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(JNIEnv *, jobject, Res_png_9patch*) -{ - return 0; -} - -extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo(JNIEnv *, jobject, jbyteArray) -{ - return 0; -} - extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20(JNIEnv *, jobject, long) { return 0; diff --git a/src/plugins/platforms/android/extract.cpp b/src/plugins/platforms/android/extract.cpp index 2f2ffa7126..acffa353f1 100644 --- a/src/plugins/platforms/android/extract.cpp +++ b/src/plugins/platforms/android/extract.cpp @@ -48,46 +48,6 @@ #define LOG_TAG "extractSyleInfo" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) -extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(JNIEnv * env, jobject, Res_png_9patch* chunk) -{ - Res_png_9patch::deserialize(chunk); - //printChunkInformation(chunk); - jintArray result; - size_t size = 3+chunk->numXDivs+chunk->numYDivs+chunk->numColors; - result = env->NewIntArray(size); - if (!result) - return 0; - - jint *data = (jint*)malloc(sizeof(jint)*size); - size_t pos = 0; - data[pos++]=chunk->numXDivs; - data[pos++]=chunk->numYDivs; - data[pos++]=chunk->numColors; - for (int x = 0; x <chunk->numXDivs; x ++) - data[pos++]=chunk->xDivs[x]; - for (int y = 0; y <chunk->numYDivs; y ++) - data[pos++]=chunk->yDivs[y]; - for (int c = 0; c <chunk->numColors; c ++) - data[pos++]=chunk->colors[c]; - env->SetIntArrayRegion(result, 0, size, data); - free(data); - return result; -} - -extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo(JNIEnv * env, jobject obj, jbyteArray chunkObj) -{ - size_t chunkSize = env->GetArrayLength(chunkObj); - void* storage = alloca(chunkSize); - env->GetByteArrayRegion(chunkObj, 0, chunkSize, - reinterpret_cast<jbyte*>(storage)); - - if (!env->ExceptionCheck()) - return Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(env, obj, static_cast<Res_png_9patch*>(storage)); - else - env->ExceptionClear(); - return 0; -} - // The following part was shamelessly stolen from ResourceTypes.cpp from Android's sources /* * Copyright (C) 2005 The Android Open Source Project diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index f26263261c..f0ef70e3a3 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -51,6 +51,19 @@ QT_USE_NAMESPACE #ifndef QT_NO_ACCESSIBILITY +/** + * Converts between absolute character offsets and line numbers of a + * QAccessibleTextInterface. Works in exactly one of two modes: + * + * - Pass *line == -1 in order to get a line containing character at the given + * *offset + * - Pass *offset == -1 in order to get the offset of first character of the + * given *line + * + * You can optionally also pass non-NULL `start` and `end`, which will in both + * modes be filled with the offset of the first and last characters of the + * relevant line. + */ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *offset, NSUInteger *start = 0, NSUInteger *end = 0) { Q_ASSERT(*line == -1 || *offset == -1); @@ -224,7 +237,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return [attributes autorelease]; } -- (id)parentElement { +- (id)accessibilityParent { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); if (!iface || !iface->isValid()) return nil; @@ -237,7 +250,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (QAccessibleInterface *parent = iface->parent()) { if (parent->role() != QAccessible::Application) { QAccessible::Id parentId = QAccessible::uniqueId(parent); - return [QMacAccessibilityElement elementWithId: parentId]; + return NSAccessibilityUnignoredAncestor([QMacAccessibilityElement elementWithId: parentId]); } } @@ -245,12 +258,18 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of QPlatformWindow *platformWindow = window->handle(); if (platformWindow) { QCocoaWindow *win = static_cast<QCocoaWindow*>(platformWindow); - return qnsview_cast(win->view()); + return NSAccessibilityUnignoredAncestor(qnsview_cast(win->view())); } } return nil; } +- (NSRect)accessibilityFrame { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return NSZeroRect; + return QCocoaScreen::mapToNative(iface->rect()); +} - (id) minValueAttribute:(QAccessibleInterface*)iface { if (QAccessibleValueInterface *val = iface->valueInterface()) @@ -285,13 +304,13 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute]; return @([focusedElement isEqual:self]); } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { - return NSAccessibilityUnignoredAncestor([self parentElement]); + return self.accessibilityParent; } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) { // We're in the same window as our parent. - return [[self parentElement] accessibilityAttributeValue:NSAccessibilityWindowAttribute]; + return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityWindowAttribute]; } else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) { // We're in the same top level element as our parent. - return [[self parentElement] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; + return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { // The position in points of the element's lower-left corner in screen-relative coordinates QPointF qtPosition = QRectF(iface->rect()).bottomLeft(); @@ -347,12 +366,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return [NSValue valueWithRange: NSMakeRange(0, iface->text(QAccessible::Name).length())]; } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { - int line = 0; // true for all single line edits - if (iface->state().multiLine) { - int position = text->cursorPosition(); - convertLineOffset(text, &line, &position); - } - return @(line); + int position = text->cursorPosition(); + return [self accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:@(position)]; } return nil; } else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) { @@ -408,8 +423,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of int index = [parameter intValue]; if (index < 0 || index > iface->textInterface()->characterCount()) return nil; - int line = -1; - convertLineOffset(iface->textInterface(), &line, &index); + int line = 0; // true for all single line edits + if (iface->state().multiLine) { + line = -1; + convertLineOffset(iface->textInterface(), &line, &index); + } return @(line); } if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) { diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index a1bed3db45..beb17ec44e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -218,6 +218,7 @@ QCocoaWindow::~QCocoaWindow() } [m_view release]; + [m_nsWindow close]; [m_nsWindow release]; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 24f82e7843..24051c352e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -423,7 +423,7 @@ void QEglFSKmsGbmScreen::updateFlipStatus() if (m_flipPending) return; - for (const CloneDestination &d : m_cloneDests) { + for (const CloneDestination &d : qAsConst(m_cloneDests)) { if (d.cloneFlipPending) return; } diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index db79780407..a996e765c4 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -72,6 +72,9 @@ # endif #endif +#include <qpa/qplatforminputcontextfactory_p.h> +#include <qpa/qplatforminputcontext.h> + #include "private/qgenericunixfontdatabase_p.h" #include "private/qgenericunixeventdispatcher_p.h" @@ -152,6 +155,7 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) , m_inputContext(0) , m_buttonsNotifier(new QQnxButtonEventNotifier()) #endif + , m_qpaInputContext(0) , m_services(0) , m_fontDatabase(new QGenericUnixFontDatabase()) , m_eventDispatcher(createUnixEventDispatcher()) @@ -194,13 +198,17 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) m_screenEventHandler->setScreenEventThread(m_screenEventThread); m_screenEventThread->start(); + m_qpaInputContext = QPlatformInputContextFactory::create(); + #if QT_CONFIG(qqnx_pps) - // Create/start the keyboard class. - m_virtualKeyboard = new QQnxVirtualKeyboardPps(); + if (!m_qpaInputContext) { + // Create/start the keyboard class. + m_virtualKeyboard = new QQnxVirtualKeyboardPps(); - // delay invocation of start() to the time the event loop is up and running - // needed to have the QThread internals of the main thread properly initialized - QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); + // delay invocation of start() to the time the event loop is up and running + // needed to have the QThread internals of the main thread properly initialized + QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); + } #endif #if QT_CONFIG(qqnx_pps) @@ -281,6 +289,7 @@ QQnxIntegration::~QQnxIntegration() // Destroy input context delete m_inputContext; #endif + delete m_qpaInputContext; // Destroy the keyboard class. delete m_virtualKeyboard; @@ -397,13 +406,13 @@ QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLCont } #endif -#if QT_CONFIG(qqnx_pps) QPlatformInputContext *QQnxIntegration::inputContext() const { qIntegrationDebug(); + if (m_qpaInputContext) + return m_qpaInputContext; return m_inputContext; } -#endif void QQnxIntegration::moveToScreen(QWindow *window, int screen) { diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index 4a6f15fc08..366556dc4b 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -153,6 +153,7 @@ private: QQnxInputContext *m_inputContext; QQnxButtonEventNotifier *m_buttonsNotifier; #endif + QPlatformInputContext *m_qpaInputContext; QQnxServices *m_services; QPlatformFontDatabase *m_fontDatabase; mutable QAbstractEventDispatcher *m_eventDispatcher; diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index e4843cb438..f29e11489b 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -381,6 +381,8 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event) if (m_lastGlobalMousePoint != globalPoint || m_lastLocalMousePoint != localPoint || m_lastButtonState != buttons) { + if (m_lastButtonState != 0 && buttons == 0) + (static_cast<QQnxWindow *>(w->handle()))->handleActivationEvent(); QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); qScreenEventDebug() << "Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast<int>(buttons); } @@ -457,6 +459,9 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType) m_lastMouseWindow = qnxWindow; if (w) { + if (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) + (static_cast<QQnxWindow *>(w->handle()))->handleActivationEvent(); + // get size of screen which contains window QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w); QSizeF screenSize = platformScreen->geometry().size(); diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 2096bc789e..7644e28b44 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -156,7 +156,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW m_visible(false), m_exposed(true), m_windowState(Qt::WindowNoState), - m_mmRendererWindow(0) + m_mmRendererWindow(0), + m_firstActivateHandled(false) { qWindowDebug() << "window =" << window << ", size =" << window->size(); @@ -341,6 +342,14 @@ void QQnxWindow::setVisible(bool visible) if (visible) { applyWindowState(); } else { + if (showWithoutActivating() && focusable() && m_firstActivateHandled) { + m_firstActivateHandled = false; + int val = SCREEN_SENSITIVITY_NO_FOCUS; + Q_SCREEN_CHECKERROR( + screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val), + "Failed to set window sensitivity"); + } + // Flush the context, otherwise it won't disappear immediately screen_flush_context(m_screenContext, 0); } @@ -618,13 +627,56 @@ void QQnxWindow::requestActivateWindow() void QQnxWindow::setFocus(screen_window_t newFocusWindow) { + screen_window_t temporaryFocusWindow = nullptr; + screen_group_t screenGroup = 0; - screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP, - reinterpret_cast<void**>(&screenGroup)); - if (screenGroup) { - screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS, - reinterpret_cast<void**>(&newFocusWindow)); + Q_SCREEN_CHECKERROR(screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP, + reinterpret_cast<void **>(&screenGroup)), + "Failed to retrieve window group"); + + if (showWithoutActivating() && focusable() && !m_firstActivateHandled) { + m_firstActivateHandled = true; + int val = SCREEN_SENSITIVITY_TEST; + Q_SCREEN_CHECKERROR( + screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val), + "Failed to set window sensitivity"); + +#if _SCREEN_VERSION < _SCREEN_MAKE_VERSION(1, 0, 0) + // For older versions of screen, the window may still have group + // focus even though it was marked NO_FOCUS when it was hidden. + // In that situation, focus has to be given to another window + // so that this window can take focus back from it. + screen_window_t oldFocusWindow = nullptr; + Q_SCREEN_CHECKERROR( + screen_get_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS, + reinterpret_cast<void **>(&oldFocusWindow)), + "Failed to retrieve group focus"); + if (newFocusWindow == oldFocusWindow) { + char groupName[256]; + memset(groupName, 0, sizeof(groupName)); + Q_SCREEN_CHECKERROR(screen_get_group_property_cv(screenGroup, SCREEN_PROPERTY_NAME, + sizeof(groupName) - 1, groupName), + "Failed to retrieve group name"); + + Q_SCREEN_CHECKERROR(screen_create_window_type(&temporaryFocusWindow, + m_screenContext, SCREEN_CHILD_WINDOW), + "Failed to create temporary focus window"); + Q_SCREEN_CHECKERROR(screen_join_window_group(temporaryFocusWindow, groupName), + "Temporary focus window failed to join window group"); + Q_SCREEN_CHECKERROR( + screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS, + reinterpret_cast<void **>(&temporaryFocusWindow)), + "Temporary focus window failed to take focus"); + screen_flush_context(m_screenContext, 0); + } +#endif } + + Q_SCREEN_CHECKERROR(screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS, + reinterpret_cast<void **>(&newFocusWindow)), + "Failed to set group focus"); + + screen_destroy_window(temporaryFocusWindow); } void QQnxWindow::setWindowState(Qt::WindowStates state) @@ -711,7 +763,11 @@ void QQnxWindow::initWindow() screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val), "Failed to set swap interval"); - if (window()->flags() & Qt::WindowDoesNotAcceptFocus) { + if (showWithoutActivating() || !focusable()) { + // NO_FOCUS is temporary for showWithoutActivating (and pop-up) windows. + // Using NO_FOCUS ensures that screen doesn't activate the window because + // it was just created. Sensitivity will be changed to TEST when the + // window is clicked or touched. val = SCREEN_SENSITIVITY_NO_FOCUS; Q_SCREEN_CHECKERROR( screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val), @@ -825,4 +881,22 @@ bool QQnxWindow::shouldMakeFullScreen() const && (QQnxIntegration::instance()->options() & QQnxIntegration::FullScreenApplication)); } + +void QQnxWindow::handleActivationEvent() +{ + if (showWithoutActivating() && focusable() && !m_firstActivateHandled) + requestActivateWindow(); +} + +bool QQnxWindow::showWithoutActivating() const +{ + return (window()->flags() & Qt::Popup) == Qt::Popup + || window()->property("_q_showWithoutActivating").toBool(); +} + +bool QQnxWindow::focusable() const +{ + return (window()->flags() & Qt::WindowDoesNotAcceptFocus) != Qt::WindowDoesNotAcceptFocus; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index 2895a547b1..20c38cb4b7 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -113,6 +113,7 @@ public: bool shouldMakeFullScreen() const; void windowPosted(); + void handleActivationEvent(); protected: virtual int pixelFormat() const = 0; @@ -131,6 +132,8 @@ private: void updateZorder(screen_window_t window, int &zOrder); void applyWindowState(); void setFocus(screen_window_t newFocusWindow); + bool showWithoutActivating() const; + bool focusable() const; screen_window_t m_window; QSize m_bufferSize; @@ -152,6 +155,7 @@ private: QByteArray m_parentGroupName; bool m_isTopLevel; + bool m_firstActivateHandled; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp index ffe00de2b1..32114c6443 100644 --- a/src/plugins/platforms/vnc/qvnc.cpp +++ b/src/plugins/platforms/vnc/qvnc.cpp @@ -600,7 +600,7 @@ void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window) cursor = *platformImage.image(); hotspot = platformImage.hotspot(); } - for (auto client : clients) + for (auto client : qAsConst(clients)) client->setDirtyCursor(); } @@ -638,16 +638,14 @@ void QVncServer::init() QVncServer::~QVncServer() { - for (auto client : clients) { - delete client; - } + qDeleteAll(clients); } void QVncServer::setDirty() { - for (auto client : clients) { + for (auto client : qAsConst(clients)) client->setDirty(qvnc_screen->dirtyRegion); - } + qvnc_screen->clearDirty(); } diff --git a/src/plugins/platforms/vnc/qvncscreen.cpp b/src/plugins/platforms/vnc/qvncscreen.cpp index 67d33de2f0..2eca18fb4d 100644 --- a/src/plugins/platforms/vnc/qvncscreen.cpp +++ b/src/plugins/platforms/vnc/qvncscreen.cpp @@ -75,7 +75,7 @@ bool QVncScreen::initialize() mDepth = 32; mPhysicalSize = QSizeF(mGeometry.width()/96.*25.4, mGeometry.height()/96.*25.4); - for (const QString &arg : mArgs) { + for (const QString &arg : qAsConst(mArgs)) { QRegularExpressionMatch match; if (arg.contains(mmSizeRx, &match)) { mPhysicalSize = QSizeF(match.captured("width").toDouble(), match.captured("height").toDouble()); diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js index 37a5308034..84694c7b9f 100644 --- a/src/plugins/platforms/wasm/qtloader.js +++ b/src/plugins/platforms/wasm/qtloader.js @@ -312,13 +312,13 @@ function QtLoader(config) // and is ready to be instantiated. Define the instantiateWasm callback which // emscripten will call to create the instance. Module.instantiateWasm = function(imports, successCallback) { - return WebAssembly.instantiate(wasmModule, imports).then(function(instance) { - successCallback(instance); - return instance; + WebAssembly.instantiate(wasmModule, imports).then(function(instance) { + successCallback(instance, wasmModule); }, function(error) { self.error = error; setStatus("Error"); }); + return {}; }; Module.locateFile = Module.locateFile || function(filename) { @@ -382,6 +382,8 @@ function QtLoader(config) } }); + Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'}); + config.restart = function() { // Restart by reloading the page. This will wipe all state which means diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 8adcf56b11..878f55e56b 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -445,7 +445,7 @@ static inline QTextFormat standardFormat(StandardFormat format) const QPalette palette = QGuiApplication::palette(); const QColor background = palette.text().color(); result.setBackground(QBrush(background)); - result.setForeground(palette.background()); + result.setForeground(palette.window()); break; } } diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 32eec322e8..7b314878f5 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -277,6 +277,8 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic); if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier()) return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic); + if (function == QWindowsWindowFunctions::setHasBorderInFullScreenDefaultIdentifier()) + return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenDefault); if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier()) return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior); if (function == QWindowsWindowFunctions::isTabletModeIdentifier()) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 6dd3e6ed56..a6b9781252 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -284,24 +284,24 @@ static inline QPalette systemPalette() result.setColor(QPalette::Link, Qt::blue); result.setColor(QPalette::LinkVisited, Qt::magenta); result.setColor(QPalette::Inactive, QPalette::Button, result.button().color()); - result.setColor(QPalette::Inactive, QPalette::Window, result.background().color()); + result.setColor(QPalette::Inactive, QPalette::Window, result.window().color()); result.setColor(QPalette::Inactive, QPalette::Light, result.light().color()); result.setColor(QPalette::Inactive, QPalette::Dark, result.dark().color()); if (result.midlight() == result.button()) result.setColor(QPalette::Midlight, result.button().color().lighter(110)); - if (result.background() != result.base()) { + if (result.window() != result.base()) { result.setColor(QPalette::Inactive, QPalette::Highlight, result.color(QPalette::Inactive, QPalette::Window)); result.setColor(QPalette::Inactive, QPalette::HighlightedText, result.color(QPalette::Inactive, QPalette::Text)); } const QColor disabled = - mixColors(result.foreground().color(), result.button().color()); + mixColors(result.windowText().color(), result.button().color()); - result.setColorGroup(QPalette::Disabled, result.foreground(), result.button(), + result.setColorGroup(QPalette::Disabled, result.windowText(), result.button(), result.light(), result.dark(), result.mid(), result.text(), result.brightText(), result.base(), - result.background()); + result.window()); result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); result.setColor(QPalette::Disabled, QPalette::Text, disabled); result.setColor(QPalette::Disabled, QPalette::ButtonText, disabled); @@ -310,7 +310,7 @@ static inline QPalette systemPalette() result.setColor(QPalette::Disabled, QPalette::HighlightedText, getSysColor(COLOR_HIGHLIGHTTEXT)); result.setColor(QPalette::Disabled, QPalette::Base, - result.background().color()); + result.window().color()); return result; } @@ -333,7 +333,7 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette) result.setColor(QPalette::All, QPalette::ToolTipBase, tipBgColor); result.setColor(QPalette::All, QPalette::ToolTipText, tipTextColor); const QColor disabled = - mixColors(result.foreground().color(), result.button().color()); + mixColors(result.windowText().color(), result.button().color()); result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); result.setColor(QPalette::Disabled, QPalette::Text, disabled); result.setColor(QPalette::Disabled, QPalette::ToolTipText, disabled); @@ -858,7 +858,8 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon int iIcon = (useDefaultFolderIcon && defaultFolderIIcon >= 0) ? defaultFolderIIcon : **dirIconEntryCache.object(filePath); if (iIcon) { - QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize), pixmap); + QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize), + &pixmap); if (pixmap.isNull()) // Let's keep both caches in sync dirIconEntryCache.remove(filePath); else @@ -889,7 +890,7 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon //using the unique icon index provided by windows save us from duplicate keys key = dirIconPixmapCacheKey(info.iIcon, iconSize, requestedImageListSize); - QPixmapCache::find(key, pixmap); + QPixmapCache::find(key, &pixmap); if (!pixmap.isNull()) { QMutexLocker locker(&mx); dirIconEntryCache.insert(filePath, FakePointer<int>::create(info.iIcon)); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index c5d57be2ad..99be4882bb 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1180,6 +1180,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, const char *QWindowsWindow::embeddedNativeParentHandleProperty = "_q_embedded_native_parent_handle"; const char *QWindowsWindow::hasBorderInFullScreenProperty = "_q_has_border_in_fullscreen"; +bool QWindowsWindow::m_borderInFullScreenDefault = false; QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) : QWindowsBaseWindow(aWindow), @@ -1217,7 +1218,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) if (aWindow->isTopLevel()) setWindowIcon(aWindow->icon()); - if (aWindow->property(hasBorderInFullScreenProperty).toBool()) + if (m_borderInFullScreenDefault || aWindow->property(hasBorderInFullScreenProperty).toBool()) setFlag(HasBorderInFullScreen); clearFlag(WithinCreate); } @@ -2816,6 +2817,11 @@ void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool border window->setProperty(hasBorderInFullScreenProperty, QVariant(border)); } +void QWindowsWindow::setHasBorderInFullScreenDefault(bool border) +{ + m_borderInFullScreenDefault = border; +} + void QWindowsWindow::setHasBorderInFullScreen(bool border) { if (testFlag(HasBorderInFullScreen) == border) diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index b9b398b67b..b07bd15d2a 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -341,6 +341,7 @@ public: static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes); void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch); static void setHasBorderInFullScreenStatic(QWindow *window, bool border); + static void setHasBorderInFullScreenDefault(bool border); void setHasBorderInFullScreen(bool border); static QString formatWindowTitle(const QString &title); @@ -386,6 +387,7 @@ private: // note: intentionally not using void * in order to avoid breaking x86 VkSurfaceKHR m_vkSurface = 0; #endif + static bool m_borderInFullScreenDefault; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp index a3e6cedecd..2688d6e884 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp @@ -458,7 +458,7 @@ static QPixmap qt_patternForAlpha(uchar alpha, int screen) % HexString<uchar>(alpha) % HexString<int>(screen); - if (!QPixmapCache::find(key, pm)) { + if (!QPixmapCache::find(key, &pm)) { // #### why not use a mono image here???? QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32); pattern.fill(0xffffffff); diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h index 9b01c0a3fc..bc82351283 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h @@ -116,7 +116,7 @@ protected: friend GC qt_x11_get_brush_gc(QPainter *); private: - Q_DISABLE_COPY(QX11PaintEngine) + Q_DISABLE_COPY_MOVE(QX11PaintEngine) }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index f9240a45cc..741317d766 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -641,17 +641,17 @@ void QXcbBackingStoreImage::flushPixmap(const QRegion ®ion, bool fullRegion) xcb_subimage.bit_order = m_xcb_image->bit_order; const bool needsByteSwap = xcb_subimage.byte_order != m_xcb_image->byte_order; + // Ensure that we don't send more than maxPutImageRequestDataBytes per request. + const auto maxPutImageRequestDataBytes = connection()->maxRequestDataBytes(sizeof(xcb_put_image_request_t)); for (const QRect &rect : region) { - // We must make sure that each request is not larger than max_req_size. - // Each request takes req_size + m_xcb_image->stride * height bytes. - static const uint32_t req_size = sizeof(xcb_put_image_request_t); - const uint32_t max_req_size = xcb_get_maximum_request_length(xcb_connection()); - const int rows_per_put = (max_req_size - req_size) / m_xcb_image->stride; + const quint32 stride = round_up_scanline(rect.width() * m_qimage.depth(), xcb_subimage.scanline_pad) >> 3; + const int rows_per_put = maxPutImageRequestDataBytes / stride; // This assert could trigger if a single row has more pixels than fit in - // a single PutImage request. However, max_req_size is guaranteed to be - // at least 16384 bytes. That should be enough for quite large images. + // a single PutImage request. In the absence of the BIG-REQUESTS extension + // the theoretical maximum lengths of maxPutImageRequestDataBytes can be + // roughly 256kB. Q_ASSERT(rows_per_put > 0); // If we upload the whole image in a single chunk, the result might be @@ -666,9 +666,10 @@ void QXcbBackingStoreImage::flushPixmap(const QRegion ®ion, bool fullRegion) while (height > 0) { const int rows = std::min(height, rows_per_put); const QRect subRect(x, y, width, rows); - const quint32 stride = round_up_scanline(width * m_qimage.depth(), xcb_subimage.scanline_pad) >> 3; const QImage subImage = native_sub_image(&m_flushBuffer, stride, m_qimage, subRect, needsByteSwap); + Q_ASSERT(static_cast<size_t>(subImage.sizeInBytes()) <= maxPutImageRequestDataBytes); + xcb_subimage.width = width; xcb_subimage.height = rows; xcb_subimage.data = const_cast<uint8_t *>(subImage.constBits()); diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index ac8b029916..2cb6720d40 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -240,8 +240,8 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask); } - // change property protocol request is 24 bytes - m_increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24; + // xcb_change_property_request_t and xcb_get_property_request_t are the same size + m_maxPropertyRequestDataBytes = connection()->maxRequestDataBytes(sizeof(xcb_change_property_request_t)); } QXcbClipboard::~QXcbClipboard() @@ -486,7 +486,7 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win if (m_clipboard_closing) allow_incr = false; - if (data.size() > m_increment && allow_incr) { + if (data.size() > m_maxPropertyRequestDataBytes && allow_incr) { long bytes = data.size(); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes); @@ -496,7 +496,7 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win } // make sure we can perform the XChangeProperty in a single request - if (data.size() > m_increment) + if (data.size() > m_maxPropertyRequestDataBytes) return XCB_NONE; // ### perhaps use several XChangeProperty calls w/ PropModeAppend? int dataSize = data.size() / (dataFormat / 8); // use a single request to transfer data @@ -678,17 +678,8 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve emitChanged(mode); } - -static inline int maxSelectionIncr(xcb_connection_t *c) -{ - int l = xcb_get_maximum_request_length(c); - return (l > 65536 ? 65536*4 : l*4) - 100; -} - bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format) { - int maxsize = maxSelectionIncr(xcb_connection()); - ulong bytes_left; // bytes_after xcb_atom_t dummy_type; int dummy_format; @@ -705,7 +696,8 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, } *type = reply->type; *format = reply->format; - bytes_left = reply->bytes_after; + + auto bytes_left = reply->bytes_after; int offset = 0, buffer_offset = 0; @@ -720,7 +712,8 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, while (bytes_left) { // more to read... - reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4); + reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, + XCB_GET_PROPERTY_TYPE_ANY, offset, m_maxPropertyRequestDataBytes / 4); if (!reply || reply->type == XCB_NONE) break; diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h index 26d3b3b395..51ae0dc1ee 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.h +++ b/src/plugins/platforms/xcb/qxcbclipboard.h @@ -113,7 +113,7 @@ public: xcb_window_t getSelectionOwner(xcb_atom_t atom) const; QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0); - int increment() const { return m_increment; } + int increment() const { return m_maxPropertyRequestDataBytes; } int clipboardTimeout() const { return clipboard_timeout; } void removeTransaction(xcb_window_t window) { m_transactions.remove(window); } @@ -137,7 +137,7 @@ private: static const int clipboard_timeout; - int m_increment = 0; + int m_maxPropertyRequestDataBytes = 0; bool m_clipboard_closing = false; xcb_timestamp_t m_incr_receive_time = 0; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 29acf0e86d..1ff06dd39e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -132,6 +132,12 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra if (!m_startupId.isNull()) qunsetenv("DESKTOP_STARTUP_ID"); + m_focusInTimer.setSingleShot(true); + m_focusInTimer.callOnTimeout([]() { + // No FocusIn events for us, proceed with FocusOut normally. + QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); + }); + sync(); } @@ -732,11 +738,6 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) m_glIntegration->handleXcbEvent(event, response_type); } -void QXcbConnection::addPeekFunc(PeekFunc f) -{ - m_peekFuncs.append(f); -} - void QXcbConnection::setFocusWindow(QWindow *w) { m_focusWindow = w ? static_cast<QXcbWindow *>(w->handle()) : nullptr; @@ -1016,15 +1017,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags) if (compressEvent(event)) continue; - auto isWaitingFor = [=](PeekFunc peekFunc) { - // These callbacks return true if the event is what they were - // waiting for, remove them from the list in that case. - return peekFunc(this, event); - }; - m_peekFuncs.erase(std::remove_if(m_peekFuncs.begin(), m_peekFuncs.end(), - isWaitingFor), - m_peekFuncs.end()); - handleXcbEvent(event); // The lock-based solution used to free the lock inside this loop, @@ -1033,12 +1025,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags) m_eventQueue->flushBufferedEvents(); } - // Indicate with a null event that the event the callbacks are waiting for - // is not in the queue currently. - for (PeekFunc f : qAsConst(m_peekFuncs)) - f(this, nullptr); - m_peekFuncs.clear(); - xcb_flush(xcb_connection()); } diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 47036ca257..0e3ecd135b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -43,6 +43,7 @@ #include <xcb/xcb.h> #include <xcb/randr.h> +#include <QtCore/QTimer> #include <QtGui/private/qtguiglobal_p.h> #include "qxcbexport.h" #include <QHash> @@ -183,9 +184,6 @@ public: QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id); QXcbWindow *platformWindowFromId(xcb_window_t id); - typedef bool (*PeekFunc)(QXcbConnection *, xcb_generic_event_t *); - void addPeekFunc(PeekFunc f); - inline xcb_timestamp_t time() const { return m_time; } inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; } @@ -247,6 +245,8 @@ public: void flush() { xcb_flush(xcb_connection()); } void processXcbEvents(QEventLoop::ProcessEventsFlags flags); + QTimer &focusInTimer() { return m_focusInTimer; } + protected: bool event(QEvent *e) override; @@ -364,8 +364,6 @@ private: WindowMapper m_mapper; - QVector<PeekFunc> m_peekFuncs; - Qt::MouseButtons m_buttonState = 0; Qt::MouseButton m_button = Qt::NoButton; @@ -386,6 +384,8 @@ private: friend class QXcbEventQueue; QByteArray m_xdgCurrentDesktop; + QTimer m_focusInTimer; + }; #if QT_CONFIG(xcb_xinput) #if QT_CONFIG(tabletevent) diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp index af72285135..9a028e5a7e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp @@ -134,6 +134,7 @@ QXcbBasicConnection::QXcbBasicConnection(const char *displayName) m_setup = xcb_get_setup(m_xcbConnection); m_xcbAtom.initialize(m_xcbConnection); + m_maximumRequestLength = xcb_get_maximum_request_length(m_xcbConnection); xcb_extension_t *extensions[] = { &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, @@ -178,6 +179,14 @@ QXcbBasicConnection::~QXcbBasicConnection() } } +size_t QXcbBasicConnection::maxRequestDataBytes(size_t requestSize) const +{ + if (hasBigRequest()) + requestSize += 4; // big-request encoding adds 4 bytes + + return m_maximumRequestLength * 4 - requestSize; +} + xcb_atom_t QXcbBasicConnection::internAtom(const char *name) { if (!name || *name == 0) @@ -199,6 +208,11 @@ QByteArray QXcbBasicConnection::atomName(xcb_atom_t atom) return QByteArray(); } +bool QXcbBasicConnection::hasBigRequest() const +{ + return m_maximumRequestLength > m_setup->maximum_request_length; +} + #if QT_CONFIG(xcb_xinput) // Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: // - "pad0" became "extension" diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.h b/src/plugins/platforms/xcb/qxcbconnection_basic.h index ca91f7fa45..3691763398 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.h +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.h @@ -73,6 +73,8 @@ public: } const xcb_setup_t *setup() const { return m_setup; } + size_t maxRequestDataBytes(size_t requestSize) const; + inline xcb_atom_t atom(QXcbAtom::Atom qatom) const { return m_xcbAtom.atom(qatom); } QXcbAtom::Atom qatom(xcb_atom_t atom) const { return m_xcbAtom.qatom(atom); } xcb_atom_t internAtom(const char *name); @@ -94,6 +96,7 @@ public: bool hasShmFd() const { return m_hasShmFd; } bool hasXSync() const { return m_hasXSync; } bool hasXinerama() const { return m_hasXinerama; } + bool hasBigRequest() const; #if QT_CONFIG(xcb_xinput) bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; } @@ -152,6 +155,8 @@ private: uint32_t m_xfixesFirstEvent = 0; uint32_t m_xrandrFirstEvent = 0; uint32_t m_xkbFirstEvent = 0; + + uint32_t m_maximumRequestLength = 0; }; #define Q_XCB_REPLY_CONNECTION_ARG(connection, ...) connection diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp index 9aba996bb9..4bafe83156 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp @@ -208,7 +208,7 @@ void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_cha const int idx = m_screens.indexOf(screen); if (idx > 0) { qAsConst(m_screens).first()->setPrimary(false); - m_screens.swap(0, idx); + m_screens.swapItemsAt(0, idx); } screen->virtualDesktop()->setPrimaryScreen(screen); QXcbIntegration::instance()->setPrimaryScreen(screen); @@ -260,7 +260,7 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen) newPrimary->setPrimary(true); const int idx = m_screens.indexOf(newPrimary); if (idx > 0) - m_screens.swap(0, idx); + m_screens.swapItemsAt(0, idx); QXcbIntegration::instance()->setPrimaryScreen(newPrimary); } diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 04ddd3c98c..78ef7760af 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -637,7 +637,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo qreal nx = -1.0, ny = -1.0; qreal w = 0.0, h = 0.0; bool majorAxisIsY = touchPoint.area.height() > touchPoint.area.width(); - for (const TouchDeviceData::ValuatorClassInfo vci : dev->valuatorInfo) { + for (const TouchDeviceData::ValuatorClassInfo &vci : qAsConst(dev->valuatorInfo)) { double value; if (!xi2GetValuatorValueIfSet(xiDeviceEvent, vci.number, &value)) continue; @@ -823,7 +823,7 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) | XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE | XCB_INPUT_XI_EVENT_MASK_TOUCH_END; - for (int id : m_xiMasterPointerIds) { + for (int id : qAsConst(m_xiMasterPointerIds)) { xcb_generic_error_t *error = nullptr; auto cookie = xcb_input_xi_grab_device(xcb_connection(), w, XCB_CURRENT_TIME, XCB_CURSOR_NONE, id, XCB_INPUT_GRAB_MODE_22_ASYNC, XCB_INPUT_GRAB_MODE_22_ASYNC, @@ -841,7 +841,7 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) free(reply); } } else { // ungrab - for (int id : m_xiMasterPointerIds) { + for (int id : qAsConst(m_xiMasterPointerIds)) { auto cookie = xcb_input_xi_ungrab_device_checked(xcb_connection(), XCB_CURRENT_TIME, id); xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie); if (error) { diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index acec0486c2..82a36c0727 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -262,7 +262,7 @@ qint32 QXcbEventQueue::generatePeekerId() bool QXcbEventQueue::removePeekerId(qint32 peekerId) { - const auto it = m_peekerToNode.find(peekerId); + const auto it = m_peekerToNode.constFind(peekerId); if (it == m_peekerToNode.constEnd()) { qCWarning(lcQpaXcb, "failed to remove unknown peeker id: %d", peekerId); return false; @@ -281,7 +281,7 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData, const bool peekerIdProvided = peekerId != -1; auto peekerToNodeIt = m_peekerToNode.find(peekerId); - if (peekerIdProvided && peekerToNodeIt == m_peekerToNode.constEnd()) { + if (peekerIdProvided && peekerToNodeIt == m_peekerToNode.end()) { qCWarning(lcQpaXcb, "failed to find index for unknown peeker id: %d", peekerId); return false; } @@ -341,7 +341,7 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData, // Before updating, make sure that a peeker callback did not remove // the peeker id. peekerToNodeIt = m_peekerToNode.find(peekerId); - if (peekerToNodeIt != m_peekerToNode.constEnd()) + if (peekerToNodeIt != m_peekerToNode.end()) *peekerToNodeIt = node; // id still in the cache, update node } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 524af5a2a7..4d526a6bda 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -304,7 +304,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::n QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterface::nativeResourceFunctionForBackingStore(const QByteArray &resource) { const QByteArray lowerCaseResource = resource.toLower(); - NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(resource); + NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(lowerCaseResource); return func; } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 57dbdc9bec..0fa0e8cd7b 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -147,7 +147,7 @@ void QXcbVirtualDesktop::setPrimaryScreen(QPlatformScreen *s) { const int idx = m_screens.indexOf(s); Q_ASSERT(idx > -1); - m_screens.swap(0, idx); + m_screens.swapItemsAt(0, idx); } QXcbXSettings *QXcbVirtualDesktop::xSettings() const diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.h b/src/plugins/platforms/xcb/qxcbsessionmanager.h index 0ad9445361..79c587b38d 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.h +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.h @@ -85,8 +85,6 @@ public: private: QEventLoop *m_eventLoop; - - Q_DISABLE_COPY(QXcbSessionManager) }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 3bfcbf2adb..9382488b74 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -843,40 +843,12 @@ void QXcbWindow::doFocusIn() QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason); } -static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event) -{ - if (!event) { - // FocusIn event is not in the queue, proceed with FocusOut normally. - QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); - return true; - } - uint response_type = event->response_type & ~0x80; - if (response_type == XCB_FOCUS_IN) { - // Ignore focus events that are being sent only because the pointer is over - // our window, even if the input focus is in a different window. - xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) event; - if (e->detail != XCB_NOTIFY_DETAIL_POINTER) - return true; - } - - /* We are also interested in XEMBED_FOCUS_IN events */ - if (response_type == XCB_CLIENT_MESSAGE) { - xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event; - if (cme->type == connection->atom(QXcbAtom::_XEMBED) - && cme->data.data32[1] == XEMBED_FOCUS_IN) - return true; - } - - return false; -} - void QXcbWindow::doFocusOut() { connection()->setFocusWindow(nullptr); relayFocusToModalWindow(); // Do not set the active window to nullptr if there is a FocusIn coming. - // The FocusIn handler will update QXcbConnection::setFocusWindow() accordingly. - connection()->addPeekFunc(focusInPeeker); + connection()->focusInTimer().start(400); } struct QtMotifWmHints { @@ -2264,6 +2236,8 @@ void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event) // our window, even if the input focus is in a different window. if (event->detail == XCB_NOTIFY_DETAIL_POINTER) return; + + connection()->focusInTimer().stop(); doFocusIn(); } @@ -2491,6 +2465,7 @@ void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event) xcbScreen()->windowShown(this); break; case XEMBED_FOCUS_IN: + connection()->focusInTimer().stop(); Qt::FocusReason reason; switch (event->data.data32[2]) { case XEMBED_FOCUS_FIRST: |