--- qtwebengine/src/core/renderer/web_channel_ipc_transport.cpp +++ qtwebengine/src/core/renderer/web_channel_ipc_transport.cpp @@ -153,6 +153,8 @@ content::RenderView *WebChannelTransport::GetRenderView(v8::Isolate *isolate) WebChannelIPCTransport::WebChannelIPCTransport(content::RenderView *renderView) : content::RenderViewObserver(renderView) + , m_installed(false) + , m_installedWorldId(0) { } @@ -162,6 +164,8 @@ void WebChannelIPCTransport::installWebChannel(uint worldId) if (!webView) return; WebChannelTransport::Install(webView->mainFrame(), worldId); + m_installed = true; + m_installedWorldId = worldId; } void WebChannelIPCTransport::uninstallWebChannel(uint worldId) @@ -170,6 +174,7 @@ void WebChannelIPCTransport::uninstallWebChannel(uint worldId) if (!webView) return; WebChannelTransport::Uninstall(webView->mainFrame(), worldId); + m_installed = false; } void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector &binaryJSON, uint worldId) @@ -217,6 +222,13 @@ void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector & frame->callFunctionEvenIfScriptDisabled(callback, webChannelObjectValue->ToObject(), argc, argv); } +void WebChannelIPCTransport::DidCreateDocumentElement(blink::WebLocalFrame* frame) +{ + blink::WebFrame* main_frame = render_view()->GetWebView()->mainFrame(); + if (m_installed && frame == main_frame) + WebChannelTransport::Install(frame, m_installedWorldId); +} + bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message) { bool handled = true; --- qtwebengine/src/core/renderer/web_channel_ipc_transport.h +++ qtwebengine/src/core/renderer/web_channel_ipc_transport.h @@ -58,7 +58,11 @@ class WebChannelIPCTransport : public content::RenderViewObserver { void dispatchWebChannelMessage(const std::vector &binaryJSON, uint worldId); void installWebChannel(uint worldId); void uninstallWebChannel(uint worldId); + virtual void DidCreateDocumentElement(blink::WebLocalFrame* frame) override; virtual bool OnMessageReceived(const IPC::Message &message) Q_DECL_OVERRIDE; + + bool m_installed; + uint m_installedWorldId; }; } // namespace --- qtwebengine/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp +++ qtwebengine/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp @@ -37,6 +37,7 @@ private Q_SLOTS: void scriptModifications(); void webChannel_data(); void webChannel(); + void noTransportWithoutWebChannel(); }; void tst_QWebEngineScript::domEditing() @@ -180,13 +181,17 @@ class TestObject : public QObject void tst_QWebEngineScript::webChannel_data() { QTest::addColumn("worldId"); - QTest::newRow("MainWorld") << static_cast(QWebEngineScript::MainWorld); - QTest::newRow("ApplicationWorld") << static_cast(QWebEngineScript::ApplicationWorld); + QTest::addColumn("reloadFirst"); + QTest::newRow("MainWorld") << static_cast(QWebEngineScript::MainWorld) << false; + QTest::newRow("ApplicationWorld") << static_cast(QWebEngineScript::ApplicationWorld) << false; + QTest::newRow("MainWorldWithReload") << static_cast(QWebEngineScript::MainWorld) << true; + QTest::newRow("ApplicationWorldWithReload") << static_cast(QWebEngineScript::ApplicationWorld) << true; } void tst_QWebEngineScript::webChannel() { QFETCH(int, worldId); + QFETCH(bool, reloadFirst); QWebEnginePage page; TestObject testObject; QScopedPointer channel(new QWebChannel(this)); @@ -205,6 +210,11 @@ void tst_QWebEngineScript::webChannel() page.scripts().insert(script); page.setHtml(QStringLiteral("")); waitForSignal(&page, SIGNAL(loadFinished(bool))); + if (reloadFirst) { + // Check that the transport is also reinstalled on navigation + page.triggerAction(QWebEnginePage::Reload); + waitForSignal(&page, SIGNAL(loadFinished(bool))); + } page.runJavaScript(QLatin1String( "new QWebChannel(qt.webChannelTransport," " function(channel) {" @@ -218,6 +228,17 @@ void tst_QWebEngineScript::webChannel() QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid)); } +void tst_QWebEngineScript::noTransportWithoutWebChannel() +{ + QWebEnginePage page; + page.setHtml(QStringLiteral("")); + + QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid)); + page.triggerAction(QWebEnginePage::Reload); + waitForSignal(&page, SIGNAL(loadFinished(bool))); + QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid)); +} + QTEST_MAIN(tst_QWebEngineScript) #include "tst_qwebenginescript.moc" --- qtbase/src/plugins/platforms/cocoa/qnswindowdelegate.mm.orig 2016-06-10 08:48:56.000000000 +0200 +++ qtbase/src/plugins/platforms/cocoa/qnswindowdelegate.mm 2016-06-20 13:57:36.000000000 +0200 @@ -115,4 +115,7 @@ return YES; } +- (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions { + return NSApplicationPresentationFullScreen | NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock; +} @end --- qtwebengine/src/core/web_engine_context.cpp.ori 2016-06-20 13:58:31.000000000 +0200 +++ qtwebengine/src/core/web_engine_context.cpp 2016-06-20 13:59:52.000000000 +0200 @@ -292,6 +292,10 @@ parsedCommandLine->AppendSwitchASCII(switches::kProfilerTiming, switches::kProfilerTimingDisabledValue); } + parsedCommandLine->AppendSwitch(switches::kEnableViewport); + parsedCommandLine->AppendSwitch(switches::kDisableGpu); + parsedCommandLine->AppendSwitch(switches::kDisableWebSecurity); + GLContextHelper::initialize(); if (usingANGLE() || usingSoftwareDynamicGL() || usingQtQuick2DRenderer()) { --- qtbase/src/gui/kernel/qsurfaceformat.cpp +++ qtbase/src/gui/kernel/qsurfaceformat.cpp @@ -108,6 +108,7 @@ public: int major; int minor; int swapInterval; + QSurfaceFormat::OrientationFlags orientationFlags; }; /*! @@ -734,6 +735,16 @@ int QSurfaceFormat::swapInterval() const return d->swapInterval; } +QSurfaceFormat::OrientationFlags QSurfaceFormat::orientationFlags() const +{ + return d->orientationFlags; +} + +void QSurfaceFormat::setOrientationFlags(QSurfaceFormat::OrientationFlags orientationFlags) +{ + d->orientationFlags = orientationFlags; +} + Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format) /*! --- qtbase/src/gui/kernel/qsurfaceformat.h +++ qtbase/src/gui/kernel/qsurfaceformat.h @@ -55,7 +55,8 @@ public: StereoBuffers = 0x0001, DebugContext = 0x0002, DeprecatedFunctions = 0x0004, - ResetNotification = 0x0008 + ResetNotification = 0x0008, + UseOptimalOrientation = 0x0010 }; Q_DECLARE_FLAGS(FormatOptions, FormatOption) @@ -79,6 +80,11 @@ public: CompatibilityProfile }; + enum OrientationFlag { + MirrorVertically = 0x0001, + }; + Q_DECLARE_FLAGS(OrientationFlags, OrientationFlag) + QSurfaceFormat(); /*implicit*/ QSurfaceFormat(FormatOptions options); QSurfaceFormat(const QSurfaceFormat &other); @@ -139,6 +145,9 @@ public: int swapInterval() const; void setSwapInterval(int interval); + QSurfaceFormat::OrientationFlags orientationFlags() const; + void setOrientationFlags(QSurfaceFormat::OrientationFlags orientationFlags); + static void setDefaultFormat(const QSurfaceFormat &format); static QSurfaceFormat defaultFormat(); --- qtbase/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ qtbase/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -282,11 +282,25 @@ QWindowsOpenGLContext *QWindowsEGLStaticContext::createContext(QOpenGLContext *c return new QWindowsEGLContext(this, context->format(), context->shareHandle()); } -void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) +void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig, const QSurfaceFormat format, int *err) { *err = 0; + + std::vector attrib_list; +#ifdef EGL_ANGLE_surface_orientation + if (format.testOption(QSurfaceFormat::UseOptimalOrientation)) { + EGLint surfaceOrientation = 0; + libEGL.eglGetConfigAttrib(m_display, nativeConfig, EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE, &surfaceOrientation); + if (surfaceOrientation & EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) { + attrib_list.push_back(EGL_SURFACE_ORIENTATION_ANGLE); + attrib_list.push_back(EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE); + } + } +#endif + attrib_list.push_back(EGL_NONE); EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, nativeConfig, - static_cast(nativeWindow), 0); + static_cast(nativeWindow), + &attrib_list[0]); if (surface == EGL_NO_SURFACE) { *err = libEGL.eglGetError(); qWarning("%s: Could not create the EGL window surface: 0x%x", __FUNCTION__, *err); @@ -335,6 +349,14 @@ QSurfaceFormat QWindowsEGLStaticContext::formatFromConfig(EGLDisplay display, EG format.setStereo(false); format.setSwapInterval(referenceFormat.swapInterval()); +#ifdef EGL_ANGLE_surface_orientation + if (referenceFormat.testOption(QSurfaceFormat::UseOptimalOrientation)) { + EGLint surfaceOrientation = 0; + libEGL.eglGetConfigAttrib(display, config, EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE, &surfaceOrientation); + format.setOrientationFlags((surfaceOrientation & EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) ? QSurfaceFormat::MirrorVertically : QSurfaceFormat::OrientationFlags()); + } +#endif + // Clear the EGL error state because some of the above may // have errored out because the attribute is not applicable // to the surface type. Such errors don't matter. @@ -430,7 +452,7 @@ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext, } } m_format.setProfile(QSurfaceFormat::NoProfile); - m_format.setOptions(QSurfaceFormat::FormatOptions()); + m_format.setOptions(m_format.options() & QSurfaceFormat::UseOptimalOrientation); QWindowsEGLStaticContext::libEGL.eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); } QWindowsEGLStaticContext::libEGL.eglDestroySurface(m_eglDisplay, pbuffer); --- qtbase/src/plugins/platforms/windows/qwindowseglcontext.h +++ qtbase/src/plugins/platforms/windows/qwindowseglcontext.h @@ -121,7 +121,7 @@ public: void *moduleHandle() const Q_DECL_OVERRIDE { return libGLESv2.moduleHandle(); } QOpenGLContext::OpenGLModuleType moduleType() const Q_DECL_OVERRIDE { return QOpenGLContext::LibGLES; } - void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE; + void *createWindowSurface(void *nativeWindow, void *nativeConfig, const QSurfaceFormat format, int *err) Q_DECL_OVERRIDE; void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE; QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat); --- qtbase/src/plugins/platforms/windows/qwindowsopenglcontext.h +++ qtbase/src/plugins/platforms/windows/qwindowsopenglcontext.h @@ -62,7 +62,7 @@ public: // If the windowing system interface needs explicitly created window surfaces (like EGL), // reimplement these. - virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, int * /*err*/) { return 0; } + virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, const QSurfaceFormat /*format*/, int * /*err*/) { return 0; } virtual void destroyWindowSurface(void * /*nativeSurface*/) { } private: --- qtbase/src/plugins/platforms/windows/qwindowswindow.cpp +++ qtbase/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2458,7 +2458,7 @@ void *QWindowsWindow::surface(void *nativeConfig, int *err) #else if (!m_surface) { if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) - m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err); + m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, m_format, err); } return m_surface; --- qtdeclarative/src/quick/items/qquickwindow.cpp +++ qtdeclarative/src/quick/items/qquickwindow.cpp @@ -458,7 +458,13 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) renderer->setDeviceRect(rect); renderer->setViewportRect(rect); } - renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size)); + QRectF projRect(QPoint(0, 0), size); + bool mirrorVertically = QOpenGLContext::currentContext()->format().orientationFlags() & QSurfaceFormat::MirrorVertically; + QRectF mirrored(projRect.left(), + mirrorVertically ? projRect.bottom() : projRect.top(), + projRect.width(), + mirrorVertically ? -projRect.height() : projRect.height()); + renderer->setProjectionMatrixToRect(mirrored); renderer->setDevicePixelRatio(devicePixelRatio); context->renderNextFrame(renderer, fboId); --- qtdeclarative/src/quick/scenegraph/qsgcontext.cpp +++ qtdeclarative/src/quick/scenegraph/qsgcontext.cpp @@ -476,6 +476,8 @@ QSurfaceFormat QSGContext::defaultSurfaceFormat() const static bool enableDebug = qEnvironmentVariableIsSet("QSG_OPENGL_DEBUG"); format.setDepthBufferSize(useDepth ? 24 : 0); format.setStencilBufferSize(useStencil ? 8 : 0); + // XXX: Uncomment to enable application-side Y-coordinates-flipping by default + // format.setOption(QSurfaceFormat::UseOptimalOrientation); if (enableDebug) format.setOption(QSurfaceFormat::DebugContext); if (QQuickWindow::hasDefaultAlphaBuffer())