diff options
Diffstat (limited to 'src/core')
22 files changed, 337 insertions, 207 deletions
diff --git a/src/core/config/common.pri b/src/core/config/common.pri index e7010a13a..d8a4fa181 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -12,9 +12,10 @@ gn_args += \ v8_use_external_startup_data=false \ treat_warnings_as_errors=false \ enable_swiftshader=false \ - use_custom_libcxx=false + use_custom_libcxx=false \ + use_jumbo_build=true -qtConfig(printing-and-pdf) { +qtConfig(webengine-printing-and-pdf) { gn_args += enable_basic_printing=true enable_print_preview=true gn_args += enable_pdf=true } else { @@ -22,25 +23,25 @@ qtConfig(printing-and-pdf) { gn_args += enable_pdf=false } -qtConfig(pepper-plugins) { +qtConfig(webengine-pepper-plugins) { gn_args += enable_plugins=true enable_widevine=true } else { gn_args += enable_plugins=false enable_widevine=false } -qtConfig(spellchecker) { +qtConfig(webengine-spellchecker) { gn_args += enable_spellcheck=true } else { gn_args += enable_spellcheck=false } -qtConfig(webrtc) { +qtConfig(webengine-webrtc) { gn_args += enable_webrtc=true } else { gn_args += enable_webrtc=false } -qtConfig(proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" +qtConfig(webengine-proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" CONFIG(release, debug|release) { force_debug_info { diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index 78f3e5093..6f7b27f10 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -112,23 +112,26 @@ host_build { # Strip '>2 /dev/null' from $$pkgConfigExecutable() PKGCONFIG = $$first($$list($$pkgConfigExecutable())) gn_args += pkg_config=\"$$PKGCONFIG\" - gn_args += host_pkg_config=\"pkg-config\" + PKG_CONFIG_HOST = $$(GN_PKG_CONFIG_HOST) + isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = pkg-config + gn_args += host_pkg_config=\"$$PKG_CONFIG_HOST\" } - qtConfig(webengine-system-zlib): qtConfig(system-minizip) { + qtConfig(webengine-system-zlib): qtConfig(webengine-system-minizip) { gn_args += use_system_zlib=true use_system_minizip=true + qtConfig(webengine-printing-and-pdf): gn_args += pdfium_use_system_zlib=true } qtConfig(webengine-system-png): gn_args += use_system_libpng=true qtConfig(system-jpeg): gn_args += use_system_libjpeg=true qtConfig(system-freetype): gn_args += use_system_freetype=true qtConfig(webengine-system-harfbuzz): gn_args += use_system_harfbuzz=true - qtConfig(system-glib): gn_args += use_glib=false - qtConfig(pulseaudio) { + qtConfig(webengine-system-glib): gn_args += use_glib=false + qtConfig(webengine-pulseaudio) { gn_args += use_pulseaudio=true } else { gn_args += use_pulseaudio=false } - qtConfig(alsa) { + qtConfig(webengine-alsa) { gn_args += use_alsa=true } else { gn_args += use_alsa=false @@ -138,18 +141,19 @@ host_build { !packagesExist(libpci): gn_args += use_libpci=false !packagesExist(xscrnsaver): gn_args += use_xscrnsaver=false - qtConfig(system-libevent): gn_args += use_system_libevent=true - qtConfig(system-libwebp): gn_args += use_system_libwebp=true - qtConfig(system-libxml2): gn_args += use_system_libxml=true use_system_libxslt=true - qtConfig(system-opus): gn_args += use_system_opus=true - qtConfig(system-snappy): gn_args += use_system_snappy=true - qtConfig(system-libvpx): gn_args += use_system_libvpx=true - qtConfig(system-icu): gn_args += use_system_icu=true icu_use_data_file=false - qtConfig(system-ffmpeg): gn_args += use_system_ffmpeg=true - qtConfig(system-re2): gn_args += use_system_re2=true + qtConfig(webengine-system-libevent): gn_args += use_system_libevent=true + qtConfig(webengine-system-libwebp): gn_args += use_system_libwebp=true + qtConfig(webengine-system-libxml2): gn_args += use_system_libxml=true use_system_libxslt=true + qtConfig(webengine-system-opus): gn_args += use_system_opus=true + qtConfig(webengine-system-snappy): gn_args += use_system_snappy=true + qtConfig(webengine-system-libvpx): gn_args += use_system_libvpx=true + qtConfig(webengine-system-icu): gn_args += use_system_icu=true icu_use_data_file=false + qtConfig(webengine-system-ffmpeg): gn_args += use_system_ffmpeg=true + qtConfig(webengine-system-re2): gn_args += use_system_re2=true + qtConfig(webengine-system-lcms2): gn_args += use_system_lcms2=true # FIXME: - #qtConfig(system-protobuf): gn_args += use_system_protobuf=true - #qtConfig(system-jsoncpp): gn_args += use_system_jsoncpp=true - #qtConfig(system-libsrtp: gn_args += use_system_libsrtp=true + #qtConfig(webengine-system-protobuf): gn_args += use_system_protobuf=true + #qtConfig(webengine-system-jsoncpp): gn_args += use_system_jsoncpp=true + #qtConfig(webengine-system-libsrtp: gn_args += use_system_libsrtp=true } diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri index 57f301f18..2d820c889 100644 --- a/src/core/config/mac_osx.pri +++ b/src/core/config/mac_osx.pri @@ -32,8 +32,8 @@ gn_args += \ toolkit_views=false \ use_external_popup_menu=false -qtConfig(spellchecker) { - qtConfig(native-spellchecker): gn_args += use_browser_spellchecker=true +qtConfig(webengine-spellchecker) { + qtConfig(webengine-native-spellchecker): gn_args += use_browser_spellchecker=true else: gn_args += use_browser_spellchecker=false } else { gn_args += use_browser_spellchecker=false diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 1016db0d5..a3a460cb4 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -236,6 +236,7 @@ void AddPepperWidevine(std::vector<content::PepperPluginInfo>* plugins) #elif defined(Q_OS_LINUX) pluginPaths << QStringLiteral("/opt/google/chrome/libwidevinecdmadapter.so") // Google Chrome << QStringLiteral("/usr/lib/chromium/libwidevinecdmadapter.so") // Arch + << QStringLiteral("/usr/lib/chromium-browser/libwidevinecdmadapter.so") // Ubuntu/neon << QStringLiteral("/usr/lib64/chromium/libwidevinecdmadapter.so"); // OpenSUSE style #endif } @@ -257,7 +258,7 @@ void AddPepperWidevine(std::vector<content::PepperPluginInfo>* plugins) std::vector<std::string> codecs; codecs.push_back(kCdmSupportedCodecVp8); codecs.push_back(kCdmSupportedCodecVp9); -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) codecs.push_back(kCdmSupportedCodecAvc1); #endif // defined(USE_PROPRIETARY_CODECS) std::string codec_string = diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index 179266900..513cd4c1f 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -28,7 +28,7 @@ RCC_DIR = $$OUT_PWD/$$getConfigDir()/.rcc # Assume that we want mobile touch and low-end hardware behaviors # whenever we are cross compiling. -qtConfig(embedded): DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES +qtConfig(webengine-embedded-build): DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES qtConfig(egl): CONFIG += egl @@ -79,7 +79,6 @@ SOURCES = \ quota_permission_controller.cpp \ render_view_observer_host_qt.cpp \ render_widget_host_view_qt.cpp \ - render_widget_host_view_qt_delegate.cpp \ renderer/content_renderer_client_qt.cpp \ renderer/render_frame_observer_qt.cpp \ renderer/render_view_observer_qt.cpp \ @@ -192,7 +191,7 @@ HEADERS = \ web_event_factory.h \ webui/webui_controller_factory_qt.h -qtConfig(pepper-plugins) { +qtConfig(webengine-pepper-plugins) { SOURCES += \ renderer_host/pepper/pepper_flash_browser_host_qt.cpp \ @@ -209,7 +208,7 @@ qtConfig(pepper-plugins) { renderer/pepper/pepper_renderer_host_factory_qt.h } -qtConfig(printing-and-pdf) { +qtConfig(webengine-printing-and-pdf) { SOURCES += \ printing_message_filter_qt.cpp \ diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 78bb8baee..2409ccb12 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -115,7 +115,7 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat resources.path = $$[QT_INSTALL_DATA]/resources INSTALLS += locales resources - !qtConfig(system-icu) { + !qtConfig(webengine-system-icu) { icu.CONFIG += no_check_exist icu.path = $$[QT_INSTALL_DATA]/resources INSTALLS += icu @@ -127,7 +127,7 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat # Copy essential files to the qtbase build directory for non-prefix builds # - !qtConfig(system-icu) { + !qtConfig(webengine-system-icu) { COPIES += icu } diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index d6ee87950..6f4a4e8db 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -218,14 +218,8 @@ public: void setupRenderPassNode(QSGTexture *layer, const QRect &rect, QSGNode *) override { + Q_ASSERT(layer); QSGInternalImageNode *imageNode = static_cast<QSGInternalImageNode*>(*m_nodeIterator++); - // In case of a missing render pass, set the target rects to be empty and return early. - // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes - if (!layer) { - imageNode->setTargetRect(QRect()); - imageNode->setInnerTargetRect(QRect()); - return; - } imageNode->setTargetRect(rect); imageNode->setInnerTargetRect(rect); imageNode->setTexture(layer); @@ -320,23 +314,16 @@ public: void setupRenderPassNode(QSGTexture *layer, const QRect &rect, QSGNode *layerChain) override { + Q_ASSERT(layer); // Only QSGInternalImageNode currently supports QSGLayer textures. QSGInternalImageNode *imageNode = m_apiDelegate->createImageNode(); - layerChain->appendChildNode(imageNode); - m_sceneGraphNodes->append(imageNode); - - // In case of a missing render pass, set the target rects to be empty and return early. - // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes - if (!layer) { - imageNode->setTargetRect(QRect()); - imageNode->setInnerTargetRect(QRect()); - return; - } - imageNode->setTargetRect(rect); imageNode->setInnerTargetRect(rect); imageNode->setTexture(layer); imageNode->update(); + + layerChain->appendChildNode(imageNode); + m_sceneGraphNodes->append(imageNode); } void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect, @@ -1110,7 +1097,8 @@ void DelegatedFrameNode::handleQuad( QSGTexture *layer = findRenderPassLayer(renderPassQuad->render_pass_id, m_sgObjects.renderPassLayers).data(); - nodeHandler->setupRenderPassNode(layer, toQt(quad->rect), currentLayerChain); + if (layer) + nodeHandler->setupRenderPassNode(layer, toQt(quad->rect), currentLayerChain); break; } case cc::DrawQuad::TEXTURE_CONTENT: { @@ -1263,6 +1251,8 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe QList<gl::TransferableFence> transferredFences; { QMutexLocker lock(&m_mutex); + QVector<MailboxTexture *> mailboxesToPull; + mailboxesToPull.reserve(mailboxesToFetch.size()); gpu::SyncPointManager *syncPointManager = sync_point_manager(); base::MessageLoop *gpuMessageLoop = gpu_message_loop(); @@ -1271,9 +1261,12 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) { gpu::SyncToken &syncToken = mailboxTexture->mailboxHolder().sync_token; const auto task = base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture); - if (syncPointManager->WaitOutOfOrderNonThreadSafe(syncToken, gpuMessageLoop->task_runner(), task)) - continue; - gpuMessageLoop->task_runner()->PostTask(FROM_HERE, task); + if (!syncPointManager->WaitOutOfOrderNonThreadSafe(syncToken, gpuMessageLoop->task_runner(), std::move(task))) + mailboxesToPull.append(mailboxTexture); + } + if (!mailboxesToPull.isEmpty()) { + auto task = base::BindOnce(&DelegatedFrameNode::pullTextures, this, std::move(mailboxesToPull)); + gpuMessageLoop->task_runner()->PostTask(FROM_HERE, std::move(task)); } m_mailboxesFetchedWaitCond.wait(&m_mutex); @@ -1349,6 +1342,25 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe } +void DelegatedFrameNode::pullTextures(DelegatedFrameNode *frameNode, const QVector<MailboxTexture *> textures) +{ +#ifndef QT_NO_OPENGL + gpu::gles2::MailboxManager *mailboxManager = mailbox_manager(); + for (MailboxTexture *texture : textures) { + gpu::SyncToken &syncToken = texture->mailboxHolder().sync_token; + if (syncToken.HasData()) + mailboxManager->PullTextureUpdates(syncToken); + texture->fetchTexture(mailboxManager); + --frameNode->m_numPendingSyncPoints; + } + + fenceAndUnlockQt(frameNode); +#else + Q_UNUSED(frameNode) + Q_UNUSED(textures) +#endif +} + void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *texture) { #ifndef QT_NO_OPENGL @@ -1357,6 +1369,18 @@ void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTextu if (syncToken.HasData()) mailboxManager->PullTextureUpdates(syncToken); texture->fetchTexture(mailboxManager); + --frameNode->m_numPendingSyncPoints; + + fenceAndUnlockQt(frameNode); +#else + Q_UNUSED(frameNode) + Q_UNUSED(texture) +#endif +} + +void DelegatedFrameNode::fenceAndUnlockQt(DelegatedFrameNode *frameNode) +{ +#ifndef QT_NO_OPENGL if (!!gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) { // Create a fence on the Chromium GPU-thread and context gl::GLFence *fence = gl::GLFence::Create(); @@ -1364,15 +1388,14 @@ void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTextu frameNode->m_textureFences.append(fence->Transfer()); delete fence; } - if (--frameNode->m_numPendingSyncPoints == 0) - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::fenceAndUnlockQt, frameNode)); + if (frameNode->m_numPendingSyncPoints == 0) + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::unlockQt, frameNode)); #else Q_UNUSED(frameNode) - Q_UNUSED(texture) #endif } -void DelegatedFrameNode::fenceAndUnlockQt(DelegatedFrameNode *frameNode) +void DelegatedFrameNode::unlockQt(DelegatedFrameNode *frameNode) { QMutexLocker lock(&frameNode->m_mutex); // Signal preprocess() the textures are ready diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h index c627cdf95..4bddf4a62 100644 --- a/src/core/delegated_frame_node.h +++ b/src/core/delegated_frame_node.h @@ -123,7 +123,9 @@ private: // Making those callbacks static bypasses base::Bind's ref-counting requirement // of the this pointer when the callback is a method. static void pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *mailbox); + static void pullTextures(DelegatedFrameNode *frameNode, const QVector<MailboxTexture *> mailboxes); static void fenceAndUnlockQt(DelegatedFrameNode *frameNode); + static void unlockQt(DelegatedFrameNode *frameNode); ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); void holdResources(const cc::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro index a9089c569..dbf859100 100644 --- a/src/core/gn_run.pro +++ b/src/core/gn_run.pro @@ -5,7 +5,7 @@ TEMPLATE = aux qtConfig(debug_and_release): CONFIG += debug_and_release build_all -qtConfig(system-ninja) { +qtConfig(webengine-system-ninja) { QT_TOOL.ninja.binary = ninja } else { QT_TOOL.ninja.binary = $$shell_quote($$shell_path($$ninjaPath())) @@ -35,7 +35,7 @@ build_pass|!debug_and_release { gn_args += "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\"" - !qtConfig(system-gn) { + !qtConfig(webengine-system-gn) { gn_binary = $$system_quote($$system_path($$gnPath())) } diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index a12dea6ad..e084de463 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -73,6 +73,7 @@ #include "ui/events/event.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" #include "ui/events/gesture_detection/motion_event.h" +#include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/geometry/size_conversions.h" #if defined(USE_AURA) @@ -97,6 +98,9 @@ #include <QVariant> #include <QWheelEvent> #include <QWindow> +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) +#include <QtGui/private/qinputcontrol_p.h> +#endif #include <QtGui/qaccessible.h> namespace QtWebEngineCore { @@ -184,6 +188,59 @@ static inline bool compareTouchPoints(const QTouchEvent::TouchPoint &lhs, const return lhs.state() < rhs.state(); } +static inline bool isCommonTextEditShortcut(const QKeyEvent *ke) +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + return QInputControl::isCommonTextEditShortcut(ke); +#else + if (ke->modifiers() == Qt::NoModifier + || ke->modifiers() == Qt::ShiftModifier + || ke->modifiers() == Qt::KeypadModifier) { + if (ke->key() < Qt::Key_Escape) { + return true; + } else { + switch (ke->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Delete: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_Backspace: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Tab: + return true; + default: + break; + } + } + } else if (ke->matches(QKeySequence::Copy) + || ke->matches(QKeySequence::Paste) + || ke->matches(QKeySequence::Cut) + || ke->matches(QKeySequence::Redo) + || ke->matches(QKeySequence::Undo) + || ke->matches(QKeySequence::MoveToNextWord) + || ke->matches(QKeySequence::MoveToPreviousWord) + || ke->matches(QKeySequence::MoveToStartOfDocument) + || ke->matches(QKeySequence::MoveToEndOfDocument) + || ke->matches(QKeySequence::SelectNextWord) + || ke->matches(QKeySequence::SelectPreviousWord) + || ke->matches(QKeySequence::SelectStartOfLine) + || ke->matches(QKeySequence::SelectEndOfLine) + || ke->matches(QKeySequence::SelectStartOfBlock) + || ke->matches(QKeySequence::SelectEndOfBlock) + || ke->matches(QKeySequence::SelectStartOfDocument) + || ke->matches(QKeySequence::SelectEndOfDocument) + || ke->matches(QKeySequence::SelectAll) + ) { + return true; + } + return false; +#endif +} + static uint32_t s_eventId = 0; class MotionEventQt : public ui::MotionEvent { public: @@ -234,7 +291,7 @@ public: float GetHistoricalTouchMajor(size_t pointer_index, size_t historical_index) const override { return 0; } float GetHistoricalX(size_t pointer_index, size_t historical_index) const override { return 0; } float GetHistoricalY(size_t pointer_index, size_t historical_index) const override { return 0; } - ToolType GetToolType(size_t pointer_index) const override { return ui::MotionEvent::TOOL_TYPE_UNKNOWN; } + ToolType GetToolType(size_t pointer_index) const override { return ui::MotionEvent::TOOL_TYPE_FINGER; } int GetButtonState() const override { return 0; } private: @@ -934,6 +991,41 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) Q_ASSERT(m_host->GetView()); switch (event->type()) { + case QEvent::ShortcutOverride: { + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); + + auto acceptKeyOutOfInputField = [](QKeyEvent *keyEvent) -> bool { +#ifdef Q_OS_MACOS + // Try triggering a registered shortcut + if (QGuiApplicationPrivate::instance()->shortcutMap.tryShortcut(keyEvent)) + return false; + + // The following shortcuts are handled out of input field too but + // disabled on macOS to let the blinking menu handling to the + // embedder application (see kKeyboardCodeKeyDownEntries in + // third_party/WebKit/Source/core/editing/EditingBehavior.cpp). + // Let them pass on macOS to generate the corresponding edit command. + return keyEvent->matches(QKeySequence::Copy) + || keyEvent->matches(QKeySequence::Paste) + || keyEvent->matches(QKeySequence::Cut) + || keyEvent->matches(QKeySequence::SelectAll); +#else + return false; +#endif + }; + + if (!inputMethodQuery(Qt::ImEnabled).toBool() && !acceptKeyOutOfInputField(keyEvent)) + return false; + + Q_ASSERT(m_editCommand.empty()); + if (WebEventFactory::getEditCommand(keyEvent, &m_editCommand) + || isCommonTextEditShortcut(keyEvent)) { + event->accept(); + return true; + } + + return false; + } case QEvent::MouseButtonPress: Focus(); // Fall through. case QEvent::MouseButtonRelease: @@ -982,6 +1074,10 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) case QEvent::InputMethodQuery: handleInputMethodQueryEvent(static_cast<QInputMethodQueryEvent*>(event)); break; + case QEvent::HoverLeave: + case QEvent::Leave: + m_host->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(event)); + break; default: return false; } @@ -1127,6 +1223,16 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev) } content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev); + if (webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && !m_editCommand.empty()) { + ui::LatencyInfo latency; + latency.set_source_event_type(ui::SourceEventType::KEY_PRESS); + content::EditCommands commands; + commands.emplace_back(m_editCommand, ""); + m_editCommand.clear(); + m_host->ForwardKeyboardEventWithCommands(webEvent, latency, &commands, nullptr); + return; + } + bool keyDownTextInsertion = webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && webEvent.text[0]; webEvent.skip_in_browser = keyDownTextInsertion; m_host->ForwardKeyboardEvent(webEvent); diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index c896cf058..1ac32456a 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -278,6 +278,8 @@ private: bool m_wheelAckPending; QList<blink::WebMouseWheelEvent> m_pendingWheelEvents; + + std::string m_editCommand; }; } // namespace QtWebEngineCore diff --git a/src/core/render_widget_host_view_qt_delegate.cpp b/src/core/render_widget_host_view_qt_delegate.cpp deleted file mode 100644 index a86900433..000000000 --- a/src/core/render_widget_host_view_qt_delegate.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render_widget_host_view_qt_delegate.h" - -#include <QtCore/qvariant.h> -#include <QtGui/qevent.h> - -#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) -#include <QtGui/private/qinputcontrol_p.h> -#endif - -static bool isCommonTextEditShortcut(const QKeyEvent *ke) -{ -#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) - return QInputControl::isCommonTextEditShortcut(ke); -#else - if (ke->modifiers() == Qt::NoModifier - || ke->modifiers() == Qt::ShiftModifier - || ke->modifiers() == Qt::KeypadModifier) { - if (ke->key() < Qt::Key_Escape) { - return true; - } else { - switch (ke->key()) { - case Qt::Key_Return: - case Qt::Key_Enter: - case Qt::Key_Delete: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Backspace: - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Tab: - return true; - default: - break; - } - } - } else if (ke->matches(QKeySequence::Copy) - || ke->matches(QKeySequence::Paste) - || ke->matches(QKeySequence::Cut) - || ke->matches(QKeySequence::Redo) - || ke->matches(QKeySequence::Undo) - || ke->matches(QKeySequence::MoveToNextWord) - || ke->matches(QKeySequence::MoveToPreviousWord) - || ke->matches(QKeySequence::MoveToStartOfDocument) - || ke->matches(QKeySequence::MoveToEndOfDocument) - || ke->matches(QKeySequence::SelectNextWord) - || ke->matches(QKeySequence::SelectPreviousWord) - || ke->matches(QKeySequence::SelectStartOfLine) - || ke->matches(QKeySequence::SelectEndOfLine) - || ke->matches(QKeySequence::SelectStartOfBlock) - || ke->matches(QKeySequence::SelectEndOfBlock) - || ke->matches(QKeySequence::SelectStartOfDocument) - || ke->matches(QKeySequence::SelectEndOfDocument) - || ke->matches(QKeySequence::SelectAll) - ) { - return true; - } - return false; -#endif -} - -namespace QtWebEngineCore { - -bool RenderWidgetHostViewQtDelegateClient::handleShortcutOverrideEvent(QKeyEvent *event) -{ - if (inputMethodQuery(Qt::ImEnabled).toBool() && isCommonTextEditShortcut(event)) { - event->accept(); - return true; - } - return false; -} - -} // namespace QtWebEngineCore diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index a126410ed..bcd0f49f7 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -48,7 +48,6 @@ QT_BEGIN_NAMESPACE class QCursor; class QEvent; -class QKeyEvent; class QPainter; class QSGLayer; class QSGNode; @@ -79,7 +78,6 @@ public: virtual void windowChanged() = 0; virtual bool forwardEvent(QEvent *) = 0; virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) = 0; - virtual bool handleShortcutOverrideEvent(QKeyEvent *event); }; class QWEBENGINE_EXPORT RenderWidgetHostViewQtDelegate { diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index 83c4d719e..5980d7b84 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -262,11 +262,11 @@ public: return true; case media::EmeInitDataType::CENC: -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) return true; #else return false; -#endif // defined(USE_PROPRIETARY_CODECS) +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) case media::EmeInitDataType::UNKNOWN: return false; @@ -277,7 +277,7 @@ public: media::SupportedCodecs GetSupportedCodecs() const override { -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) return media::EME_CODEC_MP4_ALL | media::EME_CODEC_WEBM_ALL; #else return media::EME_CODEC_WEBM_ALL; @@ -390,10 +390,10 @@ static void AddPepperBasedWidevine(std::vector<std::unique_ptr<media::KeySystemP supported_codecs |= media::EME_CODEC_WEBM_VORBIS; supported_codecs |= media::EME_CODEC_WEBM_VP8; supported_codecs |= media::EME_CODEC_WEBM_VP9; -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) supported_codecs |= media::EME_CODEC_MP4_AVC1; supported_codecs |= media::EME_CODEC_MP4_AAC; -#endif // defined(USE_PROPRIETARY_CODECS) +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) using Robustness = cdm::WidevineKeySystemProperties::Robustness; concrete_key_systems->emplace_back(new cdm::WidevineKeySystemProperties( diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index 8374a8e6b..534ee302d 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -186,7 +186,7 @@ void WebChannelIPCTransport::installWebChannel(uint worldId) void WebChannelIPCTransport::uninstallWebChannel(uint worldId) { - Q_ASSERT(worldId = m_installedWorldId); + Q_ASSERT(worldId == m_installedWorldId); blink::WebView *webView = render_view()->GetWebView(); if (!webView) return; diff --git a/src/core/url_request_qrc_job_qt.cpp b/src/core/url_request_qrc_job_qt.cpp index b4e960921..a2712653d 100644 --- a/src/core/url_request_qrc_job_qt.cpp +++ b/src/core/url_request_qrc_job_qt.cpp @@ -112,7 +112,7 @@ int URLRequestQrcJobQt::ReadRawData(IOBuffer *buf, int bufSize) void URLRequestQrcJobQt::startGetHead() { // Get qrc file path. - QString qrcFilePath = ':' + toQt(request_->url()).path(QUrl::RemovePath | QUrl::RemoveQuery); + QString qrcFilePath = ':' + toQt(request_->url()).path(); m_file.setFileName(qrcFilePath); QFileInfo qrcFileInfo(m_file); // Get qrc file mime type. diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 6576a9c3b..68481dccc 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -600,6 +600,8 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) } d->webContents->GetController().LoadURLWithParams(params); + // Follow chrome::Navigate and invalidate the URL immediately. + d->webContentsDelegate->NavigationStateChanged(d->webContents.get(), content::INVALIDATE_TYPE_URL); focusIfNecessary(); } @@ -641,7 +643,7 @@ void WebContentsAdapter::save(const QString &filePath, int savePageFormat) QUrl WebContentsAdapter::activeUrl() const { Q_D(const WebContentsAdapter); - return toQt(d->webContents->GetLastCommittedURL()); + return d->webContentsDelegate->url(); } QUrl WebContentsAdapter::requestedUrl() const @@ -676,7 +678,7 @@ QUrl WebContentsAdapter::iconUrl() const QString WebContentsAdapter::pageTitle() const { Q_D(const WebContentsAdapter); - return toQt(d->webContents->GetTitle()); + return d->webContentsDelegate->title(); } QString WebContentsAdapter::selectedText() const @@ -1469,6 +1471,12 @@ void WebContentsAdapter::focusIfNecessary() d->webContents->Focus(); } +bool WebContentsAdapter::isFindTextInProgress() const +{ + Q_D(const WebContentsAdapter); + return d->lastFindRequestId != d->webContentsDelegate->lastReceivedFindReply(); +} + WebContentsAdapterClient::RenderProcessTerminationStatus WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) { auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 67fcbe7af..51fd2891d 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -184,6 +184,7 @@ public: void viewSource(); bool canViewSource(); void focusIfNecessary(); + bool isFindTextInProgress() const; private: diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 54aeac710..25aa9ae04 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -132,10 +132,21 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) { - if (changed_flags & content::INVALIDATE_TYPE_URL) - m_viewClient->urlChanged(toQt(source->GetVisibleURL())); - if (changed_flags & content::INVALIDATE_TYPE_TITLE) - m_viewClient->titleChanged(toQt(source->GetTitle())); + if (changed_flags & content::INVALIDATE_TYPE_URL) { + QUrl newUrl = toQt(source->GetVisibleURL()); + if (m_url != newUrl) { + m_url = newUrl; + m_viewClient->urlChanged(m_url); + } + } + + if (changed_flags & content::INVALIDATE_TYPE_TITLE) { + QString newTitle = toQt(source->GetTitle()); + if (m_title != newTitle) { + m_title = newTitle; + m_viewClient->titleChanged(m_title); + } + } // NavigationStateChanged gets called with INVALIDATE_TYPE_TAB by AudioStateProvider::Notify, // whenever an audio sound gets played or stopped, this is the only way to actually figure out @@ -147,20 +158,6 @@ void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source, } } -bool WebContentsDelegateQt::ShouldPreserveAbortedURLs(content::WebContents *source) -{ - Q_UNUSED(source) - - // Allow failed URLs to stick around in the URL bar, but only when the error-page is enabled. - WebEngineSettings *settings = m_viewClient->webEngineSettings(); - bool isErrorPageEnabled = settings->testAttribute(settings->Attribute::ErrorPageEnabled); - - if (isErrorPageEnabled) - return true; - - return false; -} - 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) diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 87b7271f6..87704d3c6 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -97,6 +97,9 @@ public: void setLastSearchedString(const QString &s) { m_lastSearchedString = s; } int lastReceivedFindReply() const { return m_lastReceivedFindReply; } + QUrl url() const { return m_url; } + QString title() const { return m_title; } + // WebContentsDelegate overrides content::WebContents *OpenURLFromTab(content::WebContents *source, const content::OpenURLParams ¶ms) override; void NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) override; @@ -119,7 +122,6 @@ public: bool IsPopupOrPanel(const content::WebContents *source) const override; void UpdateTargetURL(content::WebContents* source, const GURL& url) override; void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) override; - bool ShouldPreserveAbortedURLs(content::WebContents *source) override; void ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text) override; void HideValidationMessage(content::WebContents *web_contents) override; void MoveValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view) override; @@ -165,6 +167,9 @@ private: QSharedPointer<FilePickerController> m_filePickerController; QUrl m_initialTargetUrl; int m_lastLoadProgress; + + QUrl m_url; + QString m_title; }; } // namespace QtWebEngineCore diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 2e0323f6d..4241a11c2 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -1020,12 +1020,14 @@ static ui::DomKey getDomKeyFromQKeyEvent(QKeyEvent *ev) } } -static inline double currentTimeForEvent(const QInputEvent* event) +static inline double currentTimeForEvent(const QEvent *event) { Q_ASSERT(event); - if (event->timestamp()) - return static_cast<double>(event->timestamp()) / 1000; + if (const QInputEvent *inputEvent = static_cast<const QInputEvent *>(event)) { + if (inputEvent->timestamp()) + return static_cast<double>(inputEvent->timestamp()) / 1000; + } static QElapsedTimer timer; if (!timer.isValid()) @@ -1209,6 +1211,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale) webKitEvent.button = mouseButtonForEvent<QMouseEvent>(ev); webKitEvent.click_count = 0; + webKitEvent.pointer_type = WebPointerProperties::PointerType::kMouse; return webKitEvent; } @@ -1223,6 +1226,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale) webKitEvent.SetPositionInWidget(ev->pos().x() / dpiScale, ev->pos().y() / dpiScale); webKitEvent.movement_x = ev->pos().x() - ev->oldPos().x(); webKitEvent.movement_y = ev->pos().y() - ev->oldPos().y(); + webKitEvent.pointer_type = WebPointerProperties::PointerType::kMouse; return webKitEvent; } @@ -1246,7 +1250,16 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev, double dpiScale webKitEvent.button = mouseButtonForEvent<QTabletEvent>(ev); webKitEvent.click_count = 0; + return webKitEvent; +} + +WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev) +{ + Q_ASSERT(ev->type() == QEvent::Leave || ev->type() == QEvent::HoverLeave); + WebMouseEvent webKitEvent; + webKitEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webKitEvent.SetType(WebInputEvent::kMouseLeave); return webKitEvent; } @@ -1370,3 +1383,83 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e return webKitEvent; } + +bool WebEventFactory::getEditCommand(QKeyEvent *event, std::string *editCommand) +{ + // Assign Qt standard key bindings to blink editor commands. Editor command names + // come from chromium/third_party/WebKit/Source/editing/commands/EditorCommandNames.h + static struct { + QKeySequence::StandardKey standardKey; + std::string name; + } editCommands[] = { + { QKeySequence::Delete, "Delete" }, + { QKeySequence::Cut, "Cut" }, + { QKeySequence::Copy, "Copy" }, + { QKeySequence::Paste, "Paste" }, + { QKeySequence::Undo, "Undo" }, + { QKeySequence::Redo, "Redo" }, + { QKeySequence::SelectAll, "SelectAll" }, + { QKeySequence::Bold, "Bold" }, + { QKeySequence::Italic, "Italic" }, + { QKeySequence::Underline, "Underline" }, + + { QKeySequence::MoveToNextChar, "MoveRight" }, + { QKeySequence::MoveToPreviousChar, "MoveLeft" }, + { QKeySequence::MoveToNextWord, "MoveWordForward" }, + { QKeySequence::MoveToPreviousWord, "MoveWordBackward" }, + { QKeySequence::MoveToNextLine, "MoveDown" }, + { QKeySequence::MoveToPreviousLine, "MoveUp" }, + { QKeySequence::MoveToNextPage, "MovePageDown" }, + { QKeySequence::MoveToPreviousPage, "MovePageUp" }, + { QKeySequence::MoveToStartOfLine, "MoveToBeginningOfLine" }, + { QKeySequence::MoveToEndOfLine, "MoveToEndOfLine" }, + { QKeySequence::MoveToStartOfBlock, "MoveToBeginningOfParagraph" }, + { QKeySequence::MoveToEndOfBlock, "MoveToEndOfParagraph" }, + { QKeySequence::MoveToStartOfDocument, "MoveToBeginningOfDocument" }, + { QKeySequence::MoveToEndOfDocument, "MoveToEndOfDocument" }, + + { QKeySequence::SelectNextChar, "MoveRightAndModifySelection" }, + { QKeySequence::SelectPreviousChar, "MoveLeftAndModifySelection" }, + { QKeySequence::SelectNextWord, "MoveWordForwardAndModifySelection" }, + { QKeySequence::SelectPreviousWord, "MoveWordBackwardAndModifySelection" }, + { QKeySequence::SelectNextLine, "MoveDownAndModifySelection" }, + { QKeySequence::SelectPreviousLine, "MoveUpAndModifySelection" }, + { QKeySequence::SelectNextPage, "MovePageDownAndModifySelection" }, + { QKeySequence::SelectPreviousPage, "MovePageUpAndModifySelection" }, + { QKeySequence::SelectStartOfLine, "MoveToBeginningOfLineAndModifySelection" }, + { QKeySequence::SelectEndOfLine, "MoveToEndOfLineAndModifySelection" }, + { QKeySequence::SelectStartOfBlock, "MoveToBeginningOfParagraphAndModifySelection" }, + { QKeySequence::SelectEndOfBlock, "MoveToEndOfParagraphAndModifySelection" }, + { QKeySequence::SelectStartOfDocument, "MoveToBeginningOfDocumentAndModifySelection" }, + { QKeySequence::SelectEndOfDocument, "MoveToEndOfDocumentAndModifySelection" }, + + { QKeySequence::DeleteStartOfWord, "DeleteWordBackward" }, + { QKeySequence::DeleteEndOfWord, "DeleteWordForward" }, + { QKeySequence::DeleteEndOfLine, "DeleteToEndOfLine" }, + { QKeySequence::Deselect, "Unselect" }, + { QKeySequence::Backspace, "BackwardDelete" }, + + { QKeySequence::UnknownKey, "" } + }; + + for (int i = 0; editCommands[i].standardKey != QKeySequence::UnknownKey; ++i) { + if (event == editCommands[i].standardKey) { + *editCommand = editCommands[i].name; + return true; + } + } + +#ifdef Q_OS_MACOS + Qt::KeyboardModifier cmdKey = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) ? + Qt::MetaModifier : + Qt::ControlModifier; + if ((event->modifiers() & ~Qt::ShiftModifier) == cmdKey) { + if (event->key() == Qt::Key_Backspace) { + *editCommand = "DeleteToBeginningOfLine"; + return true; + } + } +#endif + + return false; +} diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h index ca0f6035f..442f04054 100644 --- a/src/core/web_event_factory.h +++ b/src/core/web_event_factory.h @@ -50,6 +50,7 @@ #include <QtGlobal> QT_BEGIN_NAMESPACE +class QEvent; class QHoverEvent; class QKeyEvent; class QMouseEvent; @@ -66,12 +67,14 @@ public: static blink::WebMouseEvent toWebMouseEvent(QMouseEvent*, double dpiScale); static blink::WebMouseEvent toWebMouseEvent(QHoverEvent*, double dpiScale); static blink::WebMouseEvent toWebMouseEvent(QTabletEvent*, double dpiScale); + static blink::WebMouseEvent toWebMouseEvent(QEvent *); #ifndef QT_NO_GESTURES static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *, double dpiScale); #endif static blink::WebMouseWheelEvent toWebWheelEvent(QWheelEvent*, double dpiScale); static bool coalesceWebWheelEvent(blink::WebMouseWheelEvent &, QWheelEvent*, double dpiScale); static content::NativeWebKeyboardEvent toWebKeyboardEvent(QKeyEvent*); + static bool getEditCommand(QKeyEvent *event, std::string *editCommand); }; |