summaryrefslogtreecommitdiffstats
path: root/src/webenginewidgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/webenginewidgets')
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.h1
-rw-r--r--src/webenginewidgets/api/qwebenginecontextmenudata.cpp41
-rw-r--r--src/webenginewidgets/api/qwebenginecontextmenudata.h2
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.cpp32
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.h9
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem_p.h1
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp230
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h18
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h7
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp90
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h5
-rw-r--r--src/webenginewidgets/api/qwebenginescript.cpp3
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp7
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.h5
-rw-r--r--src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc (renamed from src/webenginewidgets/doc/snippets/qtwebengine_build_snippet.qdoc)0
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc1
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc4
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc5
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc13
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc17
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp183
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h25
-rw-r--r--src/webenginewidgets/webenginewidgets.pro2
25 files changed, 523 insertions, 182 deletions
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.cpp b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
index 289bb7ec0..a0641c9dd 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.cpp
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
@@ -104,6 +104,8 @@ QWebEngineCertificateError::~QWebEngineCertificateError()
\value CertificateWeakKey The certificate contains a weak key.
\value CertificateNameConstraintViolation The certificate claimed DNS names that are in violation of name constraints.
\value CertificateValidityTooLong The certificate has a validity period that is too long. (Added in Qt 5.7)
+ \value CertificateTransparencyRequired Certificate Transparency was required for this connection, but the server
+ did not provide CT information that complied with the policy. (Added in Qt 5.8)
*/
/*!
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.h b/src/webenginewidgets/api/qwebenginecertificateerror.h
index 7cb6341bc..82ac281be 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.h
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.h
@@ -70,6 +70,7 @@ public:
CertificateWeakKey = -211,
CertificateNameConstraintViolation = -212,
CertificateValidityTooLong = -213,
+ CertificateTransparencyRequired = -214,
};
Error error() const;
diff --git a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp
index 4d72071e5..5d68ed0ec 100644
--- a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp
+++ b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp
@@ -135,7 +135,7 @@ void QWebEngineContextMenuData::reset()
*/
QPoint QWebEngineContextMenuData::position() const
{
- return d ? d->pos : QPoint();
+ return d ? d->position() : QPoint();
}
/*!
@@ -143,7 +143,7 @@ QPoint QWebEngineContextMenuData::position() const
*/
QString QWebEngineContextMenuData::linkText() const
{
- return d ? d->linkText : QString();
+ return d ? d->linkText() : QString();
}
/*!
@@ -151,7 +151,7 @@ QString QWebEngineContextMenuData::linkText() const
*/
QUrl QWebEngineContextMenuData::linkUrl() const
{
- return d ? d->linkUrl : QUrl();
+ return d ? d->linkUrl() : QUrl();
}
/*!
@@ -159,7 +159,7 @@ QUrl QWebEngineContextMenuData::linkUrl() const
*/
QString QWebEngineContextMenuData::selectedText() const
{
- return d ? d->selectedText : QString();
+ return d ? d->selectedText() : QString();
}
/*!
@@ -167,7 +167,7 @@ QString QWebEngineContextMenuData::selectedText() const
*/
QUrl QWebEngineContextMenuData::mediaUrl() const
{
- return d ? d->mediaUrl : QUrl();
+ return d ? d->mediaUrl() : QUrl();
}
/*!
@@ -175,7 +175,7 @@ QUrl QWebEngineContextMenuData::mediaUrl() const
*/
QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() const
{
- return d ? static_cast<QWebEngineContextMenuData::MediaType>(d->mediaType) : MediaTypeNone;
+ return d ? static_cast<QWebEngineContextMenuData::MediaType>(d->mediaType()) : MediaTypeNone;
}
/*!
@@ -183,7 +183,34 @@ QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() cons
*/
bool QWebEngineContextMenuData::isContentEditable() const
{
- return d ? d->isEditable : false;
+ return d ? d->isEditable() : false;
+}
+
+/*!
+ If the context is a word considered misspelled by the spell-checker, returns the misspelled word.
+
+ For possible replacements of the word, see spellCheckerSuggestions().
+
+ \since 5.8
+*/
+QString QWebEngineContextMenuData::misspelledWord() const
+{
+ if (d)
+ return d->misspelledWord();
+ return QString();
+}
+
+/*!
+ If the context is a word considered misspelled by the spell-checker, returns a list of suggested replacements
+ for misspelledWord().
+
+ \since 5.8
+*/
+QStringList QWebEngineContextMenuData::spellCheckerSuggestions() const
+{
+ if (d)
+ return d->spellCheckerSuggestions();
+ return QStringList();
}
/*!
diff --git a/src/webenginewidgets/api/qwebenginecontextmenudata.h b/src/webenginewidgets/api/qwebenginecontextmenudata.h
index 8e85fee16..97cfe9f65 100644
--- a/src/webenginewidgets/api/qwebenginecontextmenudata.h
+++ b/src/webenginewidgets/api/qwebenginecontextmenudata.h
@@ -76,6 +76,8 @@ public:
QUrl mediaUrl() const;
MediaType mediaType() const;
bool isContentEditable() const;
+ QString misspelledWord() const;
+ QStringList spellCheckerSuggestions() const;
private:
void reset();
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index bfb0dd0e8..b777a0898 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -80,6 +80,7 @@ QWebEngineDownloadItemPrivate::QWebEngineDownloadItemPrivate(QWebEngineProfilePr
, downloadId(-1)
, downloadState(QWebEngineDownloadItem::DownloadCancelled)
, savePageFormat(QWebEngineDownloadItem::MimeHtmlSaveFormat)
+ , type(QWebEngineDownloadItem::Attachment)
, downloadUrl(url)
, totalBytes(-1)
, receivedBytes(0)
@@ -218,6 +219,25 @@ quint32 QWebEngineDownloadItem::id() const
*/
/*!
+ \enum QWebEngineDownloadItem::DownloadType
+ \since 5.8
+
+ Describes the requested download's type.
+
+ \value Attachment The web server's response includes a
+ \c Content-Disposition header with the \c attachment directive. If \c Content-Disposition
+ is present in the reply, the web server is indicating that the client should prompt the
+ user to save the content regardless of the content type.
+ See \l {RFC 2616 section 19.5.1} for details.
+ \value DownloadAttribute The user clicked a link with the \c download
+ attribute. See \l {HTML download attribute} for details.
+ \value UserRequested The user initiated the download, for example by
+ selecting a web action.
+ \value SavePage Saving of the current page was requested (for example by
+ the \l{QWebEnginePage::WebAction}{QWebEnginePage::SavePage} web action).
+*/
+
+/*!
Returns the download item's current state.
\sa QWebEngineDownloadItem::DownloadState
@@ -342,6 +362,18 @@ void QWebEngineDownloadItem::setSavePageFormat(QWebEngineDownloadItem::SavePageF
d->savePageFormat = format;
}
+/*!
+ Returns the requested download's type.
+ \since 5.8
+
+ */
+
+QWebEngineDownloadItem::DownloadType QWebEngineDownloadItem::type() const
+{
+ Q_D(const QWebEngineDownloadItem);
+ return d->type;
+}
+
QWebEngineDownloadItem::QWebEngineDownloadItem(QWebEngineDownloadItemPrivate *p, QObject *parent)
: QObject(parent)
, d_ptr(p)
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.h b/src/webenginewidgets/api/qwebenginedownloaditem.h
index 80b5c06c5..4b58748ad 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.h
@@ -72,6 +72,14 @@ public:
};
Q_ENUM(SavePageFormat)
+ enum DownloadType {
+ Attachment = 0,
+ DownloadAttribute,
+ UserRequested,
+ SavePage
+ };
+ Q_ENUM(DownloadType)
+
quint32 id() const;
DownloadState state() const;
qint64 totalBytes() const;
@@ -83,6 +91,7 @@ public:
bool isFinished() const;
SavePageFormat savePageFormat() const;
void setSavePageFormat(SavePageFormat format);
+ DownloadType type() const;
public Q_SLOTS:
void accept();
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem_p.h b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
index ddb3b443a..9ddb45444 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem_p.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
@@ -72,6 +72,7 @@ public:
quint32 downloadId;
QWebEngineDownloadItem::DownloadState downloadState;
QWebEngineDownloadItem::SavePageFormat savePageFormat;
+ QWebEngineDownloadItem::DownloadType type;
QString downloadPath;
const QUrl downloadUrl;
QString mimeType;
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index df4031712..ca160c362 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -90,6 +90,8 @@ QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
+static const int MaxTooltipLength = 1024;
+
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
@@ -381,6 +383,13 @@ void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &re
m_callbacks.invoke(requestId, result);
}
+#ifndef QT_NO_PRINTER
+void QWebEnginePagePrivate::didPrintPageOnPrinter(quint64 requestId, bool result)
+{
+ m_callbacks.invoke(requestId, result);
+}
+#endif
+
void QWebEnginePagePrivate::passOnFocus(bool reverse)
{
if (view)
@@ -480,6 +489,9 @@ void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
case QWebEnginePage::ReloadAndBypassCache:
enabled = !isLoading;
break;
+ case QWebEnginePage::ViewSource:
+ enabled = adapter->canViewSource();
+ break;
default:
break;
}
@@ -495,6 +507,7 @@ void QWebEnginePagePrivate::updateNavigationActions()
updateAction(QWebEnginePage::Stop);
updateAction(QWebEnginePage::Reload);
updateAction(QWebEnginePage::ReloadAndBypassCache);
+ updateAction(QWebEnginePage::ViewSource);
}
#ifndef QT_NO_ACTION
@@ -779,6 +792,29 @@ void QWebEnginePage::setBackgroundColor(const QColor &color)
}
/*!
+ * Save the currently loaded web page to disk.
+ *
+ * The web page is saved to \a filePath in the specified \a{format}.
+ *
+ * This is a short cut for the following actions:
+ * \list
+ * \li Trigger the Save web action.
+ * \li Accept the next download item and set the specified file path and save format.
+ * \endlist
+ *
+ * This function issues an asynchronous download request for the web page and returns immediately.
+ *
+ * \sa QWebEngineDownloadItem::SavePageFormat
+ * \since 5.8
+ */
+void QWebEnginePage::save(const QString &filePath,
+ QWebEngineDownloadItem::SavePageFormat format) const
+{
+ Q_D(const QWebEnginePage);
+ d->adapter->save(filePath, format);
+}
+
+/*!
\property QWebEnginePage::audioMuted
\brief whether the current page audio is muted.
\since 5.7
@@ -963,6 +999,9 @@ QAction *QWebEnginePage::action(WebAction action) const
case SavePage:
text = tr("Save &Page");
break;
+ case ViewSource:
+ text = tr("&View Page Source");
+ break;
case NoWebAction:
case WebActionCount:
Q_UNREACHABLE();
@@ -1027,122 +1066,122 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
d->adapter->unselect();
break;
case OpenLinkInThisWindow:
- if (menuData.linkUrl.isValid())
- setUrl(menuData.linkUrl);
+ if (menuData.linkUrl().isValid())
+ setUrl(menuData.linkUrl());
break;
case OpenLinkInNewWindow:
- if (menuData.linkUrl.isValid()) {
+ if (menuData.linkUrl().isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserWindow);
if (newPage)
- newPage->setUrl(menuData.linkUrl);
+ newPage->setUrl(menuData.linkUrl());
}
break;
case OpenLinkInNewTab:
- if (menuData.linkUrl.isValid()) {
+ if (menuData.linkUrl().isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserTab);
if (newPage)
- newPage->setUrl(menuData.linkUrl);
+ newPage->setUrl(menuData.linkUrl());
}
break;
case OpenLinkInNewBackgroundTab:
- if (menuData.linkUrl.isValid()) {
+ if (menuData.linkUrl().isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserBackgroundTab);
if (newPage)
- newPage->setUrl(menuData.linkUrl);
+ newPage->setUrl(menuData.linkUrl());
}
break;
case CopyLinkToClipboard:
- if (menuData.linkUrl.isValid()) {
- QString urlString = menuData.linkUrl.toString(QUrl::FullyEncoded);
- QString title = menuData.linkText.toHtmlEscaped();
+ if (menuData.linkUrl().isValid()) {
+ QString urlString = menuData.linkUrl().toString(QUrl::FullyEncoded);
+ QString title = menuData.linkText().toHtmlEscaped();
QMimeData *data = new QMimeData();
data->setText(urlString);
QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>");
data->setHtml(html);
- data->setUrls(QList<QUrl>() << menuData.linkUrl);
+ data->setUrls(QList<QUrl>() << menuData.linkUrl());
qApp->clipboard()->setMimeData(data);
}
break;
case DownloadLinkToDisk:
- if (menuData.linkUrl.isValid())
- d->adapter->download(menuData.linkUrl, menuData.suggestedFileName);
+ if (menuData.linkUrl().isValid())
+ d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName());
break;
case CopyImageToClipboard:
- if (menuData.hasImageContent &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeImage ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas))
+ if (menuData.hasImageContent() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas))
{
- d->adapter->copyImageAt(menuData.pos);
+ d->adapter->copyImageAt(menuData.position());
}
break;
case CopyImageUrlToClipboard:
- if (menuData.mediaUrl.isValid() && menuData.mediaType == WebEngineContextMenuData::MediaTypeImage) {
- QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded);
- QString title = menuData.linkText;
+ if (menuData.mediaUrl().isValid() && menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage) {
+ QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded);
+ QString title = menuData.linkText();
if (!title.isEmpty())
title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped());
QMimeData *data = new QMimeData();
data->setText(urlString);
QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>");
data->setHtml(html);
- data->setUrls(QList<QUrl>() << menuData.mediaUrl);
+ data->setUrls(QList<QUrl>() << menuData.mediaUrl());
qApp->clipboard()->setMimeData(data);
}
break;
case DownloadImageToDisk:
case DownloadMediaToDisk:
- if (menuData.mediaUrl.isValid())
- d->adapter->download(menuData.mediaUrl, menuData.suggestedFileName);
+ if (menuData.mediaUrl().isValid())
+ d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName());
break;
case CopyMediaUrlToClipboard:
- if (menuData.mediaUrl.isValid() &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ if (menuData.mediaUrl().isValid() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo))
{
- QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded);
+ QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded);
QMimeData *data = new QMimeData();
data->setText(urlString);
- if (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio)
+ if (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio)
data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>"));
else
data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>"));
- data->setUrls(QList<QUrl>() << menuData.mediaUrl);
+ data->setUrls(QList<QUrl>() << menuData.mediaUrl());
qApp->clipboard()->setMimeData(data);
}
break;
case ToggleMediaControls:
- if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) {
- bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaControls);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerControls, enable);
+ if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) {
+ bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaControls);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerControls, enable);
}
break;
case ToggleMediaLoop:
- if (menuData.mediaUrl.isValid() &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ if (menuData.mediaUrl().isValid() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo))
{
- bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaLoop);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerLoop, enable);
+ bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaLoop);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerLoop, enable);
}
break;
case ToggleMediaPlayPause:
- if (menuData.mediaUrl.isValid() &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ if (menuData.mediaUrl().isValid() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo))
{
- bool enable = (menuData.mediaFlags & WebEngineContextMenuData::MediaPaused);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerPlay, enable);
+ bool enable = (menuData.mediaFlags() & WebEngineContextMenuData::MediaPaused);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerPlay, enable);
}
break;
case ToggleMediaMute:
- if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
+ if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) {
// Make sure to negate the value, so that toggling actually works.
- bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerMute, enable);
+ bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaMuted);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerMute, enable);
}
break;
case InspectElement:
- d->adapter->inspectElementAt(menuData.pos);
+ d->adapter->inspectElementAt(menuData.position());
break;
case ExitFullScreen:
d->adapter->exitFullScreen();
@@ -1153,6 +1192,17 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
case SavePage:
d->adapter->save();
break;
+ case ViewSource:
+ // This is a workaround to make the ViewSource action working in a context menu.
+ // The WebContentsAdapter::viewSource() method deletes a
+ // RenderWidgetHostViewQtDelegateWidget instance which passes the control to the event
+ // loop. If the QMenu::aboutToHide() signal is connected to the QObject::deleteLater()
+ // slot the QMenu is deleted by the event handler while the ViewSource action is still not
+ // completed. This may lead to a crash. To avoid this the WebContentsAdapter::viewSource()
+ // method is called indirectly via the QTimer::singleShot() function which schedules the
+ // the viewSource() call after the QMenu's destruction.
+ QTimer::singleShot(0, this, [d](){ d->adapter->viewSource(); });
+ break;
case NoWebAction:
break;
case WebActionCount:
@@ -1161,6 +1211,22 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
}
+/*!
+ * \since 5.8
+ * Replace the current misspelled word with \a replacement.
+ *
+ * The current misspelled word can be found in QWebEngineContextMenuData::misspelledWord(),
+ * and suggested replacements in QWebEngineContextMenuData::spellCheckerSuggestions().
+ *
+ * \sa contextMenuData(),
+ */
+
+void QWebEnginePage::replaceMisspelledWord(const QString &replacement)
+{
+ Q_D(QWebEnginePage);
+ d->adapter->replaceMisspelling(replacement);
+}
+
void QWebEnginePage::findText(const QString &subString, FindFlags options, const QWebEngineCallback<bool> &resultCallback)
{
Q_D(QWebEnginePage);
@@ -1197,7 +1263,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
return false;
contextData.reset();
- QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos));
+ QContextMenuEvent event(QContextMenuEvent::Mouse, data.position(), view->mapToGlobal(data.position()));
switch (view->contextMenuPolicy()) {
case Qt::PreventContextMenu:
return false;
@@ -1207,7 +1273,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
break;
case Qt::CustomContextMenu:
contextData = data;
- Q_EMIT view->customContextMenuRequested(data.pos);
+ Q_EMIT view->customContextMenuRequested(data.position());
break;
case Qt::ActionsContextMenu:
if (view->actions().count()) {
@@ -1342,6 +1408,16 @@ bool QWebEnginePagePrivate::isEnabled() const
return true;
}
+void QWebEnginePagePrivate::setToolTip(const QString &toolTipText)
+{
+ if (view) {
+ QString wrappedTip;
+ if (!toolTipText.isEmpty())
+ wrappedTip = QLatin1String("<p>") % toolTipText.toHtmlEscaped().left(MaxTooltipLength) % QLatin1String("</p>");
+ view->setToolTip(wrappedTip);
+ }
+}
+
QMenu *QWebEnginePage::createStandardContextMenu()
{
Q_D(QWebEnginePage);
@@ -1352,13 +1428,25 @@ QMenu *QWebEnginePage::createStandardContextMenu()
QAction *action = 0;
const WebEngineContextMenuData &contextMenuData = *d->contextData.d;
- if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
+ if (contextMenuData.isEditable() && !contextMenuData.spellCheckerSuggestions().isEmpty()) {
+ QPointer<QWebEnginePage> thisRef(this);
+ for (int i=0; i < contextMenuData.spellCheckerSuggestions().count() && i < 4; i++) {
+ QAction *action = new QAction(menu);
+ QString replacement = contextMenuData.spellCheckerSuggestions().at(i);
+ QObject::connect(action, &QAction::triggered, [thisRef, replacement] { if (thisRef) thisRef->replaceMisspelledWord(replacement); });
+ action->setText(replacement);
+ menu->addAction(action);
+ }
+ menu->addSeparator();
+ }
+
+ if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) {
action = QWebEnginePage::action(OpenLinkInThisWindow);
action->setText(tr("Follow Link"));
menu->addAction(action);
menu->addAction(QWebEnginePage::action(DownloadLinkToDisk));
}
- if (contextMenuData.selectedText.isEmpty()) {
+ if (contextMenuData.selectedText().isEmpty()) {
action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::back);
action->setEnabled(d->adapter->canGoBack());
@@ -1372,16 +1460,18 @@ QMenu *QWebEnginePage::createStandardContextMenu()
action = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), tr("&Reload"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::reload);
menu->addAction(action);
+
+ menu->addAction(QWebEnginePage::action(ViewSource));
} else {
menu->addAction(QWebEnginePage::action(Copy));
menu->addAction(QWebEnginePage::action(Unselect));
}
- if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
+ if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) {
menu->addAction(QWebEnginePage::action(CopyLinkToClipboard));
}
- if (contextMenuData.mediaUrl.isValid()) {
- switch (contextMenuData.mediaType) {
+ if (contextMenuData.mediaUrl().isValid()) {
+ switch (contextMenuData.mediaType()) {
case WebEngineContextMenuData::MediaTypeImage:
menu->addAction(QWebEnginePage::action(DownloadImageToDisk));
menu->addAction(QWebEnginePage::action(CopyImageUrlToClipboard));
@@ -1396,15 +1486,15 @@ QMenu *QWebEnginePage::createStandardContextMenu()
menu->addAction(QWebEnginePage::action(CopyMediaUrlToClipboard));
menu->addAction(QWebEnginePage::action(ToggleMediaPlayPause));
menu->addAction(QWebEnginePage::action(ToggleMediaLoop));
- if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio)
+ if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio)
menu->addAction(QWebEnginePage::action(ToggleMediaMute));
- if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls)
+ if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls)
menu->addAction(QWebEnginePage::action(ToggleMediaControls));
break;
default:
break;
}
- } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) {
+ } else if (contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) {
menu->addAction(QWebEnginePage::action(CopyImageToClipboard));
}
@@ -1462,7 +1552,7 @@ static inline QWebEnginePage::FileSelectionMode toPublic(FilePickerController::F
return static_cast<QWebEnginePage::FileSelectionMode>(mode);
}
-void QWebEnginePagePrivate::runFileChooser(FilePickerController *controller)
+void QWebEnginePagePrivate::runFileChooser(QSharedPointer<FilePickerController> controller)
{
Q_Q(QWebEnginePage);
@@ -1472,8 +1562,6 @@ void QWebEnginePagePrivate::runFileChooser(FilePickerController *controller)
controller->accepted(selectedFileNames);
else
controller->rejected();
-
- delete controller;
}
WebEngineSettings *QWebEnginePagePrivate::webEngineSettings() const
@@ -1770,6 +1858,28 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
d->m_callbacks.registerCallback(requestId, resultCallback);
}
+#ifndef QT_NO_PRINTER
+/*!
+ \fn void QWebEnginePage::print(QPrinter *printer, FunctorOrLambda resultCallback)
+ Renders the current content of the page into a temporary PDF document, then prints it using \a printer.
+
+ The settings for creating and printing the PDF document will be retrieved from the \a printer
+ object.
+ It is the users responsibility to ensure the \a printer remains valid until \a resultCallback
+ has been called.
+
+ The \a resultCallback must take a boolean as parameter. If printing was successful, this
+ boolean will have the value \c true, otherwise, its value will be \c false.
+ \since 5.8
+*/
+void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
+{
+ Q_D(QWebEnginePage);
+ quint64 requestId = d->adapter->printOnPrinterCallbackResult(printer);
+ d->m_callbacks.registerCallback(requestId, resultCallback);
+}
+#endif // QT_NO_PRINTER
+
/*!
\since 5.7
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 2ac8e0f3e..e85f9b30e 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -42,6 +42,7 @@
#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
#include <QtWebEngineWidgets/qwebenginecertificateerror.h>
+#include <QtWebEngineWidgets/qwebenginedownloaditem.h>
#include <QtWebEngineCore/qwebenginecallback.h>
#include <QtCore/qobject.h>
@@ -53,6 +54,9 @@
QT_BEGIN_NAMESPACE
class QMenu;
+#ifndef QT_NO_PRINTER
+class QPrinter;
+#endif
class QWebChannel;
class QWebEngineContextMenuData;
class QWebEngineFullScreenRequest;
@@ -123,6 +127,7 @@ public:
Unselect,
SavePage,
OpenLinkInNewBackgroundTab,
+ ViewSource,
WebActionCount
};
@@ -206,6 +211,8 @@ public:
#endif
virtual void triggerAction(WebAction action, bool checked = false);
+ void replaceMisspelledWord(const QString &replacement);
+
virtual bool event(QEvent*);
#ifdef Q_QDOC
void findText(const QString &subString, FindFlags options = FindFlags());
@@ -261,6 +268,9 @@ public:
QColor backgroundColor() const;
void setBackgroundColor(const QColor &color);
+ void save(const QString &filePath, QWebEngineDownloadItem::SavePageFormat format
+ = QWebEngineDownloadItem::MimeHtmlSaveFormat) const;
+
bool isAudioMuted() const;
void setAudioMuted(bool muted);
bool recentlyAudible() const;
@@ -272,6 +282,14 @@ public:
void printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF()));
#endif
+#ifndef QT_NO_PRINTER
+#ifdef Q_QDOC
+ void print(QPrinter *printer, FunctorOrLambda resultCallback);
+#else
+ void print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback);
+#endif // QDOC
+#endif // QT_NO_PRINTER
+
const QWebEngineContextMenuData &contextMenuData() const;
Q_SIGNALS:
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 96640a63a..8d78429d8 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -112,13 +112,16 @@ public:
virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) Q_DECL_OVERRIDE;
virtual bool isFullScreenMode() const Q_DECL_OVERRIDE;
virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE;
- virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE;
+ virtual void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) Q_DECL_OVERRIDE;
virtual void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) Q_DECL_OVERRIDE;
virtual void didRunJavaScript(quint64 requestId, const QVariant& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE;
virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
+#ifndef QT_NO_PRINTER
+ virtual void didPrintPageOnPrinter(quint64 requestId, bool result) Q_DECL_OVERRIDE;
+#endif
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
@@ -141,6 +144,7 @@ public:
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE;
virtual bool isEnabled() const Q_DECL_OVERRIDE;
+ virtual void setToolTip(const QString &toolTipText) Q_DECL_OVERRIDE;
const QObject *holdingQObject() const Q_DECL_OVERRIDE;
virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE;
@@ -173,6 +177,7 @@ public:
QWebChannel *webChannel;
unsigned int webChannelWorldId;
QUrl iconUrl;
+ bool m_navigationActionTriggered;
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 664323034..886a7207e 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -96,6 +96,11 @@ using QtWebEngineCore::BrowserContextAdapter;
A QWebEngineUrlSchemeHandler can be registered for a profile by installUrlSchemeHandler()
to add support for custom URL schemes. Requests for the scheme are then issued to
QWebEngineUrlSchemeHandler::requestStarted() as QWebEngineUrlRequestJob objects.
+
+ Spellchecking HTML form fields can be enabled per profile by using the setSpellCheckEnabled()
+ method and the current languages used for spellchecking can be set by using the
+ setSpellCheckLanguages() method.
+
*/
/*!
@@ -180,10 +185,12 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
Q_ASSERT(!m_ongoingDownloads.contains(info.id));
QWebEngineDownloadItemPrivate *itemPrivate = new QWebEngineDownloadItemPrivate(this, info.url);
itemPrivate->downloadId = info.id;
- itemPrivate->downloadState = QWebEngineDownloadItem::DownloadRequested;
+ itemPrivate->downloadState = info.accepted ? QWebEngineDownloadItem::DownloadInProgress
+ : QWebEngineDownloadItem::DownloadRequested;
itemPrivate->downloadPath = info.path;
itemPrivate->mimeType = info.mimeType;
itemPrivate->savePageFormat = static_cast<QWebEngineDownloadItem::SavePageFormat>(info.savePageFormat);
+ itemPrivate->type = static_cast<QWebEngineDownloadItem::DownloadType>(info.downloadType);
QWebEngineDownloadItem *download = new QWebEngineDownloadItem(itemPrivate, q);
@@ -556,6 +563,87 @@ QWebEngineProfile *QWebEngineProfile::defaultProfile()
}
/*!
+ \since 5.8
+
+ Sets the current list of \a languages for the spell checker.
+ Each language should match the name of the \c .bdic dictionary.
+ For example, the language \c en-US will load the \c en-US.bdic
+ dictionary file.
+
+ Qt WebEngine checks for the \c qtwebengine_dictionaries subdirectory
+ first in the local directory and if it is not found, in the Qt
+ installation directory.
+
+ On macOS, depending on how Qt WebEngine is configured at build time, there are two possibilities
+ how spellchecking data is found:
+
+ \list
+ \li Hunspell dictionaries (default) - .bdic dictionaries are used, just like on other
+ platforms
+ \li Native dictionaries - the macOS spellchecking APIs are used (which means the results
+ will depend on the installed OS dictionaries)
+ \endlist
+
+ Thus, in the macOS Hunspell case, Qt WebEngine will look in the \e qtwebengine_dictionaries
+ subdirectory located inside the application bundle \c Resources directory, and also in the
+ \c Resources directory located inside the Qt framework bundle.
+
+ To summarize, in case of Hunspell usage, the following paths are considered:
+
+ \list
+ \li QCoreApplication::applicationDirPath()/qtwebengine_dictionaries
+ or QCoreApplication::applicationDirPath()/../Contents/Resources/qtwebengine_dictionaries
+ (on macOS)
+ \li [QLibraryInfo::DataPath]/qtwebengine_dictionaries
+ or path/to/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries (Qt framework
+ bundle on macOS)
+ \endlist
+
+ For more information about how to compile \c .bdic dictionaries, see the
+ \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}.
+
+*/
+void QWebEngineProfile::setSpellCheckLanguages(const QStringList &languages)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setSpellCheckLanguages(languages);
+}
+
+/*!
+ \since 5.8
+
+ Returns the list of languages used by the spell checker.
+*/
+QStringList QWebEngineProfile::spellCheckLanguages() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->spellCheckLanguages();
+}
+
+/*!
+ \since 5.8
+
+ Enables spell checker if \a enable is \c true, otherwise disables it.
+ \sa isSpellCheckEnabled()
+ */
+void QWebEngineProfile::setSpellCheckEnabled(bool enable)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setSpellCheckEnabled(enable);
+}
+/*!
+ \since 5.8
+
+ Returns \c true if the spell checker is enabled; otherwise returns \c false.
+ \sa setSpellCheckEnabled()
+ */
+bool QWebEngineProfile::isSpellCheckEnabled() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->isSpellCheckEnabled();
+}
+
+/*!
Returns the default settings for all pages in this profile.
*/
QWebEngineSettings *QWebEngineProfile::settings() const
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index d981fa5bb..1ce4bfe17 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -121,6 +121,11 @@ public:
void clearHttpCache();
+ void setSpellCheckLanguages(const QStringList &languages);
+ QStringList spellCheckLanguages() const;
+ void setSpellCheckEnabled(bool enabled);
+ bool isSpellCheckEnabled() const;
+
static QWebEngineProfile *defaultProfile();
Q_SIGNALS:
diff --git a/src/webenginewidgets/api/qwebenginescript.cpp b/src/webenginewidgets/api/qwebenginescript.cpp
index 73dd5075e..04a9d979a 100644
--- a/src/webenginewidgets/api/qwebenginescript.cpp
+++ b/src/webenginewidgets/api/qwebenginescript.cpp
@@ -61,7 +61,8 @@ using QtWebEngineCore::UserScript;
not accessible from a different one. ScriptWorldId provides some predefined IDs for this
purpose.
- \note Chromium extensions, such as \c @include, \c @match, and \c @exclude, are not supported.
+ The following \l Greasemonkey attributes are supported since Qt 5.8:
+ \c @exclude, \c @include, \c @name, \c @match, and \c @run-at.
Use QWebEnginePage::scripts() and QWebEngineProfile::scripts() to access
the collection of scripts associated with a single page or a
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
index 4b77b4699..8d393924f 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
@@ -40,7 +40,7 @@
#include "qwebenginescriptcollection.h"
#include "qwebenginescriptcollection_p.h"
-#include "user_resource_controller_host.h"
+#include "renderer_host/user_resource_controller_host.h"
using QtWebEngineCore::UserScript;
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index dfca16287..50002e3e6 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -89,6 +89,13 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
return WebEngineSettings::AutoLoadIconsForPage;
case QWebEngineSettings::TouchIconsEnabled:
return WebEngineSettings::TouchIconsEnabled;
+ case QWebEngineSettings::FocusOnNavigationEnabled:
+ return WebEngineSettings::FocusOnNavigationEnabled;
+ case QWebEngineSettings::PrintElementBackgrounds:
+ return WebEngineSettings::PrintElementBackgrounds;
+ case QWebEngineSettings::AllowRunningInsecureContent:
+ return WebEngineSettings::AllowRunningInsecureContent;
+
default:
return WebEngineSettings::UnsupportedInCoreSettings;
}
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index 8eda50ee2..e3fb83ff5 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -85,7 +85,10 @@ public:
WebGLEnabled,
Accelerated2dCanvasEnabled,
AutoLoadIconsForPage,
- TouchIconsEnabled
+ TouchIconsEnabled,
+ FocusOnNavigationEnabled,
+ PrintElementBackgrounds,
+ AllowRunningInsecureContent
};
enum FontSize {
diff --git a/src/webenginewidgets/doc/snippets/qtwebengine_build_snippet.qdoc b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc
index dcdd82e04..dcdd82e04 100644
--- a/src/webenginewidgets/doc/snippets/qtwebengine_build_snippet.qdoc
+++ b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
index 59d7bc5d1..abfd17ce3 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
@@ -28,7 +28,6 @@
/*!
\page qtwebenginewidgets-index.html
\title Qt WebEngine Widgets
- \ingroup modules
\brief Provides a web browser engine as well as C++ classes to render web content and interact
with it.
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
index d0f2fd930..959f96b10 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
@@ -40,9 +40,9 @@
To include the definitions of the module's classes, use the
following directive:
- \snippet qtwebengine_build_snippet.qdoc 1
+ \snippet qtwebenginewidgets_build_snippet.qdoc 1
To link against the module, add the following to your qmake project file:
- \snippet qtwebengine_build_snippet.qdoc 0
+ \snippet qtwebenginewidgets_build_snippet.qdoc 0
*/
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 539e809d4..58abc9fa1 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -87,6 +87,10 @@
QWebEngineScript::ScriptWorldId provides some predefined IDs for this purpose. Using the
\c runJavaScript() version without the world ID is the same as running the script in the
\c MainWorld.
+
+ The \l {QWebEngineSettings::FocusOnNavigationEnabled} {FocusOnNavigationEnabled} setting can be
+ used to stop the view associated with the page from automatically receiving focus when a
+ navigation operation occurs (like loading or reloading a page or navigating through history).
*/
/*!
@@ -152,6 +156,7 @@
\value Unselect Clear the current selection. (Added in Qt 5.7)
\value SavePage Save the current page to disk. MHTML is the default format that is used to store
the web page on disk. (Added in Qt 5.7)
+ \value ViewSource Show the source of the current page in a new tab. (Added in Qt 5.8)
\omitvalue WebActionCount
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index 07c4965d0..07afd6501 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -147,6 +147,19 @@
\value TouchIconsEnabled
Enables support for touch icons and precomposed touch icons
Disabled by default. (Added in Qt 5.7)
+ \value FocusOnNavigationEnabled
+ Gives focus to the view associated with the page, whenever a navigation operation occurs
+ (load, stop, reload, reload and bypass cache, forward, backward, set content, and so
+ on).
+ Enabled by default. (Added in Qt 5.8)
+ \value PrintElementBackgrounds
+ Turns on printing of CSS backgrounds when printing a web page.
+ Enabled by default. (Added in Qt 5.8)
+ \value AllowRunningInsecureContent
+ By default, HTTPS pages cannot run JavaScript, CSS, plugins or
+ web-sockets from HTTP URLs. This provides an override to get
+ the old insecure behavior.
+ Disabled by default. (Added in Qt 5.8)
*/
/*!
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 5a4c1b52b..5b96459af 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -65,16 +65,13 @@
The zoomFactor() property enables zooming the contents of the web page by a
scale factor.
- If you require a custom context menu, you can implement it by reimplementing
- \l{QWidget::}{contextMenuEvent()} and populating your QMenu with the actions
- obtained from pageAction(). Additional functionality, such as reloading the view,
- copying selected text to the clipboard, or pasting into the view, is
- encapsulated within the QAction objects returned by pageAction(). These
- actions can be programmatically triggered using triggerPageAction().
- Alternatively, the actions can be added to a toolbar or a menu directly.
- The web view maintains the state of the returned actions but allows
- modification of action properties such as \l{QAction::}{text} or
- \l{QAction::}{icon}.
+ The widget features a context menu that is tailored to the element at
+ hand, and includes actions useful in a browser. For a custom context menu,
+ or for embedding actions in a menu or toolbar, the individual actions are available
+ via \l pageAction(). The web view maintains the state of the returned actions,
+ but allows modification of action properties such as \l{QAction::}{text} or
+ \l{QAction::}{icon}. The action semantics can also be triggered directly through
+ triggerPageAction().
If you want to provide support for web sites that allow the user to open
new windows, such as pop-up windows, you can subclass QWebEngineView and
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 23a203eab..eb3a3931a 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -49,21 +49,52 @@
#include <QSGAbstractRenderer>
#include <QSGNode>
#include <QWindow>
-#include <private/qsgcontext_p.h>
-#include <private/qsgengine_p.h>
+#include <private/qquickwindow_p.h>
+
+#if (QT_VERSION < QT_VERSION_CHECK(5, 8, 0))
+#include <QSGSimpleRectNode>
+#include <QSGSimpleTextureNode>
+#endif
#include <private/qwidget_p.h>
namespace QtWebEngineCore {
-static const int MaxTooltipLength = 1024;
+class RenderWidgetHostViewQuickItem : public QQuickItem {
+public:
+ RenderWidgetHostViewQuickItem(RenderWidgetHostViewQtDelegateClient *client) : m_client(client)
+ {
+ setFlag(ItemHasContents, true);
+ }
+protected:
+ void focusInEvent(QFocusEvent *event) override
+ {
+ m_client->forwardEvent(event);
+ }
+ void focusOutEvent(QFocusEvent *event) override
+ {
+ m_client->forwardEvent(event);
+ }
+ void keyPressEvent(QKeyEvent *event) override
+ {
+ m_client->forwardEvent(event);
+ }
+ void keyReleaseEvent(QKeyEvent *event) override
+ {
+ m_client->forwardEvent(event);
+ }
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override
+ {
+ return m_client->updatePaintNode(oldNode);
+ }
+private:
+ RenderWidgetHostViewQtDelegateClient *m_client;
+};
RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent)
- : QOpenGLWidget(parent)
+ : QQuickWidget(parent)
, m_client(client)
- , m_rootNode(new QSGRootNode)
- , m_sgEngine(new QSGEngine)
+ , m_rootItem(new RenderWidgetHostViewQuickItem(client))
, m_isPopup(false)
- , m_clearColor(Qt::white)
{
setFocusPolicy(Qt::StrongFocus);
@@ -73,6 +104,7 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
+#ifndef QT_NO_OPENGL
QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext();
if (globalSharedContext) {
QSurfaceFormat sharedFormat = globalSharedContext->format();
@@ -91,7 +123,7 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
}
#endif
- // Make sure the OpenGL profile of the QOpenGLWidget matches the shared context profile.
+ // Make sure the OpenGL profile of the QQuickWidget matches the shared context profile.
if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
format.setMajorVersion(sharedFormat.majorVersion());
format.setMinorVersion(sharedFormat.minorVersion());
@@ -101,7 +133,7 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
setFormat(format);
#endif
-
+#endif
setMouseTracking(true);
setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_OpaquePaintEvent);
@@ -110,6 +142,8 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
void RenderWidgetHostViewQtDelegateWidget::initAsChild(WebContentsAdapterClient* container)
{
+ setContent(QUrl(), nullptr, m_rootItem.data());
+
QWebEnginePagePrivate *pagePrivate = static_cast<QWebEnginePagePrivate *>(container);
if (pagePrivate->view) {
pagePrivate->view->layout()->addWidget(this);
@@ -122,6 +156,8 @@ void RenderWidgetHostViewQtDelegateWidget::initAsChild(WebContentsAdapterClient*
void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect)
{
m_isPopup = true;
+ setContent(QUrl(), nullptr, m_rootItem.data());
+
// The keyboard events are supposed to go to the parent RenderHostView
// so the WebUI popups should never have focus. Besides, if the parent view
// loses focus, WebKit will cause its associated popups (including this one)
@@ -147,12 +183,12 @@ QRectF RenderWidgetHostViewQtDelegateWidget::contentsRect() const
void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus()
{
- setFocus();
+ m_rootItem->forceActiveFocus();
}
bool RenderWidgetHostViewQtDelegateWidget::hasKeyboardFocus()
{
- return hasFocus();
+ return m_rootItem->hasActiveFocus();
}
void RenderWidgetHostViewQtDelegateWidget::lockMouse()
@@ -170,65 +206,85 @@ void RenderWidgetHostViewQtDelegateWidget::show()
// Check if we're attached to a QWebEngineView, we don't
// want to show anything else than popups as top-level.
if (parent() || m_isPopup) {
- QOpenGLWidget::show();
+ QQuickWidget::show();
}
}
void RenderWidgetHostViewQtDelegateWidget::hide()
{
- QOpenGLWidget::hide();
+ QQuickWidget::hide();
}
bool RenderWidgetHostViewQtDelegateWidget::isVisible() const
{
- return QOpenGLWidget::isVisible();
+ return QQuickWidget::isVisible();
}
QWindow* RenderWidgetHostViewQtDelegateWidget::window() const
{
- const QWidget* root = QOpenGLWidget::window();
+ const QWidget* root = QQuickWidget::window();
return root ? root->windowHandle() : 0;
}
QSGTexture *RenderWidgetHostViewQtDelegateWidget::createTextureFromImage(const QImage &image)
{
- return m_sgEngine->createTextureFromImage(image, QSGEngine::TextureCanUseAtlas);
+ return quickWindow()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
}
QSGLayer *RenderWidgetHostViewQtDelegateWidget::createLayer()
{
- QSGEnginePrivate *enginePrivate = QSGEnginePrivate::get(m_sgEngine.data());
- return enginePrivate->sgContext->createLayer(enginePrivate->sgRenderContext.data());
+ QSGRenderContext *renderContext = QQuickWindowPrivate::get(quickWindow())->context;
+ return renderContext->sceneGraphContext()->createLayer(renderContext);
}
-QSGImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode()
+QSGInternalImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode()
{
- return QSGEnginePrivate::get(m_sgEngine.data())->sgContext->createImageNode();
+ QSGRenderContext *renderContext = QQuickWindowPrivate::get(quickWindow())->context;
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
+ return renderContext->sceneGraphContext()->createInternalImageNode();
+#else
+ return renderContext->sceneGraphContext()->createImageNode();
+#endif
}
-void RenderWidgetHostViewQtDelegateWidget::update()
+QSGTextureNode *RenderWidgetHostViewQtDelegateWidget::createTextureNode()
+{
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
+ return quickWindow()->createImageNode();
+#else
+ return new QSGSimpleTextureNode();
+#endif
+}
+
+QSGRectangleNode *RenderWidgetHostViewQtDelegateWidget::createRectangleNode()
{
-#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
- updateGL();
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
+ return quickWindow()->createRectangleNode();
#else
- QOpenGLWidget::update();
+ QSGRenderContext *renderContext = QQuickWindowPrivate::get(quickWindow())->context;
+ return renderContext->sceneGraphContext()->createRectangleNode();
#endif
}
+void RenderWidgetHostViewQtDelegateWidget::update()
+{
+ m_rootItem->update();
+}
+
void RenderWidgetHostViewQtDelegateWidget::updateCursor(const QCursor &cursor)
{
- QOpenGLWidget::setCursor(cursor);
+ QQuickWidget::setCursor(cursor);
}
void RenderWidgetHostViewQtDelegateWidget::resize(int width, int height)
{
- QOpenGLWidget::resize(width, height);
+ QQuickWidget::resize(width, height);
}
void RenderWidgetHostViewQtDelegateWidget::move(const QPoint &screenPos)
{
Q_ASSERT(m_isPopup);
- QOpenGLWidget::move(screenPos);
+ QQuickWidget::move(screenPos);
}
void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVisible)
@@ -236,23 +292,15 @@ void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVi
if (qApp->inputMethod()->isVisible() == editorVisible)
return;
- QOpenGLWidget::setAttribute(Qt::WA_InputMethodEnabled, editorVisible);
+ QQuickWidget::setAttribute(Qt::WA_InputMethodEnabled, editorVisible);
qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
qApp->inputMethod()->setVisible(editorVisible);
}
-void RenderWidgetHostViewQtDelegateWidget::setTooltip(const QString &tooltip)
-{
- QString wrappedTip;
- if (!tooltip.isEmpty())
- wrappedTip = QLatin1String("<p>") % tooltip.toHtmlEscaped().left(MaxTooltipLength) % QLatin1String("</p>");
- setToolTip(wrappedTip);
-}
-
void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color)
{
- m_clearColor = color;
- // QOpenGLWidget is usually blended by punching holes into widgets
+ QQuickWidget::setClearColor(color);
+ // QQuickWidget is usually blended by punching holes into widgets
// above it to simulate the visual stacking order. If we want it to be
// transparent we have to throw away the proper stacking order and always
// blend the complete normal widgets backing store under it.
@@ -269,7 +317,7 @@ QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQ
void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent)
{
- QOpenGLWidget::resizeEvent(resizeEvent);
+ QQuickWidget::resizeEvent(resizeEvent);
const QPoint globalPos = mapToGlobal(pos());
if (globalPos != m_lastGlobalPos) {
@@ -282,7 +330,7 @@ void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent
void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
{
- QOpenGLWidget::showEvent(event);
+ QQuickWidget::showEvent(event);
// We don't have a way to catch a top-level window change with QWidget
// but a widget will most likely be shown again if it changes, so do
// the reconnection at this point.
@@ -299,7 +347,7 @@ void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event)
{
- QOpenGLWidget::hideEvent(event);
+ QQuickWidget::hideEvent(event);
m_client->notifyHidden();
}
@@ -334,11 +382,25 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
}
}
- if (event->type() == QEvent::ShortcutOverride) {
+ switch (event->type()) {
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ // We forward focus events later, once they have made it to the m_rootItem.
+ return QQuickWidget::event(event);
+ case QEvent::ShortcutOverride:
if (editorActionForKeyEvent(static_cast<QKeyEvent*>(event)) != QWebEnginePage::NoWebAction) {
event->accept();
return true;
}
+ break;
+ case QEvent::DragEnter:
+ case QEvent::DragLeave:
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ // Let the parent handle these events.
+ return false;
+ default:
+ break;
}
QEvent::Type type = event->type();
@@ -360,45 +422,10 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
handled = m_client->forwardEvent(event);
if (!handled)
- return QOpenGLWidget::event(event);
+ return QQuickWidget::event(event);
return true;
}
-void RenderWidgetHostViewQtDelegateWidget::initializeGL()
-{
- m_sgEngine->initialize(QOpenGLContext::currentContext());
- m_sgRenderer.reset(m_sgEngine->createRenderer());
- m_sgRenderer->setRootNode(m_rootNode.data());
- m_sgRenderer->setClearColor(m_clearColor);
-
- // When RenderWidgetHostViewQt::GetScreenInfo is called for the first time, the associated
- // QWindow is NULL, and the screen device pixel ratio can not be queried.
- // Re-initialize the screen information after the QWindow handle is available,
- // so Chromium receives the correct device pixel ratio.
- m_client->windowChanged();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::paintGL()
-{
-#if (QT_VERSION < QT_VERSION_CHECK(5, 3, 1))
- // A workaround for a missing check in 5.3.0 when updating an unparented delegate.
- if (!QOpenGLContext::currentContext())
- return;
-#endif
- QSGNode *paintNode = m_client->updatePaintNode(m_rootNode->firstChild());
- if (paintNode != m_rootNode->firstChild()) {
- delete m_rootNode->firstChild();
- m_rootNode->appendChildNode(paintNode);
- }
-
- QSize deviceSize = size() * devicePixelRatio();
- m_sgRenderer->setDeviceRect(deviceSize);
- m_sgRenderer->setViewportRect(deviceSize);
- m_sgRenderer->setProjectionMatrixToRect(QRectF(QPointF(), size()));
-
- m_sgRenderer->renderScene(defaultFramebufferObject());
-}
-
void RenderWidgetHostViewQtDelegateWidget::onWindowPosChanged()
{
m_lastGlobalPos = mapToGlobal(pos());
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 7307bcd55..77907ec5a 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -43,19 +43,12 @@
#include "render_widget_host_view_qt_delegate.h"
#include "web_contents_adapter_client.h"
-#include <QSGAbstractRenderer>
-#include <QSGEngine>
-#include <QSGNode>
-
-#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
-#include <QtWidgets/private/qopenglwidget_p.h>
-#else
-#include <QtWidgets/QOpenGLWidget>
-#endif
+#include <QQuickItem>
+#include <QQuickWidget>
namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegateWidget : public QOpenGLWidget, public RenderWidgetHostViewQtDelegate {
+class RenderWidgetHostViewQtDelegateWidget : public QQuickWidget, public RenderWidgetHostViewQtDelegate {
Q_OBJECT
public:
RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent = 0);
@@ -74,13 +67,14 @@ public:
virtual QWindow* window() const Q_DECL_OVERRIDE;
virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE;
virtual QSGLayer *createLayer() Q_DECL_OVERRIDE;
- virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE;
+ virtual QSGInternalImageNode *createImageNode() Q_DECL_OVERRIDE;
+ virtual QSGTextureNode *createTextureNode() Q_DECL_OVERRIDE;
+ virtual QSGRectangleNode *createRectangleNode() Q_DECL_OVERRIDE;
virtual void update() Q_DECL_OVERRIDE;
virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE;
virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
- virtual void setTooltip(const QString &tooltip) Q_DECL_OVERRIDE;
virtual void setClearColor(const QColor &color) Q_DECL_OVERRIDE;
protected:
@@ -88,8 +82,6 @@ protected:
void resizeEvent(QResizeEvent *resizeEvent) Q_DECL_OVERRIDE;
void showEvent(QShowEvent *) Q_DECL_OVERRIDE;
void hideEvent(QHideEvent *) Q_DECL_OVERRIDE;
- void initializeGL() Q_DECL_OVERRIDE;
- void paintGL() Q_DECL_OVERRIDE;
QVariant inputMethodQuery(Qt::InputMethodQuery query) const Q_DECL_OVERRIDE;
@@ -98,10 +90,7 @@ private slots:
private:
RenderWidgetHostViewQtDelegateClient *m_client;
- // Put the root node first to make sure it gets destroyed after the SG renderer.
- QScopedPointer<QSGRootNode> m_rootNode;
- QScopedPointer<QSGEngine> m_sgEngine;
- QScopedPointer<QSGAbstractRenderer> m_sgRenderer;
+ QScopedPointer<QQuickItem> m_rootItem;
bool m_isPopup;
QColor m_clearColor;
QPoint m_lastGlobalPos;
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 279ec79f8..abd487e5f 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -4,7 +4,7 @@ TARGET = QtWebEngineWidgets
DEFINES += QT_BUILD_WEBENGINEWIDGETS_LIB
QT += webenginecore widgets network quick
-QT_PRIVATE += quick-private gui-private core-private widgets-private
+QT_PRIVATE += quick-private gui-private core-private widgets-private quickwidgets
INCLUDEPATH += $$PWD api ../core ../core/api ../webengine/api