summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-02-23 15:57:45 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2016-02-23 15:57:45 +0000
commit3823c00dc3128a8ebae2ddf3590231ed7cdfe94a (patch)
treefa4af260ad7e95ec2c3fe82c6418a4eec9ef4c2b
parenta46caa17c285d07a8b9d3835d8de4f85fcf9a940 (diff)
parentd3525d33cb9085cf1ee61b437931555fe7d932ae (diff)
Merge "Merge remote-tracking branch 'origin/5.6' into 5.7" into refs/staging/5.7
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.cpp11
-rw-r--r--src/core/delegated_frame_node.cpp71
-rw-r--r--src/core/network_delegate_qt.cpp2
-rw-r--r--src/core/render_widget_host_view_qt.cpp24
-rw-r--r--src/core/render_widget_host_view_qt.h1
-rw-r--r--src/core/resources/resources.gyp2
-rw-r--r--src/core/web_contents_delegate_qt.cpp15
-rw-r--r--src/webengine/api/qquickwebengineview.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp12
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc3
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp8
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp33
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp3
13 files changed, 161 insertions, 26 deletions
diff --git a/examples/webenginewidgets/demobrowser/browserapplication.cpp b/examples/webenginewidgets/demobrowser/browserapplication.cpp
index 745e38865..a2e47cd9f 100644
--- a/examples/webenginewidgets/demobrowser/browserapplication.cpp
+++ b/examples/webenginewidgets/demobrowser/browserapplication.cpp
@@ -156,12 +156,11 @@ BrowserApplication::BrowserApplication(int &argc, char **argv)
m_localServer = new QLocalServer(this);
connect(m_localServer, SIGNAL(newConnection()),
this, SLOT(newLocalSocketConnection()));
- if (!m_localServer->listen(serverName)) {
- if (m_localServer->serverError() == QAbstractSocket::AddressInUseError
- && QFile::exists(m_localServer->serverName())) {
- QFile::remove(m_localServer->serverName());
- m_localServer->listen(serverName);
- }
+ if (!m_localServer->listen(serverName)
+ && m_localServer->serverError() == QAbstractSocket::AddressInUseError) {
+ QLocalServer::removeServer(serverName);
+ if (!m_localServer->listen(serverName))
+ qWarning("Could not create local socket %s.", qPrintable(serverName));
}
#ifndef QT_NO_OPENSSL
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 62b5398ce..51c858abc 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -72,6 +72,7 @@
#include <QSGSimpleRectNode>
#include <QSGSimpleTextureNode>
#include <QSGTexture>
+#include <QtGui/QOffscreenSurface>
#include <private/qsgadaptationlayer_p.h>
#if !defined(QT_NO_EGL)
@@ -112,6 +113,7 @@ private:
#ifdef Q_OS_QNX
EGLStreamData m_eglStreamData;
#endif
+ friend class DelegatedFrameNode;
};
class ResourceHolder {
@@ -427,12 +429,69 @@ void DelegatedFrameNode::preprocess()
m_mailboxGLFences.swap(transferredFences);
}
- // Tell GL to wait until Chromium is done generating resource textures on the GPU thread
- // for each mailbox. We can safely start referencing those textures onto geometries afterward.
- Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
- gfx::TransferableFence fence = transferredFences.take(mailboxTexture->mailboxHolder().sync_point);
- waitChromiumSync(&fence);
- deleteChromiumSync(&fence);
+#if defined(USE_X11)
+ // Workaround when context is not shared QTBUG-48969
+ // Make slow copy between two contexts.
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext() ;
+ QOpenGLContext *sharedContext = qt_gl_global_share_context();
+ if (!QOpenGLContext::areSharing(currentContext,sharedContext)) {
+ static bool allowNotSharedContextWarningShown = true;
+ if (allowNotSharedContextWarningShown) {
+ allowNotSharedContextWarningShown = false;
+ qWarning("Context is not shared, textures will be copied between contexts.");
+ }
+
+ Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
+ gfx::TransferableFence fence = transferredFences.take(mailboxTexture->mailboxHolder().sync_point);
+ waitChromiumSync(&fence);
+ deleteChromiumSync(&fence);
+
+ QSurface *surface = currentContext->surface();
+ // Read texture into QImage from shared context.
+ // Switch to shared context.
+ QOffscreenSurface offsurface;
+ offsurface.create();
+ sharedContext->makeCurrent(&offsurface);
+ QOpenGLFunctions *funcs = sharedContext->functions();
+ QImage img(mailboxTexture->textureSize(), QImage::Format_RGBA8888_Premultiplied);
+ GLuint fbo = 0;
+ funcs->glGenFramebuffers(1, &fbo);
+ funcs->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mailboxTexture->m_textureId, 0);
+ GLenum status = funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ qWarning("fbo error, skipping slow copy...");
+ continue;
+ }
+
+ funcs->glReadPixels(0, 0, mailboxTexture->textureSize().width(), mailboxTexture->textureSize().height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+ funcs->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Restore current context.
+ currentContext->makeCurrent(surface);
+ // Create texture from QImage in current context.
+ GLuint texture = 0;
+ funcs = currentContext->functions();
+ funcs->glGenTextures(1, &texture);
+ funcs->glBindTexture(GL_TEXTURE_2D, texture);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mailboxTexture->textureSize().width(), mailboxTexture->textureSize().height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+ mailboxTexture->m_textureId = texture;
+ }
+ } else
+#endif
+ {
+ // Tell GL to wait until Chromium is done generating resource textures on the GPU thread
+ // for each mailbox. We can safely start referencing those textures onto geometries afterward.
+ Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
+ gfx::TransferableFence fence = transferredFences.take(mailboxTexture->mailboxHolder().sync_point);
+ waitChromiumSync(&fence);
+ deleteChromiumSync(&fence);
+ }
}
// We transferred all sync point fences from Chromium,
// destroy all the ones not referenced by one of our mailboxes without waiting.
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index 51acbb644..427e24332 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -114,7 +114,7 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::C
QWebEngineUrlRequestInfo requestInfo(infoPrivate);
interceptor->interceptRequest(requestInfo);
if (requestInfo.changed()) {
- int result = infoPrivate->shouldBlockRequest ? net::ERR_ABORTED : net::OK;
+ int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
if (qUrl != infoPrivate->url)
*newUrl = toGurl(infoPrivate->url);
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 308a99fd3..01f46bdfc 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -232,6 +232,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget
, m_needsDelegatedFrameAck(false)
, m_didFirstVisuallyNonEmptyLayout(false)
, m_adapterClient(0)
+ , m_imeInProgress(false)
, m_anchorPositionWithinSelection(0)
, m_cursorPositionWithinSelection(0)
, m_initPending(false)
@@ -890,6 +891,23 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
if (IsMouseLocked() && ev->key() == Qt::Key_Escape && ev->type() == QEvent::KeyRelease)
UnlockMouse();
+ if (m_imeInProgress) {
+ // IME composition was not finished with a valid commit string.
+ // We're getting the composition result in a key event.
+ if (ev->key() != 0) {
+ // The key event is not a result of an IME composition. Cancel IME.
+ m_host->ImeCancelComposition();
+ m_imeInProgress = false;
+ } else {
+ if (ev->type() == QEvent::KeyRelease) {
+ m_host->ImeConfirmComposition(toString16(ev->text()), gfx::Range::InvalidRange(),
+ false);
+ m_imeInProgress = false;
+ }
+ return;
+ }
+ }
+
content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev);
if (webEvent.type == blink::WebInputEvent::RawKeyDown && !ev->text().isEmpty()) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
@@ -946,11 +964,12 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
}
}
- if (preeditString.isEmpty()) {
+ if (!commitString.isEmpty()) {
gfx::Range replacementRange = (replacementLength > 0) ? gfx::Range(replacementStart, replacementStart + replacementLength)
: gfx::Range::InvalidRange();
m_host->ImeConfirmComposition(toString16(commitString), replacementRange, false);
- } else {
+ m_imeInProgress = false;
+ } else if (!preeditString.isEmpty()) {
if (!selectionRange.IsValid()) {
// We did not receive a valid selection range, hence the range is going to mark the cursor position.
int newCursorPosition = (cursorPositionInPreeditString < 0) ? preeditString.length() : cursorPositionInPreeditString;
@@ -958,6 +977,7 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
selectionRange.set_end(newCursorPosition);
}
m_host->ImeSetComposition(toString16(preeditString), underlines, selectionRange.start(), selectionRange.end());
+ m_imeInProgress = true;
}
}
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 8a5a157ee..a8ae91824 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -233,6 +233,7 @@ private:
MultipleMouseClickHelper m_clickHelper;
ui::TextInputType m_currentInputType;
+ bool m_imeInProgress;
QRect m_cursorRect;
size_t m_anchorPositionWithinSelection;
size_t m_cursorPositionWithinSelection;
diff --git a/src/core/resources/resources.gyp b/src/core/resources/resources.gyp
index f2acab670..4226b7561 100644
--- a/src/core/resources/resources.gyp
+++ b/src/core/resources/resources.gyp
@@ -47,6 +47,7 @@
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_100_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_100_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/chrome/renderer_resources_100_percent.pak',
+ '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_image_resources_100_percent.pak',
],
'pak_outputs': [
'<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_100p.pak'
@@ -61,6 +62,7 @@
'<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_200_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_200_percent.pak',
'<(SHARED_INTERMEDIATE_DIR)/chrome/renderer_resources_200_percent.pak',
+ '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_image_resources_200_percent.pak',
],
'pak_outputs': [
'<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_200p.pak'
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 1dbb38e97..011becf83 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -211,7 +211,15 @@ void WebContentsDelegateQt::DidFailProvisionalLoad(content::RenderFrameHost* ren
void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description, bool was_ignored_by_handler)
{
Q_UNUSED(was_ignored_by_handler);
- if (m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID()) || render_frame_host->GetParent())
+ if (validated_url.spec() == content::kUnreachableWebDataURL) {
+ m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
+ qCritical("Loading error-page failed. This shouldn't happen.");
+ if (!render_frame_host->GetParent())
+ m_viewClient->loadFinished(false /* success */, toQt(validated_url), true /* isErrorPage */);
+ return;
+ }
+
+ if (render_frame_host->GetParent())
return;
m_viewClient->iconChanged(QUrl());
@@ -221,8 +229,9 @@ void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_h
void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url)
{
- if (m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID())) {
- Q_ASSERT(validated_url.is_valid() && validated_url.spec() == content::kUnreachableWebDataURL);
+ Q_ASSERT(validated_url.is_valid());
+ if (validated_url.spec() == content::kUnreachableWebDataURL) {
+ m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
m_viewClient->iconChanged(QUrl());
// Trigger LoadFinished signal for main frame's error page only.
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 742cd6cf8..f1bd817b6 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -1537,7 +1537,7 @@ void QQuickWebEngineView::triggerWebAction(WebAction action)
break;
case ToggleMediaMute:
if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
- bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
+ bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerMute, enable);
}
break;
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index eecd40708..a45139ead 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -213,13 +213,21 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE
Q_UNUSED(errorCode);
Q_UNUSED(errorDescription);
- if (isErrorPage)
+ if (isErrorPage) {
+ Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled));
+ Q_ASSERT(success);
+ Q_EMIT q->loadFinished(false);
return;
+ }
isLoading = false;
if (success)
explicitUrl = QUrl();
- Q_EMIT q->loadFinished(success);
+ // Delay notifying failure until the error-page is done loading.
+ // Error-pages are not loaded on failures due to abort.
+ if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) {
+ Q_EMIT q->loadFinished(success);
+ }
updateNavigationActions();
}
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index d179e4f2b..624381a42 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -134,7 +134,8 @@
through the \c charset attribute of the HTML script tag. Alternatively, the
encoding can be specified by the web server.
- This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
+ This is a convenience function equivalent to
+ \c{setContent(html, "text/html;charset=UTF-8", baseUrl)}.
\warning This function works only for HTML. For other MIME types (such as XHTML or SVG),
setContent() should be used instead.
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index 90eb0e76e..161983b70 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -86,9 +86,11 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
#endif
// Make sure the OpenGL profile of the QOpenGLWidget matches the shared context profile.
- format.setMajorVersion(sharedFormat.majorVersion());
- format.setMinorVersion(sharedFormat.minorVersion());
- format.setProfile(sharedFormat.profile());
+ if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
+ format.setMajorVersion(sharedFormat.majorVersion());
+ format.setMinorVersion(sharedFormat.minorVersion());
+ format.setProfile(sharedFormat.profile());
+ }
}
setFormat(format);
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 690cf70e4..207eb019a 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -241,6 +241,8 @@ private Q_SLOTS:
void loadInSignalHandlers();
void restoreHistory();
+ void toPlainTextLoadFinishedRace_data();
+ void toPlainTextLoadFinishedRace();
private:
QWebEngineView* m_view;
@@ -5115,5 +5117,36 @@ void tst_QWebEnginePage::restoreHistory()
delete channel;
}
+void tst_QWebEnginePage::toPlainTextLoadFinishedRace_data()
+{
+ QTest::addColumn<bool>("enableErrorPage");
+ QTest::newRow("disableErrorPage") << false;
+ QTest::newRow("enableErrorPage") << true;
+}
+
+void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
+{
+ QFETCH(bool, enableErrorPage);
+
+ QWebEnginePage *page = new QWebEnginePage;
+ page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, enableErrorPage);
+ QSignalSpy spy(page, SIGNAL(loadFinished(bool)));
+
+ page->load(QUrl("data:text/plain,foobarbaz"));
+ QTRY_VERIFY(spy.count() == 1);
+ QCOMPARE(toPlainTextSync(page), QString("foobarbaz"));
+
+ page->load(QUrl("fail:unknown/scheme"));
+ QTRY_VERIFY(spy.count() == 2);
+ QString s = toPlainTextSync(page);
+ QVERIFY(s.contains("foobarbaz") == !enableErrorPage);
+
+ page->load(QUrl("data:text/plain,lalala"));
+ QTRY_VERIFY(spy.count() == 3);
+ QCOMPARE(toPlainTextSync(page), QString("lalala"));
+ delete page;
+ QVERIFY(spy.count() == 3);
+}
+
QTEST_MAIN(tst_QWebEnginePage)
#include "tst_qwebenginepage.moc"
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 26980df7b..e73ab637b 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -247,9 +247,10 @@ void tst_QWebEngineProfile::urlSchemeHandlerFailRequest()
QWebEngineView view;
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
view.setPage(new QWebEnginePage(&profile, &view));
+ view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
view.load(QUrl(QStringLiteral("foo://bar")));
QVERIFY(loadFinishedSpy.wait());
- QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ QCOMPARE(toPlainTextSync(view.page()), QString());
}
QTEST_MAIN(tst_QWebEngineProfile)