diff options
Diffstat (limited to 'src/plugins')
32 files changed, 321 insertions, 290 deletions
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index c7c82e255c..99cb58830c 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -432,7 +432,6 @@ static void *startMainMethod(void */*data*/) params[i] = static_cast<const char *>(m_applicationParams[i].constData()); int ret = m_main(m_applicationParams.length(), const_cast<char **>(params.data())); - Q_UNUSED(ret); if (m_mainLibraryHnd) { int res = dlclose(m_mainLibraryHnd); @@ -448,6 +447,8 @@ static void *startMainMethod(void */*data*/) if (vm != 0) vm->DetachCurrentThread(); + // We must call exit() to ensure that all global objects will be destructed + exit(ret); return 0; } diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index 4466d28128..8aa7a6b583 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -127,16 +127,17 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o) dragBoard.setMimeData(m_drag->mimeData(), QMacPasteboard::LazyRequest); NSPoint event_location = [m_lastEvent locationInWindow]; - NSPoint local_point = [m_lastView convertPoint:event_location fromView:nil]; - local_point.x -= hotSpot.x(); + NSWindow *theWindow = [m_lastEvent window]; + Q_ASSERT(theWindow != nil); + event_location.x -= hotSpot.x(); CGFloat flippedY = pm.height() - hotSpot.y(); - local_point.y += flippedY; - NSSize mouseOffset = NSMakeSize(0.0, 0.0); + event_location.y -= flippedY; + NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0); NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; - [m_lastView dragImage:nsimage - at:local_point - offset:mouseOffset + [theWindow dragImage:nsimage + at:event_location + offset:mouseOffset_unused event:m_lastEvent pasteboard:pboard source:m_lastView diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 4a2cb42f87..8a2a478a72 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -83,8 +83,8 @@ #include <QtCore/qstack.h> #include <QtGui/qwindowdefs.h> #include <QtCore/private/qabstracteventdispatcher_p.h> +#include <QtCore/private/qcfsocketnotifier_p.h> #include <QtCore/private/qtimerinfo_unix_p.h> -#include <QtPlatformSupport/private/qcfsocketnotifier_p.h> #include <CoreFoundation/CoreFoundation.h> diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 8ad80333f8..f51c21ee9b 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -634,10 +634,14 @@ QString qt_mac_applicationName() int qt_mac_mainScreenHeight() { QMacAutoReleasePool pool; - // The first screen in the screens array is documented - // to have the (0,0) origin. - NSRect screenFrame = [[[NSScreen screens] firstObject] frame]; - return screenFrame.size.height; + NSArray *screens = [NSScreen screens]; + if ([screens count] > 0) { + // The first screen in the screens array is documented + // to have the (0,0) origin. + NSRect screenFrame = [[screens objectAtIndex: 0] frame]; + return screenFrame.size.height; + } + return 0; } int qt_mac_flipYCoordinate(int y) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index adfef81117..4c6b1bac9f 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -894,10 +894,13 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) Qt::WindowType type = window()->type(); if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) { NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior]; - if (flags & Qt::WindowFullscreenButtonHint) + if (flags & Qt::WindowFullscreenButtonHint) { behavior |= NSWindowCollectionBehaviorFullScreenPrimary; - else + behavior &= ~NSWindowCollectionBehaviorFullScreenAuxiliary; + } else { + behavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary; + } [m_nsWindow setCollectionBehavior:behavior]; } setWindowZoomButton(flags); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index 2274c5b228..393ddd14a5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -8,6 +8,8 @@ QT += core-private gui-private platformsupport-private eglfs_device_lib-private INCLUDEPATH += $$PWD/../.. +DEFINES += MESA_EGL_NO_X11_HEADERS + CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 2f32bd73a3..1ddcb3b862 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -45,6 +45,7 @@ QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration() , m_drm_connector(Q_NULLPTR) , m_drm_encoder(Q_NULLPTR) , m_drm_crtc(0) + , m_funcs(Q_NULLPTR) { qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created"); } @@ -54,7 +55,7 @@ void QEglFSKmsEglDeviceIntegration::platformInit() if (!query_egl_device()) qFatal("Could not set up EGL device!"); - const char *deviceName = m_query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); + const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); if (!deviceName) qFatal("Failed to query device name from EGLDevice"); @@ -76,6 +77,9 @@ void QEglFSKmsEglDeviceIntegration::platformDestroy() qErrnoWarning("Could not close DRM device"); m_dri_fd = -1; + + delete m_funcs; + m_funcs = Q_NULLPTR; } EGLNativeDisplayType QEglFSKmsEglDeviceIntegration::platformDisplay() const @@ -87,18 +91,13 @@ EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nat { qCDebug(qLcEglfsKmsDebug, "Creating display"); - const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - - m_get_platform_display = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT")); - m_has_egl_platform_device = extensions && strstr(extensions, "EGL_EXT_platform_device"); - EGLDisplay display; - if (!m_has_egl_platform_device) { + if (m_funcs->has_egl_platform_device) { + display = m_funcs->get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, Q_NULLPTR); + } else { qWarning("EGL_EXT_platform_device not available, falling back to legacy path!"); display = eglGetDisplay(nativeDisplay); - } else { - display = m_get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, Q_NULLPTR); } if (display == EGL_NO_DISPLAY) @@ -165,7 +164,7 @@ public: void QEglJetsonTK1Window::invalidateSurface() { QEglFSWindow::invalidateSurface(); - m_integration->m_destroy_stream(screen()->display(), m_egl_stream); + m_integration->m_funcs->destroy_stream(screen()->display(), m_egl_stream); } void QEglJetsonTK1Window::resetSurface() @@ -176,7 +175,7 @@ void QEglJetsonTK1Window::resetSurface() EGLOutputLayerEXT layer = EGL_NO_OUTPUT_LAYER_EXT; EGLint count; - m_egl_stream = m_integration->m_create_stream(display, Q_NULLPTR); + m_egl_stream = m_integration->m_funcs->create_stream(display, Q_NULLPTR); if (m_egl_stream == EGL_NO_STREAM_KHR) { qWarning("resetSurface: Couldn't create EGLStream for native window"); return; @@ -184,7 +183,7 @@ void QEglJetsonTK1Window::resetSurface() qCDebug(qLcEglfsKmsDebug, "Created stream %p on display %p", m_egl_stream, display); - if (!m_integration->m_get_output_layers(display, Q_NULLPTR, Q_NULLPTR, 0, &count) || count == 0) { + if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, Q_NULLPTR, 0, &count) || count == 0) { qWarning("No output layers found"); return; } @@ -194,20 +193,20 @@ void QEglJetsonTK1Window::resetSurface() QVector<EGLOutputLayerEXT> layers; layers.resize(count); EGLint actualCount; - if (!m_integration->m_get_output_layers(display, Q_NULLPTR, layers.data(), count, &actualCount)) { + if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, layers.data(), count, &actualCount)) { qWarning("Failed to get layers"); return; } for (int i = 0; i < actualCount; ++i) { EGLAttrib id; - if (m_integration->m_query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) { - qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], id); + if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) { + qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], (int) id); if (id == EGLAttrib(m_integration->m_drm_crtc)) layer = layers[i]; - } else if (m_integration->m_query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) { + } else if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) { // Not used yet, just for debugging. - qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], id); + qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], (int) id); } else { qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - unknown", i, layers[i]); } @@ -227,7 +226,7 @@ void QEglJetsonTK1Window::resetSurface() qCDebug(qLcEglfsKmsDebug, "Using layer %p", layer); - if (!m_integration->m_stream_consumer_output(display, m_egl_stream, layer)) + if (!m_integration->m_funcs->stream_consumer_output(display, m_egl_stream, layer)) qWarning("resetSurface: Unable to connect stream"); m_config = QEglFSIntegration::chooseConfig(display, m_integration->surfaceFormatFor(window()->requestedFormat())); @@ -244,7 +243,7 @@ void QEglJetsonTK1Window::resetSurface() EGL_NONE }; - m_surface = m_integration->m_create_stream_producer_surface(display, m_config, m_egl_stream, stream_producer_attribs); + m_surface = m_integration->m_funcs->create_stream_producer_surface(display, m_config, m_egl_stream, stream_producer_attribs); if (m_surface == EGL_NO_SURFACE) return; @@ -255,7 +254,9 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const { QEglJetsonTK1Window *eglWindow = new QEglJetsonTK1Window(window, this); - if (!const_cast<QEglFSKmsEglDeviceIntegration *>(this)->query_egl_extensions(eglWindow->screen()->display())) + m_funcs->initialize(eglWindow->screen()->display()); + if (!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream + && m_funcs->has_egl_stream_producer_eglsurface && m_funcs->has_egl_stream_consumer_egloutput)) qFatal("Required extensions missing!"); return eglWindow; @@ -385,21 +386,12 @@ bool QEglFSKmsEglDeviceIntegration::setup_kms() bool QEglFSKmsEglDeviceIntegration::query_egl_device() { - const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (!extensions) { - qWarning("eglQueryString failed"); - return false; - } - - m_has_egl_device_base = strstr(extensions, "EGL_EXT_device_base"); - m_query_devices = reinterpret_cast<PFNEGLQUERYDEVICESEXTPROC>(eglGetProcAddress("eglQueryDevicesEXT")); - m_query_device_string = reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(eglGetProcAddress("eglQueryDeviceStringEXT")); - - if (!m_has_egl_device_base || !m_query_devices || !m_query_device_string) + m_funcs = new QEGLStreamConvenience; + if (!m_funcs->has_egl_device_base) qFatal("EGL_EXT_device_base missing"); EGLint num_devices = 0; - if (m_query_devices(1, &m_egl_device, &num_devices) != EGL_TRUE) { + if (m_funcs->query_devices(1, &m_egl_device, &num_devices) != EGL_TRUE) { qWarning("eglQueryDevicesEXT failed: eglError: %x", eglGetError()); return false; } @@ -414,51 +406,4 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device() return true; } -bool QEglFSKmsEglDeviceIntegration::query_egl_extensions(EGLDisplay display) -{ - if (!eglBindAPI(EGL_OPENGL_ES_API)) { - qWarning() << Q_FUNC_INFO << "failed to bind EGL_OPENGL_ES_API"; - return false; - } - - m_create_stream = reinterpret_cast<PFNEGLCREATESTREAMKHRPROC>(eglGetProcAddress("eglCreateStreamKHR")); - m_destroy_stream = reinterpret_cast<PFNEGLDESTROYSTREAMKHRPROC>(eglGetProcAddress("eglDestroyStreamKHR")); - m_stream_attrib = reinterpret_cast<PFNEGLSTREAMATTRIBKHRPROC>(eglGetProcAddress("eglStreamAttribKHR")); - m_query_stream = reinterpret_cast<PFNEGLQUERYSTREAMKHRPROC>(eglGetProcAddress("eglQueryStreamKHR")); - m_query_stream_u64 = reinterpret_cast<PFNEGLQUERYSTREAMU64KHRPROC>(eglGetProcAddress("eglQueryStreamu64KHR")); - m_create_stream_producer_surface = reinterpret_cast<PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC>(eglGetProcAddress("eglCreateStreamProducerSurfaceKHR")); - m_stream_consumer_output = reinterpret_cast<PFNEGLSTREAMCONSUMEROUTPUTEXTPROC>(eglGetProcAddress("eglStreamConsumerOutputEXT")); - m_get_output_layers = reinterpret_cast<PFNEGLGETOUTPUTLAYERSEXTPROC>(eglGetProcAddress("eglGetOutputLayersEXT")); - m_get_output_ports = reinterpret_cast<PFNEGLGETOUTPUTPORTSEXTPROC>(eglGetProcAddress("eglGetOutputPortsEXT")); - m_output_layer_attrib = reinterpret_cast<PFNEGLOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglOutputLayerAttribEXT")); - m_query_output_layer_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputLayerAttribEXT")); - m_query_output_layer_string = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputLayerStringEXT")); - m_query_output_port_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputPortAttribEXT")); - m_query_output_port_string = reinterpret_cast<PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputPortStringEXT")); - m_get_stream_file_descriptor = reinterpret_cast<PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglGetStreamFileDescriptorKHR")); - m_create_stream_from_file_descriptor = reinterpret_cast<PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglCreateStreamFromFileDescriptorKHR")); - m_stream_consumer_gltexture = reinterpret_cast<PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC>(eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR")); - m_stream_consumer_acquire = reinterpret_cast<PFNEGLSTREAMCONSUMERACQUIREKHRPROC>(eglGetProcAddress("eglStreamConsumerAcquireKHR")); - - const char *extensions = eglQueryString(display, EGL_EXTENSIONS); - if (!extensions) { - qWarning() << Q_FUNC_INFO << "eglQueryString failed"; - return false; - } - - m_has_egl_stream = strstr(extensions, "EGL_KHR_stream"); - m_has_egl_stream_producer_eglsurface = strstr(extensions, "EGL_KHR_stream_producer_eglsurface"); - m_has_egl_stream_consumer_egloutput = strstr(extensions, "EGL_EXT_stream_consumer_egloutput"); - m_has_egl_output_drm = strstr(extensions, "EGL_EXT_output_drm"); - m_has_egl_output_base = strstr(extensions, "EGL_EXT_output_base"); - m_has_egl_stream_cross_process_fd = strstr(extensions, "EGL_KHR_stream_cross_process_fd"); - m_has_egl_stream_consumer_gltexture = strstr(extensions, "EGL_KHR_stream_consumer_gltexture"); - - return m_has_egl_output_base && - m_has_egl_output_drm && - m_has_egl_stream && - m_has_egl_stream_producer_eglsurface && - m_has_egl_stream_consumer_egloutput; -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index c6132354a8..a89a65ca55 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -49,8 +49,7 @@ #include <xf86drm.h> #include <xf86drmMode.h> -#include <EGL/egl.h> -#include <EGL/eglext.h> +#include <QtPlatformSupport/private/qeglstreamconvenience_p.h> QT_BEGIN_NAMESPACE @@ -75,9 +74,7 @@ public: bool supportsSurfacelessContexts() const Q_DECL_OVERRIDE; bool setup_kms(); - bool query_egl_device(); - bool query_egl_extensions(EGLDisplay display); // device bits QByteArray m_device; @@ -92,44 +89,7 @@ public: quint32 m_drm_crtc; // EGLStream infrastructure - PFNEGLGETPLATFORMDISPLAYEXTPROC m_get_platform_display; - bool m_has_egl_platform_device; - - PFNEGLQUERYDEVICESEXTPROC m_query_devices; - PFNEGLQUERYDEVICESTRINGEXTPROC m_query_device_string; - bool m_has_egl_device_base; - - PFNEGLCREATESTREAMKHRPROC m_create_stream; - PFNEGLDESTROYSTREAMKHRPROC m_destroy_stream; - PFNEGLSTREAMATTRIBKHRPROC m_stream_attrib; - PFNEGLQUERYSTREAMKHRPROC m_query_stream; - PFNEGLQUERYSTREAMU64KHRPROC m_query_stream_u64; - bool m_has_egl_stream; - - PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC m_create_stream_producer_surface; - bool m_has_egl_stream_producer_eglsurface; - - PFNEGLSTREAMCONSUMEROUTPUTEXTPROC m_stream_consumer_output; - bool m_has_egl_stream_consumer_egloutput; - - bool m_has_egl_output_drm; - - PFNEGLGETOUTPUTLAYERSEXTPROC m_get_output_layers; - PFNEGLGETOUTPUTPORTSEXTPROC m_get_output_ports; - PFNEGLOUTPUTLAYERATTRIBEXTPROC m_output_layer_attrib; - PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC m_query_output_layer_attrib; - PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC m_query_output_layer_string; - PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC m_query_output_port_attrib; - PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC m_query_output_port_string; - bool m_has_egl_output_base; - - PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC m_get_stream_file_descriptor; - PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC m_create_stream_from_file_descriptor; - bool m_has_egl_stream_cross_process_fd; - - PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC m_stream_consumer_gltexture; - PFNEGLSTREAMCONSUMERACQUIREKHRPROC m_stream_consumer_acquire; - bool m_has_egl_stream_consumer_gltexture; + QEGLStreamConvenience *m_funcs; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 22ec424451..6f8d0b88dd 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -45,7 +45,6 @@ QT_BEGIN_NAMESPACE QEglFSScreen::QEglFSScreen(EGLDisplay dpy) : m_dpy(dpy), - m_pointerWindow(0), m_surface(EGL_NO_SURFACE), m_cursor(0) { diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index dc291285ad..44e9da4a5a 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -35,6 +35,7 @@ #define QEGLFSSCREEN_H #include "qeglfsglobal.h" +#include <QtCore/QPointer> #include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -73,7 +74,7 @@ private: void setPrimarySurface(EGLSurface surface); EGLDisplay m_dpy; - QWindow *m_pointerWindow; + QPointer<QWindow> m_pointerWindow; EGLSurface m_surface; QPlatformCursor *m_cursor; diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index e8ea1cc28b..98977eb670 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -34,7 +34,7 @@ #ifndef QIOSEVENTDISPATCHER_H #define QIOSEVENTDISPATCHER_H -#include <QtPlatformSupport/private/qeventdispatcher_cf_p.h> +#include <QtCore/private/qeventdispatcher_cf_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index f1500409fe..5d8bd56a1e 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -54,6 +54,18 @@ "features": [ "disable_desktopgl" ] - } + }, + { + "id": 5, + "description": "Intel GMA 3150 crashes (QTBUG-43243)", + "vendor_id": "0x8086", + "device_id": [ "0xA001", "0xA011" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl", "disable_angle" + ] + } ] } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 4ec34c05bd..4d18e7ea58 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -860,6 +860,11 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) return result; } +static inline QWindowsInputContext *windowsInputContext() +{ + return qobject_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext()); +} + /*! \brief Main windows procedure registered for windows. @@ -909,8 +914,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, } } if (et & QtWindows::InputMethodEventFlag) { - QWindowsInputContext *windowsInputContext = - qobject_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext()); + QWindowsInputContext *windowsInputContext = ::windowsInputContext(); // Disable IME assuming this is a special implementation hooking into keyboard input. // "Real" IME implementations should use a native event filter intercepting IME events. if (!windowsInputContext) { @@ -1006,11 +1010,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, } switch (et) { + case QtWindows::KeyboardLayoutChangeEvent: + if (QWindowsInputContext *wic = windowsInputContext()) + wic->handleInputLanguageChanged(wParam, lParam); // fallthrough intended. case QtWindows::KeyDownEvent: case QtWindows::KeyEvent: case QtWindows::InputMethodKeyEvent: case QtWindows::InputMethodKeyDownEvent: - case QtWindows::KeyboardLayoutChangeEvent: case QtWindows::AppCommandEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index a7c14ed2ac..e372acc747 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -856,16 +856,11 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current() { QWindowsOpenGLContextFormat result; const QByteArray version = QOpenGLStaticContext::getGlString(GL_VERSION); - const int majorDot = version.indexOf('.'); - if (majorDot != -1) { - int minorDot = version.indexOf('.', majorDot + 1); - if (minorDot == -1) - minorDot = version.size(); - result.version = (version.mid(0, majorDot).toInt() << 8) - + version.mid(majorDot + 1, minorDot - majorDot - 1).toInt(); - } else { + int major, minor; + if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) + result.version = (major << 8) + minor; + else result.version = 0x0200; - } result.profile = QSurfaceFormat::NoProfile; if (result.version < 0x0300) { result.options |= QSurfaceFormat::DeprecatedFunctions; diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index e016b84bba..7e1cc563cb 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -84,6 +84,18 @@ static inline void imeNotifyCancelComposition(HWND hwnd) ImmReleaseContext(hwnd, himc); } +static inline LCID languageIdFromLocaleId(LCID localeId) +{ + return localeId & 0xFFFF; +} + +static inline LCID currentInputLanguageId() +{ + return languageIdFromLocaleId(reinterpret_cast<quintptr>(GetKeyboardLayout(0))); +} + +Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp + /*! \class QWindowsInputContext \brief Windows Input context implementation @@ -153,7 +165,9 @@ QWindowsInputContext::CompositionContext::CompositionContext() : QWindowsInputContext::QWindowsInputContext() : m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")), - m_endCompositionRecursionGuard(false) + m_endCompositionRecursionGuard(false), + m_languageId(currentInputLanguageId()), + m_locale(qt_localeFromLCID(m_languageId)) { connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QWindowsInputContext::cursorRectChanged); @@ -371,7 +385,7 @@ bool QWindowsInputContext::startComposition(HWND hwnd) QWindow *window = QGuiApplication::focusWindow(); if (!window) return false; - qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window; + qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window << "language=" << m_languageId; if (!fo || QWindowsWindow::handleOf(window) != hwnd) return false; initContext(hwnd, fo); @@ -555,6 +569,21 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam, return false; } +void QWindowsInputContext::handleInputLanguageChanged(WPARAM wparam, LPARAM lparam) +{ + const LCID newLanguageId = languageIdFromLocaleId(lparam); + if (newLanguageId == m_languageId) + return; + const LCID oldLanguageId = m_languageId; + m_languageId = newLanguageId; + m_locale = qt_localeFromLCID(m_languageId); + emitLocaleChanged(); + + qCDebug(lcQpaInputMethods) << __FUNCTION__ << hex << showbase + << oldLanguageId << "->" << newLanguageId << "Character set:" + << DWORD(wparam) << dec << noshowbase << m_locale; +} + /*! \brief Determines the string for reconversion with selection. diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h index eb4e3a3faa..636d481e70 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.h +++ b/src/plugins/platforms/windows/qwindowsinputcontext.h @@ -36,6 +36,7 @@ #include "qtwindows_additional.h" +#include <QtCore/QLocale> #include <QtCore/QPointer> #include <qpa/qplatforminputcontext.h> @@ -66,6 +67,8 @@ public: static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled); bool hasCapability(Capability capability) const Q_DECL_OVERRIDE; + QLocale locale() const Q_DECL_OVERRIDE { return m_locale; } + void reset() Q_DECL_OVERRIDE; void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE; @@ -79,6 +82,7 @@ public: int reconvertString(RECONVERTSTRING *reconv); bool handleIME_Request(WPARAM wparam, LPARAM lparam, LRESULT *result); + void handleInputLanguageChanged(WPARAM wparam, LPARAM lparam); private slots: void cursorRectChanged(); @@ -94,6 +98,8 @@ private: static HIMC m_defaultContext; CompositionContext m_compositionContext; bool m_endCompositionRecursionGuard; + LCID m_languageId; + QLocale m_locale; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index abfddcfed6..5cb34e7fd3 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1062,7 +1062,7 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w) if (const QPlatformWindow *handle = w->handle()) { const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(handle); - if (ww->isEmbedded(0)) { + if (ww->isEmbedded()) { HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT); const HWND desktopHwnd = GetDesktopWindow(); const QWindowsContext *ctx = QWindowsContext::instance(); @@ -1140,7 +1140,7 @@ bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const } if (!m_data.embedded && parent()) - return parent()->isEmbedded(0); + return parent()->isEmbedded(); return m_data.embedded; } diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index d96022e3a5..c73c8ca8f3 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -152,7 +152,7 @@ public: bool isVisible() const; bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); } bool isActive() const Q_DECL_OVERRIDE; - bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE; + bool isEmbedded(const QPlatformWindow *parentWindow = 0) const Q_DECL_OVERRIDE; QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index f3b390b4d6..750233c94f 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -131,7 +131,7 @@ HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane) return S_OK; } -#ifdef Q_OS_WINPHONE +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2) { @@ -160,13 +160,11 @@ static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2) void QWinRTInputContext::showInputPanel() { - ComPtr<IInputPane2> inputPane; - HRESULT hr = getInputPane(&inputPane); - if (FAILED(hr)) - return; - - QEventDispatcherWinRT::runOnXamlThread([&inputPane]() { - HRESULT hr; + QEventDispatcherWinRT::runOnXamlThread([&]() { + ComPtr<IInputPane2> inputPane; + HRESULT hr = getInputPane(&inputPane); + if (FAILED(hr)) + return hr; boolean success; hr = inputPane->TryShow(&success); if (FAILED(hr) || !success) @@ -177,13 +175,11 @@ void QWinRTInputContext::showInputPanel() void QWinRTInputContext::hideInputPanel() { - ComPtr<IInputPane2> inputPane; - HRESULT hr = getInputPane(&inputPane); - if (FAILED(hr)) - return; - - QEventDispatcherWinRT::runOnXamlThread([&inputPane]() { - HRESULT hr; + QEventDispatcherWinRT::runOnXamlThread([&]() { + ComPtr<IInputPane2> inputPane; + HRESULT hr = getInputPane(&inputPane); + if (FAILED(hr)) + return hr; boolean success; hr = inputPane->TryHide(&success); if (FAILED(hr) || !success) @@ -192,6 +188,6 @@ void QWinRTInputContext::hideInputPanel() }); } -#endif // Q_OS_WINPHONE +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h index cc3bce435f..6f88ff46e6 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.h +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h @@ -68,7 +68,7 @@ public: bool isInputPanelVisible() const; -#ifdef Q_OS_WINPHONE +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) void showInputPanel(); void hideInputPanel(); #endif diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index fce77c56d1..7ee3bf8593 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -45,7 +45,6 @@ #include "qwinrtfontdatabase.h" #include "qwinrttheme.h" -#include <QtCore/QCoreApplication> #include <QtGui/QSurface> #include <QtGui/QOpenGLContext> #include <qfunctions_winrt.h> @@ -133,24 +132,14 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) Q_ASSERT_SUCCEEDED(hr); #endif // Q_OS_WINPHONE - hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() { - HRESULT hr; - ComPtr<Xaml::IWindowStatics> windowStatics; - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(), - IID_PPV_ARGS(&windowStatics)); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<Xaml::IWindow> window; - hr = windowStatics->get_Current(&window); - Q_ASSERT_SUCCEEDED(hr); - hr = window->Activate(); - Q_ASSERT_SUCCEEDED(hr); - - d->mainScreen = new QWinRTScreen(window.Get()); - d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); - screenAdded(d->mainScreen); + QEventDispatcherWinRT::runOnXamlThread([d]() { + d->mainScreen = new QWinRTScreen; return S_OK; }); - Q_ASSERT_SUCCEEDED(hr); + + d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); + screenAdded(d->mainScreen); + d->platformServices = new QWinRTServices; } QWinRTIntegration::~QWinRTIntegration() @@ -182,6 +171,15 @@ QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const return new QWinRTEventDispatcher; } +void QWinRTIntegration::initialize() +{ + Q_D(const QWinRTIntegration); + QEventDispatcherWinRT::runOnXamlThread([d]() { + d->mainScreen->initialize(); + return S_OK; + }); +} + bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { @@ -245,8 +243,7 @@ QStringList QWinRTIntegration::themeNames() const return QStringList(QLatin1String("winrt")); } -QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString & -name) const +QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString &name) const { if (name == QLatin1String("winrt")) return new QWinRTTheme(); @@ -260,21 +257,12 @@ name) const HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args) { Q_D(QWinRTIntegration); - - QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier); - QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier); - backPress.setAccepted(false); - backRelease.setAccepted(false); - QWindow *window = d->mainScreen->topWindow(); - QObject *receiver = window ? static_cast<QObject *>(window) - : static_cast<QObject *>(QCoreApplication::instance()); - - // If the event is ignored, the app go to the background - QCoreApplication::sendEvent(receiver, &backPress); - QCoreApplication::sendEvent(receiver, &backRelease); - args->put_Handled(backPress.isAccepted() || backRelease.isAccepted()); - + QWindowSystemInterface::setSynchronousWindowSystemEvents(true); + const bool pressed = QWindowSystemInterface::handleKeyEvent(window, QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier); + const bool released = QWindowSystemInterface::handleKeyEvent(window, QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier); + QWindowSystemInterface::setSynchronousWindowSystemEvents(false); + args->put_Handled(pressed || released); return S_OK; } #endif // Q_OS_WINPHONE diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 0115e034b5..3a151e1ed8 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -81,20 +81,21 @@ public: bool succeeded() const; - bool hasCapability(QPlatformIntegration::Capability cap) const; - QVariant styleHint(StyleHint hint) const; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE; - QPlatformWindow *createPlatformWindow(QWindow *window) const; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; - QAbstractEventDispatcher *createEventDispatcher() const; - QPlatformFontDatabase *fontDatabase() const; - QPlatformInputContext *inputContext() const; - QPlatformServices *services() const; - Qt::KeyboardModifiers queryKeyboardModifiers() const; + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + void initialize() Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; + QPlatformServices *services() const Q_DECL_OVERRIDE; + Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; - QStringList themeNames() const; - QPlatformTheme *createPlatformTheme(const QString &name) const; + QStringList themeNames() const Q_DECL_OVERRIDE; + QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE; private: #ifdef Q_OS_WINPHONE diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 563753cfcb..0fe3262398 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -447,7 +447,7 @@ public: }; // To be called from the XAML thread -QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) +QWinRTScreen::QWinRTScreen() : d_ptr(new QWinRTScreenPrivate) { Q_D(QWinRTScreen); @@ -455,7 +455,17 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) d->touchDevice = Q_NULLPTR; HRESULT hr; - hr = xamlWindow->get_CoreWindow(&d->coreWindow); + ComPtr<Xaml::IWindowStatics> windowStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(), + IID_PPV_ARGS(&windowStatics)); + Q_ASSERT_SUCCEEDED(hr); + ComPtr<Xaml::IWindow> window; + hr = windowStatics->get_Current(&window); + Q_ASSERT_SUCCEEDED(hr); + hr = window->Activate(); + Q_ASSERT_SUCCEEDED(hr); + + hr = window->get_CoreWindow(&d->coreWindow); Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->Activate(); Q_ASSERT_SUCCEEDED(hr); @@ -465,35 +475,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) Q_ASSERT_SUCCEEDED(hr); d->logicalSize = QSizeF(rect.Width, rect.Height); - hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); - Q_ASSERT_SUCCEEDED(hr); -#ifndef Q_OS_WINPHONE - hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); - Q_ASSERT_SUCCEEDED(hr); -#endif - hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]); - Q_ASSERT_SUCCEEDED(hr); - // Orientation handling ComPtr<IDisplayInformationStatics> displayInformationStatics; hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), @@ -509,12 +490,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) Q_ASSERT_SUCCEEDED(hr); d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation))); - hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]); - Q_ASSERT_SUCCEEDED(hr); - - hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]); - Q_ASSERT_SUCCEEDED(hr); - // Set initial orientation & pixel density onDpiChanged(Q_NULLPTR, Q_NULLPTR); d->orientation = d->nativeOrientation; @@ -542,7 +517,7 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) ComPtr<Xaml::IUIElement> uiElement; hr = canvas.As(&uiElement); Q_ASSERT_SUCCEEDED(hr); - hr = xamlWindow->put_Content(uiElement.Get()); + hr = window->put_Content(uiElement.Get()); Q_ASSERT_SUCCEEDED(hr); hr = canvas.As(&d->canvas); Q_ASSERT_SUCCEEDED(hr); @@ -556,10 +531,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) Q_ASSERT_SUCCEEDED(hr); hr = statusBarStatics->GetForCurrentView(&d->statusBar); Q_ASSERT_SUCCEEDED(hr); - hr = d->statusBar->add_Showing(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->statusBar->add_Hiding(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]); - Q_ASSERT_SUCCEEDED(hr); #endif // Q_OS_WINPHONE } @@ -726,6 +697,50 @@ void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window) } #endif //Q_OS_WINPHONE +void QWinRTScreen::initialize() +{ + Q_D(QWinRTScreen); + HRESULT hr; + hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); + Q_ASSERT_SUCCEEDED(hr); +#ifndef Q_OS_WINPHONE + hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); + Q_ASSERT_SUCCEEDED(hr); +#else + hr = d->statusBar->add_Showing(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->statusBar->add_Hiding(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]); + Q_ASSERT_SUCCEEDED(hr); +#endif + hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]); + Q_ASSERT_SUCCEEDED(hr); + onVisibilityChanged(nullptr, nullptr); +} + QWindow *QWinRTScreen::topWindow() const { Q_D(const QWinRTScreen); @@ -1089,8 +1104,10 @@ HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *) HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEventArgs *args) { + Q_D(QWinRTScreen); boolean visible; - args->get_Visible(&visible); + HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible); + RETURN_OK_IF_FAILED("Failed to get visbile."); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); if (visible) handleExpose(); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 3297617740..0043b2cfa3 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -83,7 +83,7 @@ class QWinRTScreenPrivate; class QWinRTScreen : public QPlatformScreen { public: - explicit QWinRTScreen(ABI::Windows::UI::Xaml::IWindow *xamlWindow); + explicit QWinRTScreen(); ~QWinRTScreen(); QRect geometry() const Q_DECL_OVERRIDE; #ifdef Q_OS_WINPHONE @@ -115,6 +115,8 @@ public: void setStatusBarVisibility(bool visible, QWindow *window); #endif + void initialize(); + private: void handleExpose(); diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 248d1b4bbb..8b75c130fb 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -275,22 +275,8 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) m_clientClipboard[QClipboard::Selection] = 0; m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME; m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME; + m_owner = connection()->getQtSelectionOwner(); - QXcbScreen *platformScreen = screen(); - - int x = 0, y = 0, w = 3, h = 3; - - m_owner = xcb_generate_id(xcb_connection()); - Q_XCB_CALL(xcb_create_window(xcb_connection(), - XCB_COPY_FROM_PARENT, // depth -- same as root - m_owner, // window id - platformScreen->screen()->root, // parent window id - x, y, w, h, - 0, // border width - XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class - platformScreen->screen()->root_visual, // visual - 0, // value mask - 0)); // value list #ifndef QT_NO_DEBUG QByteArray ba("Qt clipboard window"); Q_XCB_CALL(xcb_change_property(xcb_connection(), @@ -353,13 +339,7 @@ void QXcbClipboard::incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepte xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const { - xcb_connection_t *c = xcb_connection(); - xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom); - xcb_get_selection_owner_reply_t *reply; - reply = xcb_get_selection_owner_reply(c, cookie, 0); - xcb_window_t win = reply->owner; - free(reply); - return win; + return connection()->getSelectionOwner(atom); } xcb_atom_t QXcbClipboard::atomForMode(QClipboard::Mode mode) const diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 13d73c7194..a20d957138 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -449,6 +449,9 @@ void QXcbConnection::initializeScreens() ++xcbScreenNumber; } // for each xcb screen + foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) + virtualDesktop->subscribeToXFixesSelectionNotify(); + // If there's no randr extension, or there was some error above, or we found a // screen which doesn't have outputs for some other reason (e.g. on VNC or ssh -X), // but the dimensions are known anyway, and we don't already have any lingering @@ -507,6 +510,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , m_systemTrayTracker(0) , m_glIntegration(Q_NULLPTR) , m_xiGrab(false) + , m_qtSelectionOwner(0) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -551,12 +555,12 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_netWmUserTime = XCB_CURRENT_TIME; initializeXRandr(); + initializeXFixes(); initializeScreens(); if (m_screens.isEmpty()) qFatal("QXcbConnection: no screens available"); - initializeXFixes(); initializeXRender(); m_xi2Enabled = false; #if defined(XCB_USE_XINPUT2) @@ -1139,10 +1143,14 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) if (!handled) { if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) { - setTime(((xcb_xfixes_selection_notify_event_t *)event)->timestamp); + xcb_xfixes_selection_notify_event_t *notify_event = (xcb_xfixes_selection_notify_event_t *)event; + setTime(notify_event->timestamp); #ifndef QT_NO_CLIPBOARD - m_clipboard->handleXFixesSelectionRequest((xcb_xfixes_selection_notify_event_t *)event); + m_clipboard->handleXFixesSelectionRequest(notify_event); #endif + foreach (QXcbVirtualDesktop *virtualDesktop, m_virtualDesktops) + virtualDesktop->handleXFixesSelectionNotify(notify_event); + handled = true; } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) { updateScreens((xcb_randr_notify_event_t *)event); @@ -1371,6 +1379,37 @@ xcb_timestamp_t QXcbConnection::getTimestamp() return timestamp; } +xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const +{ + xcb_connection_t *c = xcb_connection(); + xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom); + xcb_get_selection_owner_reply_t *reply; + reply = xcb_get_selection_owner_reply(c, cookie, 0); + xcb_window_t win = reply->owner; + free(reply); + return win; +} + +xcb_window_t QXcbConnection::getQtSelectionOwner() +{ + if (!m_qtSelectionOwner) { + xcb_screen_t *xcbScreen = primaryVirtualDesktop()->screen(); + int x = 0, y = 0, w = 3, h = 3; + m_qtSelectionOwner = xcb_generate_id(xcb_connection()); + Q_XCB_CALL(xcb_create_window(xcb_connection(), + XCB_COPY_FROM_PARENT, // depth -- same as root + m_qtSelectionOwner, // window id + xcbScreen->root, // parent window id + x, y, w, h, + 0, // border width + XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class + xcbScreen->root_visual, // visual + 0, // value mask + 0)); // value list + } + return m_qtSelectionOwner; +} + xcb_window_t QXcbConnection::rootWindow() { QXcbScreen *s = primaryScreen(); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index fb5b941fff..3c82170679 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -460,6 +460,8 @@ public: bool threadedEventHandling() const { return m_reader->isRunning(); } xcb_timestamp_t getTimestamp(); + xcb_window_t getSelectionOwner(xcb_atom_t atom) const; + xcb_window_t getQtSelectionOwner(); void setButton(Qt::MouseButton button, bool down) { if (down) m_buttons |= button; else m_buttons &= ~button; } Qt::MouseButtons buttons() const { return m_buttons; } @@ -650,6 +652,8 @@ private: QXcbGlIntegration *m_glIntegration; bool m_xiGrab; + xcb_window_t m_qtSelectionOwner; + friend class QXcbEventReader; }; diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index f9c3aa7fed..d19ea241f1 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -191,6 +191,8 @@ void QXcbDrag::startDrag() xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(), atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData()); + + setUseCompositing(current_virtual_desktop->compositingActive()); QBasicDrag::startDrag(); } @@ -316,6 +318,7 @@ void QXcbDrag::move(const QPoint &globalPos) QPoint deviceIndependentPos = QHighDpiScaling::mapPositionFromNative(globalPos, screen); if (virtualDesktop != current_virtual_desktop) { + setUseCompositing(virtualDesktop->compositingActive()); recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos); current_virtual_desktop = virtualDesktop; } else { diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index da4db5edcb..4f71ac8693 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -54,6 +54,10 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t , m_number(number) , m_xSettings(Q_NULLPTR) { + QByteArray cmAtomName("_NET_WM_CM_S"); + cmAtomName += QByteArray::number(m_number); + m_net_wm_cm_atom = connection->internAtom(cmAtomName.constData()); + m_compositingActive = connection->getSelectionOwner(m_net_wm_cm_atom); } QXcbVirtualDesktop::~QXcbVirtualDesktop() @@ -79,6 +83,30 @@ QXcbXSettings *QXcbVirtualDesktop::xSettings() const return m_xSettings; } +bool QXcbVirtualDesktop::compositingActive() const +{ + if (connection()->hasXFixes()) + return m_compositingActive; + else + return connection()->getSelectionOwner(m_net_wm_cm_atom); +} + +void QXcbVirtualDesktop::handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event) +{ + if (notify_event->selection == m_net_wm_cm_atom) + m_compositingActive = notify_event->owner; +} + +void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify() +{ + if (connection()->hasXFixes()) { + const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | + XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | + XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE; + Q_XCB_CALL(xcb_xfixes_select_selection_input_checked(xcb_connection(), connection()->getQtSelectionOwner(), m_net_wm_cm_atom, mask)); + } +} + QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, QString outputName) diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index d8d63608e7..51c92a40ae 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -39,6 +39,7 @@ #include <xcb/xcb.h> #include <xcb/randr.h> +#include <xcb/xfixes.h> #include "qxcbobject.h" #include "qxcbscreen.h" @@ -69,11 +70,18 @@ public: QXcbXSettings *xSettings() const; + bool compositingActive() const; + + void handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event); + void subscribeToXFixesSelectionNotify(); + private: xcb_screen_t *m_screen; int m_number; QXcbXSettings *m_xSettings; + xcb_atom_t m_net_wm_cm_atom; + bool m_compositingActive; }; class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e7f5bbf0e9..bde8826792 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -389,7 +389,8 @@ void QXcbWindow::create() resolveFormat(); #ifdef XCB_USE_XLIB - if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { + if (window()->surfaceType() != QSurface::RasterSurface + && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { XVisualInfo *visualInfo = Q_NULLPTR; if (connection()->hasDefaultVisualId()) visualInfo = CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(this); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 8968664bad..b2c5fa7d4d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -81,7 +81,7 @@ public: void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE; bool isExposed() const Q_DECL_OVERRIDE; - bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE; + bool isEmbedded(const QPlatformWindow *parentWindow = 0) const Q_DECL_OVERRIDE; QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; |