From e67c21a033121618bfe4cf62686d009d0bacd8c3 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte <jocelyn.turcotte@digia.com> Date: Tue, 11 Jun 2013 15:40:30 +0200 Subject: [PATCH] Get rid of BlinqApplication. Rename the class to WebEngineContext and keep it as a ref-counted member of pages instead. Also: - Change the user-agent product to QtWebEngine - Don't pass actual command line arguments to Chromium anymore - Allow attaching to the event loop through Before/AfterRun instead of blocking --- example/main.cpp | 9 +- lib/lib.pro | 10 +-- lib/qquickwebcontentsview.cpp | 10 +++ lib/qquickwebcontentsview.h | 2 + lib/qwebcontentsview.cpp | 4 + ...application.cpp => web_engine_context.cpp} | 83 +++++++++++-------- ...linqapplication.h => web_engine_context.h} | 23 +++-- patches/0001-My-local-fixes.patch | 12 +-- ...ebEngineContext-to-RunLoop-s-friends.patch | 33 ++++++++ patches/patch-chromium.sh | 2 +- 10 files changed, 131 insertions(+), 57 deletions(-) rename lib/{blinqapplication.cpp => web_engine_context.cpp} (80%) rename lib/{blinqapplication.h => web_engine_context.h} (81%) create mode 100644 patches/0002-Add-WebEngineContext-to-RunLoop-s-friends.patch diff --git a/example/main.cpp b/example/main.cpp index edd75f3ec..01850b879 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -39,13 +39,14 @@ ** ****************************************************************************/ -#include <blinqapplication.h> #include "quickwindow.h" #include "widgetwindow.h" +#include "qquickwebcontentsview.h" + int mainWidget(int argc, char **argv) { - BlinqApplication app(argc, argv); + QApplication app(argc, argv); WidgetWindow window; window.show(); @@ -55,7 +56,9 @@ int mainWidget(int argc, char **argv) int mainQuick(int argc, char **argv) { - BlinqApplication app(argc, argv); + QGuiApplication app(argc, argv); + + QQuickWebContentsView::registerType(); QuickWindow window; window.show(); diff --git a/lib/lib.pro b/lib/lib.pro index d8c47ef88..4db81a6f8 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -20,23 +20,21 @@ CONFIG(release, debug|release): DEFINES += NDEBUG QT += widgets quick SOURCES = \ - blinqapplication.cpp \ content_browser_client_qt.cpp \ qquickwebcontentsview.cpp \ qwebcontentsview.cpp \ resource_context_qt.cpp \ url_request_context_getter_qt.cpp \ - web_contents_delegate_qt.cpp - web_event_factory.cpp + web_contents_delegate_qt.cpp \ + web_engine_context.cpp HEADERS = \ - blinqapplication.h \ browser_context_qt.h \ content_browser_client_qt.h \ qquickwebcontentsview.h \ qwebcontentsview.h \ resource_context_qt.h \ url_request_context_getter_qt.h \ - web_contents_delegate_qt.h - web_event_factory.h + web_contents_delegate_qt.h \ + web_engine_context.h diff --git a/lib/qquickwebcontentsview.cpp b/lib/qquickwebcontentsview.cpp index 469b030fd..06ba95b79 100644 --- a/lib/qquickwebcontentsview.cpp +++ b/lib/qquickwebcontentsview.cpp @@ -51,19 +51,29 @@ #include "browser_context_qt.h" #include "content_browser_client_qt.h" #include "web_contents_delegate_qt.h" +#include "web_engine_context.h" #include <QWidget> #include <QUrl> +void QQuickWebContentsView::registerType() +{ + // FIXME: Do a proper plugin. + qmlRegisterType<QQuickWebContentsView>("QtWebEngine", 1, 0, "WebContentsView"); +} + class QQuickWebContentsViewPrivate { public: + scoped_refptr<WebEngineContext> context; scoped_ptr<WebContentsDelegateQt> webContentsDelegate; }; QQuickWebContentsView::QQuickWebContentsView() { d.reset(new QQuickWebContentsViewPrivate); + // This has to be the first thing we do. + d->context = WebEngineContext::current(); content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); d->webContentsDelegate.reset(WebContentsDelegateQt::CreateNewWindow(browser_context, GURL(std::string("http://qt-project.org/")), NULL, MSG_ROUTING_NONE, gfx::Size(), this)); diff --git a/lib/qquickwebcontentsview.h b/lib/qquickwebcontentsview.h index 809bbf25e..9e9979b0a 100644 --- a/lib/qquickwebcontentsview.h +++ b/lib/qquickwebcontentsview.h @@ -51,6 +51,8 @@ class Q_DECL_EXPORT QQuickWebContentsView : public QQuickItem { Q_OBJECT Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) public: + static void registerType(); + QQuickWebContentsView(); ~QQuickWebContentsView(); diff --git a/lib/qwebcontentsview.cpp b/lib/qwebcontentsview.cpp index 64bdb9c36..1f23fb0d1 100644 --- a/lib/qwebcontentsview.cpp +++ b/lib/qwebcontentsview.cpp @@ -51,6 +51,7 @@ #include "browser_context_qt.h" #include "content_browser_client_qt.h" #include "web_contents_delegate_qt.h" +#include "web_engine_context.h" #include <QWidget> #include <QUrl> @@ -58,12 +59,15 @@ class QWebContentsViewPrivate { public: + scoped_refptr<WebEngineContext> context; scoped_ptr<WebContentsDelegateQt> webContentsDelegate; }; QWebContentsView::QWebContentsView() { d.reset(new QWebContentsViewPrivate); + // This has to be the first thing we do. + d->context = WebEngineContext::current(); content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); d->webContentsDelegate.reset(WebContentsDelegateQt::CreateNewWindow(browser_context, GURL(std::string("http://qt-project.org/")), NULL, MSG_ROUTING_NONE, gfx::Size(), this)); diff --git a/lib/blinqapplication.cpp b/lib/web_engine_context.cpp similarity index 80% rename from lib/blinqapplication.cpp rename to lib/web_engine_context.cpp index 732b7d1c7..5b9855a27 100644 --- a/lib/blinqapplication.cpp +++ b/lib/web_engine_context.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "blinqapplication.h" +#include "web_engine_context.h" #include <math.h> @@ -57,10 +57,13 @@ #include "webkit/common/user_agent/user_agent_util.h" #include "content_browser_client_qt.h" -#include "qquickwebcontentsview.h" +#include <QCoreApplication> +#include <QStringList> namespace { +static WebEngineContext* sContext = 0; + static inline base::FilePath::StringType qStringToStringType(const QString &str) { #if defined(OS_POSIX) @@ -70,7 +73,7 @@ static inline base::FilePath::StringType qStringToStringType(const QString &str) #endif } -static QByteArray blinqProcessPath() { +static QByteArray subProcessPath() { static bool initialized = false; #ifdef BLINQ_PROCESS_PATH static QByteArray processPath(BLINQ_PROCESS_PATH); @@ -95,7 +98,7 @@ static void initializeBlinkPaths() if (initialized) return; - PathService::Override(content::CHILD_PROCESS_EXE, base::FilePath(qStringToStringType(QString(blinqProcessPath())))); + PathService::Override(content::CHILD_PROCESS_EXE, base::FilePath(qStringToStringType(QString(subProcessPath())))); } // Return a timeout suitable for the glib loop, -1 to block forever, @@ -114,29 +117,27 @@ int GetTimeIntervalMilliseconds(const base::TimeTicks& from) { return delay < 0 ? 0 : delay; } -class MessagePump : public QObject, +class MessagePumpForUIQt : public QObject, public base::MessagePump { public: - MessagePump() - : m_delegate(0) + MessagePumpForUIQt() + // Usually this gets passed through Run, but since we have + // our own event loop, attach it explicitely ourselves. + : m_delegate(base::MessageLoopForUI::current()) { } virtual void Run(Delegate *delegate) { - // It would be possible to do like the Android message loop and use - // Start(Delegate*) instead of Run to avoid blocking, but we still - // need to grab the command line arguments, so keep it simple for now - // by forcing the use of BlinqApplication. - m_delegate = delegate; - QApplication::exec(); - m_delegate = 0; + // FIXME: This could be needed if we want to run Chromium tests. + // We could run a QEventLoop here. + Q_ASSERT(false); } virtual void Quit() { - QCoreApplication::instance()->quit(); + Q_ASSERT(false); } virtual void ScheduleWork() @@ -189,7 +190,7 @@ private: base::MessagePump* messagePumpFactory() { - return new MessagePump; + return new MessagePumpForUIQt; } class ContentMainDelegateQt : public content::ContentMainDelegate @@ -207,31 +208,31 @@ private: } -BlinqApplication::BlinqApplication(int &argc, char **argv) - : QApplication(argc, argv) +WebEngineContext::WebEngineContext() { - { - int myArgc = argc + 3; - const char **myArgv = new const char *[myArgc]; + Q_ASSERT(!sContext); + sContext = this; - for (int i = 0; i < argc; ++i) - myArgv[i] = argv[i]; + { QByteArray subProcessPathOption("--browser-subprocess-path="); - subProcessPathOption.append(blinqProcessPath()); - myArgv[argc] = subProcessPathOption.constData(); - myArgv[argc + 1] = "--no-sandbox"; + subProcessPathOption.append(subProcessPath()); - std::string ua = webkit_glue::BuildUserAgentFromProduct("Qrome/0.1"); + std::string ua = webkit_glue::BuildUserAgentFromProduct("QtWebEngine/0.1"); QByteArray userAgentParameter("--user-agent="); userAgentParameter.append(QString::fromStdString(ua).toUtf8()); - myArgv[argc + 2] = userAgentParameter.constData(); - CommandLine::Init(myArgc, myArgv); + const int argc = 4; + const char* argv[4]; + argv[0] = QCoreApplication::arguments()[0].toLatin1().constData(); + argv[1] = subProcessPathOption.constData(); + argv[2] = "--no-sandbox"; + argv[3] = userAgentParameter.constData(); - delete [] myArgv; + CommandLine::Init(argc, argv); } + // This needs to be set before the MessageLoop is created by BrowserMainRunner. base::MessageLoop::InitMessagePumpForUIFactory(::messagePumpFactory); static content::ContentMainRunner *runner = 0; @@ -253,12 +254,24 @@ BlinqApplication::BlinqApplication(int &argc, char **argv) base::ThreadRestrictions::SetIOAllowed(true); - // FIXME: Do a proper plugin. - qmlRegisterType<QQuickWebContentsView>("QtWebEngine", 1, 0, "WebContentsView"); + // Once the MessageLoop has been created, attach a top-level RunLoop. + m_runLoop.reset(new base::RunLoop); + m_runLoop->BeforeRun(); +} + +WebEngineContext::~WebEngineContext() +{ + m_runLoop->AfterRun(); + + Q_ASSERT(sContext == this); + sContext = 0; } -int BlinqApplication::exec() +scoped_refptr<WebEngineContext> WebEngineContext::current() { - base::RunLoop runLoop; - runLoop.Run(); + scoped_refptr<WebEngineContext> current = sContext; + if (!current) + current = new WebEngineContext; + Q_ASSERT(sContext == current); + return current; } diff --git a/lib/blinqapplication.h b/lib/web_engine_context.h similarity index 81% rename from lib/blinqapplication.h rename to lib/web_engine_context.h index 68034e613..2bf20ac4b 100644 --- a/lib/blinqapplication.h +++ b/lib/web_engine_context.h @@ -39,15 +39,26 @@ ** ****************************************************************************/ -#ifndef BLINQAPPLICATION_H -#define BLINQAPPLICATION_H +#ifndef WEB_ENGINE_CONTEXT_H +#define WEB_ENGINE_CONTEXT_H -#include <QApplication> +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" -class Q_DECL_EXPORT BlinqApplication : public QApplication { +namespace base { +class RunLoop; +} + +class WebEngineContext : public base::RefCounted<WebEngineContext> { public: - BlinqApplication(int &argc, char **argv); - static int exec(); + static scoped_refptr<WebEngineContext> current(); + +private: + friend class base::RefCounted<WebEngineContext>; + WebEngineContext(); + ~WebEngineContext(); + + scoped_ptr<base::RunLoop> m_runLoop; }; #endif diff --git a/patches/0001-My-local-fixes.patch b/patches/0001-My-local-fixes.patch index ff5e1308c..87a08aab9 100644 --- a/patches/0001-My-local-fixes.patch +++ b/patches/0001-My-local-fixes.patch @@ -1,7 +1,7 @@ -From 4ce3baa412e9799684c0b7379814384489c2ae5a Mon Sep 17 00:00:00 2001 +From 0a3b4029af83089cb313b555a47c5c510dc94cc7 Mon Sep 17 00:00:00 2001 From: Simon Hausmann <simon.hausmann@digia.com> Date: Mon, 29 Apr 2013 11:25:37 +0200 -Subject: [PATCH] My local fixes +Subject: [PATCH 1/2] My local fixes --- content/browser/zygote_host/zygote_host_impl_linux.cc | 1 + @@ -10,7 +10,7 @@ Subject: [PATCH] My local fixes 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc -index 4e28c55..ddd3513 100644 +index ba7884f8..50eacc8 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc @@ -70,6 +70,7 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) { @@ -43,10 +43,10 @@ index bed5ff2..992e0d0 100644 virtual ~ContentMainRunner() {} diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h -index 198ecad..778fcac 100644 +index 4c1d110..ddf6a32 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h -@@ -60,7 +60,7 @@ CONTENT_EXPORT void SetContentClient(ContentClient* client); +@@ -63,7 +63,7 @@ CONTENT_EXPORT void SetContentClient(ContentClient* client); #if defined(CONTENT_IMPLEMENTATION) // Content's embedder API should only be used by content. @@ -56,5 +56,5 @@ index 198ecad..778fcac 100644 // Used for tests to override the relevant embedder interfaces. Each method -- -1.8.1.2 +1.8.3 diff --git a/patches/0002-Add-WebEngineContext-to-RunLoop-s-friends.patch b/patches/0002-Add-WebEngineContext-to-RunLoop-s-friends.patch new file mode 100644 index 000000000..c822c0162 --- /dev/null +++ b/patches/0002-Add-WebEngineContext-to-RunLoop-s-friends.patch @@ -0,0 +1,33 @@ +From 1f686ea3aafa4d950d92a7f945cfec5b6fb02dfd Mon Sep 17 00:00:00 2001 +From: Jocelyn Turcotte <jocelyn.turcotte@digia.com> +Date: Tue, 11 Jun 2013 15:44:26 +0200 +Subject: [PATCH 2/2] Add WebEngineContext to RunLoop's friends. + +--- + base/run_loop.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/base/run_loop.h b/base/run_loop.h +index 380c8bf..12f810a 100644 +--- a/base/run_loop.h ++++ b/base/run_loop.h +@@ -10,6 +10,8 @@ + #include "base/memory/weak_ptr.h" + #include "base/message_loop.h" + ++class WebEngineContext; ++ + namespace base { + #if defined(OS_ANDROID) + class MessagePumpForUI; +@@ -74,6 +76,7 @@ class BASE_EXPORT RunLoop { + + private: + friend class MessageLoop; ++ friend class ::WebEngineContext; + #if defined(OS_ANDROID) + // Android doesn't support the blocking MessageLoop::Run, so it calls + // BeforeRun and AfterRun directly. +-- +1.8.3 + diff --git a/patches/patch-chromium.sh b/patches/patch-chromium.sh index cb74fecc1..5abc44203 100755 --- a/patches/patch-chromium.sh +++ b/patches/patch-chromium.sh @@ -20,7 +20,7 @@ if [ "$2" = "--update" ]; then fi echo "Applying patches..." -git am $PATCH_DIR/0001-My-local-fixes.patch +git am $PATCH_DIR/0001-My-local-fixes.patch $PATCH_DIR/0002-Add-WebEngineContext-to-RunLoop-s-friends.patch cd tools/gyp echo "Entering $PWD" -- GitLab