diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/android/androidjniinput.cpp | 14 | ||||
-rw-r--r-- | src/plugins/platforms/android/androidjniinput.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/android/qandroidinputcontext.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 49 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaglcontext.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaglcontext.mm | 71 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_drawing.mm | 11 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qprintengine_mac.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/haiku/qhaikuapplication.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbsessionmanager.cpp | 5 | ||||
-rw-r--r-- | src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 10 |
11 files changed, 81 insertions, 95 deletions
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp index 9cdc5de0e1..56885f2e23 100644 --- a/src/plugins/platforms/android/androidjniinput.cpp +++ b/src/plugins/platforms/android/androidjniinput.cpp @@ -195,20 +195,6 @@ namespace QtAndroidInput angleDelta); } - void releaseMouse(int x, int y) - { - m_ignoreMouseEvents = true; - QPoint globalPos(x,y); - QWindow *tlw = topLevelWindowAt(globalPos); - QPoint localPos = tlw ? (globalPos-tlw->position()) : globalPos; - - // Release left button - QWindowSystemInterface::handleMouseEvent(tlw, - localPos, - globalPos, - Qt::MouseButtons(Qt::NoButton)); - } - static void longPress(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y) { QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext(); diff --git a/src/plugins/platforms/android/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h index 2e2470ae8f..cc3070c4aa 100644 --- a/src/plugins/platforms/android/androidjniinput.h +++ b/src/plugins/platforms/android/androidjniinput.h @@ -61,8 +61,6 @@ namespace QtAndroidInput void updateHandles(int handleCount, QPoint editMenuPos = QPoint(), uint32_t editButtons = 0, QPoint cursor = QPoint(), QPoint anchor = QPoint(), bool rtl = false); bool registerNatives(JNIEnv *env); - - void releaseMouse(int x, int y); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 5614d3b04f..e78c317863 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -827,9 +827,6 @@ void QAndroidInputContext::longPress(int x, int y) focusObjectStopComposing(); - // Release left button, otherwise the following events will cancel the menu popup - QtAndroidInput::releaseMouse(x, y); - const double pixelDensity = QGuiApplication::focusWindow() ? QHighDpiScaling::factor(QGuiApplication::focusWindow()) diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 33a45985a8..9b0a6b1b86 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -88,10 +88,13 @@ #include <qpa/qwindowsysteminterface.h> #include <qwindowdefs.h> +QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application"); +QT_END_NAMESPACE + QT_USE_NAMESPACE @implementation QCocoaApplicationDelegate { - bool startedQuit; NSObject <NSApplicationDelegate> *reflectionDelegate; bool inLaunch; } @@ -140,46 +143,30 @@ QT_USE_NAMESPACE return [[self.dockMenu retain] autorelease]; } -- (BOOL)canQuit -{ - QCloseEvent ev; - QGuiApplication::sendEvent(qGuiApp, &ev); - return ev.isAccepted(); -} - // This function will only be called when NSApp is actually running. - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { if ([reflectionDelegate respondsToSelector:_cmd]) return [reflectionDelegate applicationShouldTerminate:sender]; - if ([self canQuit]) { - if (!startedQuit) { - startedQuit = true; - // Close open windows. This is done in order to deliver de-expose - // events while the event loop is still running. - const QWindowList topLevels = QGuiApplication::topLevelWindows(); - for (int i = 0; i < topLevels.size(); ++i) { - QWindow *topLevelWindow = topLevels.at(i); - // Already closed windows will not have a platform window, skip those - if (topLevelWindow->handle()) - QWindowSystemInterface::handleCloseEvent(topLevelWindow); - } - QWindowSystemInterface::flushWindowSystemEvents(); - - QGuiApplication::exit(0); - startedQuit = false; - } - } - if (QGuiApplicationPrivate::instance()->threadData->eventLoops.isEmpty()) { - // INVARIANT: No event loop is executing. This probably - // means that Qt is used as a plugin, or as a part of a native - // Cocoa application. In any case it should be fine to - // terminate now: + // No event loop is executing. This probably means that Qt is used as a plugin, + // or as a part of a native Cocoa application. In any case it should be fine to + // terminate now. + qCDebug(lcQpaApplication) << "No running event loops, terminating now"; return NSTerminateNow; } + if (!QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>()) { + qCDebug(lcQpaApplication) << "Application termination canceled"; + return NSTerminateCancel; + } + + // Even if the application termination was accepted by the application we can't + // return NSTerminateNow, as that would trigger AppKit to ultimately call exit(). + // We need to ensure that the runloop continues spinning so that we can return + // from our own event loop back to main(), and exit from there. + qCDebug(lcQpaApplication) << "Termination accepted, but returning to runloop for exit through main()"; return NSTerminateCancel; } diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index bb309c0713..4210a4ed3f 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE +class QCocoaWindow; + class QCocoaGLContext : public QPlatformOpenGLContext { public: @@ -76,12 +78,12 @@ private: static NSOpenGLPixelFormat *pixelFormatForSurfaceFormat(const QSurfaceFormat &format); bool setDrawable(QPlatformSurface *surface); + void prepareDrawable(QCocoaWindow *platformWindow); void updateSurfaceFormat(); NSOpenGLContext *m_context = nil; NSOpenGLContext *m_shareContext = nil; QSurfaceFormat m_format; - bool m_didCheckForSoftwareContext = false; QVarLengthArray<QMacNotificationObserver, 3> m_updateObservers; QAtomicInt m_needsUpdate = false; }; diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index ba7d12ce30..b312e033cd 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -223,12 +223,10 @@ NSOpenGLPixelFormat *QCocoaGLContext::pixelFormatForSurfaceFormat(const QSurface attrs << NSOpenGLPFAAllowOfflineRenderers; } - // FIXME: Pull this information out of the NSView - QByteArray useLayer = qgetenv("QT_MAC_WANTS_LAYER"); - if (!useLayer.isEmpty() && useLayer.toInt() > 0) { - // Disable the software rendering fallback. This makes compositing - // OpenGL and raster NSViews using Core Animation layers possible. - attrs << NSOpenGLPFANoRecovery; + if (qGuiApp->testAttribute(Qt::AA_UseSoftwareOpenGL)) { + // kCGLRendererGenericFloatID is the modern software renderer on macOS, + // as opposed to kCGLRendererGenericID, which is deprecated. + attrs << NSOpenGLPFARendererID << kCGLRendererGenericFloatID; } attrs << 0; // 0-terminate array @@ -368,23 +366,6 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface) [m_context makeCurrentContext]; if (surface->surface()->surfaceClass() == QSurface::Window) { - // Disable high-resolution surfaces when using the software renderer, which has the - // problem that the system silently falls back to a to using a low-resolution buffer - // when a high-resolution buffer is requested. This is not detectable using the NSWindow - // convertSizeToBacking and backingScaleFactor APIs. A typical result of this is that Qt - // will display a quarter of the window content when running in a virtual machine. - if (!m_didCheckForSoftwareContext) { - // FIXME: This ensures we check only once per context, - // but the context may be used for multiple surfaces. - m_didCheckForSoftwareContext = true; - - const GLubyte* renderer = glGetString(GL_RENDERER); - if (qstrcmp((const char *)renderer, "Apple Software Renderer") == 0) { - NSView *view = static_cast<QCocoaWindow *>(surface)->m_view; - [view setWantsBestResolutionOpenGLSurface:NO]; - } - } - if (m_needsUpdate.fetchAndStoreRelaxed(false)) update(); } @@ -413,11 +394,14 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface) } Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window); - QNSView *view = qnsview_cast(static_cast<QCocoaWindow *>(surface)->view()); + auto *cocoaWindow = static_cast<QCocoaWindow *>(surface); + QNSView *view = qnsview_cast(cocoaWindow->view()); if (view == m_context.view) return true; + prepareDrawable(cocoaWindow); + // Setting the drawable may happen on a separate thread as a result of // a call to makeCurrent, so we need to set up the observers before we // associate the view with the context. That way we will guarantee that @@ -460,6 +444,30 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface) return true; } +void QCocoaGLContext::prepareDrawable(QCocoaWindow *platformWindow) +{ + // We generally want high-DPI GL surfaces, unless the user has explicitly disabled them + bool prefersBestResolutionOpenGLSurface = qt_mac_resolveOption(YES, + platformWindow->window(), "_q_mac_wantsBestResolutionOpenGLSurface", + "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); + + auto *view = platformWindow->view(); + + // The only case we have to opt out ourselves is when using the Apple software renderer + // in combination with surface-backed views, as these together do not support high-DPI. + if (prefersBestResolutionOpenGLSurface) { + int rendererID = 0; + [m_context getValues:&rendererID forParameter:NSOpenGLContextParameterCurrentRendererID]; + bool isSoftwareRenderer = (rendererID & kCGLRendererIDMatchingMask) == kCGLRendererGenericFloatID; + if (isSoftwareRenderer && !view.layer) { + qCInfo(lcQpaOpenGLContext) << "Disabling high resolution GL surface due to software renderer"; + prefersBestResolutionOpenGLSurface = false; + } + } + + view.wantsBestResolutionOpenGLSurface = prefersBestResolutionOpenGLSurface; +} + // NSOpenGLContext is not re-entrant. Even when using separate contexts per thread, // view, and window, calls into the API will still deadlock. For more information // see https://openradar.appspot.com/37064579 @@ -491,6 +499,21 @@ void QCocoaGLContext::swapBuffers(QPlatformSurface *surface) return; } + if (m_context.view.layer) { + // Flushing an NSOpenGLContext will hit the screen immediately, ignoring + // any Core Animation transactions in place. This may result in major + // visual artifacts if the flush happens out of sync with the size + // of the layer, view, and window reflected by other parts of the UI, + // e.g. if the application flushes in the resize event or a timer during + // window resizing, instead of in the expose event. + auto *cocoaWindow = static_cast<QCocoaWindow *>(surface); + if (cocoaWindow->geometry().size() != cocoaWindow->m_exposedRect.size()) { + qCInfo(lcQpaOpenGLContext) << "Window exposed size does not match geometry (yet)." + << "Skipping flush to avoid visual artifacts."; + return; + } + } + QMutexLocker locker(&s_reentrancyMutex); [m_context flushBuffer]; } diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm index eb9286519d..2fd63fad67 100644 --- a/src/plugins/platforms/cocoa/qnsview_drawing.mm +++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm @@ -44,17 +44,6 @@ - (void)initDrawing { [self updateLayerBacking]; - - // Enable high-DPI OpenGL for retina displays. Enabling has the side - // effect that Cocoa will start calling glViewport(0, 0, width, height), - // overriding any glViewport calls in application code. This is usually not a - // problem, except if the application wants to have a "custom" viewport. - // (like the hellogl example) - if (m_platformWindow->window()->supportsOpenGL()) { - self.wantsBestResolutionOpenGLSurface = qt_mac_resolveOption(YES, m_platformWindow->window(), - "_q_mac_wantsBestResolutionOpenGLSurface", "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); - // See also QCocoaGLContext::makeCurrent for software renderer workarounds. - } } - (BOOL)isOpaque diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index 58ad53a6e1..dcb9a85a3c 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -59,6 +59,8 @@ QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode, const QString &devi QString id = deviceId; if (id.isEmpty()) id = QCocoaPrinterSupport().defaultPrintDeviceId(); + else + setProperty(QPrintEngine::PPK_PrinterName, deviceId); d->m_printDevice.reset(new QCocoaPrintDevice(id)); d->m_pageLayout.setPageSize(d->m_printDevice->defaultPageSize()); d->initialize(); diff --git a/src/plugins/platforms/haiku/qhaikuapplication.cpp b/src/plugins/platforms/haiku/qhaikuapplication.cpp index b75810c453..de4acdfd4a 100644 --- a/src/plugins/platforms/haiku/qhaikuapplication.cpp +++ b/src/plugins/platforms/haiku/qhaikuapplication.cpp @@ -42,6 +42,8 @@ #include <QCoreApplication> #include <QFileOpenEvent> +#include <qpa/qwindowsysteminterface.h> + #include <Entry.h> #include <Path.h> @@ -52,8 +54,7 @@ QHaikuApplication::QHaikuApplication(const char *signature) bool QHaikuApplication::QuitRequested() { - QEvent quitEvent(QEvent::Quit); - QCoreApplication::sendEvent(QCoreApplication::instance(), &quitEvent); + QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>(); return true; } diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp index 2303ccf806..f880d4d722 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -42,6 +42,8 @@ #ifndef QT_NO_SESSIONMANAGER +#include <qpa/qwindowsysteminterface.h> + #include <qguiapplication.h> #include <qdatetime.h> #include <qfileinfo.h> @@ -289,8 +291,7 @@ static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */) if (smcConn != smcConnection) return; resetSmState(); - QEvent quitEvent(QEvent::Quit); - QGuiApplication::sendEvent(qApp, &quitEvent); + QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>(); } static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData) diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index 7f98efccba..7709b13cd1 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -221,18 +221,18 @@ public: int disconnectCount; bool hasSQLFetchScroll; - bool isStmtHandleValid(); + bool isStmtHandleValid() const; void updateStmtHandleState(); }; -bool QODBCResultPrivate::isStmtHandleValid() +bool QODBCResultPrivate::isStmtHandleValid() const { - return disconnectCount == drv_d_func()->disconnectCount; + return drv_d_func() && disconnectCount == drv_d_func()->disconnectCount; } void QODBCResultPrivate::updateStmtHandleState() { - disconnectCount = drv_d_func()->disconnectCount; + disconnectCount = drv_d_func() ? drv_d_func()->disconnectCount : 0; } static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode = 0) @@ -975,7 +975,7 @@ QODBCResult::QODBCResult(const QODBCDriver *db) QODBCResult::~QODBCResult() { Q_D(QODBCResult); - if (d->hStmt && d->isStmtHandleValid() && driver()->isOpen()) { + if (d->hStmt && d->isStmtHandleValid() && driver() && driver()->isOpen()) { SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); if (r != SQL_SUCCESS) qSqlWarning(QLatin1String("QODBCDriver: Unable to free statement handle ") |