From jocelyn.turcotte at digia.com Thu Jan 2 17:09:32 2014 From: jocelyn.turcotte at digia.com (Jocelyn Turcotte) Date: Thu, 2 Jan 2014 17:09:32 +0100 Subject: [Qtwebengine] new QML window API In-Reply-To: <9160F3295FA8E24781968BBD40362991FEA429@IT-EXMB02-HKI.it.local> References: <9160F3295FA8E24781968BBD40362991FEA429@IT-EXMB02-HKI.it.local> Message-ID: <20140102160932.GA1388@poutine.it.local> Hello, I've been chatting with Simon about this on IRC and after having put aside most issues that I raised in my "After trying to get it work and try it out, here is the snapshot.." comment at we came to the conclusion that the choice between his suggested simple component approach vs. the current API is the power that a signal handler (current API) would give vs. the convenience of not having to instantiate the component manually and have the adoption done behind the scene through the creation QQmlContext (API in this email). There are still two important bugs in the way to get something reliable: https://bugreports.qt-project.org/browse/QTBUG-35910 https://bugreports.qt-project.org/browse/QTBUG-35913 Once we have this solved we can try to implement it properly. The current "onCreateWindow" API will stay experimental until 1.0 anyway and we can try out a few things before committing to a public API. That said, this means that the current experimental new window API will change soon if everything goes right. Regards, Jocelyn On Fri, Dec 27, 2013 at 06:01:46PM +0000, Hausmann Simon wrote: > Hi, > > I keep on thinking about the new window QML API and how much I'd like it to be > convenient, i.e. hide the process of stitching the newly created window > component to engine-given web contents object entirey from the developer. I > think I have found a solution: > > Generally speaking the webview can be created in two different contexts: > > 1) A new window is created by the user, or for example on start-up. In this > context there's nothing for the implementation to adopt or do. > > 2) A new window is created in the context of an engine requesting/informing us > to do so. > > Now if we want to allow the user to specify the environment the QML webview > lives in as a QML component, then we are presented with an arbitrary QML type. > It could be simple like this: > > Component { > id: viewComponent > > WebView { > newWindowComponent: viewComponent > } > } > > Or it could be deeply nested: > > Component { > id: viewComponent > > SomeOtherType { > ... > } > } > > SomeOtherType.qml: > import QtQuick 2.0 > import QtWebEngine 1.0 > > SomeCrazyItem { > WebView { > newWindowComponent: viewComponent // this works, but it's better to use an intermediate property > } > } > > In these two cases the user supplied component will eventually create one > WebView. It is also possible that multiple WebViews are created, maybe each > WebView also has a WebView for the web inspector or some meta-data. I'd like > to classify the first two cases as very common and the latter as rare. > > I think the solution for the common case is simply to specify and determine the > the context of creation, in the literal as well as in the QML sense. When a new > instance is created with 'viewComponent", the QML context for the new type will > be a child context of viewComponent's context. > > We can utilize this concept and whenever the WebView itself wants to create a > new window with a given WebContents, we take the creation context of the view > component, but inject an intermediate QQmlContext - the NewWindowContext. In > this context we can put anything we want. We could do it on a QML property > level, but I actually think it's easier to simply do that in C++. > > So when a WebView is created, in its componentComplete() implementation we can > fetch the QML context that belongs do this instance and walk up the parent > context chain until we either find the root context or a NewWindowContext. If > the latter, then we can extract all the data we need for a successful > WebContents adoption. That's entirely transparent to the user of the API. > > In the rare case where somebody specifies multiple WebView instances, we need > an API for the developer to specify which WebView in the component shall be the > primary one for new window content, for example through a property that > indicates whether the WebView should adopt web contents or not. > > The resulting API makes the common case intuitive and trivial: The component > specified must have a WebView _somewhere_ in its object hierarchy and it'll > automatically be picked up and used for the context of newly created windows. > The rare case we can make possible by requiring a little bit of help from the > user. > > In addition to all this we can of course still have informational signals about > newly created windows, etc. - but they don't come with any contractual > obligations :) > > I've hacked up a prototype below that demonstrates the concept. Right now it > uses a dedicated QQmlContext for each new-window created WebView, but using an > incubator we could also avoid the "overhead" and get rid of the dummy context I > think. > > Let me know what you think :) > > > Simon > > #include > > class NewWindowContext : public QQmlContext > { > Q_OBJECT > public: > NewWindowContext(QQmlContext *parentContext) > : QQmlContext(parentContext) > , handle(0) > {} > > // Use QExplicitlySharedDataPointer in real version :) > void *handle; > }; > > class WebView : public QObject, public QQmlParserStatus > { > Q_OBJECT > Q_INTERFACES(QQmlParserStatus) > Q_PROPERTY(QQmlComponent* newWindowComponent READ newWindowComponent WRITE setNewWindowComponent) > public: > WebView(); > > void setNewWindowComponent(QQmlComponent *comp) { m_newWindowComponent = comp; } > QQmlComponent *newWindowComponent() const { return m_newWindowComponent; } > > Q_INVOKABLE void createNewWindow(); > > virtual void classBegin() {} > virtual void componentComplete(); > > private: > QQmlComponent *m_newWindowComponent; > }; > > WebView::WebView() > : m_newWindowComponent(0) > { > qDebug() << "WebView::WebView()"; > } > > void WebView::createNewWindow() > { > Q_ASSERT(m_newWindowComponent); > > QQmlContext *parentContext = m_newWindowComponent->creationContext(); > if (!parentContext) > parentContext = qmlContext(this); > // ### can this happen?? > if (!parentContext) { > QQmlEngine *engine = qmlEngine(this); > Q_ASSERT(engine); > parentContext = engine->rootContext(); > } > NewWindowContext *newContext = new NewWindowContext(parentContext); > newContext->handle = this; // Or anything, really :) > m_newWindowComponent->create(newContext); > } > > void WebView::componentComplete() > { > QQmlContext *context = qmlContext(this); > > void *handle = 0; > while (context) { > if (NewWindowContext *newWindowContext = qobject_cast(context)) { > qSwap(newWindowContext->handle, handle); > break; > } > context = context->parentContext(); > } > if (handle) > qDebug() << "WebView created from another WebView!" << handle; > else > qDebug() << "Standalone WebView complete"; > } > > int main(int argc, char **argv) > { > QCoreApplication app(argc, argv); > > QQmlEngine engine; > > qmlRegisterType("TestWebEngine", 1, 0, "WebView"); > > QQmlComponent doc(&engine); > doc.setData("" > "import QtQml 2.0\n" > "import TestWebEngine 1.0\n" > > "QtObject {\n" > " id: root\n" > " property string test: 'Hello World'\n" > "\n" > " property Component factory: Component {\n" > " id: viewComponent\n" > "\n" > " WebView {\n" > " newWindowComponent: viewComponent\n" > " }\n" > " }\n" > "\n" > " property QtObject initialWebView: factory.createObject();\n" > "}", QUrl()); > > QScopedPointer root(doc.create()); > if (!root) { > qDebug() << doc.errors().first().toString(); > return 1; > } > > QObject *initialView = qvariant_cast(root->property("initialWebView")); > QMetaObject::invokeMethod(initialView, "createNewWindow"); > > return 0; > } > > #include "main.moc" > _______________________________________________ > QtWebEngine mailing list > QtWebEngine at qt-project.org > http://lists.qt-project.org/mailman/listinfo/qtwebengine From simon.hausmann at digia.com Fri Jan 3 11:43:07 2014 From: simon.hausmann at digia.com (Simon Hausmann) Date: Fri, 3 Jan 2014 11:43:07 +0100 Subject: [Qtwebengine] new QML window API In-Reply-To: <20140102160932.GA1388@poutine.it.local> References: <9160F3295FA8E24781968BBD40362991FEA429@IT-EXMB02-HKI.it.local> <20140102160932.GA1388@poutine.it.local> Message-ID: <2996471.9txzbbE7Nu@rhea> On Thursday 2. January 2014 17.09.32 Jocelyn Turcotte wrote: > Hello, > > I've been chatting with Simon about this on IRC and after having put aside > most issues that I raised in my "After trying to get it work and try it > out, here is the snapshot.." comment at we > came to the conclusion that the choice between his suggested simple > component approach vs. the current API is the power that a signal handler > (current API) would give vs. the convenience of not having to instantiate > the component manually and have the adoption done behind the scene through > the creation QQmlContext (API in this email). > > There are still two important bugs in the way to get something reliable: > https://bugreports.qt-project.org/browse/QTBUG-35910 > https://bugreports.qt-project.org/browse/QTBUG-35913 > > Once we have this solved we can try to implement it properly. The current > "onCreateWindow" API will stay experimental until 1.0 anyway and we can try > out a few things before committing to a public API. > > That said, this means that the current experimental new window API will > change soon if everything goes right. I think finally it's going to look pretty simple. Without any new window stuff, you'd write it like this: TabView { Tab { WebView { } } } With new-tab support, we'd replace the "Tab" with "Component": TabView { Component { id: newTabFactory WebView { newWindowComponent: newTabFactory } } // Initial tab for example: Tab { component: newTabFactory onLoaded: item.url = "http://initial-url.com/" } // Dynamically created tabs: function dynamicFoo() { var tab = addTab("", newTabFactory) } } And the web view doesn't need to know anything about tabs. I'll talk to the compo^H^Hcontrols folks about automatic support for propagating a title property from the created component. Simon From fbernhard at gmail.com Tue Jan 21 08:06:15 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Tue, 21 Jan 2014 08:06:15 +0100 Subject: [Qtwebengine] How to change user agent? Message-ID: Dear list, Thank you for this project! I need to create a small fallback application for a WebRTC web application for those Windows users who, for whatever reason, can't install Google Chrome on their machines. I have not advanced much with testing because I first need to change the user agent to the standard Google Chrome user agent. Otherwise Javascript frameworks won't recognise the browser and throw an error. Check for instance: https://apprtc.appspot.com How can I change the complete user agent string, preferably in the example project "widgetsnanobrowser"? Thank you! Fabian -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre.rossi at gmail.com Tue Jan 21 13:22:16 2014 From: pierre.rossi at gmail.com (Pierre Rossi) Date: Tue, 21 Jan 2014 13:22:16 +0100 Subject: [Qtwebengine] How to change user agent? In-Reply-To: References: Message-ID: Hi, I think you'll most likely need something like this for your needs: https://codereview.qt-project.org/#change,75125 It is essentially just missing the permission granting part (which could be a bit of a problem if the contents you load are untrusted, you have been warned). We don't have user agent string overriding implemented yet (shouldn't be too hard, we just didn't get around to it), but in that case, WebRTC should work everywhere they sniff the UA-string thanks to adding the a mention of Chromium and the version we're based off alongside the usual suspects (Mozilla, WebKit, KHTML, Gecko and Safari). Feedback is most welcome of course. Cheers, -- Pierre On Tue, Jan 21, 2014 at 8:06 AM, Fabian Bernhard wrote: > Dear list, > > Thank you for this project! > > I need to create a small fallback application for a WebRTC web application > for those Windows users who, for whatever reason, can't install Google > Chrome on their machines. > > I have not advanced much with testing because I first need to change the > user agent to the standard Google Chrome user agent. Otherwise Javascript > frameworks won't recognise the browser and throw an error. Check for > instance: > > https://apprtc.appspot.com > > How can I change the complete user agent string, preferably in the example > project "widgetsnanobrowser"? > > Thank you! > > Fabian > > _______________________________________________ > QtWebEngine mailing list > QtWebEngine at qt-project.org > http://lists.qt-project.org/mailman/listinfo/qtwebengine > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fbernhard at gmail.com Tue Jan 21 13:41:48 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Tue, 21 Jan 2014 13:41:48 +0100 Subject: [Qtwebengine] How to change user agent? In-Reply-To: References: Message-ID: Hi Pierre I think you'll most likely need something like this for your needs: > https://codereview.qt-project.org/#change,75125 > > It is essentially just missing the permission granting part (which could > be a bit of a problem if the contents you load are untrusted, you have been > warned). > Thats fine in my case since I let the QtWebEngine only open exactly one website which we control ourselves. > We don't have user agent string overriding implemented yet (shouldn't be > too hard, we just didn't get around to it), but in that case, WebRTC should > work everywhere they sniff the UA-string thanks to adding the a mention of > Chromium and the version we're based off alongside the usual suspects > (Mozilla, WebKit, KHTML, Gecko and Safari). > Many of the WebRTC websites including ours use Google's adapter.js [0] to set up the peer connection. With the current user agent this script fails at: webrtcDetectedVersion = parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10); Thats the reason I'd like to change the user agent. Would you by any chance know where in the source the current user agent is defined? I have grep'ed all .h, .c and .cpp files for AppleWebKit and couldn't find a match... Thanks and regards, Fabian [0] https://code.google.com/p/webrtc/source/browse/stable/samples/js/base/adapter.js -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre.rossi at gmail.com Tue Jan 21 14:07:05 2014 From: pierre.rossi at gmail.com (Pierre Rossi) Date: Tue, 21 Jan 2014 14:07:05 +0100 Subject: [Qtwebengine] How to change user agent? In-Reply-To: References: Message-ID: Hi Fabian, On Tue, Jan 21, 2014 at 1:41 PM, Fabian Bernhard wrote: > Many of the WebRTC websites including ours use Google's adapter.js [0] to > set up the peer connection I know, it was actually almost the biggest obstacle to getting WebRTC-powered apps working, that's why the patch I pointed to does change our default user agent slightly [1]. Let me know if that works for you. Cheers, -- Pierre [1] https://codereview.qt-project.org/#patch,sidebyside,75125,1,src/core/web_engine_context.cpp -------------- next part -------------- An HTML attachment was scrubbed... URL: From fbernhard at gmail.com Tue Jan 21 15:53:45 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Tue, 21 Jan 2014 15:53:45 +0100 Subject: [Qtwebengine] How to change user agent? In-Reply-To: References: Message-ID: Hi Pierre Many of the WebRTC websites including ours use Google's adapter.js [0] to >> set up the peer connection > > > I know, it was actually almost the biggest obstacle to getting > WebRTC-powered apps working, that's why the patch I pointed to does change > our default user agent slightly [1]. > > [1] > https://codereview.qt-project.org/#patch,sidebyside,75125,1,src/core/web_engine_context.cpp > > Changing the user agent this way works, I don't have Javascript errors anymore. I have other issues [0], i.e. I can't get WebRTC working yet. I will investigate and post new questions in a separate thread. Thanks for your assistance! Regards, Fabian [0] Warnings and error: [0121/154659:WARNING:resource_bundle.cc(269)] locale_file_path.empty() 2014-01-21 15:46:59.866 QtWebEngineProcess[99752:507] Internals of CFAllocator not known; out-of-memory failures via CFAllocator will not result in termination. http://crbug.com/45650 [0121/154659:WARNING:resource_bundle.cc(269)] locale_file_path.empty() [0121/154659:ERROR:renderer_main.cc(227)] Running without renderer sandbox -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.hausmann at digia.com Wed Jan 22 15:04:15 2014 From: simon.hausmann at digia.com (Simon Hausmann) Date: Wed, 22 Jan 2014 15:04:15 +0100 Subject: [Qtwebengine] new QML window API In-Reply-To: <2996471.9txzbbE7Nu@rhea> References: <9160F3295FA8E24781968BBD40362991FEA429@IT-EXMB02-HKI.it.local> <20140102160932.GA1388@poutine.it.local> <2996471.9txzbbE7Nu@rhea> Message-ID: <4168176.7gknsjeXCd@rhea> On Friday 3. January 2014 11.43.07 Simon Hausmann wrote: [...] Finally this idea didn't pan out because the component hierarchy wouldn't support this if the webview component was inside a loader but declared elsewhere, as pointed out by Jocelyn. So after a brief discussion with Jens and Gabriel I'd now also like to request (partial) membership in the party that advocates the imperative API ;-). Summary of suggestion by code: TabView { id: tabView Component { id: webViewComponent WebView { newWebViewComponent: webViewComponent // invisible "view" parameter, the newly created view that has no visual parent onViewCreated: { if (view.url == "http://i-want-to-block-this.com/") { view.parent = null; // Not needed, but more readable that way. The calling webview will delete a view again if it has no visual parent after signal emission return; } if (wantItInAWindow) { ... add it to a window } else { tabView.addTab(view); // They'll add support for item based insertion to controls :) } } } } An alternative to "magic" rejection on the signal handler for implementing popup blocking for example would be the use of an attached property perhaps: onViewCreated: { if (view.url = "bad") { WebView.rejectView = true; return; } Or perhaps this should be consistent with events? onViewCreated: { if (view.url == "bad") { view.accept = false; (or reject = true or both?) return } Thoughts? :) Simon From fbernhard at gmail.com Thu Jan 23 04:31:08 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Thu, 23 Jan 2014 04:31:08 +0100 Subject: [Qtwebengine] Websockets not working -> debug Javascript? Message-ID: Dear list, I can’t make web sockets work. At least thats what I believe goes wrong with the WebRTC application. I use OSX 10.9 for development. Has anyone successfully used web sockets in QTWebEngine? And, is there a way to debug Javascript in QtWebEngine? I would like to pinpoint the exact issue. Thank you! Fabian -------------- next part -------------- An HTML attachment was scrubbed... URL: From jocelyn.turcotte at digia.com Thu Jan 23 11:28:44 2014 From: jocelyn.turcotte at digia.com (Jocelyn Turcotte) Date: Thu, 23 Jan 2014 11:28:44 +0100 Subject: [Qtwebengine] Websockets not working -> debug Javascript? In-Reply-To: References: Message-ID: <20140123102844.GD11318@poutine.it.local> Hi Fabian, WebSockets seem to work for me (on Linux) with this test page: http://www.websocket.org/echo.html For debugging in general, make sure that you start your application with --single-process. It will run the render and plugin processes as thread in the main process instead and should allow you to debug more easily. Cheers, Jocelyn On Thu, Jan 23, 2014 at 04:31:08AM +0100, Fabian Bernhard wrote: > Dear list, > > I can’t make web sockets work. At least thats what I believe goes wrong > with the WebRTC application. I use OSX 10.9 for development. > > Has anyone successfully used web sockets in QTWebEngine? > > And, is there a way to debug Javascript in QtWebEngine? I would like to > pinpoint the exact issue. > > Thank you! > > Fabian > _______________________________________________ > QtWebEngine mailing list > QtWebEngine at qt-project.org > http://lists.qt-project.org/mailman/listinfo/qtwebengine From fbernhard at gmail.com Thu Jan 23 11:49:26 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Thu, 23 Jan 2014 11:49:26 +0100 Subject: [Qtwebengine] Websockets not working -> debug Javascript? In-Reply-To: <20140123102844.GD11318@poutine.it.local> References: <20140123102844.GD11318@poutine.it.local> Message-ID: Hoi Jocelyn, Thanks for your report, I am glad that it works generally speaking. WebSockets seem to work for me (on Linux) with this test page: > http://www.websocket.org/echo.html It doesn't work for me though. I am using the "examples/widgets/browser" project for testing. The website just hangs and does not finish loading. > For debugging in general, make sure that you start your application with > --single-process. > It will run the render and plugin processes as thread in the main process > instead and should allow you to debug more easily. > With this flag the browser crashes consistently when I load above websocket.org website, see crash log below. Google.com works fine though. May be its just an OSX issue? Thanks for your assistance! Fabian Thread 18 Crashed:: Chrome_InProcRendererThread 0 libQt5WebEngineCore.dylib 0x00000001032f7b38 WebCore::V8HTMLElement::createWrapper(WTF::PassRefPtr, v8::Handle, v8::Isolate*) + 232 1 libQt5WebEngineCore.dylib 0x000000010343fa8c WebCore::createHTMLVideoElementWrapper(WebCore::HTMLElement*, v8::Handle, v8::Isolate*) + 140 2 libQt5WebEngineCore.dylib 0x000000010343e27f WebCore::createV8HTMLWrapper(WebCore::HTMLElement*, v8::Handle, v8::Isolate*) + 12863 3 libQt5WebEngineCore.dylib 0x0000000103413d92 WebCore::wrap(WebCore::Element*, v8::Handle, v8::Isolate*) + 18 4 libQt5WebEngineCore.dylib 0x0000000103337087 WebCore::DocumentV8Internal::createElementMethodCallbackForMainWorld(v8::FunctionCallbackInfo const&) + 951 5 libQt5WebEngineCore.dylib 0x000000010239d5de v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo const&)) + 158 6 libQt5WebEngineCore.dylib 0x00000001023b6d69 v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) + 393 7 ??? 0x00003906113069ce 0 + 62698220972494 8 ??? 0x0000390611357598 0 + 62698221303192 9 ??? 0x0000390611344d18 0 + 62698221227288 10 ??? 0x0000390611311394 0 + 62698221015956 11 ??? 0x0000390611342aa9 0 + 62698221218473 12 ??? 0x0000390611336a24 0 + 62698221169188 13 ??? 0x000039061131a477 0 + 62698221053047 14 libQt5WebEngineCore.dylib 0x00000001023edfb6 v8::internal::Invoke(bool, v8::internal::Handle, v8::internal::Handle, int, v8::internal::Handle*, bool*) + 342 15 libQt5WebEngineCore.dylib 0x00000001023849a6 v8::Script::Run() + 486 16 libQt5WebEngineCore.dylib 0x0000000103405c9f WebCore::V8ScriptRunner::runCompiledScript(v8::Handle, WebCore::ScriptExecutionContext*, v8::Isolate*) + 271 17 libQt5WebEngineCore.dylib 0x00000001033df276 WebCore::ScriptController::compileAndRunScript(WebCore::ScriptSourceCode const&, WebCore::AccessControlStatus) + 518 18 libQt5WebEngineCore.dylib 0x00000001033e08b2 WebCore::ScriptController::executeScriptInMainWorld(WebCore::ScriptSourceCode const&, WebCore::AccessControlStatus) + 418 19 libQt5WebEngineCore.dylib 0x00000001027ec8dc WebCore::ScriptLoader::executeScript(WebCore::ScriptSourceCode const&) + 716 20 libQt5WebEngineCore.dylib 0x00000001029f1a9a WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent(WebCore::PendingScript&) + 234 21 libQt5WebEngineCore.dylib 0x00000001029f2202 WebCore::HTMLScriptRunner::executeParsingBlockingScripts() + 386 22 libQt5WebEngineCore.dylib 0x00000001029e64e0 WebCore::HTMLDocumentParser::notifyFinished(WebCore::Resource*) + 80 23 libQt5WebEngineCore.dylib 0x0000000102cd5d48 WebCore::Resource::checkNotify() + 344 24 libQt5WebEngineCore.dylib 0x0000000102cd605a WebCore::Resource::finish(double) + 26 25 libQt5WebEngineCore.dylib 0x0000000102ce207b WebCore::ResourceLoader::didFinishLoading(WebKit::WebURLLoader*, double) + 123 26 libQt5WebEngineCore.dylib 0x00000001037460cf webkit_glue::WebURLLoaderImpl::Context::OnCompletedRequest(int, bool, std::__1::basic_string, std::__1::allocator > const&, base::TimeTicks const&) + 479 27 libQt5WebEngineCore.dylib 0x000000010372c071 content::ResourceDispatcher::OnRequestComplete(int, int, bool, std::__1::basic_string, std::__1::allocator > const&, base::TimeTicks const&) + 449 28 libQt5WebEngineCore.dylib 0x000000010372aaf1 content::ResourceDispatcher::DispatchMessage(IPC::Message const&) + 561 29 libQt5WebEngineCore.dylib 0x000000010372a2db content::ResourceDispatcher::OnMessageReceived(IPC::Message const&) + 811 30 libQt5WebEngineCore.dylib 0x00000001036ee9d6 content::ChildThread::OnMessageReceived(IPC::Message const&) + 38 31 libQt5WebEngineCore.dylib 0x00000001018b545f IPC::ChannelProxy::Context::OnDispatchMessage(IPC::Message const&) + 575 32 libQt5WebEngineCore.dylib 0x000000010187ceda base::MessageLoop::RunTask(base::PendingTask const&) + 1082 33 libQt5WebEngineCore.dylib 0x000000010187d407 base::MessageLoop::DoWork() + 727 34 libQt5WebEngineCore.dylib 0x000000010187fcea base::MessagePumpDefault::Run(base::MessagePump::Delegate*) + 346 35 libQt5WebEngineCore.dylib 0x000000010187c7c2 base::MessageLoop::RunInternal() + 226 36 libQt5WebEngineCore.dylib 0x000000010189173a base::RunLoop::Run() + 26 37 libQt5WebEngineCore.dylib 0x000000010187bf9d base::MessageLoop::Run() + 29 38 libQt5WebEngineCore.dylib 0x00000001018a7b4b base::Thread::ThreadMain() + 203 39 libQt5WebEngineCore.dylib 0x00000001018a249b base::(anonymous namespace)::ThreadFunc(void*) + 171 40 libsystem_pthread.dylib 0x00007fff92937899 _pthread_body + 138 41 libsystem_pthread.dylib 0x00007fff9293772a _pthread_start + 137 42 libsystem_pthread.dylib 0x00007fff9293bfc9 thread_start + 13 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jocelyn.turcotte at digia.com Thu Jan 23 13:34:40 2014 From: jocelyn.turcotte at digia.com (Jocelyn Turcotte) Date: Thu, 23 Jan 2014 13:34:40 +0100 Subject: [Qtwebengine] Websockets not working -> debug Javascript? In-Reply-To: References: <20140123102844.GD11318@poutine.it.local> Message-ID: <20140123123440.GA7258@poutine.it.local> Hello Fabian, On Thu, Jan 23, 2014 at 11:49:26AM +0100, Fabian Bernhard wrote: > > For debugging in general, make sure that you start your application with > > --single-process. > > It will run the render and plugin processes as thread in the main process > > instead and should allow you to debug more easily. > > > > With this flag the browser crashes consistently when I load above > websocket.org website, see crash log below. Google.com works fine though. Please pull to get this change, it landed yesterday in master: https://codereview.qt-project.org/76276 If it still crashes, we have a pending patch that remove the release assert causing it, you can try to apply it to your clone: https://codereview.qt-project.org/76151 > May be its just an OSX issue? It could be yes, but I would suspect that it's something else than WebSockets unless you have concrete observations that show it not working. Cheers, Jocelyn From fbernhard at gmail.com Thu Jan 23 16:53:08 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Thu, 23 Jan 2014 16:53:08 +0100 Subject: [Qtwebengine] Websockets not working -> debug Javascript? In-Reply-To: <20140123123440.GA7258@poutine.it.local> References: <20140123102844.GD11318@poutine.it.local> <20140123123440.GA7258@poutine.it.local> Message-ID: Hi Jocelyn Please pull to get this change, it landed yesterday in master: > https://codereview.qt-project.org/76276 > If it still crashes, we have a pending patch that remove the release > assert causing it, you can try to apply it to your clone: > https://codereview.qt-project.org/76151 Nice, this works perfectly! > May be its just an OSX issue? > > It could be yes, but I would suspect that it's something else than > WebSockets unless you have concrete observations that show it not working. > Most probably it was not the WebSockets but the video element that caused my problem ;-) Thanks for your help! -------------- next part -------------- An HTML attachment was scrubbed... URL: From fbernhard at gmail.com Mon Jan 27 17:30:37 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Mon, 27 Jan 2014 17:30:37 +0100 Subject: [Qtwebengine] WebRTC camera and mic access Message-ID: Dear list, Is there a quick and dirty way to automatically grant access to the camera and the mic? In an earlier question on this list Pierre has suggested the following patch: https://codereview.qt-project.org/#change,75125 I have applied the patch manually but failed to compile the result, due to errors such as the one below. In file included from ../../src/core/content_browser_client_qt.cpp:42: [...]/qtwebengine/src/core/content_browser_client_qt.h:84:43: error: 'GetMediaRequestContextForRenderProcess' marked 'override' but does not override any member functions virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(int renderer_child_id) Q_DECL_OVERRIDE; URLRequestContextGetter is indeed not defined in the chromium source code, afaik. I am not familiar at all with the chromium source code and very new to QT though. I am not writing a full blown web browser, just a small program that opens one website only. I can safely grant automatic access to the devices without user interaction because thats what the user anyway expects in my case. Thank you and regards, Fabian -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre.rossi at gmail.com Tue Jan 28 12:16:04 2014 From: pierre.rossi at gmail.com (Pierre Rossi) Date: Tue, 28 Jan 2014 12:16:04 +0100 Subject: [Qtwebengine] WebRTC camera and mic access In-Reply-To: References: Message-ID: Hi Fabian, On Mon, Jan 27, 2014 at 5:30 PM, Fabian Bernhard wrote: > GetMediaRequestContextForRenderProcess > This sounds weird, I double checked and that function is declared in content/public/browser/browser_context.h, even in the snapshot. Could you post the contents of that file for you? maybe the chromium sources you are using are out of sync somehow? Cheers, --Pierre -------------- next part -------------- An HTML attachment was scrubbed... URL: From fbernhard at gmail.com Tue Jan 28 14:41:47 2014 From: fbernhard at gmail.com (Fabian Bernhard) Date: Tue, 28 Jan 2014 14:41:47 +0100 Subject: [Qtwebengine] WebRTC camera and mic access In-Reply-To: References: Message-ID: Hi Pierre, GetMediaRequestContextForRenderProcess > > > This sounds weird, I double checked and that function is declared > in content/public/browser/browser_context.h, even in the snapshot. > GetMediaRequestContextForRenderProcess is declared in content/public/browser/browser_context.h, indeed. I don’t understand the class hierarchy but from what I can see ContentBrowserClientQt (content_browser_client_qt.h) extends ContentBrowserClient (content/public/browser/content_browser_client.h) where this function is not declared. Thanks for your help! Regards, Fabian -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre.rossi at gmail.com Tue Jan 28 15:13:24 2014 From: pierre.rossi at gmail.com (Pierre Rossi) Date: Tue, 28 Jan 2014 15:13:24 +0100 Subject: [Qtwebengine] WebRTC camera and mic access In-Reply-To: References: Message-ID: Hi Fabian, Right, I replied only looking at the current state of QtWebEngine and without tlooking at the patch, so now that you point it out, yes, the patch is outdated, and it seems this method has been moved to the BrowserContext, which in practice means one lest cast for us. I'll try to get around to updating the patch, also hopefully adding a first draft for an API. Thanks for the feedback so far, :) --Pierre On Tue, Jan 28, 2014 at 2:41 PM, Fabian Bernhard wrote: > Hi Pierre, > > GetMediaRequestContextForRenderProcess >> >> >> This sounds weird, I double checked and that function is declared >> in content/public/browser/browser_context.h, even in the snapshot. >> > > GetMediaRequestContextForRenderProcess is declared in > content/public/browser/browser_context.h, indeed. > > I don't understand the class hierarchy but from what I can see > ContentBrowserClientQt (content_browser_client_qt.h) extends > ContentBrowserClient (content/public/browser/content_browser_client.h) > where this function is not declared. > > Thanks for your help! > > Regards, > > Fabian > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kirankenz at gmail.com Thu Jan 30 21:00:49 2014 From: kirankenz at gmail.com (kenz kiran) Date: Thu, 30 Jan 2014 14:00:49 -0600 Subject: [Qtwebengine] Preparing external textures for HTML5 video in qtwebengine Message-ID: Hello We (qnx port of blink) are developing a blink based browser with QTWebEngine in delegated rendering mode. To implement HTML5 Video we introduced Android like StreamTexture class. This is based on the EGL Image external extension. We have extended delegated_frame_node and added a YUV Node like class (with custom shaders etc) to support EGL Image External extension. We are discussing a current design limitation with Chromium graphics dev mailing list. The subject to search is: "Updating StreamTextures in Delegated Rendering". The design issue we need to solve (we have worked around it, but is not optimal). Here is the problem: When ever we get a new frame from the Video Decoder, before we blit the Quads from the Quad list received for the frame, we need to 'update()' which would internally do glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName) and glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image). where 'image' would be the EGLImage of the latest video frame from the decoder. In Chromium's existing design, before "ANY" draw call say DrawArrays or DrawElements, Chromium calls "PrepareTexturesForRender()" which internally calls Update() on each of the StreamTextures. But In case of delegated rendering, since we don't use chromium's GL Rendeder but use QT as the parent compositor rendering the received Quadlist, we don't make any draw calls using Chromium's gl infrastructure. So at this point we need a "preparetextures()" like call from delegated_frame_node. And this should happen in GPU thread and QT render thread should be blocked till this completes. So wanted to check this forum (specifically: Jocelyn and maybe Gunnar) to get some ideas on how to resolve this problem. Also chromium folks have raised some concerns of texture's being deleted while they are being composited by QT. I think mailboxes and existing infra should cover this case. But I haven't studied them in much depth. Here is the excerpt: Q: How exactly do you render with the texture if not DrawArrays or DrawElements? Does the actual final drawing not go through the gpu/commandbuffer layer, i.e. do you pull out or share the underlying GL texture somehow with an external GL context? WillUseTexture() is supposed to be called from any GL command being parsed that causes the texture to be used for drawing or blits. I am certain we don't go through, gpu/command buffer setup for drawing (hence no DrawArray/DrawElements). Yes we have shared context setup. The texture ids are known to the QT rendering context (which is not the same used by GPU thread). Concern: Does that not cause problems to share the texture that way since the gpu TextureManager and ContextGroup manages the lifetime of the texture (and could try to delete it)? I recommend you either have your view system use the gpu stack's GL client interface, or you share the texture externally in a more explicit way. Otherwise, if you are already pulling out the GL texture from underneath the chromium gpu stack, you might as well pull out the SurfaceTexture handle as well and update it (see GetLevelImage()). regards Ravi -------------- next part -------------- An HTML attachment was scrubbed... URL: From jocelyn.turcotte at digia.com Fri Jan 31 10:23:58 2014 From: jocelyn.turcotte at digia.com (Jocelyn Turcotte) Date: Fri, 31 Jan 2014 10:23:58 +0100 Subject: [Qtwebengine] Preparing external textures for HTML5 video in qtwebengine In-Reply-To: References: Message-ID: <20140131092358.GA19887@poutine.it.local> Hello Ravi, On Thu, Jan 30, 2014 at 02:00:49PM -0600, kenz kiran wrote: > Here is the problem: > When ever we get a new frame from the Video Decoder, before we blit the > Quads from the Quad list received for the frame, we need to 'update()' > which would internally do > > glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName) and > glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image). > > where 'image' would be the EGLImage of the latest video frame from the > decoder. > > In Chromium's existing design, before "ANY" draw call say DrawArrays or > DrawElements, Chromium calls "PrepareTexturesForRender()" which internally > calls Update() on each of the StreamTextures. > > But In case of delegated rendering, since we don't use chromium's GL > Rendeder but use QT as the parent compositor rendering the received > Quadlist, we don't make any draw calls using Chromium's gl infrastructure. > > So at this point we need a "preparetextures()" like call from > delegated_frame_node. And this should happen in GPU thread and QT render > thread should be blocked till this completes. > > So wanted to check this forum (specifically: Jocelyn and maybe Gunnar) to > get some ideas on how to resolve this problem. The latest moment that the Chromium GPU thread touches the textures is in DelegatedFrameNode::fetchTexturesAndUnlockQt. This happens _ONCE_ for every TransferableResource, so if you absolutely need to update your stream on the Chromium GPU thread, we will have to add some way to update this kind of resource every time that Qt will draw this texture. If on the other hand it's possible for you to do the stream update in the Qt rendering thread, you could do so in MailboxTexture::bind, or in a subclass of MailboxTexture. This happens right before a QSGGeometryNode attached to this texture gets drawn by the Qt scene graph. > Also chromium folks have raised some concerns of texture's being deleted > while they are being composited by QT. I think mailboxes and existing infra > should cover this case. But I haven't studied them in much depth. > > Here is the excerpt: > > Q: How exactly do you render with the texture if not DrawArrays or > DrawElements? Does the actual final drawing not go through the > gpu/commandbuffer layer, i.e. do you pull out or share the underlying GL > texture somehow with an external GL context? > > WillUseTexture() is supposed to be called from any GL command being parsed > that causes the texture to be used for drawing or blits. > > I am certain we don't go through, gpu/command buffer setup for drawing > (hence no DrawArray/DrawElements). Yes we have shared context setup. The > texture ids are known to the QT rendering context (which is not the same > used by GPU thread). Anything that Chromium does _in the browser process_ using ui::Compositor and cc::LayerTreeHost in order to render delegated frames, is instead rendered by the Qt Quick scene graph. We use DrawQuads and TransferableResources provided through DelegatedFrameData as input, convert them to QSGNode/QSGTexture subclasses, and then fetch the texture IDs directly from the MailboxManager in the in-process GPU thread using the provided mailboxes in the TransferableResources. The command buffer layer in Chromium interfaces two sets of texture IDs with one-another, the client IDs (the ones known by cc::GLRenderer, each context has its own set of client IDs) and the global service IDs (the real GL texture IDs used by GLES2DecoderImpl in the GPU process to do the actual rendering). By interfacing with the MailboxManager we get access to the service texture IDs directly, and since we setup our GL context as shared as you mentioned, we are able to render them. We don't use the command buffer layer in QtWebEngine since we want Qt to control the main GL frame buffer and we want to avoid having to render to an intermediate FBO. > Concern: Does that not cause problems to share the texture that way since > the gpu TextureManager and ContextGroup manages the lifetime of the texture > (and could try to delete it)? > I recommend you either have your view system use the gpu stack's GL client > interface, or you share the texture externally in a more explicit way. AFAIK the delegated renderer already provides this functionality. The way it works is that a TransferableResource is owned by the producing child compositor, but is held alive when tranfered to a parent compositor through a DelegatedFrameData and won't be deleted/reused until the parent decided to return it to the child compositor through a cc::CompositorFrameAck. The resource shouldn't be returned as long as it's possibly referenced by any unswapped frame in the GL pipeline. I don't know how you manage the lifetime of your SurfaceTexture, but if it behaves differently on this level we might have to adjust. > Otherwise, if you are already pulling out the GL texture from underneath > the chromium gpu stack, you might as well pull out the SurfaceTexture > handle as well and update it (see GetLevelImage()). Right now we've been able to do everything we needed only with the provided texture IDs, but adding image support sounds like something that we can do too at this level. Regards, Jocelyn