diff options
Diffstat (limited to 'src/core/web_contents_adapter.cpp')
-rw-r--r-- | src/core/web_contents_adapter.cpp | 82 |
1 files changed, 74 insertions, 8 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 3f223f733..9398046d0 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -41,6 +41,7 @@ #include "web_contents_adapter.h" #include "web_contents_adapter_p.h" +#include "browser_context_adapter.h" #include "browser_context_qt.h" #include "content_browser_client_qt.h" #include "javascript_dialog_manager_qt.h" @@ -175,9 +176,8 @@ static QStringList listRecursively(const QDir& dir) { return ret; } -static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient) +static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext) { - content::BrowserContext* browserContext = ContentBrowserClientQt::Get()->browser_context(); content::WebContents::CreateParams create_params(browserContext, NULL); create_params.routing_id = MSG_ROUTING_NONE; create_params.initial_size = gfx::Size(kTestWindowWidth, kTestWindowHeight); @@ -222,7 +222,7 @@ static void serializeNavigationHistory(const content::NavigationController &cont } } -void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<content::NavigationEntry*> *entries) +static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<content::NavigationEntry*> *entries, content::BrowserContext *browserContext) { int version; input >> version; @@ -278,7 +278,7 @@ void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::ve false, // The extra headers are not sync'ed across sessions. std::string(), - ContentBrowserClientQt::Get()->browser_context()); + browserContext); entry->SetTitle(toString16(title)); entry->SetPageState(content::PageState::CreateFromEncodedData(std::string(pageState.data(), pageState.size()))); @@ -292,6 +292,30 @@ void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::ve } } +namespace { +static QList<WebContentsAdapter *> recursive_guard_loading_adapters; + +class LoadRecursionGuard { + public: + static bool isGuarded(WebContentsAdapter *adapter) + { + return recursive_guard_loading_adapters.contains(adapter); + } + LoadRecursionGuard(WebContentsAdapter *adapter) + : m_adapter(adapter) + { + recursive_guard_loading_adapters.append(adapter); + } + + ~LoadRecursionGuard() { + recursive_guard_loading_adapters.removeOne(m_adapter); + } + + private: + WebContentsAdapter *m_adapter; +}; +} // Anonymous namespace + WebContentsAdapterPrivate::WebContentsAdapterPrivate() // This has to be the first thing we create, and the last we destroy. : engineContext(WebEngineContext::current()) @@ -308,13 +332,13 @@ QExplicitlySharedDataPointer<WebContentsAdapter> WebContentsAdapter::createFromS { int currentIndex; std::vector<content::NavigationEntry*> entries; - deserializeNavigationHistory(input, ¤tIndex, &entries); + deserializeNavigationHistory(input, ¤tIndex, &entries, adapterClient->browserContextAdapter()->browserContext()); if (currentIndex == -1) return QExplicitlySharedDataPointer<WebContentsAdapter>(); // Unlike WebCore, Chromium only supports Restoring to a new WebContents instance. - content::WebContents* newWebContents = createBlankWebContents(adapterClient); + content::WebContents* newWebContents = createBlankWebContents(adapterClient, adapterClient->browserContextAdapter()->browserContext()); content::NavigationController &controller = newWebContents->GetController(); controller.Restore(currentIndex, content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries); @@ -347,10 +371,13 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient) { Q_D(WebContentsAdapter); d->adapterClient = adapterClient; + // We keep a reference to browserContextAdapter to keep it alive as long as we use it. + // This is needed in case the QML WebEngineProfile is garbage collected before the WebEnginePage. + d->browserContextAdapter = adapterClient->browserContextAdapter(); // Create our own if a WebContents wasn't provided at construction. if (!d->webContents) - d->webContents.reset(createBlankWebContents(adapterClient)); + d->webContents.reset(createBlankWebContents(adapterClient, d->browserContextAdapter->browserContext())); // This might replace any adapter that has been initialized with this WebEngineSettings. adapterClient->webEngineSettings()->setWebContentsAdapter(this); @@ -421,6 +448,19 @@ void WebContentsAdapter::reload() void WebContentsAdapter::load(const QUrl &url) { + // The situation can occur when relying on the editingFinished signal in QML to set the url + // of the WebView. + // When enter is pressed, onEditingFinished fires and the url of the webview is set, which + // calls into this and focuses the webview, taking the focus from the TextField/TextInput, + // which in turn leads to editingFinished firing again. This scenario would cause a crash + // down the line when unwinding as the first RenderWidgetHostViewQtDelegateQuick instance is + // a dangling pointer by that time. + + if (LoadRecursionGuard::isGuarded(this)) + return; + LoadRecursionGuard guard(this); + Q_UNUSED(guard); + Q_D(WebContentsAdapter); content::NavigationController::LoadURLParams params(toGurl(url)); params.transition_type = content::PageTransitionFromInt(content::PAGE_TRANSITION_TYPED | content::PAGE_TRANSITION_FROM_ADDRESS_BAR); @@ -625,7 +665,13 @@ qreal WebContentsAdapter::currentZoomFactor() const void WebContentsAdapter::enableInspector(bool enable) { - ContentBrowserClientQt::Get()->enableInspector(enable); + ContentBrowserClientQt::Get()->enableInspector(enable, browserContext()); +} + +BrowserContextQt* WebContentsAdapter::browserContext() +{ + Q_D(WebContentsAdapter); + return d->browserContextAdapter->browserContext(); } QAccessibleInterface *WebContentsAdapter::browserAccessible() @@ -724,6 +770,26 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin, MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(d->webContents.get(), securityOrigin, flags); } +void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed) +{ + Q_D(WebContentsAdapter); + d->webContentsDelegate->m_lastGeolocationRequestCallbacks.first.Run(allowed); +} + +void WebContentsAdapter::grantMouseLockPermission(bool granted) +{ + Q_D(WebContentsAdapter); + + if (granted) { + if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt *>(d->webContents->GetRenderWidgetHostView())) + rwhv->Focus(); + else + granted = false; + } + + d->webContents->GotResponseToLockMouseRequest(granted); +} + void WebContentsAdapter::dpiScaleChanged() { Q_D(WebContentsAdapter); |