diff options
author | Liang Qi <liang.qi@qt.io> | 2016-08-04 07:29:26 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-08-05 11:35:18 +0200 |
commit | 179463fd2b17343dae291ab6f7617311bcfbdb75 (patch) | |
tree | e32e298ca5d6e2b6e206dab7d42538a6ce68eba1 /src/core | |
parent | c8851dd1a77e730bc6a3c17b7c75b1a4c6b41f53 (diff) | |
parent | 336e706cbc839dd7b7c1d461b6b015600b5f009e (diff) |
Merge remote-tracking branch 'origin/5.7' into dev
Also blacklist tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
and comboBoxPopupPositionAfterMove().
Conflicts:
.qmake.conf
src/3rdparty
src/core/render_widget_host_view_qt.cpp
src/core/resources/resources.gyp
src/webengine/doc/src/qtwebengine-platform-notes.qdoc
src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
tests/auto/widgets/qwebenginepage/BLACKLIST
tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
tools/qmake/mkspecs/features/functions.prf
Task-number: QTBUG-55158
Change-Id: I1d73ac9b3ca5293ad3c7e3a56f4c395da930e6f4
Diffstat (limited to 'src/core')
26 files changed, 226 insertions, 112 deletions
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index 57afb7c33..03150d322 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -254,6 +254,16 @@ QString BrowserContextAdapter::cookiesPath() const return QString(); } +QString BrowserContextAdapter::channelIdPath() const +{ + if (m_offTheRecord) + return QString(); + QString basePath = dataPath(); + if (!basePath.isEmpty()) + return basePath % QLatin1String("/Origin Bound Certs"); + return QString(); +} + QString BrowserContextAdapter::httpCachePath() const { if (m_offTheRecord) diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h index 94bc5fcde..a6e5a2a3e 100644 --- a/src/core/browser_context_adapter.h +++ b/src/core/browser_context_adapter.h @@ -103,6 +103,7 @@ public: QString httpCachePath() const; QString cookiesPath() const; + QString channelIdPath() const; QString httpUserAgent() const; void setHttpUserAgent(const QString &userAgent); diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri index 83ddea233..c447add4a 100644 --- a/src/core/config/mac_osx.pri +++ b/src/core/config/mac_osx.pri @@ -1,4 +1,5 @@ include(common.pri) +load(functions) # Reuse the cached sdk version value from mac/sdk.prf if available # otherwise query for it. @@ -26,5 +27,9 @@ GYP_CONFIG += \ clang_use_chrome_plugins=0 \ enable_widevine=1 +# Force touch API is used in 49-based Chromium, which is included starting with 10.10.3 SDK, so we +# disable the API usage if the SDK version is lower. +!isMinOSXSDKVersion(10, 10, 3): GYP_CONFIG += disable_force_touch=1 + QMAKE_MAC_SDK_PATH = "$$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path)" exists($$QMAKE_MAC_SDK_PATH): GYP_CONFIG += mac_sdk_path=\"$${QMAKE_MAC_SDK_PATH}\" diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index 379c42468..095e54caa 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -160,7 +160,6 @@ bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code) #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE PathService::Override(base::DIR_QT_LIBRARY_DATA, WebEngineLibraryInfo::getPath(base::DIR_QT_LIBRARY_DATA)); #endif - PathService::Override(content::DIR_MEDIA_LIBS, WebEngineLibraryInfo::getPath(content::DIR_MEDIA_LIBS)); PathService::Override(ui::DIR_LOCALES, WebEngineLibraryInfo::getPath(ui::DIR_LOCALES)); #if defined(ENABLE_SPELLCHECK) PathService::Override(base::DIR_APP_DICTIONARIES, WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES)); diff --git a/src/core/core.gyp b/src/core/core.gyp deleted file mode 100644 index ea5478cf1..000000000 --- a/src/core/core.gyp +++ /dev/null @@ -1,12 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'qtwebengine', - 'type': 'none', - 'dependencies': [ - 'core_generated.gyp:*', - 'resources/resources.gyp:*', - ], - }, - ] -} diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro index 155d81f5d..70644e5f6 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_gyp_generator.pro @@ -2,8 +2,9 @@ # We want the gyp generation step to happen after all the other config steps. For that we need to prepend # our gyp_generator.prf feature to the CONFIG variable since it is processed backwards CONFIG = gyp_generator $$CONFIG -GYPFILE = $$PWD/core_generated.gyp -GYPINCLUDES += qtwebengine.gypi +GYPFILE = $$OUT_PWD/core_generated.gyp +GYPINCLUDES += $$PWD/qtwebengine.gypi +GYPSRCDIR = $$PWD TEMPLATE = lib @@ -18,6 +19,7 @@ DEFINES += QT_NO_KEYWORDS \ # Ensure that response files, generated by qtbase/mkspecs/features/moc.prf, are found by moc. MOC_DIR = $$OUT_PWD/$$getConfigDir()/.moc +RCC_DIR = $$OUT_PWD/$$getConfigDir()/.rcc # Assume that we want mobile touch and low-end hardware behaviors # whenever we are cross compiling. diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 20b719547..3b9dab457 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -96,6 +96,13 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat } } +!win32:!build_pass:debug_and_release { + # Special GNU make target that ensures linking isn't done for both debug and release builds + # at the same time. + notParallel.target = .NOTPARALLEL + QMAKE_EXTRA_TARGETS += notParallel +} + OTHER_FILES = \ $$files(../3rdparty/chromium/*.h, true) \ $$files(../3rdparty/chromium/*.cc, true) \ diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro index a1b33e258..2264d9b70 100644 --- a/src/core/gyp_run.pro +++ b/src/core/gyp_run.pro @@ -89,9 +89,16 @@ contains(QT_ARCH, "arm") { contains(QT_ARCH, "mips") { GYP_CONFIG += target_arch=mipsel - contains(QMAKE_CFLAGS, "mips32r6"): mips_arch_variant=\"r6\" - else: contains(QMAKE_CFLAGS, "mips32r2"): mips_arch_variant=\"r2\" - else: contains(QMAKE_CFLAGS, "mips32"): mips_arch_variant=\"r1\" + MARCH = $$extractCFlag("-march=.*") + !isEmpty(MARCH) { + equals(MARCH, "mips32r6"): GYP_CONFIG += mips_arch_variant=\"r6\" + else: equals(MARCH, "mips32r2"): GYP_CONFIG += mips_arch_variant=\"r2\" + else: equals(MARCH, "mips32"): GYP_CONFIG += mips_arch_variant=\"r1\" + } else { + contains(QMAKE_CFLAGS, "mips32r6"): GYP_CONFIG += mips_arch_variant=\"r6\" + else: contains(QMAKE_CFLAGS, "mips32r2"): GYP_CONFIG += mips_arch_variant=\"r2\" + else: contains(QMAKE_CFLAGS, "mips32"): GYP_CONFIG += mips_arch_variant=\"r1\" + } contains(QMAKE_CFLAGS, "-mdsp2"): GYP_CONFIG += mips_dsp_rev=2 else: contains(QMAKE_CFLAGS, "-mdsp"): GYP_CONFIG += mips_dsp_rev=1 @@ -126,7 +133,7 @@ contains(WEBENGINE_CONFIG, no_spellcheck): { for (config, GYP_CONFIG): GYP_ARGS += "-D $$config" !build_pass { - message("Running gyp_qtwebengine \"$$OUT_PWD\" $${GYP_ARGS}...") + message("Running gyp_qtwebengine \"$$OUT_PWD\" $${GYP_ARGS}.") !system("python $$QTWEBENGINE_ROOT/tools/buildscripts/gyp_qtwebengine \"$$OUT_PWD\" $${GYP_ARGS}"): error("-- running gyp_qtwebengine failed --") } diff --git a/src/core/proxy_config_service_qt.cpp b/src/core/proxy_config_service_qt.cpp index 7affd9045..bd5d0375d 100644 --- a/src/core/proxy_config_service_qt.cpp +++ b/src/core/proxy_config_service_qt.cpp @@ -134,6 +134,7 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy qtRules.type = net::ProxyConfig::ProxyRules::TYPE_NO_RULES; } + qtRules.bypass_rules.AddRuleToBypassLocal(); // don't use proxy for connections to localhost m_qtProxyConfig.proxy_rules() = qtRules; *config = m_qtProxyConfig; return CONFIG_VALID; diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi index 00c65fdd4..84a9ff564 100644 --- a/src/core/qtwebengine.gypi +++ b/src/core/qtwebengine.gypi @@ -38,7 +38,7 @@ '<(chromium_src_dir)/url/url.gyp:url_lib', '<(chromium_src_dir)/v8/tools/gyp/v8.gyp:v8', - 'chrome_qt.gyp:chrome_qt', + '<(qtwebengine_root)/src/core/chrome_qt.gyp:chrome_qt', ], 'include_dirs': [ '<(chromium_src_dir)', diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 326965416..a0ad53c1e 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -239,6 +239,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget , m_didFirstVisuallyNonEmptyLayout(false) , m_adapterClient(0) , m_imeInProgress(false) + , m_receivedEmptyImeText(false) , m_anchorPositionWithinSelection(0) , m_cursorPositionWithinSelection(0) , m_initPending(false) @@ -945,6 +946,19 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) QCursor::setPos(m_lockedMousePosition); } + if (m_imeInProgress && event->type() == QMouseEvent::MouseButtonPress) { + m_imeInProgress = false; + // Tell input method to commit the pre-edit string entered so far, and finish the + // composition operation. +#ifdef Q_OS_WIN + // Yes the function name is counter-intuitive, but commit isn't actually implemented + // by the Windows QPA, and reset does exactly what is necessary in this case. + qApp->inputMethod()->reset(); +#else + qApp->inputMethod()->commit(); +#endif + } + m_host->ForwardMouseEvent(webEvent); } @@ -953,15 +967,16 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev) if (IsMouseLocked() && ev->key() == Qt::Key_Escape && ev->type() == QEvent::KeyRelease) UnlockMouse(); - if (m_imeInProgress) { + if (m_receivedEmptyImeText) { // 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; + m_receivedEmptyImeText = false; } else { if (ev->type() == QEvent::KeyRelease) { + m_receivedEmptyImeText = false; m_host->ImeConfirmComposition(toString16(ev->text()), gfx::Range::InvalidRange(), false); m_imeInProgress = false; @@ -1001,6 +1016,17 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev) const QList<QInputMethodEvent::Attribute> &attributes = ev->attributes(); std::vector<blink::WebCompositionUnderline> underlines; + auto ensureValidSelectionRange = [&]() { + 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; + selectionRange.set_start(newCursorPosition); + selectionRange.set_end(newCursorPosition); + } + }; Q_FOREACH (const QInputMethodEvent::Attribute &attribute, attributes) { switch (attribute.type) { @@ -1014,8 +1040,11 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev) break; } case QInputMethodEvent::Cursor: - if (attribute.length) - cursorPositionInPreeditString = attribute.start; + // Always set the position of the cursor, even if it's marked invisible by Qt, otherwise + // there is no way the user will know which part of the composition string will be + // changed, when performing an IME-specific action (like selecting a different word + // suggestion). + cursorPositionInPreeditString = attribute.start; break; case QInputMethodEvent::Selection: selectionRange.set_start(qMin(attribute.start, (attribute.start + attribute.length))); @@ -1028,18 +1057,54 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev) gfx::Range replacementRange = (replacementLength > 0) ? gfx::Range(replacementStart, replacementStart + replacementLength) : gfx::Range::InvalidRange(); + + auto setCompositionForPreEditString = [&](){ + ensureValidSelectionRange(); + m_host->ImeSetComposition(toString16(preeditString), + underlines, + replacementRange, + selectionRange.start(), + selectionRange.end()); + }; + if (!commitString.isEmpty()) { m_host->ImeConfirmComposition(toString16(commitString), replacementRange, false); - 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; - selectionRange.set_start(newCursorPosition); - selectionRange.set_end(newCursorPosition); + + // We might get a commit string and a pre-edit string in a single event, which means + // we need to confirm thećlast composition, and start a new composition. + if (!preeditString.isEmpty()) { + setCompositionForPreEditString(); + m_imeInProgress = true; + } else { + m_imeInProgress = false; } - m_host->ImeSetComposition(toString16(preeditString), underlines, replacementRange, selectionRange.start(), selectionRange.end()); + m_receivedEmptyImeText = false; + + } else if (!preeditString.isEmpty()) { + setCompositionForPreEditString(); m_imeInProgress = true; + m_receivedEmptyImeText = false; + } else { + // There are so-far two known cases, when an empty QInputMethodEvent is received. + // First one happens when backspace is used to remove the last character in the pre-edit + // string, thus signaling the end of the composition. + // The second one happens (on Windows) when a Korean char gets composed, but instead of + // the event having a commit string, both strings are empty, and the actual char is received + // as a QKeyEvent after the QInputMethodEvent is processed. + // In lieu of the second case, we can't simply cancel the composition on an empty event, + // and then add the Korean char when QKeyEvent is received, because that leads to text + // flickering in the textarea (or any other element). + // Instead we postpone the processing of the empty QInputMethodEvent by posting it + // to the same focused object, and cancelling the composition on the next event loop tick. + if (!m_receivedEmptyImeText && m_imeInProgress) { + m_receivedEmptyImeText = true; + m_imeInProgress = false; + QInputMethodEvent *eventCopy = new QInputMethodEvent(*ev); + QGuiApplication::postEvent(qApp->focusObject(), eventCopy); + } else { + m_receivedEmptyImeText = false; + m_host->ImeCancelComposition(); + } } } diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index a6d34fd6a..fa698f0ea 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -228,6 +228,7 @@ private: ui::TextInputType m_currentInputType; bool m_imeInProgress; + bool m_receivedEmptyImeText; 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 7c22c8d9f..8b7d520a9 100644 --- a/src/core/resources/resources.gyp +++ b/src/core/resources/resources.gyp @@ -13,18 +13,18 @@ 'qt_install_data%': '', 'qt_install_translations%': '', }, - 'dependencies': [ - '<(chromium_src_dir)/content/app/strings/content_strings.gyp:content_strings', - '<(chromium_src_dir)/blink/public/blink_resources.gyp:blink_resources', - '<(chromium_src_dir)/content/browser/devtools/devtools_resources.gyp:devtools_resources', - '<(chromium_src_dir)/components/components_resources.gyp:components_resources', - '<(chromium_src_dir)/components/components_strings.gyp:components_strings', - '../chrome_qt.gyp:chrome_resources', - ], 'targets': [ { 'target_name': 'qtwebengine_resources', 'type': 'none', + 'dependencies': [ + '<(chromium_src_dir)/content/app/strings/content_strings.gyp:content_strings', + '<(chromium_src_dir)/content/browser/devtools/devtools_resources.gyp:devtools_resources', + '<(chromium_src_dir)/components/components_resources.gyp:components_resources', + '<(chromium_src_dir)/components/components_strings.gyp:components_strings', + '<(chromium_src_dir)/third_party/WebKit/public/blink_resources.gyp:blink_resources', + '<(qtwebengine_root)/src/core/chrome_qt.gyp:chrome_resources', + ], 'actions' : [ { 'action_name': 'repack_resources', diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 5fb324b6c..959dd3d95 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -51,6 +51,7 @@ #include "net/disk_cache/disk_cache.h" #include "net/dns/host_resolver.h" #include "net/dns/mapped_host_resolver.h" +#include "net/extras/sqlite/sqlite_channel_id_store.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_cache.h" #include "net/http/http_network_session.h" @@ -126,6 +127,7 @@ void URLRequestContextGetterQt::setFullConfiguration(QSharedPointer<BrowserConte m_requestInterceptor = browserContext->requestInterceptor(); m_persistentCookiesPolicy = browserContext->persistentCookiesPolicy(); m_cookiesPath = browserContext->cookiesPath(); + m_channelIdPath = browserContext->channelIdPath(); m_httpAcceptLanguage = browserContext->httpAcceptLanguage(); m_httpUserAgent = browserContext->httpUserAgent(); m_httpCacheType = browserContext->httpCacheType(); @@ -221,11 +223,6 @@ void URLRequestContextGetterQt::generateStorage() net::ProxyConfigService *proxyConfigService = m_proxyConfigService.fetchAndStoreAcquire(0); Q_ASSERT(proxyConfigService); - - m_storage->set_channel_id_service(scoped_ptr<net::ChannelIDService>(new net::ChannelIDService( - new net::DefaultChannelIDStore(NULL), - base::WorkerPool::GetTaskRunner(true)))); - m_storage->set_cert_verifier(net::CertVerifier::CreateDefault()); scoped_ptr<net::HostResolver> host_resolver(net::HostResolver::CreateDefaultResolver(NULL)); @@ -257,8 +254,9 @@ void URLRequestContextGetterQt::updateCookieStore() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); QMutexLocker lock(&m_mutex); - m_httpAcceptLanguage = m_browserContext.data()->httpAcceptLanguage(); - m_httpUserAgent = m_browserContext.data()->httpUserAgent(); + m_persistentCookiesPolicy = m_browserContext.data()->persistentCookiesPolicy(); + m_cookiesPath = m_browserContext.data()->cookiesPath(); + m_channelIdPath = m_browserContext.data()->channelIdPath(); if (m_contextInitialized && !m_updateAllStorage && !m_updateCookieStore) { m_updateCookieStore = true; @@ -276,6 +274,19 @@ void URLRequestContextGetterQt::generateCookieStore() QMutexLocker lock(&m_mutex); m_updateCookieStore = false; + scoped_refptr<net::SQLiteChannelIDStore> channel_id_db; + if (!m_channelIdPath.isEmpty() && m_persistentCookiesPolicy != BrowserContextAdapter::NoPersistentCookies) { + channel_id_db = new net::SQLiteChannelIDStore( + toFilePath(m_channelIdPath), + BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( + BrowserThread::GetBlockingPool()->GetSequenceToken())); + } + + m_storage->set_channel_id_service( + scoped_ptr<net::ChannelIDService>(new net::ChannelIDService( + new net::DefaultChannelIDStore(channel_id_db.get()), + base::WorkerPool::GetTaskRunner(true)))); + // Unset it first to get a chance to destroy and flush the old cookie store before opening a new on possibly the same file. m_storage->set_cookie_store(0); m_cookieDelegate->setCookieMonster(0); diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h index b4bd3fdfe..b6209030b 100644 --- a/src/core/url_request_context_getter_qt.h +++ b/src/core/url_request_context_getter_qt.h @@ -134,6 +134,7 @@ private: // FIXME: Should later be moved to a separate ProfileIOData class. BrowserContextAdapter::PersistentCookiesPolicy m_persistentCookiesPolicy; QString m_cookiesPath; + QString m_channelIdPath; QString m_httpAcceptLanguage; QString m_httpUserAgent; BrowserContextAdapter::HttpCacheType m_httpCacheType; diff --git a/src/core/web_channel_ipc_transport_host.cpp b/src/core/web_channel_ipc_transport_host.cpp index ce5ea320b..aef16f0a0 100644 --- a/src/core/web_channel_ipc_transport_host.cpp +++ b/src/core/web_channel_ipc_transport_host.cpp @@ -61,6 +61,13 @@ WebChannelIPCTransportHost::~WebChannelIPCTransportHost() { } +void WebChannelIPCTransportHost::RenderViewHostChanged(content::RenderViewHost *, content::RenderViewHost *) +{ + // This means that we were moved into a different RenderView, possibly in a different + // render process and that we lost our WebChannelIPCTransport object and its state. + Send(new WebChannelIPCTransport_Install(routing_id(), m_worldId)); +} + void WebChannelIPCTransportHost::setWorldId(uint worldId) { if (worldId == m_worldId) diff --git a/src/core/web_channel_ipc_transport_host.h b/src/core/web_channel_ipc_transport_host.h index 51adcb95f..75b40477e 100644 --- a/src/core/web_channel_ipc_transport_host.h +++ b/src/core/web_channel_ipc_transport_host.h @@ -58,6 +58,9 @@ public: WebChannelIPCTransportHost(content::WebContents *, uint worldId = 0, QObject *parent = 0); virtual ~WebChannelIPCTransportHost(); + // WebContentsObserver + virtual void RenderViewHostChanged(content::RenderViewHost* old_host, content::RenderViewHost* new_host) Q_DECL_OVERRIDE; + // QWebChannelAbstractTransport void sendMessage(const QJsonObject &message) Q_DECL_OVERRIDE; diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index c3789318a..b0aae6ca9 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -349,14 +349,14 @@ WebContentsAdapterPrivate::~WebContentsAdapterPrivate() webContents.reset(); } -QExplicitlySharedDataPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient) +QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient) { int currentIndex; std::vector<scoped_ptr<content::NavigationEntry>> entries; deserializeNavigationHistory(input, ¤tIndex, &entries, adapterClient->browserContextAdapter()->browserContext()); if (currentIndex == -1) - return QExplicitlySharedDataPointer<WebContentsAdapter>(); + return QSharedPointer<WebContentsAdapter>(); // Unlike WebCore, Chromium only supports Restoring to a new WebContents instance. content::WebContents* newWebContents = createBlankWebContents(adapterClient, adapterClient->browserContextAdapter()->browserContext()); @@ -374,7 +374,7 @@ QExplicitlySharedDataPointer<WebContentsAdapter> WebContentsAdapter::createFromS content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(id, *file); } - return QExplicitlySharedDataPointer<WebContentsAdapter>(new WebContentsAdapter(newWebContents)); + return QSharedPointer<WebContentsAdapter>::create(newWebContents); } WebContentsAdapter::WebContentsAdapter(content::WebContents *webContents) @@ -837,6 +837,9 @@ void WebContentsAdapter::stopFinding() { Q_D(WebContentsAdapter); d->webContentsDelegate->setLastSearchedString(QString()); + // Clear any previous selection, + // but keep the renderer blue rectangle selection just like Chromium does. + d->webContents->Unselect(); d->webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION); } diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 72e1f6447..a29778a7e 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -44,7 +44,7 @@ #include "web_contents_adapter_client.h" #include <QScopedPointer> -#include <QSharedData> +#include <QSharedPointer> #include <QString> #include <QUrl> @@ -69,9 +69,9 @@ class MessagePassingInterface; class WebContentsAdapterPrivate; class FaviconManager; -class QWEBENGINE_EXPORT WebContentsAdapter : public QSharedData { +class QWEBENGINE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<WebContentsAdapter> { public: - static QExplicitlySharedDataPointer<WebContentsAdapter> createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient); + static QSharedPointer<WebContentsAdapter> createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient); // Takes ownership of the WebContents. WebContentsAdapter(content::WebContents *webContents = 0); ~WebContentsAdapter(); diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 3118c36b1..31786a8f8 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -218,7 +218,7 @@ public: virtual void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) = 0; virtual void focusContainer() = 0; virtual void unhandledKeyEvent(QKeyEvent *event) = 0; - virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0; + virtual void adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0; virtual bool isBeingAdopted() = 0; virtual void close() = 0; virtual void windowCloseRejected() = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 2dd75df83..b96452093 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -100,7 +100,7 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents { content::WebContents *target = source; if (params.disposition != CURRENT_TAB) { - WebContentsAdapter *targetAdapter = createWindow(0, params.disposition, gfx::Rect(), params.user_gesture); + QSharedPointer<WebContentsAdapter> targetAdapter = createWindow(0, params.disposition, gfx::Rect(), params.user_gesture); if (targetAdapter) target = targetAdapter->webContents(); } @@ -152,7 +152,7 @@ bool WebContentsDelegateQt::ShouldPreserveAbortedURLs(content::WebContents *sour void WebContentsDelegateQt::AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked) { Q_UNUSED(source) - WebContentsAdapter *newAdapter = createWindow(new_contents, disposition, initial_pos, user_gesture); + QWeakPointer<WebContentsAdapter> newAdapter = createWindow(new_contents, disposition, initial_pos, user_gesture); if (was_blocked) *was_blocked = !newAdapter; } @@ -389,20 +389,13 @@ void WebContentsDelegateQt::overrideWebPreferences(content::WebContents *, conte m_viewClient->webEngineSettings()->overrideWebPreferences(webPreferences); } -WebContentsAdapter *WebContentsDelegateQt::createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture) +QWeakPointer<WebContentsAdapter> WebContentsDelegateQt::createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture) { - WebContentsAdapter *newAdapter = new WebContentsAdapter(new_contents); - // Do the first ref-count manually to be able to know if the application is handling adoptNewWindow through the public API. - newAdapter->ref.ref(); + QSharedPointer<WebContentsAdapter> newAdapter = QSharedPointer<WebContentsAdapter>::create(new_contents); m_viewClient->adoptNewWindow(newAdapter, static_cast<WebContentsAdapterClient::WindowOpenDisposition>(disposition), user_gesture, toQt(initial_pos)); - if (!newAdapter->ref.deref()) { - // adoptNewWindow didn't increase the ref-count, newAdapter and its new_contents (if non-null) need to be discarded. - delete newAdapter; - newAdapter = 0; - } - + // If the client didn't reference the adapter, it will be deleted now, and the weak pointer zeroed. return newAdapter; } diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index b60f31ac3..9aa584369 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -146,7 +146,7 @@ public: const SavePageInfo &savePageInfo() { return m_savePageInfo; } private: - WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); + QWeakPointer<WebContentsAdapter> createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); WebContentsAdapterClient *m_viewClient; QString m_lastSearchedString; diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 43dc943e7..329f9c9db 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -86,8 +86,10 @@ #include "web_engine_library_info.h" #include <QFileInfo> #include <QGuiApplication> +#include <QOffscreenSurface> #include <QOpenGLContext> #include <QStringList> +#include <QSurfaceFormat> #include <QVector> #include <qpa/qplatformnativeinterface.h> @@ -301,15 +303,40 @@ WebEngineContext::WebEngineContext() GLContextHelper::initialize(); - if (usingANGLE() || usingSoftwareDynamicGL() || usingQtQuick2DRenderer()) { - parsedCommandLine->AppendSwitch(switches::kDisableGpu); - } else { - const char *glType = 0; + const char *glType = 0; + if (!usingANGLE() && !usingSoftwareDynamicGL() && !usingQtQuick2DRenderer()) { if (qt_gl_global_share_context()) { - if (qt_gl_global_share_context()->isOpenGLES()) { - glType = gfx::kGLImplementationEGLName; + if (!strcmp(qt_gl_global_share_context()->nativeHandle().typeName(), "QEGLNativeContext")) { + if (qt_gl_global_share_context()->isOpenGLES()) { + glType = gfx::kGLImplementationEGLName; + } else { + QOpenGLContext context; + QSurfaceFormat format; + + format.setRenderableType(QSurfaceFormat::OpenGLES); + format.setVersion(2, 0); + + context.setFormat(format); + context.setShareContext(qt_gl_global_share_context()); + if (context.create()) { + QOffscreenSurface surface; + + surface.setFormat(format); + surface.create(); + + if (context.makeCurrent(&surface)) { + if (context.hasExtension("GL_ARB_ES2_compatibility")) + glType = gfx::kGLImplementationEGLName; + + context.doneCurrent(); + } + + surface.destroy(); + } + } } else { - glType = gfx::kGLImplementationDesktopName; + if (!qt_gl_global_share_context()->isOpenGLES()) + glType = gfx::kGLImplementationDesktopName; } } else { qWarning("WebEngineContext used before QtWebEngine::initialize()"); @@ -323,9 +350,12 @@ WebEngineContext::WebEngineContext() break; } } + } + if (glType) parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType); - } + else + parsedCommandLine->AppendSwitch(switches::kDisableGpu); content::UtilityProcessHostImpl::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread); content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread); diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index a81a26d16..2be59d1c6 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -154,33 +154,6 @@ QString subProcessPath() return processPath; } -QString pluginsPath() -{ -#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) - static QString pluginsPath = getPath(frameworkBundle()) % QLatin1String("/Libraries"); -#else - static bool initialized = false; - static QString pluginsPath; - - if (!initialized) { - initialized = true; - const QStringList directories = QCoreApplication::libraryPaths(); - Q_FOREACH (const QString &dir, directories) { - const QString candidate = dir % "/" % QLatin1String("qtwebengine"); - if (QFileInfo::exists(candidate)) { - pluginsPath = candidate; - break; - } - } - - if (pluginsPath.isEmpty()) { - pluginsPath = fallbackDir(); - } - } -#endif - return pluginsPath; -} - QString localesPath() { #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) @@ -306,8 +279,6 @@ base::FilePath WebEngineLibraryInfo::getPath(int key) break; case base::DIR_QT_LIBRARY_DATA: return toFilePath(icuDataPath()); - case content::DIR_MEDIA_LIBS: - return toFilePath(pluginsPath()); case ui::DIR_LOCALES: return toFilePath(localesPath()); #if defined(ENABLE_SPELLCHECK) diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h index b623f1ec2..e21eee8a9 100644 --- a/src/core/web_engine_settings.h +++ b/src/core/web_engine_settings.h @@ -42,7 +42,6 @@ #include "qtwebenginecoreglobal.h" -#include <QExplicitlySharedDataPointer> #include <QScopedPointer> #include <QHash> #include <QUrl> diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 505a684eb..80850af70 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -492,6 +492,19 @@ static WebMouseEvent::Button mouseButtonForEvent(QMouseEvent *event) return WebMouseEvent::ButtonRight; else if (event->button() == Qt::MidButton) return WebMouseEvent::ButtonMiddle; + + if (event->type() != QEvent::MouseMove) + return WebMouseEvent::ButtonNone; + + // This is technically wrong, mouse move should always have ButtonNone, + // but it is consistent with aura and selection code depends on it: + if (event->buttons() & Qt::LeftButton) + return WebMouseEvent::ButtonLeft; + else if (event->buttons() & Qt::RightButton) + return WebMouseEvent::ButtonRight; + else if (event->buttons() & Qt::MidButton) + return WebMouseEvent::ButtonMiddle; + return WebMouseEvent::ButtonNone; } @@ -659,14 +672,11 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, doub webEvent.modifiers = modifiersForEvent(ev); webEvent.timeStampSeconds = currentTimeForEvent(ev); - if (ev->orientation() == Qt::Horizontal) - webEvent.wheelTicksX = ev->delta() / 120.0f; - else - webEvent.wheelTicksY = ev->delta() / 120.0f; - + webEvent.wheelTicksX = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheelTicksY = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; - // Since we report the scroll by the pixel, convert the delta to pixel distance using standard scroll step. - // Use the same single scroll step as QTextEdit (in QTextEditPrivate::init [h,v]bar->setSingleStep) + // We can't use the device specific QWheelEvent::pixelDelta(), so we calculate + // a pixel delta based on ticks and scroll per line. static const float cDefaultQtScrollStep = 20.f; webEvent.deltaX = webEvent.wheelTicksX * wheelScrollLines * cDefaultQtScrollStep; |