summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2024-06-11 13:21:32 +0300
committerTarja Sundqvist <tarja.sundqvist@qt.io>2024-06-11 13:31:01 +0300
commit3cd4e0aa7961889eb06374885ed648f5b9bd85bc (patch)
tree6a089aedea155b1f1a74b553f4d1b57c70554a8f
parent6d029165d1593c514db08c34d6b08a00a4435d5e (diff)
parent38063a6332b9f948a0381763271e9a9ac7af0999 (diff)
Merge tag 'v6.2.9-lts' into tqtc/lts-6.2-opensource6.2.9
Qt 6.2.9-lts release Conflicts solved: dependencies.yaml examples/webenginewidgets/push-notifications/CMakeLists.txt Change-Id: I0127c2575369f6939df89f3301659470d481b9bf
-rw-r--r--.cmake.conf2
-rw-r--r--CHROMIUM_VERSION4
-rw-r--r--CMakeLists.txt7
-rw-r--r--cmake/FindGPerf.cmake3
-rw-r--r--cmake/FindGn.cmake3
-rw-r--r--cmake/FindNinja.cmake3
-rw-r--r--cmake/FindNodejs.cmake3
-rw-r--r--cmake/FindPkgConfigHost.cmake3
-rw-r--r--cmake/FindSnappy.cmake3
-rw-r--r--cmake/Functions.cmake133
-rw-r--r--cmake/Gn.cmake3
-rw-r--r--cmake/License.cmake42
-rw-r--r--cmake/SubmoduleUpdate.cmake70
-rw-r--r--configure.cmake30
-rw-r--r--dependencies.yaml8
-rw-r--r--examples/CMakeLists.txt3
-rw-r--r--examples/pdf/CMakeLists.txt3
-rw-r--r--examples/pdf/multipage/CMakeLists.txt3
-rw-r--r--examples/pdf/multipage/viewer.qml2
-rw-r--r--examples/pdf/pdfviewer/CMakeLists.txt3
-rw-r--r--examples/pdfwidgets/pdfviewer/CMakeLists.txt3
-rw-r--r--examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc6
-rw-r--r--examples/webenginequick/CMakeLists.txt10
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.pngbin18549 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.pngbin5064 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-color1.pngbin9729 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-color2.pngbin3952 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-file1.pngbin18540 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-file2.pngbin6773 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-menu.pngbin5484 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.pngbin14845 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.pngbin4764 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.pngbin1617 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs.pngbin9093 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc309
-rw-r--r--examples/webenginequick/customtouchhandle/CMakeLists.txt45
-rw-r--r--examples/webenginequick/customtouchhandle/doc/images/customtouchhandle.jpgbin47646 -> 0 bytes
-rw-r--r--examples/webenginequick/customtouchhandle/doc/src/customtouchhandle.qdoc42
-rw-r--r--examples/webenginequick/lifecycle/CMakeLists.txt4
-rw-r--r--examples/webenginequick/lifecycle/WebTab.qml2
-rw-r--r--examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc3
-rw-r--r--examples/webenginequick/lifecycle/lifecycle.pro1
-rw-r--r--examples/webenginequick/lifecycle/main.cpp6
-rw-r--r--examples/webenginequick/lifecycle/utils.h25
-rw-r--r--examples/webenginequick/minimal/CMakeLists.txt45
-rw-r--r--examples/webenginequick/minimal/doc/src/minimal.qdoc63
-rw-r--r--examples/webenginequick/quicknanobrowser/BrowserWindow.qml89
-rw-r--r--examples/webenginequick/quicknanobrowser/CMakeLists.txt4
-rw-r--r--examples/webenginequick/quicknanobrowser/DownloadView.qml2
-rw-r--r--examples/webenginequick/quicknanobrowser/FindBar.qml16
-rw-r--r--examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc25
-rw-r--r--examples/webenginequick/quicknanobrowser/main.cpp2
-rw-r--r--examples/webenginequick/recipebrowser/CMakeLists.txt155
-rw-r--r--examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpgbin33398 -> 0 bytes
-rw-r--r--examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc209
-rw-r--r--examples/webenginequick/recipebrowser/main.cpp30
-rw-r--r--examples/webenginequick/recipebrowser/recipebrowser.pro21
-rw-r--r--examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json34
-rw-r--r--examples/webenginequick/recipebrowser/resources/pages/assets/custom.js20
-rw-r--r--examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml125
-rw-r--r--examples/webenginequick/recipebrowser/resources/qml/main.qml121
-rw-r--r--examples/webenginequick/recipebrowser/resources/resources.qrc27
-rw-r--r--examples/webenginequick/webengineaction/CMakeLists.txt45
-rw-r--r--examples/webenginequick/webengineaction/doc/images/webengineaction-example.pngbin100266 -> 0 bytes
-rw-r--r--examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc44
-rw-r--r--examples/webenginequick/webengineaction/webengineaction.pro10
-rw-r--r--examples/webenginequick/webenginequick.pro9
-rw-r--r--examples/webenginewidgets/CMakeLists.txt9
-rw-r--r--examples/webenginewidgets/contentmanipulation/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/cookiebrowser/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/html2pdf/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/maps/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/maps/doc/src/maps.qdoc6
-rw-r--r--examples/webenginewidgets/markdowneditor/CMakeLists.txt55
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.pngbin41883 -> 0 bytes
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc159
-rw-r--r--examples/webenginewidgets/markdowneditor/document.cpp12
-rw-r--r--examples/webenginewidgets/markdowneditor/document.h26
-rw-r--r--examples/webenginewidgets/markdowneditor/main.cpp19
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp147
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.h45
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.ui115
-rw-r--r--examples/webenginewidgets/markdowneditor/markdowneditor.pro32
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.cpp17
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.h19
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt16
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt19
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css260
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.js1514
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json34
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/default.md12
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/index.html32
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc8
-rw-r--r--examples/webenginewidgets/minimal/CMakeLists.txt33
-rw-r--r--examples/webenginewidgets/minimal/doc/images/minimal-example.pngbin89294 -> 0 bytes
-rw-r--r--examples/webenginewidgets/minimal/doc/src/minimal.qdoc55
-rw-r--r--examples/webenginewidgets/notifications/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/printme/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/push-notifications/CMakeLists.txt (renamed from examples/webenginewidgets/webui/CMakeLists.txt)28
-rw-r--r--examples/webenginewidgets/push-notifications/content/index.html26
-rw-r--r--examples/webenginewidgets/push-notifications/content/ping.js84
-rw-r--r--examples/webenginewidgets/push-notifications/content/style.css29
-rw-r--r--examples/webenginewidgets/push-notifications/content/worker.js7
-rw-r--r--examples/webenginewidgets/push-notifications/data/data.qrc (renamed from examples/webenginewidgets/webui/webui.qrc)2
-rw-r--r--examples/webenginewidgets/push-notifications/data/icon.pngbin0 -> 2252 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/notification.pngbin0 -> 1279 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/permissions.pngbin0 -> 4749 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/push-notifications.pngbin0 -> 10573 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/website.pngbin0 -> 7539 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc202
-rw-r--r--examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel837
-rw-r--r--examples/webenginewidgets/push-notifications/main.cpp41
-rw-r--r--examples/webenginewidgets/push-notifications/notificationpopup.h91
-rw-r--r--examples/webenginewidgets/push-notifications/push-notifications.pro10
-rw-r--r--examples/webenginewidgets/push-notifications/server.js65
-rw-r--r--examples/webenginewidgets/recipebrowser/CMakeLists.txt71
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKDOWN-LICENSE.txt (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKED-LICENSE.txt (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/markdown.css (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/markdown.css)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/marked.js (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/marked.js)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json34
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/custom.css (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/custom.css)2
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/custom.js13
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/burger.html (renamed from examples/webenginequick/recipebrowser/resources/pages/burger.html)27
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/cupcakes.html (renamed from examples/webenginequick/recipebrowser/resources/pages/cupcakes.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/burger.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/burger.jpg)bin48882 -> 48882 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/cupcakes.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/cupcakes.jpg)bin38653 -> 38653 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/pasta.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/pasta.jpg)bin42411 -> 42411 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/pizza.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/pizza.jpg)bin49068 -> 49068 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/skewers.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/skewers.jpg)bin49246 -> 49246 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/soup.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/soup.jpg)bin49028 -> 49028 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/steak.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/steak.jpg)bin49202 -> 49202 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/pasta.html (renamed from examples/webenginequick/recipebrowser/resources/pages/pasta.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/pizza.html (renamed from examples/webenginequick/recipebrowser/resources/pages/pizza.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/skewers.html (renamed from examples/webenginequick/recipebrowser/resources/pages/skewers.html)27
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/soup.html (renamed from examples/webenginequick/recipebrowser/resources/pages/soup.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/steak.html (renamed from examples/webenginequick/recipebrowser/resources/pages/steak.html)27
-rw-r--r--examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webpbin0 -> 34058 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc197
-rw-r--r--examples/webenginewidgets/recipebrowser/document.cpp48
-rw-r--r--examples/webenginewidgets/recipebrowser/document.h36
-rw-r--r--examples/webenginewidgets/recipebrowser/main.cpp (renamed from examples/webenginewidgets/stylesheetbrowser/main.cpp)4
-rw-r--r--examples/webenginewidgets/recipebrowser/mainwindow.cpp153
-rw-r--r--examples/webenginewidgets/recipebrowser/mainwindow.h (renamed from examples/webenginewidgets/stylesheetbrowser/mainwindow.h)14
-rw-r--r--examples/webenginewidgets/recipebrowser/mainwindow.ui106
-rw-r--r--examples/webenginewidgets/recipebrowser/recipebrowser.pro (renamed from examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.pro)12
-rw-r--r--examples/webenginewidgets/recipebrowser/recipebrowser.qrc15
-rw-r--r--examples/webenginewidgets/recipebrowser/stylesheetdialog.cpp (renamed from examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.cpp)23
-rw-r--r--examples/webenginewidgets/recipebrowser/stylesheetdialog.h (renamed from examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.h)2
-rw-r--r--examples/webenginewidgets/recipebrowser/stylesheetdialog.ui (renamed from examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.ui)0
-rw-r--r--examples/webenginewidgets/simplebrowser/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.cpp57
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.h19
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp1
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h2
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadwidget.cpp21
-rw-r--r--examples/webenginewidgets/simplebrowser/main.cpp2
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.cpp4
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.h2
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.cpp23
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.h2
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.h2
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.cpp23
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.h4
-rw-r--r--examples/webenginewidgets/spellchecker/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING1
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json24
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.pngbin1364 -> 0 bytes
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt50
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.pngbin45161 -> 0 bytes
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc44
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp122
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/mainwindow.ui133
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc5
-rw-r--r--examples/webenginewidgets/videoplayer/CMakeLists.txt3
-rw-r--r--examples/webenginewidgets/webenginewidgets.pro8
-rw-r--r--examples/webenginewidgets/webui/about.html129
-rw-r--r--examples/webenginewidgets/webui/doc/images/webui-example.pngbin28862 -> 0 bytes
-rw-r--r--examples/webenginewidgets/webui/doc/src/webui.qdoc141
-rw-r--r--examples/webenginewidgets/webui/main.cpp33
-rw-r--r--examples/webenginewidgets/webui/webui.pro16
-rw-r--r--examples/webenginewidgets/webui/webuihandler.cpp51
-rw-r--r--examples/webenginewidgets/webui/webuihandler.h23
-rw-r--r--qt_cmdline.cmake3
m---------src/3rdparty0
-rw-r--r--src/CMakeLists.txt11
-rw-r--r--src/core/CMakeLists.txt101
-rw-r--r--src/core/accessibility_activation_observer.cpp4
-rw-r--r--src/core/accessibility_activation_observer.h6
-rw-r--r--src/core/accessibility_tree_formatter_qt.cpp140
-rw-r--r--src/core/api/CMakeLists.txt31
-rw-r--r--src/core/api/Qt6WebEngineCoreMacros.cmake3
-rw-r--r--src/core/api/configure.cmake22
-rw-r--r--src/core/api/qt_cmdline.cmake3
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp33
-rw-r--r--src/core/api/qtwebenginecoreglobal.h1
-rw-r--r--src/core/api/qwebenginepage.cpp57
-rw-r--r--src/core/api/qwebenginepage.h5
-rw-r--r--src/core/api/qwebenginepage_p.h14
-rw-r--r--src/core/api/qwebengineprofile.cpp31
-rw-r--r--src/core/api/qwebengineprofile.h3
-rw-r--r--src/core/api/qwebenginequotarequest.cpp42
-rw-r--r--src/core/api/qwebenginequotarequest.h18
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp30
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h1
-rw-r--r--src/core/api/qwebengineurlrequestinfo_p.h6
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp33
-rw-r--r--src/core/authentication_dialog_controller.cpp3
-rw-r--r--src/core/autofill_client_qt.cpp4
-rw-r--r--src/core/autofill_client_qt.h2
-rw-r--r--src/core/autofill_popup_controller.cpp7
-rw-r--r--src/core/browser_accessibility_manager_qt.cpp39
-rw-r--r--src/core/browser_accessibility_manager_qt.h12
-rw-r--r--src/core/browser_accessibility_qt.cpp51
-rw-r--r--src/core/browser_accessibility_qt.h5
-rw-r--r--src/core/browser_main_parts_qt.cpp15
-rw-r--r--src/core/browsing_data_remover_delegate_qt.h2
-rw-r--r--src/core/chromium_overrides.cpp93
-rw-r--r--src/core/client_hints.cpp173
-rw-r--r--src/core/client_hints.h102
-rw-r--r--src/core/common/extensions/extensions_client_qt.cpp6
-rw-r--r--src/core/common/extensions/extensions_client_qt.h2
-rw-r--r--src/core/compositor/compositor.cpp21
-rw-r--r--src/core/compositor/compositor.h44
-rw-r--r--src/core/compositor/content_gpu_client_qt.cpp5
-rw-r--r--src/core/compositor/content_gpu_client_qt.h1
-rw-r--r--src/core/compositor/display_gl_output_surface.cpp304
-rw-r--r--src/core/compositor/display_gl_output_surface.h113
-rw-r--r--src/core/compositor/display_overrides.cpp52
-rw-r--r--src/core/compositor/display_skia_output_device.cpp333
-rw-r--r--src/core/compositor/display_skia_output_device.h21
-rw-r--r--src/core/compositor/display_software_output_surface.cpp32
-rw-r--r--src/core/compositor/display_software_output_surface.h2
-rw-r--r--src/core/compositor/native_skia_output_device.cpp443
-rw-r--r--src/core/compositor/native_skia_output_device.h103
-rw-r--r--src/core/compositor/native_skia_output_device_mac.mm30
-rw-r--r--src/core/compositor/native_skia_output_device_mac2.mm25
-rw-r--r--src/core/compositor/vulkan_implementation_qt.cpp156
-rw-r--r--src/core/compositor/vulkan_implementation_qt.h48
-rw-r--r--src/core/configure.json303
-rw-r--r--src/core/configure/BUILD.root.gn.in110
-rw-r--r--src/core/content_browser_client_qt.cpp66
-rw-r--r--src/core/content_browser_client_qt.h10
-rw-r--r--src/core/content_client_qt.cpp32
-rw-r--r--src/core/content_client_qt.h13
-rw-r--r--src/core/content_main_delegate_qt.cpp28
-rw-r--r--src/core/content_main_delegate_qt.h3
-rw-r--r--src/core/content_utility_client_qt.cpp18
-rw-r--r--src/core/desktop_screen_qt.cpp20
-rw-r--r--src/core/desktop_screen_qt.h2
-rw-r--r--src/core/devtools_frontend_qt.cpp556
-rw-r--r--src/core/devtools_frontend_qt.h92
-rw-r--r--src/core/doc/about_credits_entry.tmpl3
-rw-r--r--src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc2
-rw-r--r--src/core/doc/src/qtwebengine-debugging.qdoc11
-rw-r--r--src/core/doc/src/qtwebengine-deploying.qdoc43
-rw-r--r--src/core/doc/src/qtwebengine-features.qdoc7
-rw-r--r--src/core/doc/src/qtwebengine-overview.qdoc2
-rw-r--r--src/core/doc/src/qtwebengine-platform-notes.qdoc8
-rw-r--r--src/core/doc/src/qwebengine-licensing.qdoc7
-rw-r--r--src/core/download_manager_delegate_qt.cpp6
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.cpp6
-rw-r--r--src/core/extensions/extension_system_qt.cpp9
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.cpp13
-rw-r--r--src/core/extensions/extensions_browser_client_qt.cpp26
-rw-r--r--src/core/extensions/extensions_browser_client_qt.h5
-rw-r--r--src/core/extensions/messaging_delegate_qt.cpp4
-rw-r--r--src/core/extensions/messaging_delegate_qt.h2
-rw-r--r--src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp20
-rw-r--r--src/core/extensions/plugin_service_filter_qt.cpp5
-rw-r--r--src/core/extensions/plugin_service_filter_qt.h4
-rw-r--r--src/core/favicon_service_factory_qt.cpp4
-rw-r--r--src/core/favicon_service_factory_qt.h1
-rw-r--r--src/core/file_picker_controller.cpp13
-rw-r--r--src/core/file_system_access/file_system_access_permission_context_qt.cpp35
-rw-r--r--src/core/file_system_access/file_system_access_permission_context_qt.h14
-rw-r--r--src/core/file_system_access/file_system_access_permission_grant_qt.cpp28
-rw-r--r--src/core/file_system_access/file_system_access_permission_grant_qt.h10
-rw-r--r--src/core/file_system_access/file_system_access_permission_request_controller.h2
-rw-r--r--src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp4
-rw-r--r--src/core/login_delegate_qt.cpp4
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp229
-rw-r--r--src/core/media_capture_devices_dispatcher.h2
-rw-r--r--src/core/net/client_cert_qt.cpp5
-rw-r--r--src/core/net/custom_url_loader_factory.cpp16
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp6
-rw-r--r--src/core/net/proxy_config_monitor.cpp11
-rw-r--r--src/core/net/proxy_config_monitor.h7
-rw-r--r--src/core/net/proxy_config_service_qt.cpp8
-rw-r--r--src/core/net/proxy_config_service_qt.h2
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp10
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.h1
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp42
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.cpp10
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.h10
-rw-r--r--src/core/net/system_network_context_manager.cpp30
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp1
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp7
-rw-r--r--src/core/ozone/gl_context_qt.cpp11
-rw-r--r--src/core/ozone/gl_ozone_egl_qt.cpp21
-rw-r--r--src/core/ozone/gl_ozone_egl_qt.h8
-rw-r--r--src/core/ozone/gl_ozone_glx_qt.cpp27
-rw-r--r--src/core/ozone/gl_ozone_glx_qt.h14
-rw-r--r--src/core/ozone/gl_share_context_qt.cpp10
-rw-r--r--src/core/ozone/gl_share_context_qt.h2
-rw-r--r--src/core/ozone/gl_surface_egl_qt.cpp190
-rw-r--r--src/core/ozone/gl_surface_egl_qt.h8
-rw-r--r--src/core/ozone/gl_surface_glx_qt.cpp18
-rw-r--r--src/core/ozone/gl_surface_glx_qt.h2
-rw-r--r--src/core/ozone/gl_surface_qt.cpp118
-rw-r--r--src/core/ozone/gl_surface_qt.h2
-rw-r--r--src/core/ozone/gl_surface_wgl_qt.cpp8
-rw-r--r--src/core/ozone/gl_surface_wgl_qt.h2
-rw-r--r--src/core/ozone/ozone_extra.gni14
-rw-r--r--src/core/ozone/ozone_platform_qt.cpp26
-rw-r--r--src/core/ozone/platform_window_qt.cpp18
-rw-r--r--src/core/ozone/platform_window_qt.h10
-rw-r--r--src/core/ozone/surface_factory_qt.cpp19
-rw-r--r--src/core/ozone/surface_factory_qt.h4
-rw-r--r--src/core/permission_manager_qt.cpp165
-rw-r--r--src/core/permission_manager_qt.h32
-rw-r--r--src/core/platform_notification_service_qt.cpp1
-rw-r--r--src/core/pointer_device_qt.cpp102
-rw-r--r--src/core/pref_service_adapter.cpp42
-rw-r--r--src/core/printing/pdf_web_contents_helper_client_qt.cpp15
-rw-r--r--src/core/printing/pdf_web_contents_helper_client_qt.h4
-rw-r--r--src/core/printing/print_view_manager_base_qt.cpp222
-rw-r--r--src/core/printing/print_view_manager_base_qt.h23
-rw-r--r--src/core/printing/print_view_manager_qt.cpp124
-rw-r--r--src/core/printing/print_view_manager_qt.h2
-rw-r--r--src/core/printing/printer_worker.cpp4
-rw-r--r--src/core/profile_adapter.cpp13
-rw-r--r--src/core/profile_adapter.h4
-rw-r--r--src/core/profile_io_data_qt.cpp1
-rw-r--r--src/core/profile_qt.cpp32
-rw-r--r--src/core/profile_qt.h3
-rw-r--r--src/core/quota_permission_context_qt.cpp84
-rw-r--r--src/core/quota_permission_context_qt.h23
-rw-r--r--src/core/quota_request_controller.h26
-rw-r--r--src/core/quota_request_controller_impl.cpp36
-rw-r--r--src/core/quota_request_controller_impl.h32
-rw-r--r--src/core/render_widget_host_view_qt.cpp84
-rw-r--r--src/core/render_widget_host_view_qt.h27
-rw-r--r--src/core/render_widget_host_view_qt_delegate_client.cpp1
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.cpp85
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.h2
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp136
-rw-r--r--src/core/renderer/content_renderer_client_qt.h6
-rw-r--r--src/core/renderer/content_settings_observer_qt.cpp5
-rw-r--r--src/core/renderer/content_settings_observer_qt.h6
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.cpp7
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.h3
-rw-r--r--src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp8
-rw-r--r--src/core/renderer/print_web_view_helper_delegate_qt.cpp8
-rw-r--r--src/core/renderer/print_web_view_helper_delegate_qt.h9
-rw-r--r--src/core/renderer/render_configuration.cpp3
-rw-r--r--src/core/renderer/render_frame_observer_qt.cpp1
-rw-r--r--src/core/renderer/user_resource_controller.cpp31
-rw-r--r--src/core/renderer/user_resource_controller.h11
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp5
-rw-r--r--src/core/renderer/web_channel_ipc_transport.h4
-rw-r--r--src/core/renderer/web_engine_page_render_frame.cpp8
-rw-r--r--src/core/renderer/web_engine_page_render_frame.h2
-rw-r--r--src/core/renderer_host/user_resource_controller_host.cpp6
-rw-r--r--src/core/renderer_host/web_channel_ipc_transport_host.cpp24
-rw-r--r--src/core/renderer_host/web_engine_page_host.cpp6
-rw-r--r--src/core/sandbox_win.cpp4
-rw-r--r--src/core/select_file_dialog_factory_qt.cpp6
-rw-r--r--src/core/tools/CMakeLists.txt3
-rw-r--r--src/core/user_script.cpp2
-rw-r--r--src/core/web_contents_adapter.cpp102
-rw-r--r--src/core/web_contents_adapter_client.h2
-rw-r--r--src/core/web_contents_delegate_qt.cpp42
-rw-r--r--src/core/web_contents_delegate_qt.h8
-rw-r--r--src/core/web_contents_view_qt.cpp3
-rw-r--r--src/core/web_contents_view_qt.h2
-rw-r--r--src/core/web_engine_context.cpp218
-rw-r--r--src/core/web_engine_context.h5
-rw-r--r--src/core/web_engine_context_threads.cpp20
-rw-r--r--src/core/web_engine_library_info.cpp13
-rw-r--r--src/core/web_engine_settings.cpp1
-rw-r--r--src/core/web_event_factory.cpp1
-rw-r--r--src/gn/CMakeLists.txt3
-rw-r--r--src/host/CMakeLists.txt7
-rw-r--r--src/ninja/CMakeLists.txt3
-rw-r--r--src/pdf/CMakeLists.txt37
-rw-r--r--src/pdf/configure.cmake3
-rw-r--r--src/pdf/configure/BUILD.root.gn.in8
-rw-r--r--src/pdf/doc/about_credits.tmpl1
-rw-r--r--src/pdf/doc/about_credits_entry.tmpl13
-rw-r--r--src/pdf/doc/images/pdfviewer.pngbin0 -> 264348 bytes
-rw-r--r--src/pdf/doc/src/qtpdf-index.qdoc8
-rw-r--r--src/pdf/doc/src/qtpdf-licensing.qdoc18
-rw-r--r--src/pdf/plugins/imageformats/pdf/CMakeLists.txt3
-rw-r--r--src/pdf/qpdfdocument.cpp17
-rw-r--r--src/pdf/qpdfdocument_p.h25
-rw-r--r--src/pdf/qpdflink.cpp11
-rw-r--r--src/pdf/qpdflinkmodel.cpp6
-rw-r--r--src/pdf/qpdfsearchmodel.cpp14
-rw-r--r--src/pdf/qpdfsearchmodel.h1
-rw-r--r--src/pdf/qpdfsearchmodel_p.h2
-rw-r--r--src/pdfquick/CMakeLists.txt3
-rw-r--r--src/pdfquick/qquickpdfdocument.cpp6
-rw-r--r--src/pdfwidgets/CMakeLists.txt3
-rw-r--r--src/process/CMakeLists.txt4
-rw-r--r--src/process/Info_mac.plist.in44
-rw-r--r--src/process/QtWebEngineProcess.entitlements2
-rw-r--r--src/webenginequick/CMakeLists.txt9
-rw-r--r--src/webenginequick/api/qquickwebengineaction.cpp10
-rw-r--r--src/webenginequick/api/qquickwebenginedialogrequests.cpp29
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.cpp35
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.h5
-rw-r--r--src/webenginequick/api/qquickwebengineview.cpp21
-rw-r--r--src/webenginequick/api/qquickwebengineview_p.h7
-rw-r--r--src/webenginequick/api/qquickwebengineview_p_p.h4
-rw-r--r--src/webenginequick/api/qtwebenginequickglobal.cpp6
-rw-r--r--src/webenginequick/configure.cmake3
-rw-r--r--src/webenginequick/doc/snippets/minimal/main.cpp18
-rw-r--r--src/webenginequick/doc/snippets/minimal/main.qml18
-rw-r--r--src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml123
-rw-r--r--src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc9
-rw-r--r--src/webenginequick/doc/src/quota_request.qdoc24
-rw-r--r--src/webenginequick/doc/src/webengineview_lgpl.qdoc34
-rw-r--r--src/webenginequick/qquickwebengine_accessible.cpp3
-rw-r--r--src/webenginequick/qquickwebengine_accessible.h4
-rw-r--r--src/webenginequick/ui/CMakeLists.txt3
-rw-r--r--src/webenginequick/ui_delegates_manager.cpp6
-rw-r--r--src/webenginewidgets/CMakeLists.txt12
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp61
-rw-r--r--src/webenginewidgets/api/qwebengineview.h2
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h9
-rw-r--r--src/webenginewidgets/doc/snippets/push-notifications/commands19
-rw-r--r--src/webenginewidgets/doc/snippets/simple/main.cpp11
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc5
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc2
-rw-r--r--src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt3
-rw-r--r--src/webenginewidgets/qwebengine_accessible.cpp4
-rw-r--r--src/webenginewidgets/qwebengine_accessible.h7
-rw-r--r--src/webenginewidgets/ui/touchhandlewidget.cpp59
-rw-r--r--src/webenginewidgets/ui/touchhandlewidget_p.h50
-rw-r--r--src/webenginewidgets/ui/touchselectionmenuwidget.cpp117
-rw-r--r--src/webenginewidgets/ui/touchselectionmenuwidget_p.h52
-rw-r--r--tests/auto/CMakeLists.txt2
-rw-r--r--tests/auto/cmake/CMakeLists.txt3
-rw-r--r--tests/auto/core/CMakeLists.txt3
-rw-r--r--tests/auto/core/certificateerror/CMakeLists.txt3
-rw-r--r--tests/auto/core/devtools/CMakeLists.txt3
-rw-r--r--tests/auto/core/origins/CMakeLists.txt3
-rw-r--r--tests/auto/core/origins/tst_origins.cpp4
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt3
-rw-r--r--tests/auto/core/qwebenginecookiestore/CMakeLists.txt3
-rw-r--r--tests/auto/core/qwebenginesettings/CMakeLists.txt3
-rw-r--r--tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp2
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt3
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp100
-rw-r--r--tests/auto/httpserver/CMakeLists.txt3
-rw-r--r--tests/auto/httpserver/httpserver.cmake3
-rw-r--r--tests/auto/pdf/CMakeLists.txt3
-rw-r--r--tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt8
-rw-r--r--tests/auto/pdf/qpdfdocument/CMakeLists.txt9
-rw-r--r--tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp8
-rw-r--r--tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt7
-rw-r--r--tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt7
-rw-r--r--tests/auto/pdfquick/multipageview/BLACKLIST7
-rw-r--r--tests/auto/pdfquick/multipageview/CMakeLists.txt6
-rw-r--r--tests/auto/pdfquick/multipageview/tst_multipageview.cpp8
-rw-r--r--tests/auto/quick/CMakeLists.txt3
-rw-r--r--tests/auto/quick/dialogs/CMakeLists.txt3
-rw-r--r--tests/auto/quick/inspectorserver/BLACKLIST2
-rw-r--r--tests/auto/quick/inspectorserver/CMakeLists.txt3
-rw-r--r--tests/auto/quick/publicapi/CMakeLists.txt3
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp2
-rw-r--r--tests/auto/quick/qmltests/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qmltests/data/tst_faviconDatabase.qml6
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml2
-rw-r--r--tests/auto/quick/qmltests/data/tst_scrollPosition.qml7
-rw-r--r--tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qquickwebengineview/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp12
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qtbug-70248/CMakeLists.txt3
-rw-r--r--tests/auto/quick/uidelegates/CMakeLists.txt3
-rw-r--r--tests/auto/util/CMakeLists.txt3
-rw-r--r--tests/auto/util/util.cmake3
-rw-r--r--tests/auto/widgets/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/accessibility/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/accessibility/tst_accessibility.cpp2
-rw-r--r--tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/favicon/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/loadsignals/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/offscreen/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/printing/CMakeLists.txt6
-rw-r--r--tests/auto/widgets/printing/tst_printing.cpp14
-rw-r--r--tests/auto/widgets/proxy/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/proxypac/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/proxypac/tst_proxypac.cpp2
-rw-r--r--tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebenginehistory/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp4
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST3
-rw-r--r--tests/auto/widgets/qwebenginepage/CMakeLists.txt5
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp289
-rw-r--r--tests/auto/widgets/qwebengineprofile/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebenginescript/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp33
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST2
-rw-r--r--tests/auto/widgets/qwebengineview/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp2
-rw-r--r--tests/auto/widgets/schemes/CMakeLists.txt6
-rw-r--r--tests/auto/widgets/schemes/tst_schemes.cpp186
-rw-r--r--tests/auto/widgets/shutdown/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/spellchecking/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/touchinput/CMakeLists.txt3
-rw-r--r--tests/manual/CMakeLists.txt1
-rw-r--r--tests/manual/examples/CMakeLists.txt2
-rw-r--r--tests/manual/examples/quick/CMakeLists.txt4
-rw-r--r--tests/manual/examples/quick/customdialogs/CMakeLists.txt (renamed from examples/webenginequick/customdialogs/CMakeLists.txt)33
-rw-r--r--tests/manual/examples/quick/customdialogs/MessageRectangle.qml (renamed from examples/webenginequick/customdialogs/MessageRectangle.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/SwitchButton.qml (renamed from examples/webenginequick/customdialogs/SwitchButton.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/WebView.qml (renamed from examples/webenginequick/customdialogs/WebView.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/customdialogs.pro (renamed from examples/webenginequick/customdialogs/customdialogs.pro)0
-rw-r--r--tests/manual/examples/quick/customdialogs/customdialogs.qrc (renamed from examples/webenginequick/customdialogs/customdialogs.qrc)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/Authentication.qml (renamed from examples/webenginequick/customdialogs/forms/Authentication.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/AuthenticationForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/AuthenticationForm.ui.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/ColorCell.qml (renamed from examples/webenginequick/customdialogs/forms/ColorCell.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/ColorPicker.qml (renamed from examples/webenginequick/customdialogs/forms/ColorPicker.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/ColorPickerForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/ColorPickerForm.ui.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/CustomButton.qml (renamed from examples/webenginequick/customdialogs/forms/CustomButton.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/FilePicker.qml (renamed from examples/webenginequick/customdialogs/forms/FilePicker.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/FilePickerForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/FilePickerForm.ui.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/FileRow.qml (renamed from examples/webenginequick/customdialogs/forms/FileRow.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/JavaScript.qml (renamed from examples/webenginequick/customdialogs/forms/JavaScript.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/JavaScriptForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/JavaScriptForm.ui.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/Menu.qml (renamed from examples/webenginequick/customdialogs/forms/Menu.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/MenuForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/MenuForm.ui.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenu.qml (renamed from examples/webenginequick/customdialogs/forms/TouchSelectionMenu.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenuForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/TouchSelectionMenuForm.ui.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/forms.qmlproject (renamed from examples/webenginequick/customdialogs/forms/forms.qmlproject)0
-rw-r--r--tests/manual/examples/quick/customdialogs/icon.svg (renamed from examples/webenginequick/customdialogs/icon.svg)0
-rw-r--r--tests/manual/examples/quick/customdialogs/index.html (renamed from examples/webenginequick/customdialogs/index.html)0
-rw-r--r--tests/manual/examples/quick/customdialogs/main.cpp (renamed from examples/webenginequick/customdialogs/main.cpp)0
-rw-r--r--tests/manual/examples/quick/customdialogs/main.qml (renamed from examples/webenginequick/customdialogs/main.qml)0
-rw-r--r--tests/manual/examples/quick/customdialogs/server.cpp (renamed from examples/webenginequick/customdialogs/server.cpp)0
-rw-r--r--tests/manual/examples/quick/customdialogs/server.h (renamed from examples/webenginequick/customdialogs/server.h)0
-rw-r--r--tests/manual/examples/quick/customdialogs/style.css (renamed from examples/webenginequick/customdialogs/style.css)0
-rw-r--r--tests/manual/examples/quick/customtouchhandle/CMakeLists.txt36
-rw-r--r--tests/manual/examples/quick/customtouchhandle/customtouchhandle.pro (renamed from examples/webenginequick/customtouchhandle/customtouchhandle.pro)0
-rw-r--r--tests/manual/examples/quick/customtouchhandle/main.cpp (renamed from examples/webenginequick/customtouchhandle/main.cpp)0
-rw-r--r--tests/manual/examples/quick/customtouchhandle/main.qml (renamed from examples/webenginequick/customtouchhandle/main.qml)0
-rw-r--r--tests/manual/examples/quick/customtouchhandle/qml.qrc (renamed from examples/webenginequick/customtouchhandle/qml.qrc)0
-rw-r--r--tests/manual/examples/quick/minimal/CMakeLists.txt36
-rw-r--r--tests/manual/examples/quick/minimal/main.cpp (renamed from examples/webenginequick/minimal/main.cpp)1
-rw-r--r--tests/manual/examples/quick/minimal/main.qml (renamed from examples/webenginequick/minimal/main.qml)0
-rw-r--r--tests/manual/examples/quick/minimal/minimal.pro (renamed from examples/webenginequick/minimal/minimal.pro)0
-rw-r--r--tests/manual/examples/quick/minimal/qml.qrc (renamed from examples/webenginequick/minimal/qml.qrc)0
-rw-r--r--tests/manual/examples/quick/webengineaction/CMakeLists.txt37
-rw-r--r--tests/manual/examples/quick/webengineaction/main.cpp (renamed from examples/webenginequick/webengineaction/main.cpp)6
-rw-r--r--tests/manual/examples/quick/webengineaction/main.qml (renamed from examples/webenginequick/webengineaction/main.qml)2
-rw-r--r--tests/manual/examples/quick/webengineaction/qml.qrc (renamed from examples/webenginequick/webengineaction/qml.qrc)0
-rw-r--r--tests/manual/examples/quick/webengineaction/utils.h25
-rw-r--r--tests/manual/examples/quick/webengineaction/webengineaction.pro8
-rw-r--r--tests/manual/examples/widgets/CMakeLists.txt1
-rw-r--r--tests/manual/examples/widgets/minimal/CMakeLists.txt24
-rw-r--r--tests/manual/examples/widgets/minimal/main.cpp (renamed from examples/webenginewidgets/minimal/main.cpp)0
-rw-r--r--tests/manual/examples/widgets/minimal/minimal.pro (renamed from examples/webenginewidgets/minimal/minimal.pro)0
-rw-r--r--tests/manual/manual.pro7
-rw-r--r--tests/manual/quick/quick.pro5
-rw-r--r--tests/manual/quick/touchbrowser/CMakeLists.txt5
-rw-r--r--tests/manual/quick/touchbrowser/touchmockingapplication.cpp32
-rw-r--r--tests/manual/widgets/inputmethods/CMakeLists.txt5
-rw-r--r--tests/manual/widgets/inputmethods/colorpicker.h2
-rw-r--r--tests/manual/widgets/inputmethods/controlview.h5
-rw-r--r--tests/manual/widgets/inputmethods/testview.h2
-rw-r--r--tests/manual/widgets/webgl/CMakeLists.txt5
-rw-r--r--tests/manual/widgets/widgets.pro5
-rw-r--r--tests/quicktestbrowser/ApplicationRoot.qml43
-rw-r--r--tests/quicktestbrowser/BrowserDialog.qml19
-rw-r--r--tests/quicktestbrowser/BrowserWindow.qml507
-rw-r--r--tests/quicktestbrowser/ButtonWithMenu.qml33
-rw-r--r--tests/quicktestbrowser/DownloadView.qml128
-rw-r--r--tests/quicktestbrowser/FeaturePermissionBar.qml67
-rw-r--r--tests/quicktestbrowser/FullScreenNotification.qml62
-rw-r--r--tests/quicktestbrowser/ZoomController.qml65
-rw-r--r--tests/quicktestbrowser/main.cpp71
-rw-r--r--tests/quicktestbrowser/quicktestbrowser.pro26
-rw-r--r--tests/quicktestbrowser/resources.qrc19
-rw-r--r--tests/quicktestbrowser/utils.h29
-rwxr-xr-xtools/scripts/take_snapshot.py28
-rw-r--r--tools/scripts/version_resolver.py4
589 files changed, 8834 insertions, 9533 deletions
diff --git a/.cmake.conf b/.cmake.conf
index faac28aaa..bb0731ca8 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -1,3 +1,3 @@
-set(QT_REPO_MODULE_VERSION "6.2.8")
+set(QT_REPO_MODULE_VERSION "6.2.9")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "")
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19")
diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 737205e4f..a024b4f70 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
-Based on Chromium version: 102.0.5005.177
-Patched with security patches up to Chromium version: 111.0.5563.110
+Based on Chromium version: 108.0.5359.181
+Patched with security patches up to Chromium version: 114.0.5735.133
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c04b9bf46..fbe69c154 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# Require the Qt (not WebEngine) minimum supported CMake version.
# Another WebEngine-specific version check will be done in configure.cmake
# and reported in the configure summary.
@@ -18,6 +21,10 @@ project(QtWebEngine
LANGUAGES CXX C
)
+if(COMMAND qt_internal_project_setup)
+ qt_internal_project_setup()
+endif()
+
find_package(Qt6 ${PROJECT_VERSION} CONFIG QUIET OPTIONAL_COMPONENTS
Gui Widgets Network OpenGL Quick Qml PrintSupport
WebChannel Positioning QuickControls2 Test QuickWidgets QuickTest WebSockets Designer
diff --git a/cmake/FindGPerf.cmake b/cmake/FindGPerf.cmake
index 85b55f1b8..e42b8a372 100644
--- a/cmake/FindGPerf.cmake
+++ b/cmake/FindGPerf.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_program(GPerf_EXECUTABLE NAMES gperf)
include(FindPackageHandleStandardArgs)
diff --git a/cmake/FindGn.cmake b/cmake/FindGn.cmake
index 6bef6009e..3f25bb585 100644
--- a/cmake/FindGn.cmake
+++ b/cmake/FindGn.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(NOT DEFINED WEBENGINE_ROOT_BUILD_DIR)
set(WEBENGINE_ROOT_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()
diff --git a/cmake/FindNinja.cmake b/cmake/FindNinja.cmake
index 720e73266..9b1e718c0 100644
--- a/cmake/FindNinja.cmake
+++ b/cmake/FindNinja.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT DEFINED WEBENGINE_ROOT_BUILD_DIR)
set(WEBENGINE_ROOT_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()
diff --git a/cmake/FindNodejs.cmake b/cmake/FindNodejs.cmake
index 0e5efe4a3..0aeef5ab3 100644
--- a/cmake/FindNodejs.cmake
+++ b/cmake/FindNodejs.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_program(Nodejs_EXECUTABLE NAMES node nodejs)
if(Nodejs_EXECUTABLE)
diff --git a/cmake/FindPkgConfigHost.cmake b/cmake/FindPkgConfigHost.cmake
index de0216384..a7f9ab0ae 100644
--- a/cmake/FindPkgConfigHost.cmake
+++ b/cmake/FindPkgConfigHost.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# this is just simply pkg config wrapper to pass executable path to gn
if(CMAKE_CROSSCOMPILING)
diff --git a/cmake/FindSnappy.cmake b/cmake/FindSnappy.cmake
index 1470c55a9..e1c7d231b 100644
--- a/cmake/FindSnappy.cmake
+++ b/cmake/FindSnappy.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(TARGET Snappy::Snappy)
set(Snappy_FOUND TRUE)
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 370ea082c..f3c836432 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1,7 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# this macro is missing in 6.2
+if(NOT COMMAND _qt_internal_validate_all_args_are_parsed)
+ macro(_qt_internal_validate_all_args_are_parsed result)
+ if(DEFINED ${result}_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown arguments (${${result}_UNPARSED_ARGUMENTS}).")
+ endif()
+ endmacro()
+endif()
+
function(assertTargets)
- qt_parse_all_arguments(arg "add_check_for_support"
- "" "" "MODULES;TARGETS" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "" "MODULES;TARGETS"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
+
foreach(module ${arg_MODULES})
if(NOT DEFINED ${module}_SUPPORT)
set(${module}_SUPPORT ON PARENT_SCOPE)
@@ -33,9 +47,11 @@ endfunction()
# TODO: this should be idealy in qtbase
function(add_check_for_support)
- qt_parse_all_arguments(arg "add_check_for_support"
- "" "" "MODULES;MESSAGE;CONDITION" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "" "MODULES;MESSAGE;CONDITION"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
+
foreach(module ${arg_MODULES})
if(NOT DEFINED ${module}_SUPPORT)
set(${module}_SUPPORT ON PARENT_SCOPE)
@@ -178,7 +194,9 @@ endmacro()
function(extend_gn_target target)
get_target_property(elements ${target} ELEMENTS)
- qt_parse_all_arguments(GN "extend_gn_target" "" "" "CONDITION;${elements}" "${ARGN}")
+ cmake_parse_arguments(PARSE_ARGV 1 GN "" "" "CONDITION;${elements}")
+ _qt_internal_validate_all_args_are_parsed(GN)
+
if("x${GN_CONDITION}" STREQUAL x)
set(GN_CONDITION ON)
endif()
@@ -190,7 +208,9 @@ function(extend_gn_target target)
endfunction()
function(extend_gn_list outList)
- qt_parse_all_arguments(GN "extend_gn_list" "" "" "ARGS;CONDITION" "${ARGN}")
+ cmake_parse_arguments(PARSE_ARGV 1 GN "" "" "ARGS;CONDITION")
+ _qt_internal_validate_all_args_are_parsed(GN)
+
if("x${GN_CONDITION}" STREQUAL x)
set(GN_CONDITION ON)
endif()
@@ -429,7 +449,7 @@ function(add_linker_options target buildDir completeStatic)
set(archives_rsp "${buildDir}/${ninjaTarget}_archives.rsp")
set(libs_rsp "${buildDir}/${ninjaTarget}_libs.rsp")
set_target_properties(${cmakeTarget} PROPERTIES STATIC_LIBRARY_OPTIONS "@${objects_rsp}")
- if(LINUX)
+ if(LINUX OR ANDROID)
get_gn_arch(cpu ${TEST_architecture_arch})
if(CMAKE_CROSSCOMPILING AND cpu STREQUAL "arm" AND ${config} STREQUAL "Debug")
target_link_options(${cmakeTarget} PRIVATE "LINKER:--long-plt")
@@ -442,9 +462,31 @@ function(add_linker_options target buildDir completeStatic)
"$<1:-Wl,--start-group $<$<CONFIG:${config}>:@${archives_rsp}> -Wl,--end-group>"
)
endif()
+
+ # we need only the '-L' flags from lflags.rsp, filter them
+ set(lflags_rsp "${buildDir}/${ninjaTarget}_lflags.rsp")
+ set(lflags_filtered_rsp "${buildDir}/${ninjaTarget}_lflags_filtered.rsp")
+ set(lflags_filter_script "${buildDir}/${ninjaTarget}_lflags_filter.cmake")
+ file(GENERATE OUTPUT ${lflags_filter_script}
+ CONTENT "file(STRINGS ${lflags_rsp} lflags)
+ string(REGEX MATCHALL \"-L.*\" lflags_filtered \${lflags})
+ file(WRITE ${lflags_filtered_rsp} \${lflags_filtered})"
+ FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ )
+ add_custom_command(
+ OUTPUT ${lflags_filtered_rsp}
+ COMMAND ${CMAKE_COMMAND} -P ${lflags_filter_script}
+ DEPENDS ${lflags_filter_script} ${lflags_rsp}
+ )
+ add_custom_target(
+ run_${cmakeTarget}_${config}_lflags_filter
+ DEPENDS ${lflags_filtered_rsp}
+ )
+ add_dependencies(${cmakeTarget} run_${cmakeTarget}_${config}_lflags_filter)
+
# linker here options are just to prevent processing it by cmake
target_link_libraries(${cmakeTarget} PRIVATE
- "$<1:-Wl,--no-fatal-warnings $<$<CONFIG:${config}>:@${libs_rsp}> -Wl,--no-fatal-warnings>"
+ "$<1:-Wl,--no-fatal-warnings $<$<CONFIG:${config}>:@${lflags_filtered_rsp}> $<$<CONFIG:${config}>:@${libs_rsp}> -Wl,--no-fatal-warnings>"
)
endif()
if(MACOS)
@@ -456,7 +498,7 @@ function(add_linker_options target buildDir completeStatic)
endif()
if(WIN32)
get_copy_of_response_file(objects_rsp ${target} objects)
- target_link_options(${cmakeTarget} PRIVATE /DELAYLOAD:mf.dll /DELAYLOAD:mfplat.dll /DELAYLOAD:mfreadwrite.dll)
+ target_link_options(${cmakeTarget} PRIVATE /DELAYLOAD:mf.dll /DELAYLOAD:mfplat.dll /DELAYLOAD:mfreadwrite.dll /DELAYLOAD:winmm.dll)
target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${objects_rsp}>")
if(NOT completeStatic)
get_copy_of_response_file(archives_rsp ${target} archives)
@@ -464,6 +506,8 @@ function(add_linker_options target buildDir completeStatic)
endif()
get_copy_of_response_file(libs_rsp ${target} libs)
target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${libs_rsp}>")
+ # enable larger PDBs
+ target_link_options(${cmakeTarget} PRIVATE "/pdbpagesize:8192")
# we need libs rsp also when linking process with sandbox lib
set_property(TARGET ${cmakeTarget} PROPERTY LIBS_RSP ${libs_rsp})
endif()
@@ -628,6 +672,8 @@ function(get_gn_arch result arch)
set(${result} "mipsel" PARENT_SCOPE)
elseif(arch STREQUAL "mipsel64")
set(${result} "mips64el" PARENT_SCOPE)
+ elseif(arch STREQUAL "riscv64")
+ set(${result} "riscv64" PARENT_SCOPE)
else()
message(DEBUG "Unsupported architecture: ${arch}")
endif()
@@ -647,6 +693,8 @@ function(get_v8_arch result targetArch hostArch)
set(${result} "mipsel" PARENT_SCOPE)
elseif(hostArch STREQUAL "mipsel64")
set(${result} "mipsel" PARENT_SCOPE)
+ elseif(hostArch STREQUAL "riscv64")
+ set(${result} "riscv64" PARENT_SCOPE)
elseif(hostArch IN_LIST list32)
set(${result} "${hostArch}" PARENT_SCOPE)
else()
@@ -734,7 +782,9 @@ function(extract_cflag result cflag)
endfunction()
function(extend_gn_list_cflag outList)
- qt_parse_all_arguments(GN "extend_gn_list_cflag" "" "" "ARG;CFLAG" "${ARGN}")
+ cmake_parse_arguments(PARSE_ARGV 1 GN "" "" "ARG;CFLAG")
+ _qt_internal_validate_all_args_are_parsed(GN)
+
extract_cflag(cflag "${GN_CFLAG}")
if(cflag)
set(${outList} "${${outList}}" "${GN_ARG}=\"${cflag}\"" PARENT_SCOPE)
@@ -793,7 +843,7 @@ endmacro()
macro(append_build_type_setup)
list(APPEND gnArgArg
- use_qt=true
+ is_qtwebengine=true
init_stack_vars=false
is_component_build=false
is_shared=true
@@ -807,7 +857,7 @@ macro(append_build_type_setup)
if(${config} STREQUAL "Debug")
list(APPEND gnArgArg is_debug=true symbol_level=2)
if(WIN32)
- list(APPEND gnArgArg enable_iterator_debugging=true v8_optimized_debug=false)
+ list(APPEND gnArgArg enable_iterator_debugging=true)
endif()
elseif(${config} STREQUAL "Release")
list(APPEND gnArgArg is_debug=false symbol_level=0)
@@ -907,6 +957,14 @@ macro(append_compiler_linker_sdk_setup)
CONDITION QT_FEATURE_stdlib_libcpp
)
endif()
+ if(ANDROID)
+ list(APPEND gnArgArg
+ android_ndk_root="${CMAKE_ANDROID_NDK}"
+ android_ndk_version="${CMAKE_ANDROID_NDK_VERSION}"
+ clang_use_default_sample_profile=false
+ #android_ndk_major_version=22
+ )
+ endif()
else()
if(QT_FEATURE_use_lld_linker)
get_filename_component(clangBasePath ${CMAKE_LINKER} DIRECTORY)
@@ -1001,11 +1059,13 @@ macro(append_toolchain_setup)
list(APPEND gnArgArg
custom_toolchain="${buildDir}/target_toolchain:target"
host_toolchain="${buildDir}/host_toolchain:host"
- v8_snapshot_toolchain="${buildDir}/v8_toolchain:v8"
)
get_gn_arch(cpu ${TEST_architecture_arch})
if(CMAKE_CROSSCOMPILING)
- list(APPEND gnArgArg target_cpu="${cpu}")
+ list(APPEND gnArgArg
+ v8_snapshot_toolchain="${buildDir}/v8_toolchain:v8"
+ target_cpu="${cpu}"
+ )
else()
list(APPEND gnArgArg host_cpu="${cpu}")
endif()
@@ -1020,6 +1080,9 @@ macro(append_toolchain_setup)
list(APPEND gnArgArg target_sysroot="${sysroot}" target_os="ios")
endif()
endif()
+ if(ANDROID)
+ list(APPEND gnArgArg target_os="android")
+ endif()
endmacro()
@@ -1033,9 +1096,11 @@ macro(append_pkg_config_setup)
endmacro()
function(add_ninja_command)
- qt_parse_all_arguments(arg "add_ninja_command"
- "" "TARGET;OUTPUT;BUILDDIR;MODULE" "BYPRODUCTS" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "TARGET;OUTPUT;BUILDDIR;MODULE" "BYPRODUCTS"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
+
string(REPLACE " " ";" NINJAFLAGS "$ENV{NINJAFLAGS}")
list(TRANSFORM arg_BYPRODUCTS PREPEND "${arg_BUILDDIR}/")
add_custom_command(
@@ -1134,9 +1199,10 @@ function(get_config_filenames c_config cxx_config static_config target_config)
endfunction()
function(add_gn_command)
- qt_parse_all_arguments(arg "add_gn_command"
- "" "CMAKE_TARGET;GN_TARGET;MODULE;BUILDDIR" "NINJA_TARGETS;GN_ARGS" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "CMAKE_TARGET;GN_TARGET;MODULE;BUILDDIR" "NINJA_TARGETS;GN_ARGS"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
get_config_filenames(cConfigFileName cxxConfigFileName staticConfigFileName targetConfigFileName)
set(gnArgArgFile ${arg_BUILDDIR}/args.gn)
@@ -1145,7 +1211,7 @@ function(add_gn_command)
file(WRITE ${gnArgArgFile} ${arg_GN_ARGS})
foreach(ninjaTarget ${arg_NINJA_TARGETS})
- list(APPEND output ${ninjaTarget}_objects.rsp ${ninjaTarget}_archives.rsp ${ninjaTarget}_libs.rsp)
+ list(APPEND output ${ninjaTarget}_objects.rsp ${ninjaTarget}_archives.rsp ${ninjaTarget}_libs.rsp ${ninjaTarget}_lflags.rsp)
endforeach()
list(TRANSFORM output PREPEND "${arg_BUILDDIR}/")
@@ -1272,3 +1338,32 @@ function(add_build feature value)
set(depTracker "${depTracker}" ${feature})
set_property(GLOBAL PROPERTY MATRIX_DEPENDENCY_TRACKER "${depTracker}")
endfunction()
+
+function(add_code_attributions_target)
+ cmake_parse_arguments(PARSE_ARGV 0 arg ""
+ "TARGET;OUTPUT;GN_TARGET;FILE_TEMPLATE;ENTRY_TEMPLATE;BUILDDIR" ""
+ )
+ _qt_internal_validate_all_args_are_parsed(arg)
+ get_filename_component(fileTemplate ${arg_FILE_TEMPLATE} ABSOLUTE)
+ get_filename_component(entryTemplate ${arg_ENTRY_TEMPLATE} ABSOLUTE)
+ add_custom_command(
+ OUTPUT ${arg_OUTPUT}
+ COMMAND ${CMAKE_COMMAND}
+ -DLICENSE_SCRIPT=${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty/chromium/tools/licenses.py
+ -DFILE_TEMPLATE=${fileTemplate}
+ -DENTRY_TEMPLATE=${entryTemplate}
+ -DGN_TARGET=${arg_GN_TARGET}
+ -DBUILDDIR=${arg_BUILDDIR}
+ -DOUTPUT=${arg_OUTPUT}
+ -DPython3_EXECUTABLE=${Python3_EXECUTABLE}
+ -P ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/License.cmake
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_BUILD_DIR}
+ DEPENDS
+ ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty/chromium/tools/licenses.py
+ ${arg_FILE_TEMPLATE}
+ ${arg_ENTRY_TEMPLATE}
+ ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/License.cmake
+ USES_TERMINAL
+ )
+ add_custom_target(${arg_TARGET} DEPENDS ${arg_OUTPUT})
+endfunction()
diff --git a/cmake/Gn.cmake b/cmake/Gn.cmake
index 38556443b..41dccc11b 100644
--- a/cmake/Gn.cmake
+++ b/cmake/Gn.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# This is gn wrapper script and it assables final BUILD.gn based on:
# gn_config_target.cmake gn_config_c.cmake gn_config_cxx.cmake
diff --git a/cmake/License.cmake b/cmake/License.cmake
new file mode 100644
index 000000000..dc1e286f1
--- /dev/null
+++ b/cmake/License.cmake
@@ -0,0 +1,42 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT CMAKE_SCRIPT_MODE_FILE)
+ message("This files should run only in script mode")
+ return()
+endif()
+
+get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." REALPATH)
+get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
+
+include(${WEBENGINE_ROOT_SOURCE_DIR}/.cmake.conf)
+include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake)
+
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT)
+if(NOT Python3_EXECUTABLE)
+ find_package(Python3 3.6 REQUIRED)
+endif()
+
+execute_process(
+ COMMAND ${Python3_EXECUTABLE} ${LICENSE_SCRIPT}
+ --file-template ${FILE_TEMPLATE}
+ --entry-template ${ENTRY_TEMPLATE}
+ --gn-binary ${Gn_EXECUTABLE}
+ --gn-target ${GN_TARGET}
+ --gn-out-dir ${BUILDDIR}
+ credits ${OUTPUT}
+ WORKING_DIRECTORY ${BUILDDIR}
+ RESULT_VARIABLE gnResult
+ OUTPUT_VARIABLE gnOutput
+ ERROR_VARIABLE gnError
+ TIMEOUT 600
+)
+
+if(NOT gnResult EQUAL 0)
+ message(FATAL_ERROR "\n-- License FAILED\n${gnOutput}\n${gnError}\n${gnResult}\n")
+else()
+ string(REGEX REPLACE "\n$" "" gnOutput "${gnOutput}")
+ message("-- License ${gnOutput}")
+endif()
diff --git a/cmake/SubmoduleUpdate.cmake b/cmake/SubmoduleUpdate.cmake
new file mode 100644
index 000000000..123db55bf
--- /dev/null
+++ b/cmake/SubmoduleUpdate.cmake
@@ -0,0 +1,70 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT CMAKE_SCRIPT_MODE_FILE)
+ message("This file should run only in script mode")
+ return()
+endif()
+
+get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." REALPATH)
+get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
+
+include(${WEBENGINE_ROOT_SOURCE_DIR}/.cmake.conf)
+include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake)
+
+find_program(GIT_EXECUTABLE NAMES git REQUIRED)
+
+execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --short=8 HEAD
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty
+ OUTPUT_VARIABLE SUBMODULE_NEW_SHA
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --short=8 HEAD:src/3rdparty
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ OUTPUT_VARIABLE SUBMODULE_OLD_SHA
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+set(shas "${SUBMODULE_OLD_SHA}..${SUBMODULE_NEW_SHA}")
+set(format "* %s")
+execute_process(
+ COMMAND ${GIT_EXECUTABLE} log
+ --pretty=format:${format}
+ --abbrev-commit ${shas}
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty
+ OUTPUT_VARIABLE SUBMODULE_COMMITS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+if(SUBMODULE_COMMITS)
+ message("commits found for ${shas}")
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} add src/3rdparty
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ )
+ set(commits ${SUBMODULE_COMMITS})
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} commit
+ --allow-empty
+ -m "Update Chromium"
+ -m "Submodule src/3rdparty ${shas}:\n${commits}"
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ RESULT_VARIABLE gitResult
+ OUTPUT_VARIABLE gitOutput
+ ERROR_VARIABLE gitError
+ )
+
+ if(NOT gitResult EQUAL 0)
+ message(FATAL_ERROR "\n-- Git Commit FAILED\n${gitOutput}\n${gitError}\n${gitResult}\n")
+ else()
+ string(REGEX REPLACE "\n$" "" gnOutput "${gitOutput}")
+ message("-- Git Commit ${gitOutput}")
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} show HEAD
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ )
+ endif()
+else()
+ message(FATAL_ERROR "-- Git Commit found no commits for ${shas}")
+endif()
diff --git a/configure.cmake b/configure.cmake
index e8f2a6a3b..835017d5f 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(QT_CONFIGURE_RUNNING)
function(assertTargets)
endfunction()
@@ -15,6 +18,7 @@ else()
find_package(GPerf)
find_package(BISON)
find_package(FLEX)
+ find_package(Perl)
find_package(PkgConfig)
find_package(Snappy)
find_package(Nodejs 12.0)
@@ -34,14 +38,14 @@ if(PkgConfig_FOUND)
pkg_check_modules(X11 x11)
pkg_check_modules(XPROTO glproto)
pkg_check_modules(GLIB glib-2.0>=2.32.0)
- pkg_check_modules(HARFBUZZ harfbuzz>=2.9.0 harfbuzz-subset>=2.9.0)
+ pkg_check_modules(HARFBUZZ harfbuzz>=4.3.0 harfbuzz-subset>=4.3.0)
pkg_check_modules(JPEG libjpeg IMPORTED_TARGET)
pkg_check_modules(LIBEVENT libevent)
pkg_check_modules(MINIZIP minizip)
pkg_check_modules(PNG libpng>=1.6.0)
pkg_check_modules(ZLIB zlib)
pkg_check_modules(RE2 re2 IMPORTED_TARGET)
- pkg_check_modules(ICU icu-uc>=68 icu-i18n>=68)
+ pkg_check_modules(ICU icu-uc>=70 icu-i18n>=70)
pkg_check_modules(WEBP libwebp libwebpmux libwebpdemux)
pkg_check_modules(LCMS2 lcms2)
pkg_check_modules(FREETYPE freetype2 IMPORTED_TARGET)
@@ -50,6 +54,7 @@ if(PkgConfig_FOUND)
pkg_check_modules(OPUS opus>=1.3.1)
pkg_check_modules(VPX vpx>=1.10.0 IMPORTED_TARGET)
pkg_check_modules(LIBPCI libpci)
+ pkg_check_modules(LIBOPENJP2 libopenjp2)
endif()
if(Python3_EXECUTABLE)
@@ -327,6 +332,10 @@ qt_feature("webengine-system-libwebp" PRIVATE
LABEL "libwebp, libwebpmux and libwebpdemux"
CONDITION UNIX AND WEBP_FOUND
)
+qt_feature("webengine-system-libopenjpeg2" PRIVATE
+ LABEL "libopenjpeg2"
+ CONDITION UNIX AND LIBOPENJP2_FOUND
+)
qt_feature("webengine-system-opus" PRIVATE
LABEL "opus"
CONDITION UNIX AND OPUS_FOUND
@@ -401,7 +410,7 @@ qt_feature("webengine-system-harfbuzz" PRIVATE
CONDITION UNIX AND TARGET Qt::Gui AND HARFBUZZ_FOUND AND QT_FEATURE_system_harfbuzz
)
qt_feature("webengine-qt-harfbuzz" PRIVATE
- LABEL "qtpng"
+ LABEL "qtharfbuzz"
CONDITION QT_FEATURE_static
AND TARGET Qt::Gui
AND QT_FEATURE_harfbuzz
@@ -467,8 +476,8 @@ add_check_for_support(
)
add_check_for_support(
MODULES QtPdf
- CONDITION LINUX OR (WIN32 AND NOT WIN_ARM_64) OR MACOS OR IOS
- MESSAGE "Build can be done only on Linux, Windows, macOS or iOS."
+ CONDITION LINUX OR (WIN32 AND NOT WIN_ARM_64) OR MACOS OR IOS OR (ANDROID AND NOT CMAKE_HOST_WIN32)
+ MESSAGE "Build can be done only on Linux, Windows, macO, iOS and Android(on non-Windows hosts only)."
)
if(LINUX AND CMAKE_CROSSCOMPILING)
get_gn_arch(testArch ${TEST_architecture_arch})
@@ -577,7 +586,8 @@ add_check_for_support(
(WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL Clang AND
CMAKE_CXX_SIMULATE_ID STREQUAL MSVC) OR
(MACOS AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang) OR
- (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang)
+ (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang) OR
+ (ANDROID AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
MESSAGE "${CMAKE_CXX_COMPILER_ID} compiler is not supported."
)
@@ -635,6 +645,7 @@ if(UNIX)
qt_configure_add_summary_entry(ARGS "webengine-system-lcms2")
qt_configure_add_summary_entry(ARGS "webengine-system-libpng")
qt_configure_add_summary_entry(ARGS "webengine-system-libjpeg")
+ qt_configure_add_summary_entry(ARGS "webengine-system-libopenjpeg2")
qt_configure_add_summary_entry(ARGS "webengine-system-harfbuzz")
qt_configure_add_summary_entry(ARGS "webengine-system-freetype")
qt_configure_add_summary_entry(ARGS "webengine-system-libpci")
@@ -677,3 +688,10 @@ if(PRINT_BFD_LINKER_WARNING)
MESSAGE "Using bfd linker requires at least 4096 open files limit"
)
endif()
+if(NOT FEATURE_webengine_opus_system AND NOT Perl_FOUND)
+ qt_configure_add_report_entry(
+ TYPE WARNING
+ MESSAGE "No perl found, compiling opus without some optimizations."
+ )
+endif()
+
diff --git a/dependencies.yaml b/dependencies.yaml
index 8d9f516eb..710f0a330 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
dependencies:
../tqtc-qtdeclarative:
- ref: 9919f58fce6329a233ca885188d0aba5f484e546
+ ref: a1b4a68d1165115779ac925f43847a5735671917
required: true
../tqtc-qtpositioning:
- ref: 176a6cef64278b3d68df0ffb03a1aeff4eb65238
+ ref: 17bde3b93354f8d706ccfa7077f278e8d6d4c2f7
required: false
../tqtc-qttools:
- ref: 2819de71fc973e79aa9b1e44716636ab194108b1
+ ref: b84d5a96ee7cfa4a69d4963c771b230613224a15
required: false
../tqtc-qtwebchannel:
- ref: e9fd688bf25f72dc257790dfb394366b214a4380
+ ref: bf6ea7cf2ada25f52bdd9aba02c69f51b1c437be
required: false
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index ccad90e11..2d3ccab7e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
qt_examples_build_begin(EXTERNAL_BUILD)
diff --git a/examples/pdf/CMakeLists.txt b/examples/pdf/CMakeLists.txt
index 265d2ab8f..f1d45d477 100644
--- a/examples/pdf/CMakeLists.txt
+++ b/examples/pdf/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_example(pdfviewer)
qt_internal_add_example(multipage)
if(NOT TARGET Qt::Svg)
diff --git a/examples/pdf/multipage/CMakeLists.txt b/examples/pdf/multipage/CMakeLists.txt
index 92c2bce22..25cc726ed 100644
--- a/examples/pdf/multipage/CMakeLists.txt
+++ b/examples/pdf/multipage/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(multipage LANGUAGES CXX)
diff --git a/examples/pdf/multipage/viewer.qml b/examples/pdf/multipage/viewer.qml
index fcf326869..d0b0a7263 100644
--- a/examples/pdf/multipage/viewer.qml
+++ b/examples/pdf/multipage/viewer.qml
@@ -412,7 +412,7 @@ ApplicationWindow {
Layout.bottomMargin: 3
onAccepted: {
sidebar.open()
- sidebarTabs.setCurrentIndex(0)
+ sidebarTabs.setCurrentIndex(1)
}
Image {
visible: searchField.text !== ""
diff --git a/examples/pdf/pdfviewer/CMakeLists.txt b/examples/pdf/pdfviewer/CMakeLists.txt
index 179734dc4..b664fb6f2 100644
--- a/examples/pdf/pdfviewer/CMakeLists.txt
+++ b/examples/pdf/pdfviewer/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(pdfviewer LANGUAGES CXX)
diff --git a/examples/pdfwidgets/pdfviewer/CMakeLists.txt b/examples/pdfwidgets/pdfviewer/CMakeLists.txt
index e1d2fb580..901509f62 100644
--- a/examples/pdfwidgets/pdfviewer/CMakeLists.txt
+++ b/examples/pdfwidgets/pdfviewer/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(pdfviewer LANGUAGES CXX)
diff --git a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
index 8a60e06d6..e585a84ef 100644
--- a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
+++ b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
@@ -6,12 +6,10 @@
\meta installpath pdfwidgets
\ingroup qtpdf-examples
- \title PDF Viewer Example
+ \title PDF Viewer Widget Example
\brief A widget-based PDF viewer that allows scrolling through the pages.
- \omit
- //! TODO add thumbnail \image pdfviewer.png
- \endomit
+ \image pdfviewer.png
\e {PDF Viewer} demonstrates how to use the QPdfView class to render
PDF documents and the QPdfPageNavigator class to navigate them.
diff --git a/examples/webenginequick/CMakeLists.txt b/examples/webenginequick/CMakeLists.txt
index dc42b3dfe..52ba7cb0b 100644
--- a/examples/webenginequick/CMakeLists.txt
+++ b/examples/webenginequick/CMakeLists.txt
@@ -1,9 +1,5 @@
-qt_internal_add_example(customdialogs)
-qt_internal_add_example(customtouchhandle)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_example(lifecycle)
-qt_internal_add_example(minimal)
qt_internal_add_example(quicknanobrowser)
-qt_internal_add_example(webengineaction)
-if(TARGET Qt::QuickControls2)
- qt_internal_add_example(recipebrowser)
-endif()
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.png
deleted file mode 100644
index 042712f5c..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.png
deleted file mode 100644
index 41828d36d..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-color1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-color1.png
deleted file mode 100644
index 7f0492f87..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-color1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-color2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-color2.png
deleted file mode 100644
index 9087fdf14..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-color2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-file1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-file1.png
deleted file mode 100644
index 5023ced6f..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-file1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-file2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-file2.png
deleted file mode 100644
index aa25579d7..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-file2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-menu.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-menu.png
deleted file mode 100644
index 3409c951c..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-menu.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.png
deleted file mode 100644
index c34080b4d..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.png
deleted file mode 100644
index 2c8d92649..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.png
deleted file mode 100644
index 498de9595..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs.png b/examples/webenginequick/customdialogs/doc/images/customdialogs.png
deleted file mode 100644
index c42114a16..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc b/examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc
deleted file mode 100644
index d89d76f71..000000000
--- a/examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginequick/customdialogs
- \title WebEngine Qt Quick Custom Dialogs Example
- \ingroup webengine-examples
- \brief Customizes UI elements of \QWE's dialogs.
-
- \image customdialogs.png
-
- A web page might request dialogs for various purposes, such as
- authentication, picking colors, choosing files, and responding to JavaScript
- alerts, confirmation requests, and prompts.
-
- \e {Custom Dialogs} demonstrates how to use WebEngine dialog request objects
- to implement custom dialogs for use instead of the default dialogs.
-
- \include examples-run.qdocinc
-
- \section1 UI Elements of WebEngineView
-
- In this example, we create a simple \c index.html page that contains buttons
- and text fields for triggering a context menu and the following dialogs:
-
- \list
- \li HTTP Authentication Dialog
- \li Proxy Authentication Dialog
- \li JavaScript Alert, Confirm, and Prompt Dialogs
- \li Color Picker Dialog
- \li File Picker Dialog
- \endlist
-
- \section1 Triggering Dialogs
-
- As mentioned, the \c index.html file is responsible for triggering the
- dialogs from the side of HTML and JavaScript. Additionally, the example
- program starts a localhost TCP server returning the mocked HTTP responses
- needed to trigger proxy and HTTP authentication dialogs.
-
- \section1 Custom Dialogs
-
- The custom dialogs are just \e {Qt Quick Designer UI Forms} without any
- business logic. The point here is to present the glue code that is required
- to display the custom dialog for a particular web engine dialog or a menu
- request.
-
- \section1 Creating the Main Window
-
- In \c main.cpp, we initialize the WebEngine the same way as in the
- \l {WebEngine Qt Quick Minimal Example}:
-
- \quotefromfile webenginequick/customdialogs/main.cpp
- \skipto main
- \printuntil }
-
- In addition, we set up a proxy and a TCP server to be able to simulate proxy
- and HTTP authetication requests.
-
- In \c main.qml, we create a top level window, which contains a StackView
- with a SwitchButton and a WebView:
-
- \quotefromfile webenginequick/customdialogs/main.qml
- \skipto Window
- \printuntil Component
- \printuntil }
- \printline }
-
- \section1 Handling Web Engine Requests
-
- In this example, we implement the handling of the following web engine
- requests:
-
- \list
- \li ContextMenuRequest
- \li AuthenticationDialogRequest
- \li JavaScriptDialogRequest
- \li ColorDialogRequest
- \li FileDialogRequest
- \endlist
-
- \section2 Context Menu Requests
-
- \l [QML]{ContextMenuRequest} is a request object that is passed as a
- parameter of the WebEngineView::contextMenuRequested signal. We use the
- \c onContextMenuRequested signal handler to handle requests for
- \c #openMenu URL links:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onContextMenuRequested
- \printuntil }
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- The first text field from the top on our page triggers the request. Next,
- we check whether we should use the default menu. If not, we accept the
- request and switch the view to show the \c MenuForm:
-
- \image customdialogs-menu.png
-
- \quotefromfile webenginequick/customdialogs/forms/Menu.qml
- \skipto MenuForm
- \printuntil }
- \printuntil }
-
- To keep things simple, we do not provide any logic on component completion,
- and we simply close the form on any action.
-
- \section2 Tooltip Requests
-
- \l [QML]{TooltipRequest} is a request object that is passed as a
- parameter of the WebEngineView::tooltipRequested signal. We use the
- \c onTooltipRequested signal handler to handle requests for
- custom tooltip menus at specific positions:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onTooltipRequested
- \printuntil }
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- The second text field from the top on our page triggers the request. Next,
- we check whether we should use the default menu. If not, we accept the
- request and show a custom QML element as tooltip:
-
- \image customdialogs-tooltip.png
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto Rectangle
- \printuntil }
-
- \section2 Authentication Dialog Requests
-
- \image customdialogs-auth1.png
-
- \l [QML]{AuthenticationDialogRequest} is a request object that is passed
- as a parameter of the WebEngineView::authenticationDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onAuthenticationDialogRequested
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- We use the \c onAuthenticationDialogRequested signal handler to check
- whether we should use the default authentication dialog. If not, we accept
- the request and switch the view to show the \c AuthenticationForm:
-
- \image customdialogs-auth2.png
-
- \quotefromfile webenginequick/customdialogs/forms/Authentication.qml
- \skipto AuthenticationForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we log the request type. The user can fill in the
- credentials and click \uicontrol Login. We provide \c onClicked handlers to
- accept or reject the authentication dialog. The TCP server on localhost does
- not handle real authentication, and therefore we call \c rejectDialog()
- instead of \c acceptDialog() also for the login button \c clicked signal.
-
- \section2 JavaScript Dialog Requests
-
- \image customdialogs-prompt1.png
-
- \l [QML]{JavaScriptDialogRequest} is a request object that is passed as a
- parameter of the WebEngineView::javaScriptDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onJavaScriptDialogRequested
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- We use the \c onJavaScriptDialogRequested signal handler to check
- whether we should use the default JavaScript dialog. If not, we accept the
- request and switch the view to show the \c JavaScriptForm:
-
- \image customdialogs-prompt2.png
-
- \quotefromfile webenginequick/customdialogs/forms/JavaScript.qml
- \skipto JavaScriptForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we customize the form based on the request type.
- For a JavaScript prompt dialog we use \c dialogAccept() with the
- \c prompt.text argument.
-
- \section2 Color Dialog Requests
-
- \image customdialogs-color1.png
-
- \l [QML]{ColorDialogRequest} is a request object that is passed as a
- parameter of the WebEngineView::colorDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onColorDialogRequested
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- We use the \c onColorDialogRequested signal handler to check whether
- we should use the default color picker dialog. If not, we accept the request
- and switch the view to show the \c ColorPickerForm:
-
- \image customdialogs-color2.png
-
- \quotefromfile webenginequick/customdialogs/forms/ColorPicker.qml
- \skipto ColorPickerForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we create callbacks for all the color cells. When
- the user selects the color and clicks \c OK, we pass the selected color to
- the \c dialogAccept() method.
-
- \section2 File Dialog Requests
-
- \image customdialogs-file1.png
-
- \l [QML]{FileDialogRequest} is a request object that is passed as a
- parameter of the WebEngineView::fileDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onFileDialogRequested
- \printuntil }
- \printuntil }
- \printuntil }
-
- We use the \c onFileDialogRequested signal handler to check whether
- we should use the default file picker dialog. If not, we accept the request
- and switch the view to show the \c FilePickerForm:
-
- \image customdialogs-file2.png
-
- \quotefromfile webenginequick/customdialogs/forms/FilePicker.qml
- \skipto FilePickerForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we create callbacks for selecting files. When the user selects a
- file and clicks \c OK, we pass the selected file to the \c dialogAccept
- method.
-
-*/
diff --git a/examples/webenginequick/customtouchhandle/CMakeLists.txt b/examples/webenginequick/customtouchhandle/CMakeLists.txt
deleted file mode 100644
index 3ec47e8bd..000000000
--- a/examples/webenginequick/customtouchhandle/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(customtouchhandle LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/customtouchhandle")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
-
-qt_add_executable(customtouchhandle
- main.cpp
-)
-
-set_target_properties(customtouchhandle PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(customtouchhandle PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineQuick
-)
-
-# Resources:
-set(qml_resource_files
- "main.qml"
-)
-
-qt6_add_resources(customtouchhandle "qml"
- PREFIX
- "/"
- FILES
- ${qml_resource_files}
-)
-
-install(TARGETS customtouchhandle
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/customtouchhandle/doc/images/customtouchhandle.jpg b/examples/webenginequick/customtouchhandle/doc/images/customtouchhandle.jpg
deleted file mode 100644
index bd65c083d..000000000
--- a/examples/webenginequick/customtouchhandle/doc/images/customtouchhandle.jpg
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customtouchhandle/doc/src/customtouchhandle.qdoc b/examples/webenginequick/customtouchhandle/doc/src/customtouchhandle.qdoc
deleted file mode 100644
index 742f65b6b..000000000
--- a/examples/webenginequick/customtouchhandle/doc/src/customtouchhandle.qdoc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginequick/customtouchhandle
- \title WebEngine Qt Quick Custom Touch Handle Example
- \ingroup webengine-examples
- \brief Shows custom touch handles upon touch selection events.
-
- \image customtouchhandle.jpg
-
- \e {WebEngine Qt Quick Touch Handle Example} demonstrates how to use
- custom touch handles when a touch selection event happens. It shows the
- minimum amount of code needed to use custom touch handle delegates, and
- can be used as a basis for further experimentation.
-
- \section1 Custom Touch Handle
-
- In \c main.qml we create the custom touch handle delegate.
-
- \quotefromfile webenginequick/customtouchhandle/main.qml
- \skipto WebEngineView
- \printuntil /^\ {4}\}/
-
- \section1 QML Code
-
- In \c main.qml we create the top level window filled by a
- \l{WebEngineView} item loading the \l{Qt Homepage}.
- To display custom touch handles, a QML item should be delegated to
- \l{WebEngineView::touchHandleDelegate}.
-
- The touch handle's position, opacity, and visibility is automatically updated.
-
- \note If no delegate is provided, Chromium's default touch handles will appear.
-
- \section1 Requirements
-
- The example requires a working internet connection to render the
- \l{Qt Homepage} and a touch-enabled input device to trigger touch
- events.
- An optional system proxy should be picked up automatically.
-*/
diff --git a/examples/webenginequick/lifecycle/CMakeLists.txt b/examples/webenginequick/lifecycle/CMakeLists.txt
index 556b50706..d0a378c13 100644
--- a/examples/webenginequick/lifecycle/CMakeLists.txt
+++ b/examples/webenginequick/lifecycle/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(lifecycle LANGUAGES CXX)
@@ -13,6 +16,7 @@ find_package(Qt6 REQUIRED COMPONENTS Core Gui QuickControls2 WebEngineQuick)
qt_add_executable(lifecycle
main.cpp
+ utils.h
)
set_target_properties(lifecycle PROPERTIES
diff --git a/examples/webenginequick/lifecycle/WebTab.qml b/examples/webenginequick/lifecycle/WebTab.qml
index d805628ad..6fb6cb386 100644
--- a/examples/webenginequick/lifecycle/WebTab.qml
+++ b/examples/webenginequick/lifecycle/WebTab.qml
@@ -132,7 +132,7 @@ ColumnLayout {
text: view.url == "about:blank" ? "" : view.url
selectByMouse: true
- onAccepted: { view.url = text }
+ onAccepted: { view.url = utils.fromUserInput(text) }
}
WebToolButton {
text: "â‹®"
diff --git a/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc
index b28e3e272..4d997b1c4 100644
--- a/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc
+++ b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc
@@ -31,6 +31,9 @@
window also has a \l {Drawer} for changing settings. The drawer can be
opened by clicking the "â‹®" button on the tool bar.
+ \note Note that \c {WebTab.qml} uses \l {QUrl::}
+ {fromUserInput} to handle incomplete URLs.
+
\section1 Lifecycle States in the Example
The example implements two ways of changing the lifecycle state: manual and
diff --git a/examples/webenginequick/lifecycle/lifecycle.pro b/examples/webenginequick/lifecycle/lifecycle.pro
index ccbe801f3..044d025d7 100644
--- a/examples/webenginequick/lifecycle/lifecycle.pro
+++ b/examples/webenginequick/lifecycle/lifecycle.pro
@@ -2,6 +2,7 @@ TEMPLATE = app
QT += quickcontrols2 webenginequick
+HEADERS += utils.h
SOURCES += main.cpp
RESOURCES += resources.qrc
diff --git a/examples/webenginequick/lifecycle/main.cpp b/examples/webenginequick/lifecycle/main.cpp
index 3601bdf5c..1f45ad0ee 100644
--- a/examples/webenginequick/lifecycle/main.cpp
+++ b/examples/webenginequick/lifecycle/main.cpp
@@ -1,6 +1,8 @@
-// Copyright (C) 2019 The Qt Company Ltd.
+// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+#include "utils.h"
+
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
@@ -12,6 +14,8 @@ int main(int argc, char *argv[])
QtWebEngineQuick::initialize();
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
+ Utils utils;
+ engine.rootContext()->setContextProperty("utils", &utils);
engine.load(QUrl(QStringLiteral("qrc:/WebBrowser.qml")));
return app.exec();
}
diff --git a/examples/webenginequick/lifecycle/utils.h b/examples/webenginequick/lifecycle/utils.h
new file mode 100644
index 000000000..d9a803907
--- /dev/null
+++ b/examples/webenginequick/lifecycle/utils.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QUrl>
+
+class Utils : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE static QUrl fromUserInput(const QString &userInput);
+};
+
+inline QUrl Utils::fromUserInput(const QString &userInput)
+{
+ QFileInfo fileInfo(userInput);
+ if (fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ return QUrl::fromUserInput(userInput);
+}
+
+#endif // UTILS_H
diff --git a/examples/webenginequick/minimal/CMakeLists.txt b/examples/webenginequick/minimal/CMakeLists.txt
deleted file mode 100644
index e0cb66733..000000000
--- a/examples/webenginequick/minimal/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(minimal LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/minimal-qml")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
-
-qt_add_executable(webengine-minimal-qml
- main.cpp
-)
-
-set_target_properties(webengine-minimal-qml PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(webengine-minimal-qml PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineQuick
-)
-
-# Resources:
-set(qml_resource_files
- "main.qml"
-)
-
-qt_add_resources(webengine-minimal-qml "qml"
- PREFIX
- "/"
- FILES
- ${qml_resource_files}
-)
-
-install(TARGETS webengine-minimal-qml
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/minimal/doc/src/minimal.qdoc b/examples/webenginequick/minimal/doc/src/minimal.qdoc
deleted file mode 100644
index aed74a7f5..000000000
--- a/examples/webenginequick/minimal/doc/src/minimal.qdoc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginequick/minimal
- \title WebEngine Qt Quick Minimal Example
- \ingroup webengine-examples
- \brief Displays a web page using the Qt Quick integration of \QWE.
-
- \image minimal-example.png
-
- \e {WebEngine Qt Quick Minimal Example} demonstrates how to use the
- \l{WebEngineView} item to render a web page. It shows the minimum amount of
- code needed to load and display an HTML page, and can be used as a basis for
- further experimentation.
-
- \include examples-run.qdocinc
-
- \section1 C++ Code
-
- In \c main.cpp we use only the QGuiApplication and QQmlApplicationEngine
- classes. We also include \c qtwebengineglobal.h to be able to use
- \l{QtWebEngineQuick::initialize}.
-
- \quotefromfile webenginequick/minimal/main.cpp
- \skipto #include
- \printto main
-
- In the \c main function we first set the
- \l{QCoreApplication::organizationName} property. This affects the locations
- where \QWE stores persistent and cached data (see also
- \l{WebEngineProfile::cachePath} and
- \l{WebEngineProfile::persistentStoragePath}).
-
- Next, we call \l{QtWebEngineQuick::initialize}, which makes sure that OpenGL
- contexts can be shared between the main process and the dedicated renderer
- process (\c QtWebEngineProcess). This method needs to be called before
- any OpenGL context is created.
-
- Then we create a QQmlApplicationEngine, and tell it to load \c main.qml
- from the \l{The Qt Resource System}{Qt Resource System}.
-
- Finally, QGuiApplication::exec() launches the main event loop.
-
- \printuntil }
-
- \section1 QML Code
-
- In \c main.qml we create the top level window, set a sensible default size
- and make it visible. The window will be filled by a WebEngineView item
- loading the \l{Qt Homepage}.
-
- \quotefromfile webenginequick/minimal/main.qml
- \skipto import
- \printuntil }
- \printline }
-
- \section1 Requirements
-
- The example requires a working internet connection to render the
- \l{Qt Homepage}.
- An optional system proxy should be picked up automatically.
-*/
diff --git a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
index ef4af5d4f..9c257de3c 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
@@ -4,7 +4,7 @@
import Qt.labs.settings
import QtQml
import QtQuick
-import QtQuick.Controls
+import QtQuick.Controls.Fusion
import QtQuick.Layouts
import QtQuick.Window
import QtWebEngine
@@ -471,7 +471,6 @@ ApplicationWindow {
}
function removeView(index) {
- tabBar.removeItem(index);
if (tabBar.count > 1) {
tabBar.removeItem(tabBar.itemAt(index));
tabLayout.children[index].destroy();
@@ -559,13 +558,6 @@ ApplicationWindow {
request.accept();
}
- onQuotaRequested: function(request) {
- if (request.requestedSize <= 5 * 1024 * 1024)
- request.accept();
- else
- request.reject();
- }
-
onRegisterProtocolHandlerRequested: function(request) {
console.log("accepting registerProtocolHandler request for "
+ request.scheme + " from " + request.origin);
@@ -610,6 +602,12 @@ ApplicationWindow {
findBar.reset();
}
+ onFeaturePermissionRequested: function(securityOrigin, feature) {
+ featurePermissionDialog.securityOrigin = securityOrigin;
+ featurePermissionDialog.feature = feature;
+ featurePermissionDialog.visible = true;
+ }
+
Timer {
id: reloadTimer
interval: 0
@@ -648,22 +646,21 @@ ApplicationWindow {
Dialog {
id: sslDialog
anchors.centerIn: parent
- contentWidth: Math.max(mainText.width, detailedText.width)
- contentHeight: mainText.height + detailedText.height
+ contentWidth: Math.max(mainTextForSSLDialog.width, detailedTextForSSLDialog.width)
+ contentHeight: mainTextForSSLDialog.height + detailedTextForSSLDialog.height
property var certErrors: []
// fixme: icon!
// icon: StandardIcon.Warning
standardButtons: Dialog.No | Dialog.Yes
title: "Server's certificate not trusted"
contentItem: Item {
- id: textContentItem
Label {
- id: mainText
+ id: mainTextForSSLDialog
text: "Do you wish to continue?"
}
Text {
- id: detailedText
- anchors.top: mainText.bottom
+ id: detailedTextForSSLDialog
+ anchors.top: mainTextForSSLDialog.bottom
text: "If you wish so, you may continue with an unverified certificate.\n" +
"Accepting an unverified certificate means\n" +
"you may not be connected with the host you tried to connect to.\n" +
@@ -689,6 +686,68 @@ ApplicationWindow {
visible = certErrors.length > 0
}
}
+ Dialog {
+ id: featurePermissionDialog
+ anchors.centerIn: parent
+ width: Math.min(browserWindow.width, browserWindow.height) / 3 * 2
+ contentWidth: mainTextForPermissionDialog.width
+ contentHeight: mainTextForPermissionDialog.height
+ standardButtons: Dialog.No | Dialog.Yes
+ title: "Permission Request"
+
+ property var feature;
+ property url securityOrigin;
+
+ contentItem: Item {
+ Label {
+ id: mainTextForPermissionDialog
+ text: featurePermissionDialog.questionForFeature()
+ }
+ }
+
+ onAccepted: currentWebView && currentWebView.grantFeaturePermission(securityOrigin, feature, true)
+ onRejected: currentWebView && currentWebView.grantFeaturePermission(securityOrigin, feature, false)
+ onVisibleChanged: {
+ if (visible)
+ width = contentWidth + 20;
+ }
+
+ function questionForFeature() {
+ var question = "Allow " + securityOrigin + " to "
+
+ switch (feature) {
+ case WebEngineView.Geolocation:
+ question += "access your location information?";
+ break;
+ case WebEngineView.MediaAudioCapture:
+ question += "access your microphone?";
+ break;
+ case WebEngineView.MediaVideoCapture:
+ question += "access your webcam?";
+ break;
+ case WebEngineView.MediaVideoCapture:
+ question += "access your microphone and webcam?";
+ break;
+ case WebEngineView.MouseLock:
+ question += "lock your mouse cursor?";
+ break;
+ case WebEngineView.DesktopVideoCapture:
+ question += "capture video of your desktop?";
+ break;
+ case WebEngineView.DesktopAudioVideoCapture:
+ question += "capture audio and video of your desktop?";
+ break;
+ case WebEngineView.Notifications:
+ question += "show notification on your desktop?";
+ break;
+ default:
+ question += "access unknown or unsupported feature [" + feature + "] ?";
+ break;
+ }
+
+ return question;
+ }
+ }
FullScreenNotification {
id: fullScreenNotification
diff --git a/examples/webenginequick/quicknanobrowser/CMakeLists.txt b/examples/webenginequick/quicknanobrowser/CMakeLists.txt
index a12570225..ac41569aa 100644
--- a/examples/webenginequick/quicknanobrowser/CMakeLists.txt
+++ b/examples/webenginequick/quicknanobrowser/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(quicknanobrowser LANGUAGES CXX)
@@ -32,6 +35,7 @@ target_link_libraries(quicknanobrowser PUBLIC
qt_add_qml_module(quicknanobrowser
URI BrowserUtils
VERSION 1.0
+ RESOURCE_PREFIX /
)
# Resources:
diff --git a/examples/webenginequick/quicknanobrowser/DownloadView.qml b/examples/webenginequick/quicknanobrowser/DownloadView.qml
index e16647cdb..421b4f55c 100644
--- a/examples/webenginequick/quicknanobrowser/DownloadView.qml
+++ b/examples/webenginequick/quicknanobrowser/DownloadView.qml
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
-import QtQuick.Controls
+import QtQuick.Controls.Fusion
import QtWebEngine
import QtQuick.Layouts
diff --git a/examples/webenginequick/quicknanobrowser/FindBar.qml b/examples/webenginequick/quicknanobrowser/FindBar.qml
index 4d130a22b..409d8dcff 100644
--- a/examples/webenginequick/quicknanobrowser/FindBar.qml
+++ b/examples/webenginequick/quicknanobrowser/FindBar.qml
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
-import QtQuick.Controls
+import QtQuick.Controls.Fusion
import QtQuick.Layouts
Rectangle {
@@ -51,6 +51,7 @@ Rectangle {
TextField {
id: findTextField
anchors.fill: parent
+ color: "black"
background: Rectangle {
color: "transparent"
}
@@ -64,6 +65,7 @@ Rectangle {
Label {
text: activeMatch + "/" + numberOfMatches
visible: findTextField.text != ""
+ color: "black"
}
Rectangle {
@@ -79,17 +81,29 @@ Rectangle {
text: "<"
enabled: numberOfMatches > 0
onClicked: root.findPrevious()
+ contentItem: Text {
+ color: "black"
+ text: parent.text
+ }
}
ToolButton {
text: ">"
enabled: numberOfMatches > 0
onClicked: root.findNext()
+ contentItem: Text {
+ color: "black"
+ text: parent.text
+ }
}
ToolButton {
text: "x"
onClicked: root.visible = false
+ contentItem: Text {
+ color: "black"
+ text: parent.text
+ }
}
}
}
diff --git a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
index b1910df95..ee94e0fd7 100644
--- a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
+++ b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
@@ -91,6 +91,31 @@
\skipto Dialog {
\printuntil /^\ {4}\}/
+ \section1 Handling Feature Permission Requests
+
+ We use the \c onFeaturePermissionRequested() signal handler to handle requests for
+ accessing a certain feature or device. The \c securityOrigin parameter identifies the
+ requester web site, and the \c feature parameter is the requested feature. We use these
+ to construct the message of the dialog:
+
+ \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml
+ \skipto onFeaturePermissionRequested
+ \printuntil }
+
+ We show a dialog where the user is asked to grant or deny access. The custom
+ \c questionForFeature() JavaScript function generates a human-readable question about
+ the request.
+ If users select \uicontrol Yes, we call the \l{WebEngineView::}{grantFeaturePermission()}
+ method with a third \c true parameter to grant the \c securityOrigin web site the permission
+ to access the \c feature.
+ If users select \uicontrol No, we call the same method but with the \c false parameter to
+ deny access:
+
+ \skipto id: sslDialog
+ \skipto Dialog {
+ \printuntil /^\ {4}\}/
+
+
\section1 Entering and Leaving Fullscreen Mode
We create a menu item for allowing fullscreen mode in a settings menu that we place on the tool
diff --git a/examples/webenginequick/quicknanobrowser/main.cpp b/examples/webenginequick/quicknanobrowser/main.cpp
index 519cfd089..850b8c443 100644
--- a/examples/webenginequick/quicknanobrowser/main.cpp
+++ b/examples/webenginequick/quicknanobrowser/main.cpp
@@ -12,6 +12,7 @@
#include <QtCore/QCommandLineParser>
#include <QtCore/QCommandLineOption>
+#include <QtCore/QLoggingCategory>
static QUrl startupUrl(const QCommandLineParser &parser)
{
@@ -31,6 +32,7 @@ int main(int argc, char **argv)
QtWebEngineQuick::initialize();
QGuiApplication app(argc, argv);
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.webenginecontext.debug=true"));
QCommandLineParser parser;
parser.addHelpOption();
diff --git a/examples/webenginequick/recipebrowser/CMakeLists.txt b/examples/webenginequick/recipebrowser/CMakeLists.txt
deleted file mode 100644
index 57a73b4aa..000000000
--- a/examples/webenginequick/recipebrowser/CMakeLists.txt
+++ /dev/null
@@ -1,155 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(recipebrowser LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/recipebrowser")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick QuickControls2 WebEngineQuick)
-
-qt_add_executable(recipebrowser
- main.cpp
-)
-
-set_target_properties(recipebrowser PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(recipebrowser PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Qml
- Qt::Quick
- Qt::QuickControls2
- Qt::WebEngineQuick
-)
-
-# Resources:
-set_source_files_properties("resources/pages/assets/3rdparty/markdown.css"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/assets/3rdparty/marked.js"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/assets/custom.css"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/assets/custom.js"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/burger.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/cupcakes.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/images/burger.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/images/cupcakes.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/images/pasta.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/images/pizza.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/images/skewers.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/images/soup.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/images/steak.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/pasta.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/pizza.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/skewers.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/soup.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/pages/steak.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/qml/RecipeList.qml"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set_source_files_properties("resources/qml/main.qml"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-
-set(resources_resource_files
- "resources/pages/assets/3rdparty/markdown.css"
- "resources/pages/assets/3rdparty/marked.js"
- "resources/pages/assets/custom.css"
- "resources/pages/assets/custom.js"
- "resources/pages/burger.html"
- "resources/pages/cupcakes.html"
- "resources/pages/images/burger.jpg"
- "resources/pages/images/cupcakes.jpg"
- "resources/pages/images/pasta.jpg"
- "resources/pages/images/pizza.jpg"
- "resources/pages/images/skewers.jpg"
- "resources/pages/images/soup.jpg"
- "resources/pages/images/steak.jpg"
- "resources/pages/pasta.html"
- "resources/pages/pizza.html"
- "resources/pages/skewers.html"
- "resources/pages/soup.html"
- "resources/pages/steak.html"
- "resources/qml/main.qml"
- "resources/qml/RecipeList.qml"
-)
-
-qt_add_resources(recipebrowser "resources"
- PREFIX
- "/"
- BASE
- "resources"
- FILES
- ${resources_resource_files}
-)
-
-if(CMAKE_CROSSCOMPILING AND (LINUX OR QNX OR posix))
- target_compile_definitions(recipebrowser PUBLIC
- QTWEBENGINE_RECIPE_BROWSER_EMBEDDED
- )
-endif()
-
-install(TARGETS recipebrowser
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpg b/examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpg
deleted file mode 100644
index 761ad3576..000000000
--- a/examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpg
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc b/examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc
deleted file mode 100644
index d2de5780c..000000000
--- a/examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginequick/recipebrowser
- \title WebEngine Recipe Browser
- \ingroup webengine-examples
- \brief A small hybrid application based on the WebEngineView QML type and Qt Quick Controls 2.
-
- \image recipebrowser-demo.jpg
-
- \e {Recipe Browser} demonstrates how to use the \l{WebEngineView} item, \l{Qt Quick} items, and
- \l{Qt Quick Controls 2} items to develop a small hybrid web browser application.
- A \l{ListView}-based item is used to display a list of recipe names. Clicking on
- a name causes the web view to load the respective recipe page. The overall appearance
- of the application is provided by the \l{Qt Quick Controls 2} items, which have their active
- style set to the \l{Material Style}{Material} style. The web content is a mix of HTML and
- Markdown source compiled to HTML, along with CSS and JavaScript.
-
- \include examples-run.qdocinc
-
- \section1 C++ Code
-
- In \c main.cpp, we use the \l{QGuiApplication} and \l{QQmlApplicationEngine}
- classes to set up and load the main QML file. We call \l{QtWebEngineQuick::initialize} so we can use
- \l{WebEngineView} in our QML code. We set the default Qt Quick Controls 2 style
- to the Material style, so we do not have to specify it for each new item we add. Finally, we use
- a C++ define to check whether the application is compiled for an embedded platform.
- The value will be used in the main QML code to determine the window size.
-
- \quotefromfile webenginequick/recipebrowser/main.cpp
- \skipto #include
- \printuntil }
-
- \section1 QML Code
-
- In the \c main.qml file, we first create a top-level window and set a title for it. We also set
- up the size of the window depending on its primary orientation as well as the platform, so that
- the application is usable on both desktop and embedded platforms. On desktop, the size
- is constrained by a minimum of 320x480 pixels up to the maximum size that the screen supports.
- The default window size is 1024 pixels wide and 768 pixels high in landscape orientation.
- On embedded devices, the window will occupy the whole screen.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
- \skipto ApplicationWindow
- \printuntil minimumHeight
-
- Next, we add a \l{RowLayout} item so we can divide the window into two parts: one being a
- custom \c RecipeList item containing the recipe titles, and the other being the
- \l{WebEngineView}, which shows the recipe details. The spacing is set to zero so the items are
- positioned directly next to each other.
-
- \printuntil RecipeList
- \dots 16
- \skipuntil webView.showRecipe
- \printline }
- \printuntil WebEngineView
- \dots 16
- \skipuntil busy.running = true
- \skipline }
- \skipline }
- \printline }
- \printline }
-
- The \c RecipeList item has a few \l{Layout}{attached Layout properties}, in order to scale the
- item to a maximum of one third of the layout width. We give the item focus, so that the keyboard
- can be used to navigate the recipes, in addition to using mouse and touch. We also add a handler
- for the custom \c recipeSelected signal, to tell the WebEngineView to load the URL of the
- selected recipe.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
- \skipto RecipeList
- \printuntil }
-
- The WebEngineView has similar layout properties, to make it occupy two thirds of the layout
- width.
-
- \skipto WebEngineView
- \printuntil Layout.fillHeight
-
- We then disable the \l{WebEngineSettings::focusOnNavigationEnabled}{focusOnNavigationEnabled}
- setting to make sure that the \l{WebEngineView} does not steal focus from the \c RecipeList
- item every time its URL is changed. This allows the user to continue navigating through the
- recipes using the keyboard. We also disable the default context menu by accepting the
- ContextMenuRequest.
-
- \skipto focusOnNavigationEnabled
- \printuntil }
-
- When the application starts, instead of directly showing the \l{WebEngineView}, we show a
- placeholder \l{Rectangle} with a \l{BusyIndicator} to provide a nicer user experience while the
- application is loading.
-
- \printuntil }
- \dots 12
- \skipto Rectangle
- \printuntil }
-
- Once the first page in the view is loaded, we start a \l{Timer} that
- will hide the placeholder and show the actual page. The delay provides more time for the recipe
- images to load, so that when the view is shown, the page is completely rendered. The timer also
- shows a help \l{ToolTip} that informs the user on how to navigate the recipes.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
- \skipto Timer {
- \printuntil }
-
- Let's see what the \c RecipeList item looks like from the inside. The root item is a
- FocusScope to allow transferring focus to the child ListView whenever the root item receives
- focus. We also declare a custom \c recipeSelected signal, which will be emitted when the current
- item of the ListView changes.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/RecipeList.qml
- \skipto FocusScope
- \printuntil recipeSelected
-
- A ColumnLayout holds a header \l{Label} above the ListView, and the ListView itself.
- Again, we set the spacing to zero and make sure the layout occupies the whole space of
- the parent item.
-
- \skipto ColumnLayout
- \printuntil anchors.fill
-
- Inside the layout there is a styled \l{ToolBar} item, with a \l{Label} inside of it serving as
- the ListView header.
-
- \skipto ToolBar
- \printuntil Label
- \printuntil }
- \printuntil }
-
- The second item inside the layout is a \l{ListView}, whose contents will fill the remaining
- space in the layout. We set \l{Item::}{clip} to true, so that the delegates that are scrolled
- up are not seen under the ToolBar item. We set \l{Item::}{focus} to true, so the ListView gains
- focus when the FocusScope does. We add a vertical scroll bar, so the user can scroll through the
- recipes if the window size is small. We also specify the recipe model to be used by the
- ListView as described later in this topic.
-
- \skipto ListView
- \printuntil model
-
- We have an \l{ItemDelegate} set as the ListView delegate, which displays the
- recipe title. The contentItem is a \l{Text} item, customized with a few properties to adjust the
- visual appearance and position of the text. We create a binding to the current delegate's model
- URL, so we can access the respective URL outside the delegate itself. We set the
- \l{ItemDelegate::}{highlighted} property to \c true whenever the item is the current one in the
- ListView to provide visual feedback. And we set the focus on the ListView whenever a delegate
- is clicked, so that keyboard navigation works in case the focus was previously in the
- WebEngineView.
-
- \skipto delegate
- \printuntil onClicked
- \printuntil }
- \printuntil }
-
- A handler is defined for the \c currentItemChanged signal to emit our own \c recipeSelected
- signal with the URL that the WebEngineView should load.
-
- \skipto onCurrentItemChanged
- \printuntil }
-
- We use a \l{ListModel} with seven \l{ListElement}s, each of which contains a recipe
- title and the URL to an HTML page contained in a resource file. The model is used to populate
- the ListView with the recipes and to show the recipe details in the WebEngineView.
-
- \skipto ListModel
- \printuntil Cupcakes
- \printuntil }
- \printuntil }
-
- We use a \l{ToolTip} item that is displayed on application startup to inform the users
- how they can navigate and view the details of each recipe. The ToolTip is shown using the
- \c showHelp method, which is invoked by the \l{Timer} in the main.qml file.
-
- \skipto ToolTip
- \printuntil help.open()
- \printuntil }
- \printuntil }
-
- An example of a recipe page can be seen below. The page uses two stylesheets and
- two JavaScript files:
- \list
- \li \l{https://bitbucket.org/kevinburke/markdowncss/src/master/}{markdown.css} is
- a markdown-friendly stylesheet created by Kevin Burke
- \li \l{https://github.com/chjj/marked}{marked.min.js} is a markdown parser and
- compiler designed for speed written by Christopher Jeffrey
- \li custom.css makes some small styling adjustments to the final recipe page
- \li custom.js is used to invoke the conversion of the recipe content (which is written in
- markdown syntax) into HTML
- \endlist
-
- The images on the pages are loaded from the compiled resource file.
-
- \quotefromfile webenginequick/recipebrowser/resources/pages/soup.html
- \printuntil </html>
-
- \section1 Files and Attributions
-
- The example bundles the following code with third-party licenses:
-
- \table
- \row
- \li \l{recipebrowser-marked}{Marked}
- \li MIT License
- \row
- \li \l{recipebrowser-markdowncss}{Markdown.css}
- \li Apache License 2.0
- \endtable
-*/
diff --git a/examples/webenginequick/recipebrowser/main.cpp b/examples/webenginequick/recipebrowser/main.cpp
deleted file mode 100644
index 076a3be9a..000000000
--- a/examples/webenginequick/recipebrowser/main.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QGuiApplication>
-#include <QQmlApplicationEngine>
-#include <QQmlContext>
-#include <QQuickStyle>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- QtWebEngineQuick::initialize();
-
- QGuiApplication app(argc, argv);
-
- QQuickStyle::setStyle(QStringLiteral("Material"));
-
- QQmlApplicationEngine engine;
-
- bool isEmbedded = false;
-#ifdef QTWEBENGINE_RECIPE_BROWSER_EMBEDDED
- isEmbedded = true;
-#endif
- engine.rootContext()->setContextProperty(QStringLiteral("isEmbedded"), isEmbedded);
-
- engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
-
- return app.exec();
-}
diff --git a/examples/webenginequick/recipebrowser/recipebrowser.pro b/examples/webenginequick/recipebrowser/recipebrowser.pro
deleted file mode 100644
index e358d00a3..000000000
--- a/examples/webenginequick/recipebrowser/recipebrowser.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-TEMPLATE = app
-
-QT += quick qml quickcontrols2 webenginequick
-
-cross_compile {
- posix|qnx|linux: DEFINES += QTWEBENGINE_RECIPE_BROWSER_EMBEDDED
-}
-
-SOURCES += main.cpp
-
-RESOURCES += resources/resources.qrc
-
-# Make sure Qt Quick compiler does not remove the source code of the .js files.
-QTQUICK_COMPILER_SKIPPED_RESOURCES = resources/resources.qrc
-
-DISTFILES += \
- resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt \
- resources/pages/assets/3rdparty/MARKED-LICENSE.txt
-
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginequick/recipebrowser
-INSTALLS += target
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json b/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json
deleted file mode 100644
index 4dafa1acd..000000000
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json
+++ /dev/null
@@ -1,34 +0,0 @@
-[
- {
- "Id": "recipebrowser-marked",
- "Name": "Marked (WebEngine RecipeBrowser example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "Marked is used in the WebEngine RecipeBrowser example",
- "QtParts": [ "examples" ],
- "Files": "marked.js",
- "Description": "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
- "Homepage": "https://github.com/chjj/marked",
- "Version": "0.4.0",
- "DownloadLocation": "https://github.com/markedjs/marked/blob/0.4.0/lib/marked.js",
- "Copyright": "Copyright (c) 2011-2018, Christopher Jeffrey",
- "License": "MIT License",
- "LicenseId": "MIT",
- "LicenseFile": "MARKED-LICENSE.txt"
- },
- {
- "Id": "recipebrowser-markdowncss",
- "Name": "Markdown.css (WebEngine RecipeBrowser example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "markdown.css is used in the WebEngine RecipeBrowser example",
- "QtParts": [ "examples" ],
- "Files": "markdown.css",
- "Description": "Markdown.css is better default styling for your Markdown files.",
- "Version": "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
- "DownloadLocation": "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
- "Copyright": "Copyright 2011 Kevin Burke
- Copyright Twitter Inc.",
- "License": "Apache License 2.0",
- "LicenseId": "Apache-2.0",
- "LicenseFile": "MARKDOWN-LICENSE.txt"
- }
-]
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.js b/examples/webenginequick/recipebrowser/resources/pages/assets/custom.js
deleted file mode 100644
index 2be2cf1ec..000000000
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-marked.setOptions({
- renderer: new marked.Renderer(),
- gfm: true,
- tables: true,
- breaks: false,
- pedantic: false,
- sanitize: false,
- smartLists: true,
- smartypants: false
-});
-
-// Poor man document.ready();
-(function() {
- var placeholder = document.getElementById('placeholder');
- var content = document.getElementById('content');
- placeholder.innerHTML = marked(content.innerHTML);
-})();
diff --git a/examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml b/examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml
deleted file mode 100644
index bfaf59112..000000000
--- a/examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Controls.Material
-import QtQuick.Layouts
-
-FocusScope {
- id: root
- signal recipeSelected(url url)
-
- ColumnLayout {
- spacing: 0
- anchors.fill: parent
-
- ToolBar {
- id: headerBackground
- Layout.fillWidth: true
- implicitHeight: headerText.height + 20
-
- Label {
- id: headerText
- width: parent.width
- text: qsTr("Favorite recipes")
- padding: 10
- anchors.centerIn: parent
- }
- }
-
- ListView {
- id: listView
- Layout.fillWidth: true
- Layout.fillHeight: true
- keyNavigationWraps: true
- clip: true
- focus: true
- ScrollBar.vertical: ScrollBar { }
-
- model: recipeModel
-
- delegate: ItemDelegate {
- width: parent.width
- text: model.name
- contentItem: Text {
- text: parent.text
- font: parent.font
- color: parent.enabled ? parent.Material.primaryTextColor
- : parent.Material.hintTextColor
- elide: Text.ElideRight
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
- wrapMode: Text.Wrap
- }
-
- property url url: model.url
- highlighted: ListView.isCurrentItem
-
- onClicked: {
- listView.forceActiveFocus()
- listView.currentIndex = model.index
- }
- }
-
- onCurrentItemChanged: {
- root.recipeSelected(currentItem.url)
- }
-
- ListModel {
- id: recipeModel
-
- ListElement {
- name: "Pizza Diavola"
- url: "qrc:///pages/pizza.html"
- }
- ListElement {
- name: "Steak"
- url: "qrc:///pages/steak.html"
- }
- ListElement {
- name: "Burger"
- url: "qrc:///pages/burger.html"
- }
- ListElement {
- name: "Soup"
- url: "qrc:///pages/soup.html"
- }
- ListElement {
- name: "Pasta"
- url: "qrc:///pages/pasta.html"
- }
- ListElement {
- name: "Grilled Skewers"
- url: "qrc:///pages/skewers.html"
- }
- ListElement {
- name: "Cupcakes"
- url: "qrc:///pages/cupcakes.html"
- }
- }
-
- ToolTip {
- id: help
- implicitWidth: root.width - padding * 3
- y: root.y + root.height
- delay: 1000
- timeout: 5000
- text: qsTr("Use keyboard, mouse, or touch controls to navigate through the\
- recipes.")
-
- contentItem: Text {
- text: help.text
- font: help.font
- color: help.Material.primaryTextColor
- wrapMode: Text.Wrap
- }
- }
- }
- }
-
- function showHelp() {
- help.open()
- }
-}
-
diff --git a/examples/webenginequick/recipebrowser/resources/qml/main.qml b/examples/webenginequick/recipebrowser/resources/qml/main.qml
deleted file mode 100644
index 7db43c871..000000000
--- a/examples/webenginequick/recipebrowser/resources/qml/main.qml
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import QtQml
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Controls.Material
-import QtQuick.Layouts
-import QtQuick.Window
-import QtWebEngine
-
-ApplicationWindow {
- id: appWindow
- title: qsTr("Recipe Browser")
- visible: true
-
- property int shorterDesktop: 768
- property int longerDesktop: 1024
- property int shorterMin: 360
- property int longerMin: 480
- property bool isPortrait: Screen.primaryOrientation === Qt.PortraitOrientation
- width: {
- if (isEmbedded)
- return Screen.width
- var potentialWidth = shorterDesktop
- if (!isPortrait)
- potentialWidth = longerDesktop
- return potentialWidth > Screen.width ? Screen.width : potentialWidth
- }
- height: {
- if (isEmbedded)
- return Screen.height
- var potentialHeight = longerDesktop
- if (!isPortrait)
- potentialHeight = shorterDesktop
- return potentialHeight > Screen.height ? Screen.height : potentialHeight
- }
- minimumWidth: isPortrait ? shorterMin : longerMin
- minimumHeight: isPortrait ? longerMin : shorterMin
-
- RowLayout {
- id: container
- anchors.fill: parent
- spacing: 0
-
- RecipeList {
- id: recipeList
- Layout.minimumWidth: 124
- Layout.preferredWidth: parent.width / 3
- Layout.maximumWidth: 300
- Layout.fillWidth: true
- Layout.fillHeight: true
- focus: true
- activeFocusOnTab: true
- onRecipeSelected: function(url) {
- webView.showRecipe(url)
- }
- }
-
- WebEngineView {
- id: webView
- Layout.preferredWidth: 2 * parent.width / 3
- Layout.fillWidth: true
- Layout.fillHeight: true
- // Make sure focus is not taken by the web view, so user can continue navigating
- // recipes with the keyboard.
- settings.focusOnNavigationEnabled: false
-
- onContextMenuRequested: function(request) {
- request.accepted = true
- }
-
- property bool firstLoadComplete: false
- onLoadingChanged: function(loadRequest) {
- if (loadRequest.status === WebEngineView.LoadSucceededStatus
- && !firstLoadComplete) {
- // Debounce the showing of the web content, so images are more likely
- // to have loaded completely.
- showTimer.start()
- }
- }
-
- Timer {
- id: showTimer
- interval: 500
- repeat: false
- onTriggered: {
- webView.show(true)
- webView.firstLoadComplete = true
- recipeList.showHelp()
- }
- }
-
- Rectangle {
- id: webViewPlaceholder
- anchors.fill: parent
- z: 1
- color: "white"
-
- BusyIndicator {
- id: busy
- anchors.centerIn: parent
- }
- }
-
- function showRecipe(url) {
- webView.url = url
- }
-
- function show(show) {
- if (show === true) {
- busy.running = false
- webViewPlaceholder.visible = false
- } else {
- webViewPlaceholder.visible = true
- busy.running = true
- }
- }
- }
- }
-}
diff --git a/examples/webenginequick/recipebrowser/resources/resources.qrc b/examples/webenginequick/recipebrowser/resources/resources.qrc
deleted file mode 100644
index bd13dcfae..000000000
--- a/examples/webenginequick/recipebrowser/resources/resources.qrc
+++ /dev/null
@@ -1,27 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>qml/main.qml</file>
- <file>qml/RecipeList.qml</file>
-
- <file>pages/pizza.html</file>
- <file>pages/burger.html</file>
- <file>pages/steak.html</file>
- <file>pages/soup.html</file>
- <file>pages/pasta.html</file>
- <file>pages/skewers.html</file>
- <file>pages/cupcakes.html</file>
-
- <file>pages/assets/3rdparty/marked.js</file>
- <file>pages/assets/3rdparty/markdown.css</file>
- <file>pages/assets/custom.css</file>
- <file>pages/assets/custom.js</file>
-
- <file>pages/images/burger.jpg</file>
- <file>pages/images/pizza.jpg</file>
- <file>pages/images/steak.jpg</file>
- <file>pages/images/soup.jpg</file>
- <file>pages/images/pasta.jpg</file>
- <file>pages/images/skewers.jpg</file>
- <file>pages/images/cupcakes.jpg</file>
- </qresource>
-</RCC>
diff --git a/examples/webenginequick/webengineaction/CMakeLists.txt b/examples/webenginequick/webengineaction/CMakeLists.txt
deleted file mode 100644
index 1d6ae3fe5..000000000
--- a/examples/webenginequick/webengineaction/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(webengineaction LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/webengineaction")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
-
-qt_add_executable(webengineaction
- main.cpp
-)
-
-set_target_properties(webengineaction PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(webengineaction PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineQuick
-)
-
-# Resources:
-set(qml_resource_files
- "main.qml"
-)
-
-qt_add_resources(webengineaction "qml"
- PREFIX
- "/"
- FILES
- ${qml_resource_files}
-)
-
-install(TARGETS webengineaction
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/webengineaction/doc/images/webengineaction-example.png b/examples/webenginequick/webengineaction/doc/images/webengineaction-example.png
deleted file mode 100644
index 2e34bbf63..000000000
--- a/examples/webenginequick/webengineaction/doc/images/webengineaction-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc b/examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc
deleted file mode 100644
index 24394ad04..000000000
--- a/examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginequick/webengineaction
- \title WebEngine Action Example
- \ingroup webengine-examples
- \brief A simple browser implemented using WebEngineActions.
-
- \image webengineaction-example.png
-
- \e {WebEngine Action Example} demonstrates how to perform actions on a web page
- using the \l{WebEngineAction} type. It shows the minimum amount of code needed
- to bind browser functionalities to input elements and build up a custom context
- menu.
-
- \include examples-run.qdocinc
-
- \section1 Working With Web Engine Actions
-
- An intended use of \l{WebEngineAction} is building a connection between UI
- elements and browser commands. It can be added to menus and toolbars via
- assigning its properties to the corresponding ones of the element.
-
- The \l{ToolButton} relies on the properties provided by a
- \l{WebEngineAction}. Clicking the button triggers backwards navigation on the
- originating \l{WebEngineView} of the action.
-
- \quotefromfile webenginequick/webengineaction/main.qml
- \skipto ToolButton {
- \printuntil }
-
- The simplest way to create custom context menus is enumerating the required
- \l{WebEngineAction} types in a data model and instantiating \l{MenuItem} types
- for them, for example using a \l{Repeater}.
-
- \quotefromfile webenginequick/webengineaction/main.qml
- \skipto property Menu contextMenu: Menu {
- \printuntil /^ {8}\}/
-
- Assigning a \l{WebEngineAction} to multiple UI elements will keep them in sync.
- As it can be seen in the picture above, if the browser engine disables a
- navigation action, both corresponding menu items will be disabled.
-*/
diff --git a/examples/webenginequick/webengineaction/webengineaction.pro b/examples/webenginequick/webengineaction/webengineaction.pro
deleted file mode 100644
index 7ef0a8bcf..000000000
--- a/examples/webenginequick/webengineaction/webengineaction.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-TEMPLATE = app
-
-QT += webenginequick
-
-SOURCES += main.cpp
-
-RESOURCES += qml.qrc
-
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginequick/webengineaction
-INSTALLS += target
diff --git a/examples/webenginequick/webenginequick.pro b/examples/webenginequick/webenginequick.pro
index edf4315a0..fb44f2c54 100644
--- a/examples/webenginequick/webenginequick.pro
+++ b/examples/webenginequick/webenginequick.pro
@@ -1,14 +1,9 @@
TEMPLATE=subdirs
SUBDIRS += \
- customdialogs \
- customtouchhandle \
- minimal \
- quicknanobrowser \
- webengineaction
+ quicknanobrowser
qtHaveModule(quickcontrols2) {
SUBDIRS += \
- lifecycle \
- recipebrowser
+ lifecycle
}
diff --git a/examples/webenginewidgets/CMakeLists.txt b/examples/webenginewidgets/CMakeLists.txt
index d9b12607f..07ffa9bc4 100644
--- a/examples/webenginewidgets/CMakeLists.txt
+++ b/examples/webenginewidgets/CMakeLists.txt
@@ -1,16 +1,17 @@
-qt_internal_add_example(minimal)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_example(contentmanipulation)
qt_internal_add_example(cookiebrowser)
qt_internal_add_example(notifications)
qt_internal_add_example(simplebrowser)
-qt_internal_add_example(stylesheetbrowser)
+qt_internal_add_example(push-notifications)
qt_internal_add_example(videoplayer)
-qt_internal_add_example(webui)
if(QT_FEATURE_webengine_geolocation)
qt_internal_add_example(maps)
endif()
if(QT_FEATURE_webengine_webchannel)
- qt_internal_add_example(markdowneditor)
+ qt_internal_add_example(recipebrowser)
endif()
if(QT_FEATURE_webengine_printing_and_pdf)
qt_internal_add_example(printme)
diff --git a/examples/webenginewidgets/contentmanipulation/CMakeLists.txt b/examples/webenginewidgets/contentmanipulation/CMakeLists.txt
index b53274507..7edf62044 100644
--- a/examples/webenginewidgets/contentmanipulation/CMakeLists.txt
+++ b/examples/webenginewidgets/contentmanipulation/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(contentmanipulation LANGUAGES CXX)
diff --git a/examples/webenginewidgets/cookiebrowser/CMakeLists.txt b/examples/webenginewidgets/cookiebrowser/CMakeLists.txt
index c5c6b41d3..e606e848d 100644
--- a/examples/webenginewidgets/cookiebrowser/CMakeLists.txt
+++ b/examples/webenginewidgets/cookiebrowser/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(cookiebrowser LANGUAGES CXX)
diff --git a/examples/webenginewidgets/html2pdf/CMakeLists.txt b/examples/webenginewidgets/html2pdf/CMakeLists.txt
index 7e3758d1a..034b89102 100644
--- a/examples/webenginewidgets/html2pdf/CMakeLists.txt
+++ b/examples/webenginewidgets/html2pdf/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(html2pdf LANGUAGES CXX)
diff --git a/examples/webenginewidgets/maps/CMakeLists.txt b/examples/webenginewidgets/maps/CMakeLists.txt
index 62eb04e42..f6e6b94ea 100644
--- a/examples/webenginewidgets/maps/CMakeLists.txt
+++ b/examples/webenginewidgets/maps/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(maps LANGUAGES CXX)
diff --git a/examples/webenginewidgets/maps/doc/src/maps.qdoc b/examples/webenginewidgets/maps/doc/src/maps.qdoc
index 547572750..ad727e165 100644
--- a/examples/webenginewidgets/maps/doc/src/maps.qdoc
+++ b/examples/webenginewidgets/maps/doc/src/maps.qdoc
@@ -22,6 +22,12 @@
geolocation requests are denied by default. This example demonstrates the
steps an application must take in order to start accepting these requests.
+ \note On Windows 11, enable settings to grant the application access to
+ Windows location services. In the Settings App under
+ \uicontrol {Privacy & Security} > \uicontrol {Location}, enable \uicontrol
+ {Location services}, \uicontrol {Let apps access your location} and \uicontrol
+ {Let desktop apps access your location}.
+
\include examples-run.qdocinc
\section1 The Code
diff --git a/examples/webenginewidgets/markdowneditor/CMakeLists.txt b/examples/webenginewidgets/markdowneditor/CMakeLists.txt
deleted file mode 100644
index c1a0974a0..000000000
--- a/examples/webenginewidgets/markdowneditor/CMakeLists.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(markdowneditor LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/markdowneditor")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui WebChannel WebEngineWidgets)
-
-qt_add_executable(markdowneditor
- document.cpp document.h
- main.cpp
- mainwindow.cpp mainwindow.h mainwindow.ui
- previewpage.cpp previewpage.h
-)
-
-set_target_properties(markdowneditor PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(markdowneditor PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebChannel
- Qt::WebEngineWidgets
-)
-
-# Resources:
-set(markdowneditor_resource_files
- "resources/3rdparty/markdown.css"
- "resources/3rdparty/marked.js"
- "resources/default.md"
- "resources/index.html"
-)
-
-qt_add_resources(markdowneditor "markdowneditor"
- PREFIX
- "/"
- BASE
- "resources"
- FILES
- ${markdowneditor_resource_files}
-)
-
-install(TARGETS markdowneditor
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png b/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
deleted file mode 100644
index 9f456c4db..000000000
--- a/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
deleted file mode 100644
index f8c67fd63..000000000
--- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginewidgets/markdowneditor
- \title WebEngine Markdown Editor Example
- \ingroup webengine-widgetexamples
- \brief Demonstrates how to integrate a web engine in a hybrid desktop
- application.
-
- \image markdowneditor-example.png
-
- \e {Markdown Editor} demonstrates how to use QWebChannel and JavaScript
- libraries to provide a rich text preview tool for a custom markup language.
-
- \l{http://daringfireball.net/projects/markdown/}{Markdown} is a lightweight
- markup language with a plain text formatting syntax.
- Some services, such as \l{http://github.com}{github}, acknowledge the
- format, and render the content as rich text when viewed in a browser.
-
- The Markdown Editor main window is split into an editor and a preview area.
- The editor supports the Markdown syntax and is implemented by using
- QPlainTextEdit. The document is rendered as rich text in the preview area,
- which is implemented by using QWebEngineView. To render the text, the
- Markdown text is converted to HTML format with the help of a JavaScript
- library inside the web engine. The preview is updated from the editor
- through QWebChannel.
-
- \include examples-run.qdocinc
-
- \section1 Exposing Document Text
-
- Because we expose the current Markdown text to be rendered to the web engine
- through QWebChannel, we need to somehow make the current text available
- through the Qt metatype system. This is done by using a dedicated
- \c Document class that exposes the document text as a \c{Q_PROPERTY}:
-
- \quotefromfile webenginewidgets/markdowneditor/document.h
- \skipto class Document
- \printto #endif
-
- The \c Document class wraps a QString to be set on the C++ side with
- the \c setText() method and exposes it at runtime as a \c text property
- with a \c textChanged signal.
-
- We define the \c setText method as follows:
-
- \quotefromfile webenginewidgets/markdowneditor/document.cpp
- \skipto Document::setText
- \printuntil
-
- \section1 Previewing Text
-
- We implement our own \c PreviewPage class that publicly inherits from
- \c QWebEnginePage:
-
- \quotefromfile webenginewidgets/markdowneditor/previewpage.h
- \skipto class PreviewPage
- \printto #endif
-
- We reimplement the virtual \c acceptNavigationRequest method to
- stop the page from navigating away from the current document. Instead,
- we redirect external links to the system browser:
-
- \quotefromfile webenginewidgets/markdowneditor/previewpage.cpp
- \skipto acceptNavigationRequest
- \printuntil
-
- \section1 Creating the Main Window
-
- The \c MainWindow class inherits the QMainWindow class:
-
- \quotefromfile webenginewidgets/markdowneditor/mainwindow.h
- \skipto class MainWindow :
- \printto endif
-
- The class declares private slots that match the actions in the menu,
- as well as the \c isModified() helper method.
-
- The actual layout of the main window is specified in a \c .ui file.
- The widgets and actions are available at runtime in the \c ui member
- variable.
-
- \c m_filePath holds the file path to the currently loaded document.
- \c m_content is an instance of the \c Document class.
-
- The actual setup of the different objects is done in the \c MainWindow
- constructor:
-
- \quotefromfile webenginewidgets/markdowneditor/mainwindow.cpp
- \skipto MainWindow::MainWindow
- \printto PreviewPage
-
- The constructor first calls \c setupUi to construct the widgets and menu
- actions according to the UI file. The text editor font is set to one
- with a fixed character width, and the QWebEngineView widget is told not
- to show a context menu.
-
- \printto connect
-
- Here the constructor makes sure our custom
- \c PreviewPage is used by the QWebEngineView instance in \c{ui->preview}.
-
- \printto ui->preview
-
- Here the \c textChanged signal of the editor is connected to a lambda that
- updates the text in \c m_content. This object is then exposed to the JS side
- by \c QWebChannel under the name \c{content}.
-
- \printto connect
-
- Now we can actually load the \e index.html file from the
- resources. For more information about the file, see
- \l{Creating an Index File}.
-
- \printto defaultTextFile
-
- The menu items are connected to the corresponding member slots. The
- \uicontrol Save item is activated or deactivated depending on whether
- the user has edited the content.
-
- \printuntil }
-
- Finally, we load a default document \e default.md from the resources.
-
- \section1 Creating an Index File
-
- \quotefile webenginewidgets/markdowneditor/resources/index.html
-
- In the \e index.html, we load a custom stylesheet and two JavaScript
- libraries. \l{https://bitbucket.org/kevinburke/markdowncss/src/master/}{markdown.css} is
- a markdown-friendly stylesheet created by Kevin Burke.
- \l{https://github.com/chjj/marked}{marked.js} is a markdown parser and
- compiler designed for speed written by Christopher Jeffrey and
- \e qwebchannel.js is part of the \l{QWebChannel} module.
-
- In the \c <body> element we first define a \c placeholder element, and
- make it available as a JavaScript variable. We then define the \c updateText
- helper method that updates the content of \c placeholder with the HTML
- that the JavaScript method \c marked() returns.
-
- Finally, we set up the web channel to access the \c content proxy object
- and make sure that \c updateText() is called whenever \c content.text
- changes.
-
- \section1 Files and Attributions
-
- The example bundles the following code with third-party licenses:
-
- \table
- \row
- \li \l{markdowneditor-marked}{Marked}
- \li MIT License
- \row
- \li \l{markdowneditor-markdowncss}{Markdown.css}
- \li Apache License 2.0
- \endtable
-*/
-
diff --git a/examples/webenginewidgets/markdowneditor/document.cpp b/examples/webenginewidgets/markdowneditor/document.cpp
deleted file mode 100644
index 8ece76509..000000000
--- a/examples/webenginewidgets/markdowneditor/document.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "document.h"
-
-void Document::setText(const QString &text)
-{
- if (text == m_text)
- return;
- m_text = text;
- emit textChanged(m_text);
-}
diff --git a/examples/webenginewidgets/markdowneditor/document.h b/examples/webenginewidgets/markdowneditor/document.h
deleted file mode 100644
index f4eabbdaa..000000000
--- a/examples/webenginewidgets/markdowneditor/document.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef DOCUMENT_H
-#define DOCUMENT_H
-
-#include <QObject>
-#include <QString>
-
-class Document : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged FINAL)
-public:
- explicit Document(QObject *parent = nullptr) : QObject(parent) {}
-
- void setText(const QString &text);
-
-signals:
- void textChanged(const QString &text);
-
-private:
- QString m_text;
-};
-
-#endif // DOCUMENT_H
diff --git a/examples/webenginewidgets/markdowneditor/main.cpp b/examples/webenginewidgets/markdowneditor/main.cpp
deleted file mode 100644
index 98e76bfba..000000000
--- a/examples/webenginewidgets/markdowneditor/main.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "document.h"
-#include "mainwindow.h"
-
-#include <QApplication>
-#include <QFile>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- QApplication a(argc, argv);
-
- MainWindow window;
- window.show();
-
- return a.exec();
-}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.cpp b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
deleted file mode 100644
index a4ef50a31..000000000
--- a/examples/webenginewidgets/markdowneditor/mainwindow.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "mainwindow.h"
-#include "previewpage.h"
-#include "ui_mainwindow.h"
-
-#include <QFile>
-#include <QFileDialog>
-#include <QFontDatabase>
-#include <QMessageBox>
-#include <QStatusBar>
-#include <QTextStream>
-#include <QWebChannel>
-
-MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
-{
- ui->setupUi(this);
- ui->editor->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
- ui->preview->setContextMenuPolicy(Qt::NoContextMenu);
-
- PreviewPage *page = new PreviewPage(this);
- ui->preview->setPage(page);
-
- connect(ui->editor, &QPlainTextEdit::textChanged,
- [this]() { m_content.setText(ui->editor->toPlainText()); });
-
- QWebChannel *channel = new QWebChannel(this);
- channel->registerObject(QStringLiteral("content"), &m_content);
- page->setWebChannel(channel);
-
- ui->preview->setUrl(QUrl("qrc:/index.html"));
-
- connect(ui->actionNew, &QAction::triggered, this, &MainWindow::onFileNew);
- connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::onFileOpen);
- connect(ui->actionSave, &QAction::triggered, this, &MainWindow::onFileSave);
- connect(ui->actionSaveAs, &QAction::triggered, this, &MainWindow::onFileSaveAs);
- connect(ui->actionExit, &QAction::triggered, this, &QWidget::close);
-
- connect(ui->editor->document(), &QTextDocument::modificationChanged,
- ui->actionSave, &QAction::setEnabled);
-
- QFile defaultTextFile(":/default.md");
- defaultTextFile.open(QIODevice::ReadOnly);
- ui->editor->setPlainText(defaultTextFile.readAll());
-}
-
-MainWindow::~MainWindow()
-{
- delete ui;
-}
-
-void MainWindow::openFile(const QString &path)
-{
- QFile f(path);
- if (!f.open(QIODevice::ReadOnly)) {
- QMessageBox::warning(this, windowTitle(),
- tr("Could not open file %1: %2").arg(
- QDir::toNativeSeparators(path), f.errorString()));
- return;
- }
- m_filePath = path;
- ui->editor->setPlainText(f.readAll());
- statusBar()->showMessage(tr("Opened %1").arg(QDir::toNativeSeparators(path)));
-}
-
-bool MainWindow::isModified() const
-{
- return ui->editor->document()->isModified();
-}
-
-void MainWindow::onFileNew()
-{
- if (isModified()) {
- QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
- tr("You have unsaved changes. Do you want to create a new document anyway?"));
- if (button != QMessageBox::Yes)
- return;
- }
-
- m_filePath.clear();
- ui->editor->setPlainText(tr("## New document"));
- ui->editor->document()->setModified(false);
-}
-
-void MainWindow::onFileOpen()
-{
- if (isModified()) {
- QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
- tr("You have unsaved changes. Do you want to open a new document anyway?"));
- if (button != QMessageBox::Yes)
- return;
- }
-
- QFileDialog dialog(this, tr("Open MarkDown File"));
- dialog.setMimeTypeFilters({"text/markdown"});
- dialog.setAcceptMode(QFileDialog::AcceptOpen);
- if (dialog.exec() == QDialog::Accepted)
- openFile(dialog.selectedFiles().constFirst());
-}
-
-void MainWindow::onFileSave()
-{
- if (m_filePath.isEmpty()) {
- onFileSaveAs();
- return;
- }
-
- QFile f(m_filePath);
- if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QMessageBox::warning(this, windowTitle(),
- tr("Could not write to file %1: %2").arg(
- QDir::toNativeSeparators(m_filePath), f.errorString()));
- return;
- }
- QTextStream str(&f);
- str << ui->editor->toPlainText();
-
- ui->editor->document()->setModified(false);
-
- statusBar()->showMessage(tr("Wrote %1").arg(QDir::toNativeSeparators(m_filePath)));
-}
-
-void MainWindow::onFileSaveAs()
-{
- QFileDialog dialog(this, tr("Save MarkDown File"));
- dialog.setMimeTypeFilters({"text/markdown"});
- dialog.setAcceptMode(QFileDialog::AcceptSave);
- dialog.setDefaultSuffix("md");
- if (dialog.exec() != QDialog::Accepted)
- return;
-
- m_filePath = dialog.selectedFiles().constFirst();
- onFileSave();
-}
-
-void MainWindow::closeEvent(QCloseEvent *e)
-{
- if (isModified()) {
- QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
- tr("You have unsaved changes. Do you want to exit anyway?"));
- if (button != QMessageBox::Yes)
- e->ignore();
- }
-}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h
deleted file mode 100644
index 271664852..000000000
--- a/examples/webenginewidgets/markdowneditor/mainwindow.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include "document.h"
-
-#include <QMainWindow>
-#include <QString>
-
-QT_BEGIN_NAMESPACE
-namespace Ui {
-class MainWindow;
-}
-QT_END_NAMESPACE
-
-class MainWindow : public QMainWindow
-{
- Q_OBJECT
-
-public:
- explicit MainWindow(QWidget *parent = nullptr);
- ~MainWindow();
-
- void openFile(const QString &path);
-
-protected:
- void closeEvent(QCloseEvent *e) override;
-
-private slots:
- void onFileNew();
- void onFileOpen();
- void onFileSave();
- void onFileSaveAs();
-
-private:
- bool isModified() const;
-
- Ui::MainWindow *ui;
- QString m_filePath;
- Document m_content;
-};
-
-#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.ui b/examples/webenginewidgets/markdowneditor/mainwindow.ui
deleted file mode 100644
index 36ab352b7..000000000
--- a/examples/webenginewidgets/markdowneditor/mainwindow.ui
+++ /dev/null
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>800</width>
- <height>600</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>MarkDown Editor</string>
- </property>
- <widget class="QWidget" name="centralwidget">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QSplitter" name="splitter">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <widget class="QPlainTextEdit" name="editor"/>
- <widget class="QWebEngineView" name="preview" native="true"/>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QMenuBar" name="menubar">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>800</width>
- <height>26</height>
- </rect>
- </property>
- <widget class="QMenu" name="menu_File">
- <property name="title">
- <string>&amp;File</string>
- </property>
- <addaction name="actionNew"/>
- <addaction name="actionOpen"/>
- <addaction name="actionSave"/>
- <addaction name="actionSaveAs"/>
- <addaction name="separator"/>
- <addaction name="actionExit"/>
- </widget>
- <addaction name="menu_File"/>
- </widget>
- <widget class="QStatusBar" name="statusbar"/>
- <action name="actionOpen">
- <property name="text">
- <string>&amp;Open...</string>
- </property>
- <property name="toolTip">
- <string>Open document</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+O</string>
- </property>
- </action>
- <action name="actionSave">
- <property name="text">
- <string>&amp;Save</string>
- </property>
- <property name="toolTip">
- <string>Save current document</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+S</string>
- </property>
- </action>
- <action name="actionExit">
- <property name="text">
- <string>E&amp;xit</string>
- </property>
- <property name="toolTip">
- <string>Exit editor</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+Q</string>
- </property>
- </action>
- <action name="actionSaveAs">
- <property name="text">
- <string>Save &amp;As...</string>
- </property>
- <property name="toolTip">
- <string>Save document under different name</string>
- </property>
- </action>
- <action name="actionNew">
- <property name="text">
- <string>&amp;New</string>
- </property>
- <property name="toolTip">
- <string>Create new document</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+N</string>
- </property>
- </action>
- </widget>
- <customwidgets>
- <customwidget>
- <class>QWebEngineView</class>
- <extends>QWidget</extends>
- <header>qwebengineview.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/examples/webenginewidgets/markdowneditor/markdowneditor.pro b/examples/webenginewidgets/markdowneditor/markdowneditor.pro
deleted file mode 100644
index 099edf4b5..000000000
--- a/examples/webenginewidgets/markdowneditor/markdowneditor.pro
+++ /dev/null
@@ -1,32 +0,0 @@
-TEMPLATE = app
-
-QT += webenginewidgets webchannel
-
-HEADERS += \
- mainwindow.h \
- previewpage.h \
- document.h
-
-SOURCES = \
- main.cpp \
- mainwindow.cpp \
- previewpage.cpp \
- document.cpp
-
-RESOURCES = \
- resources/markdowneditor.qrc
-
-# Disable Qt Quick compiler because the example doesn't use QML, but more importantly so that
-# the source code of the .js files is not removed from the embedded qrc file.
-CONFIG -= qtquickcompiler
-
-FORMS += \
- mainwindow.ui
-
-DISTFILES += \
- resources/3rdparty/MARKDOWN-LICENSE.txt \
- resources/3rdparty/MARKED-LICENSE.txt
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/markdowneditor
-INSTALLS += target
diff --git a/examples/webenginewidgets/markdowneditor/previewpage.cpp b/examples/webenginewidgets/markdowneditor/previewpage.cpp
deleted file mode 100644
index 17249fdb0..000000000
--- a/examples/webenginewidgets/markdowneditor/previewpage.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "previewpage.h"
-
-#include <QDesktopServices>
-
-bool PreviewPage::acceptNavigationRequest(const QUrl &url,
- QWebEnginePage::NavigationType /*type*/,
- bool /*isMainFrame*/)
-{
- // Only allow qrc:/index.html.
- if (url.scheme() == QString("qrc"))
- return true;
- QDesktopServices::openUrl(url);
- return false;
-}
diff --git a/examples/webenginewidgets/markdowneditor/previewpage.h b/examples/webenginewidgets/markdowneditor/previewpage.h
deleted file mode 100644
index 4a5d98c7c..000000000
--- a/examples/webenginewidgets/markdowneditor/previewpage.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef PREVIEWPAGE_H
-#define PREVIEWPAGE_H
-
-#include <QWebEnginePage>
-
-class PreviewPage : public QWebEnginePage
-{
- Q_OBJECT
-public:
- using QWebEnginePage::QWebEnginePage;
-
-protected:
- bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) override;
-};
-
-#endif // PREVIEWPAGE_H
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt
deleted file mode 100644
index 23c52cc43..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Copyright 2011 Kevin Burke unless otherwise noted.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Some content is copyrighted by Twitter, Inc., and also released under an
-Apache License; these sections are noted in the source.
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt
deleted file mode 100644
index 8e3ba0e0a..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css b/examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css
deleted file mode 100644
index 24fc2ffe2..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css
+++ /dev/null
@@ -1,260 +0,0 @@
-body{
- margin: 0 auto;
- font-family: Georgia, Palatino, serif;
- color: #444444;
- line-height: 1;
- max-width: 960px;
- padding: 30px;
-}
-h1, h2, h3, h4 {
- color: #111111;
- font-weight: 400;
-}
-h1, h2, h3, h4, h5, p {
- margin-bottom: 24px;
- padding: 0;
-}
-h1 {
- font-size: 48px;
-}
-h2 {
- font-size: 36px;
- /* The bottom margin is small. It's designed to be used with gray meta text
- * below a post title. */
- margin: 24px 0 6px;
-}
-h3 {
- font-size: 24px;
-}
-h4 {
- font-size: 21px;
-}
-h5 {
- font-size: 18px;
-}
-a {
- color: #0099ff;
- margin: 0;
- padding: 0;
- vertical-align: baseline;
-}
-a:hover {
- text-decoration: none;
- color: #ff6600;
-}
-a:visited {
- color: purple;
-}
-ul, ol {
- padding: 0;
- margin: 0;
-}
-li {
- line-height: 24px;
-}
-li ul, li ul {
- margin-left: 24px;
-}
-p, ul, ol {
- font-size: 16px;
- line-height: 24px;
- max-width: 540px;
-}
-pre {
- padding: 0px 24px;
- max-width: 800px;
- white-space: pre-wrap;
-}
-code {
- font-family: Consolas, Monaco, Andale Mono, monospace;
- line-height: 1.5;
- font-size: 13px;
-}
-aside {
- display: block;
- float: right;
- width: 390px;
-}
-blockquote {
- border-left:.5em solid #eee;
- padding: 0 2em;
- margin-left:0;
- max-width: 476px;
-}
-blockquote cite {
- font-size:14px;
- line-height:20px;
- color:#bfbfbf;
-}
-blockquote cite:before {
- content: '\2014 \00A0';
-}
-
-blockquote p {
- color: #666;
- max-width: 460px;
-}
-hr {
- width: 540px;
- text-align: left;
- margin: 0 auto 0 0;
- color: #999;
-}
-
-/* Code below this line is copyright Twitter Inc. */
-
-button,
-input,
-select,
-textarea {
- font-size: 100%;
- margin: 0;
- vertical-align: baseline;
- *vertical-align: middle;
-}
-button, input {
- line-height: normal;
- *overflow: visible;
-}
-button::-moz-focus-inner, input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-button,
-input[type="button"],
-input[type="reset"],
-input[type="submit"] {
- cursor: pointer;
- -webkit-appearance: button;
-}
-input[type=checkbox], input[type=radio] {
- cursor: pointer;
-}
-/* override default chrome & firefox settings */
-input:not([type="image"]), textarea {
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-}
-
-input[type="search"] {
- -webkit-appearance: textfield;
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-}
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-label,
-input,
-select,
-textarea {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 13px;
- font-weight: normal;
- line-height: normal;
- margin-bottom: 18px;
-}
-input[type=checkbox], input[type=radio] {
- cursor: pointer;
- margin-bottom: 0;
-}
-input[type=text],
-input[type=password],
-textarea,
-select {
- display: inline-block;
- width: 210px;
- padding: 4px;
- font-size: 13px;
- font-weight: normal;
- line-height: 18px;
- height: 18px;
- color: #808080;
- border: 1px solid #ccc;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
-}
-select, input[type=file] {
- height: 27px;
- line-height: 27px;
-}
-textarea {
- height: auto;
-}
-
-/* grey out placeholders */
-:-moz-placeholder {
- color: #bfbfbf;
-}
-::-webkit-input-placeholder {
- color: #bfbfbf;
-}
-
-input[type=text],
-input[type=password],
-select,
-textarea {
- -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
- -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
- transition: border linear 0.2s, box-shadow linear 0.2s;
- -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
- -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
-}
-input[type=text]:focus, input[type=password]:focus, textarea:focus {
- outline: none;
- border-color: rgba(82, 168, 236, 0.8);
- -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
- -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
-}
-
-/* buttons */
-button {
- display: inline-block;
- padding: 4px 14px;
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 13px;
- line-height: 18px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- background-color: #0064cd;
- background-repeat: repeat-x;
- background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));
- background-image: -moz-linear-gradient(top, #049cdb, #0064cd);
- background-image: -ms-linear-gradient(top, #049cdb, #0064cd);
- background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));
- background-image: -webkit-linear-gradient(top, #049cdb, #0064cd);
- background-image: -o-linear-gradient(top, #049cdb, #0064cd);
- background-image: linear-gradient(top, #049cdb, #0064cd);
- color: #fff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- border: 1px solid #004b9a;
- border-bottom-color: #003f81;
- -webkit-transition: 0.1s linear all;
- -moz-transition: 0.1s linear all;
- transition: 0.1s linear all;
- border-color: #0064cd #0064cd #003f81;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-}
-button:hover {
- color: #fff;
- background-position: 0 -15px;
- text-decoration: none;
-}
-button:active {
- -webkit-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-button::-moz-focus-inner {
- padding: 0;
- border: 0;
-}
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.js b/examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.js
deleted file mode 100644
index 33c02d9cf..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.js
+++ /dev/null
@@ -1,1514 +0,0 @@
-/**
- * marked - a markdown parser
- * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/markedjs/marked
- */
-
-;(function(root) {
-'use strict';
-
-/**
- * Block-Level Grammar
- */
-
-var block = {
- newline: /^\n+/,
- code: /^( {4}[^\n]+\n*)+/,
- fences: noop,
- hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
- heading: /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,
- nptable: noop,
- blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
- list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
- html: '^ {0,3}(?:' // optional indentation
- + '<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
- + '|comment[^\\n]*(\\n+|$)' // (2)
- + '|<\\?[\\s\\S]*?\\?>\\n*' // (3)
- + '|<![A-Z][\\s\\S]*?>\\n*' // (4)
- + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\n*' // (5)
- + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)' // (6)
- + '|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) open tag
- + '|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) closing tag
- + ')',
- def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
- table: noop,
- lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
- paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,
- text: /^[^\n]+/
-};
-
-block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
-block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
-block.def = edit(block.def)
- .replace('label', block._label)
- .replace('title', block._title)
- .getRegex();
-
-block.bullet = /(?:[*+-]|\d+\.)/;
-block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
-block.item = edit(block.item, 'gm')
- .replace(/bull/g, block.bullet)
- .getRegex();
-
-block.list = edit(block.list)
- .replace(/bull/g, block.bullet)
- .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
- .replace('def', '\\n+(?=' + block.def.source + ')')
- .getRegex();
-
-block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
- + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
- + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
- + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
- + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
- + '|track|ul';
-block._comment = /<!--(?!-?>)[\s\S]*?-->/;
-block.html = edit(block.html, 'i')
- .replace('comment', block._comment)
- .replace('tag', block._tag)
- .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
- .getRegex();
-
-block.paragraph = edit(block.paragraph)
- .replace('hr', block.hr)
- .replace('heading', block.heading)
- .replace('lheading', block.lheading)
- .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
- .getRegex();
-
-block.blockquote = edit(block.blockquote)
- .replace('paragraph', block.paragraph)
- .getRegex();
-
-/**
- * Normal Block Grammar
- */
-
-block.normal = merge({}, block);
-
-/**
- * GFM Block Grammar
- */
-
-block.gfm = merge({}, block.normal, {
- fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,
- paragraph: /^/,
- heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
-});
-
-block.gfm.paragraph = edit(block.paragraph)
- .replace('(?!', '(?!'
- + block.gfm.fences.source.replace('\\1', '\\2') + '|'
- + block.list.source.replace('\\1', '\\3') + '|')
- .getRegex();
-
-/**
- * GFM + Tables Block Grammar
- */
-
-block.tables = merge({}, block.gfm, {
- nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
- table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
-});
-
-/**
- * Pedantic grammar
- */
-
-block.pedantic = merge({}, block.normal, {
- html: edit(
- '^ *(?:comment *(?:\\n|\\s*$)'
- + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
- + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
- .replace('comment', block._comment)
- .replace(/tag/g, '(?!(?:'
- + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
- + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
- + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
- .getRegex(),
- def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/
-});
-
-/**
- * Block Lexer
- */
-
-function Lexer(options) {
- this.tokens = [];
- this.tokens.links = {};
- this.options = options || marked.defaults;
- this.rules = block.normal;
-
- if (this.options.pedantic) {
- this.rules = block.pedantic;
- } else if (this.options.gfm) {
- if (this.options.tables) {
- this.rules = block.tables;
- } else {
- this.rules = block.gfm;
- }
- }
-}
-
-/**
- * Expose Block Rules
- */
-
-Lexer.rules = block;
-
-/**
- * Static Lex Method
- */
-
-Lexer.lex = function(src, options) {
- var lexer = new Lexer(options);
- return lexer.lex(src);
-};
-
-/**
- * Preprocessing
- */
-
-Lexer.prototype.lex = function(src) {
- src = src
- .replace(/\r\n|\r/g, '\n')
- .replace(/\t/g, ' ')
- .replace(/\u00a0/g, ' ')
- .replace(/\u2424/g, '\n');
-
- return this.token(src, true);
-};
-
-/**
- * Lexing
- */
-
-Lexer.prototype.token = function(src, top) {
- src = src.replace(/^ +$/gm, '');
- var next,
- loose,
- cap,
- bull,
- b,
- item,
- space,
- i,
- tag,
- l,
- isordered,
- istask,
- ischecked;
-
- while (src) {
- // newline
- if (cap = this.rules.newline.exec(src)) {
- src = src.substring(cap[0].length);
- if (cap[0].length > 1) {
- this.tokens.push({
- type: 'space'
- });
- }
- }
-
- // code
- if (cap = this.rules.code.exec(src)) {
- src = src.substring(cap[0].length);
- cap = cap[0].replace(/^ {4}/gm, '');
- this.tokens.push({
- type: 'code',
- text: !this.options.pedantic
- ? cap.replace(/\n+$/, '')
- : cap
- });
- continue;
- }
-
- // fences (gfm)
- if (cap = this.rules.fences.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'code',
- lang: cap[2],
- text: cap[3] || ''
- });
- continue;
- }
-
- // heading
- if (cap = this.rules.heading.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'heading',
- depth: cap[1].length,
- text: cap[2]
- });
- continue;
- }
-
- // table no leading pipe (gfm)
- if (top && (cap = this.rules.nptable.exec(src))) {
- item = {
- type: 'table',
- header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
- align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
- cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : []
- };
-
- if (item.header.length === item.align.length) {
- src = src.substring(cap[0].length);
-
- for (i = 0; i < item.align.length; i++) {
- if (/^ *-+: *$/.test(item.align[i])) {
- item.align[i] = 'right';
- } else if (/^ *:-+: *$/.test(item.align[i])) {
- item.align[i] = 'center';
- } else if (/^ *:-+ *$/.test(item.align[i])) {
- item.align[i] = 'left';
- } else {
- item.align[i] = null;
- }
- }
-
- for (i = 0; i < item.cells.length; i++) {
- item.cells[i] = splitCells(item.cells[i], item.header.length);
- }
-
- this.tokens.push(item);
-
- continue;
- }
- }
-
- // hr
- if (cap = this.rules.hr.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'hr'
- });
- continue;
- }
-
- // blockquote
- if (cap = this.rules.blockquote.exec(src)) {
- src = src.substring(cap[0].length);
-
- this.tokens.push({
- type: 'blockquote_start'
- });
-
- cap = cap[0].replace(/^ *> ?/gm, '');
-
- // Pass `top` to keep the current
- // "toplevel" state. This is exactly
- // how markdown.pl works.
- this.token(cap, top);
-
- this.tokens.push({
- type: 'blockquote_end'
- });
-
- continue;
- }
-
- // list
- if (cap = this.rules.list.exec(src)) {
- src = src.substring(cap[0].length);
- bull = cap[2];
- isordered = bull.length > 1;
-
- this.tokens.push({
- type: 'list_start',
- ordered: isordered,
- start: isordered ? +bull : ''
- });
-
- // Get each top-level item.
- cap = cap[0].match(this.rules.item);
-
- next = false;
- l = cap.length;
- i = 0;
-
- for (; i < l; i++) {
- item = cap[i];
-
- // Remove the list item's bullet
- // so it is seen as the next token.
- space = item.length;
- item = item.replace(/^ *([*+-]|\d+\.) +/, '');
-
- // Outdent whatever the
- // list item contains. Hacky.
- if (~item.indexOf('\n ')) {
- space -= item.length;
- item = !this.options.pedantic
- ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
- : item.replace(/^ {1,4}/gm, '');
- }
-
- // Determine whether the next list item belongs here.
- // Backpedal if it does not belong in this list.
- if (this.options.smartLists && i !== l - 1) {
- b = block.bullet.exec(cap[i + 1])[0];
- if (bull !== b && !(bull.length > 1 && b.length > 1)) {
- src = cap.slice(i + 1).join('\n') + src;
- i = l - 1;
- }
- }
-
- // Determine whether item is loose or not.
- // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
- // for discount behavior.
- loose = next || /\n\n(?!\s*$)/.test(item);
- if (i !== l - 1) {
- next = item.charAt(item.length - 1) === '\n';
- if (!loose) loose = next;
- }
-
- // Check for task list items
- istask = /^\[[ xX]\] /.test(item);
- ischecked = undefined;
- if (istask) {
- ischecked = item[1] !== ' ';
- item = item.replace(/^\[[ xX]\] +/, '');
- }
-
- this.tokens.push({
- type: loose
- ? 'loose_item_start'
- : 'list_item_start',
- task: istask,
- checked: ischecked
- });
-
- // Recurse.
- this.token(item, false);
-
- this.tokens.push({
- type: 'list_item_end'
- });
- }
-
- this.tokens.push({
- type: 'list_end'
- });
-
- continue;
- }
-
- // html
- if (cap = this.rules.html.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: this.options.sanitize
- ? 'paragraph'
- : 'html',
- pre: !this.options.sanitizer
- && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
- text: cap[0]
- });
- continue;
- }
-
- // def
- if (top && (cap = this.rules.def.exec(src))) {
- src = src.substring(cap[0].length);
- if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1);
- tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
- if (!this.tokens.links[tag]) {
- this.tokens.links[tag] = {
- href: cap[2],
- title: cap[3]
- };
- }
- continue;
- }
-
- // table (gfm)
- if (top && (cap = this.rules.table.exec(src))) {
- item = {
- type: 'table',
- header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
- align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
- cells: cap[3] ? cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') : []
- };
-
- if (item.header.length === item.align.length) {
- src = src.substring(cap[0].length);
-
- for (i = 0; i < item.align.length; i++) {
- if (/^ *-+: *$/.test(item.align[i])) {
- item.align[i] = 'right';
- } else if (/^ *:-+: *$/.test(item.align[i])) {
- item.align[i] = 'center';
- } else if (/^ *:-+ *$/.test(item.align[i])) {
- item.align[i] = 'left';
- } else {
- item.align[i] = null;
- }
- }
-
- for (i = 0; i < item.cells.length; i++) {
- item.cells[i] = splitCells(
- item.cells[i].replace(/^ *\| *| *\| *$/g, ''),
- item.header.length);
- }
-
- this.tokens.push(item);
-
- continue;
- }
- }
-
- // lheading
- if (cap = this.rules.lheading.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'heading',
- depth: cap[2] === '=' ? 1 : 2,
- text: cap[1]
- });
- continue;
- }
-
- // top-level paragraph
- if (top && (cap = this.rules.paragraph.exec(src))) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'paragraph',
- text: cap[1].charAt(cap[1].length - 1) === '\n'
- ? cap[1].slice(0, -1)
- : cap[1]
- });
- continue;
- }
-
- // text
- if (cap = this.rules.text.exec(src)) {
- // Top-level should never reach here.
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'text',
- text: cap[0]
- });
- continue;
- }
-
- if (src) {
- throw new Error('Infinite loop on byte: ' + src.charCodeAt(0));
- }
- }
-
- return this.tokens;
-};
-
-/**
- * Inline-Level Grammar
- */
-
-var inline = {
- escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
- autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
- url: noop,
- tag: '^comment'
- + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
- + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
- + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
- + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
- + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', // CDATA section
- link: /^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,
- reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
- nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
- strong: /^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)|^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)/,
- em: /^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*][\s\S]*?[^\s])\*(?!\*)|^_([^\s_])_(?!_)|^\*([^\s*])\*(?!\*)/,
- code: /^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,
- br: /^ {2,}\n(?!\s*$)/,
- del: noop,
- text: /^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/
-};
-
-inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
-
-inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
-inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
-inline.autolink = edit(inline.autolink)
- .replace('scheme', inline._scheme)
- .replace('email', inline._email)
- .getRegex();
-
-inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
-
-inline.tag = edit(inline.tag)
- .replace('comment', block._comment)
- .replace('attribute', inline._attribute)
- .getRegex();
-
-inline._label = /(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/;
-inline._href = /\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f()\\]*\)|[^\s\x00-\x1f()\\])*?)/;
-inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
-
-inline.link = edit(inline.link)
- .replace('label', inline._label)
- .replace('href', inline._href)
- .replace('title', inline._title)
- .getRegex();
-
-inline.reflink = edit(inline.reflink)
- .replace('label', inline._label)
- .getRegex();
-
-/**
- * Normal Inline Grammar
- */
-
-inline.normal = merge({}, inline);
-
-/**
- * Pedantic Inline Grammar
- */
-
-inline.pedantic = merge({}, inline.normal, {
- strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
- em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
- link: edit(/^!?\[(label)\]\((.*?)\)/)
- .replace('label', inline._label)
- .getRegex(),
- reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
- .replace('label', inline._label)
- .getRegex()
-});
-
-/**
- * GFM Inline Grammar
- */
-
-inline.gfm = merge({}, inline.normal, {
- escape: edit(inline.escape).replace('])', '~|])').getRegex(),
- url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/)
- .replace('email', inline._email)
- .getRegex(),
- _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
- del: /^~~(?=\S)([\s\S]*?\S)~~/,
- text: edit(inline.text)
- .replace(']|', '~]|')
- .replace('|', '|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&\'*+/=?^_`{\\|}~-]+@|')
- .getRegex()
-});
-
-/**
- * GFM + Line Breaks Inline Grammar
- */
-
-inline.breaks = merge({}, inline.gfm, {
- br: edit(inline.br).replace('{2,}', '*').getRegex(),
- text: edit(inline.gfm.text).replace('{2,}', '*').getRegex()
-});
-
-/**
- * Inline Lexer & Compiler
- */
-
-function InlineLexer(links, options) {
- this.options = options || marked.defaults;
- this.links = links;
- this.rules = inline.normal;
- this.renderer = this.options.renderer || new Renderer();
- this.renderer.options = this.options;
-
- if (!this.links) {
- throw new Error('Tokens array requires a `links` property.');
- }
-
- if (this.options.pedantic) {
- this.rules = inline.pedantic;
- } else if (this.options.gfm) {
- if (this.options.breaks) {
- this.rules = inline.breaks;
- } else {
- this.rules = inline.gfm;
- }
- }
-}
-
-/**
- * Expose Inline Rules
- */
-
-InlineLexer.rules = inline;
-
-/**
- * Static Lexing/Compiling Method
- */
-
-InlineLexer.output = function(src, links, options) {
- var inline = new InlineLexer(links, options);
- return inline.output(src);
-};
-
-/**
- * Lexing/Compiling
- */
-
-InlineLexer.prototype.output = function(src) {
- var out = '',
- link,
- text,
- href,
- title,
- cap;
-
- while (src) {
- // escape
- if (cap = this.rules.escape.exec(src)) {
- src = src.substring(cap[0].length);
- out += cap[1];
- continue;
- }
-
- // autolink
- if (cap = this.rules.autolink.exec(src)) {
- src = src.substring(cap[0].length);
- if (cap[2] === '@') {
- text = escape(this.mangle(cap[1]));
- href = 'mailto:' + text;
- } else {
- text = escape(cap[1]);
- href = text;
- }
- out += this.renderer.link(href, null, text);
- continue;
- }
-
- // url (gfm)
- if (!this.inLink && (cap = this.rules.url.exec(src))) {
- cap[0] = this.rules._backpedal.exec(cap[0])[0];
- src = src.substring(cap[0].length);
- if (cap[2] === '@') {
- text = escape(cap[0]);
- href = 'mailto:' + text;
- } else {
- text = escape(cap[0]);
- if (cap[1] === 'www.') {
- href = 'http://' + text;
- } else {
- href = text;
- }
- }
- out += this.renderer.link(href, null, text);
- continue;
- }
-
- // tag
- if (cap = this.rules.tag.exec(src)) {
- if (!this.inLink && /^<a /i.test(cap[0])) {
- this.inLink = true;
- } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
- this.inLink = false;
- }
- src = src.substring(cap[0].length);
- out += this.options.sanitize
- ? this.options.sanitizer
- ? this.options.sanitizer(cap[0])
- : escape(cap[0])
- : cap[0]
- continue;
- }
-
- // link
- if (cap = this.rules.link.exec(src)) {
- src = src.substring(cap[0].length);
- this.inLink = true;
- href = cap[2];
- if (this.options.pedantic) {
- link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
-
- if (link) {
- href = link[1];
- title = link[3];
- } else {
- title = '';
- }
- } else {
- title = cap[3] ? cap[3].slice(1, -1) : '';
- }
- href = href.trim().replace(/^<([\s\S]*)>$/, '$1');
- out += this.outputLink(cap, {
- href: InlineLexer.escapes(href),
- title: InlineLexer.escapes(title)
- });
- this.inLink = false;
- continue;
- }
-
- // reflink, nolink
- if ((cap = this.rules.reflink.exec(src))
- || (cap = this.rules.nolink.exec(src))) {
- src = src.substring(cap[0].length);
- link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
- link = this.links[link.toLowerCase()];
- if (!link || !link.href) {
- out += cap[0].charAt(0);
- src = cap[0].substring(1) + src;
- continue;
- }
- this.inLink = true;
- out += this.outputLink(cap, link);
- this.inLink = false;
- continue;
- }
-
- // strong
- if (cap = this.rules.strong.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.strong(this.output(cap[4] || cap[3] || cap[2] || cap[1]));
- continue;
- }
-
- // em
- if (cap = this.rules.em.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.em(this.output(cap[6] || cap[5] || cap[4] || cap[3] || cap[2] || cap[1]));
- continue;
- }
-
- // code
- if (cap = this.rules.code.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.codespan(escape(cap[2].trim(), true));
- continue;
- }
-
- // br
- if (cap = this.rules.br.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.br();
- continue;
- }
-
- // del (gfm)
- if (cap = this.rules.del.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.del(this.output(cap[1]));
- continue;
- }
-
- // text
- if (cap = this.rules.text.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.text(escape(this.smartypants(cap[0])));
- continue;
- }
-
- if (src) {
- throw new Error('Infinite loop on byte: ' + src.charCodeAt(0));
- }
- }
-
- return out;
-};
-
-InlineLexer.escapes = function(text) {
- return text ? text.replace(InlineLexer.rules._escapes, '$1') : text;
-}
-
-/**
- * Compile Link
- */
-
-InlineLexer.prototype.outputLink = function(cap, link) {
- var href = link.href,
- title = link.title ? escape(link.title) : null;
-
- return cap[0].charAt(0) !== '!'
- ? this.renderer.link(href, title, this.output(cap[1]))
- : this.renderer.image(href, title, escape(cap[1]));
-};
-
-/**
- * Smartypants Transformations
- */
-
-InlineLexer.prototype.smartypants = function(text) {
- if (!this.options.smartypants) return text;
- return text
- // em-dashes
- .replace(/---/g, '\u2014')
- // en-dashes
- .replace(/--/g, '\u2013')
- // opening singles
- .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
- // closing singles & apostrophes
- .replace(/'/g, '\u2019')
- // opening doubles
- .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
- // closing doubles
- .replace(/"/g, '\u201d')
- // ellipses
- .replace(/\.{3}/g, '\u2026');
-};
-
-/**
- * Mangle Links
- */
-
-InlineLexer.prototype.mangle = function(text) {
- if (!this.options.mangle) return text;
- var out = '',
- l = text.length,
- i = 0,
- ch;
-
- for (; i < l; i++) {
- ch = text.charCodeAt(i);
- if (Math.random() > 0.5) {
- ch = 'x' + ch.toString(16);
- }
- out += '&#' + ch + ';';
- }
-
- return out;
-};
-
-/**
- * Renderer
- */
-
-function Renderer(options) {
- this.options = options || marked.defaults;
-}
-
-Renderer.prototype.code = function(code, lang, escaped) {
- if (this.options.highlight) {
- var out = this.options.highlight(code, lang);
- if (out != null && out !== code) {
- escaped = true;
- code = out;
- }
- }
-
- if (!lang) {
- return '<pre><code>'
- + (escaped ? code : escape(code, true))
- + '</code></pre>';
- }
-
- return '<pre><code class="'
- + this.options.langPrefix
- + escape(lang, true)
- + '">'
- + (escaped ? code : escape(code, true))
- + '</code></pre>\n';
-};
-
-Renderer.prototype.blockquote = function(quote) {
- return '<blockquote>\n' + quote + '</blockquote>\n';
-};
-
-Renderer.prototype.html = function(html) {
- return html;
-};
-
-Renderer.prototype.heading = function(text, level, raw) {
- if (this.options.headerIds) {
- return '<h'
- + level
- + ' id="'
- + this.options.headerPrefix
- + raw.toLowerCase().replace(/[^\w]+/g, '-')
- + '">'
- + text
- + '</h'
- + level
- + '>\n';
- }
- // ignore IDs
- return '<h' + level + '>' + text + '</h' + level + '>\n';
-};
-
-Renderer.prototype.hr = function() {
- return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
-};
-
-Renderer.prototype.list = function(body, ordered, start) {
- var type = ordered ? 'ol' : 'ul',
- startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
- return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
-};
-
-Renderer.prototype.listitem = function(text) {
- return '<li>' + text + '</li>\n';
-};
-
-Renderer.prototype.checkbox = function(checked) {
- return '<input '
- + (checked ? 'checked="" ' : '')
- + 'disabled="" type="checkbox"'
- + (this.options.xhtml ? ' /' : '')
- + '> ';
-}
-
-Renderer.prototype.paragraph = function(text) {
- return '<p>' + text + '</p>\n';
-};
-
-Renderer.prototype.table = function(header, body) {
- if (body) body = '<tbody>' + body + '</tbody>';
-
- return '<table>\n'
- + '<thead>\n'
- + header
- + '</thead>\n'
- + body
- + '</table>\n';
-};
-
-Renderer.prototype.tablerow = function(content) {
- return '<tr>\n' + content + '</tr>\n';
-};
-
-Renderer.prototype.tablecell = function(content, flags) {
- var type = flags.header ? 'th' : 'td';
- var tag = flags.align
- ? '<' + type + ' align="' + flags.align + '">'
- : '<' + type + '>';
- return tag + content + '</' + type + '>\n';
-};
-
-// span level renderer
-Renderer.prototype.strong = function(text) {
- return '<strong>' + text + '</strong>';
-};
-
-Renderer.prototype.em = function(text) {
- return '<em>' + text + '</em>';
-};
-
-Renderer.prototype.codespan = function(text) {
- return '<code>' + text + '</code>';
-};
-
-Renderer.prototype.br = function() {
- return this.options.xhtml ? '<br/>' : '<br>';
-};
-
-Renderer.prototype.del = function(text) {
- return '<del>' + text + '</del>';
-};
-
-Renderer.prototype.link = function(href, title, text) {
- if (this.options.sanitize) {
- try {
- var prot = decodeURIComponent(unescape(href))
- .replace(/[^\w:]/g, '')
- .toLowerCase();
- } catch (e) {
- return text;
- }
- if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
- return text;
- }
- }
- if (this.options.baseUrl && !originIndependentUrl.test(href)) {
- href = resolveUrl(this.options.baseUrl, href);
- }
- try {
- href = encodeURI(href).replace(/%25/g, '%');
- } catch (e) {
- return text;
- }
- var out = '<a href="' + escape(href) + '"';
- if (title) {
- out += ' title="' + title + '"';
- }
- out += '>' + text + '</a>';
- return out;
-};
-
-Renderer.prototype.image = function(href, title, text) {
- if (this.options.baseUrl && !originIndependentUrl.test(href)) {
- href = resolveUrl(this.options.baseUrl, href);
- }
- var out = '<img src="' + href + '" alt="' + text + '"';
- if (title) {
- out += ' title="' + title + '"';
- }
- out += this.options.xhtml ? '/>' : '>';
- return out;
-};
-
-Renderer.prototype.text = function(text) {
- return text;
-};
-
-/**
- * TextRenderer
- * returns only the textual part of the token
- */
-
-function TextRenderer() {}
-
-// no need for block level renderers
-
-TextRenderer.prototype.strong =
-TextRenderer.prototype.em =
-TextRenderer.prototype.codespan =
-TextRenderer.prototype.del =
-TextRenderer.prototype.text = function (text) {
- return text;
-}
-
-TextRenderer.prototype.link =
-TextRenderer.prototype.image = function(href, title, text) {
- return '' + text;
-}
-
-TextRenderer.prototype.br = function() {
- return '';
-}
-
-/**
- * Parsing & Compiling
- */
-
-function Parser(options) {
- this.tokens = [];
- this.token = null;
- this.options = options || marked.defaults;
- this.options.renderer = this.options.renderer || new Renderer();
- this.renderer = this.options.renderer;
- this.renderer.options = this.options;
-}
-
-/**
- * Static Parse Method
- */
-
-Parser.parse = function(src, options) {
- var parser = new Parser(options);
- return parser.parse(src);
-};
-
-/**
- * Parse Loop
- */
-
-Parser.prototype.parse = function(src) {
- this.inline = new InlineLexer(src.links, this.options);
- // use an InlineLexer with a TextRenderer to extract pure text
- this.inlineText = new InlineLexer(
- src.links,
- merge({}, this.options, {renderer: new TextRenderer()})
- );
- this.tokens = src.reverse();
-
- var out = '';
- while (this.next()) {
- out += this.tok();
- }
-
- return out;
-};
-
-/**
- * Next Token
- */
-
-Parser.prototype.next = function() {
- return this.token = this.tokens.pop();
-};
-
-/**
- * Preview Next Token
- */
-
-Parser.prototype.peek = function() {
- return this.tokens[this.tokens.length - 1] || 0;
-};
-
-/**
- * Parse Text Tokens
- */
-
-Parser.prototype.parseText = function() {
- var body = this.token.text;
-
- while (this.peek().type === 'text') {
- body += '\n' + this.next().text;
- }
-
- return this.inline.output(body);
-};
-
-/**
- * Parse Current Token
- */
-
-Parser.prototype.tok = function() {
- switch (this.token.type) {
- case 'space': {
- return '';
- }
- case 'hr': {
- return this.renderer.hr();
- }
- case 'heading': {
- return this.renderer.heading(
- this.inline.output(this.token.text),
- this.token.depth,
- unescape(this.inlineText.output(this.token.text)));
- }
- case 'code': {
- return this.renderer.code(this.token.text,
- this.token.lang,
- this.token.escaped);
- }
- case 'table': {
- var header = '',
- body = '',
- i,
- row,
- cell,
- j;
-
- // header
- cell = '';
- for (i = 0; i < this.token.header.length; i++) {
- cell += this.renderer.tablecell(
- this.inline.output(this.token.header[i]),
- { header: true, align: this.token.align[i] }
- );
- }
- header += this.renderer.tablerow(cell);
-
- for (i = 0; i < this.token.cells.length; i++) {
- row = this.token.cells[i];
-
- cell = '';
- for (j = 0; j < row.length; j++) {
- cell += this.renderer.tablecell(
- this.inline.output(row[j]),
- { header: false, align: this.token.align[j] }
- );
- }
-
- body += this.renderer.tablerow(cell);
- }
- return this.renderer.table(header, body);
- }
- case 'blockquote_start': {
- body = '';
-
- while (this.next().type !== 'blockquote_end') {
- body += this.tok();
- }
-
- return this.renderer.blockquote(body);
- }
- case 'list_start': {
- body = '';
- var ordered = this.token.ordered,
- start = this.token.start;
-
- while (this.next().type !== 'list_end') {
- body += this.tok();
- }
-
- return this.renderer.list(body, ordered, start);
- }
- case 'list_item_start': {
- body = '';
-
- if (this.token.task) {
- body += this.renderer.checkbox(this.token.checked);
- }
-
- while (this.next().type !== 'list_item_end') {
- body += this.token.type === 'text'
- ? this.parseText()
- : this.tok();
- }
-
- return this.renderer.listitem(body);
- }
- case 'loose_item_start': {
- body = '';
-
- while (this.next().type !== 'list_item_end') {
- body += this.tok();
- }
-
- return this.renderer.listitem(body);
- }
- case 'html': {
- // TODO parse inline content if parameter markdown=1
- return this.renderer.html(this.token.text);
- }
- case 'paragraph': {
- return this.renderer.paragraph(this.inline.output(this.token.text));
- }
- case 'text': {
- return this.renderer.paragraph(this.parseText());
- }
- }
-};
-
-/**
- * Helpers
- */
-
-function escape(html, encode) {
- return html
- .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
- .replace(/</g, '&lt;')
- .replace(/>/g, '&gt;')
- .replace(/"/g, '&quot;')
- .replace(/'/g, '&#39;');
-}
-
-function unescape(html) {
- // explicitly match decimal, hex, and named HTML entities
- return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, function(_, n) {
- n = n.toLowerCase();
- if (n === 'colon') return ':';
- if (n.charAt(0) === '#') {
- return n.charAt(1) === 'x'
- ? String.fromCharCode(parseInt(n.substring(2), 16))
- : String.fromCharCode(+n.substring(1));
- }
- return '';
- });
-}
-
-function edit(regex, opt) {
- regex = regex.source || regex;
- opt = opt || '';
- return {
- replace: function(name, val) {
- val = val.source || val;
- val = val.replace(/(^|[^\[])\^/g, '$1');
- regex = regex.replace(name, val);
- return this;
- },
- getRegex: function() {
- return new RegExp(regex, opt);
- }
- };
-}
-
-function resolveUrl(base, href) {
- if (!baseUrls[' ' + base]) {
- // we can ignore everything in base after the last slash of its path component,
- // but we might need to add _that_
- // https://tools.ietf.org/html/rfc3986#section-3
- if (/^[^:]+:\/*[^/]*$/.test(base)) {
- baseUrls[' ' + base] = base + '/';
- } else {
- baseUrls[' ' + base] = base.replace(/[^/]*$/, '');
- }
- }
- base = baseUrls[' ' + base];
-
- if (href.slice(0, 2) === '//') {
- return base.replace(/:[\s\S]*/, ':') + href;
- } else if (href.charAt(0) === '/') {
- return base.replace(/(:\/*[^/]*)[\s\S]*/, '$1') + href;
- } else {
- return base + href;
- }
-}
-var baseUrls = {};
-var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
-
-function noop() {}
-noop.exec = noop;
-
-function merge(obj) {
- var i = 1,
- target,
- key;
-
- for (; i < arguments.length; i++) {
- target = arguments[i];
- for (key in target) {
- if (Object.prototype.hasOwnProperty.call(target, key)) {
- obj[key] = target[key];
- }
- }
- }
-
- return obj;
-}
-
-function splitCells(tableRow, count) {
- var cells = tableRow.replace(/([^\\])\|/g, '$1 |').split(/ +\| */),
- i = 0;
-
- if (cells.length > count) {
- cells.splice(count);
- } else {
- while (cells.length < count) cells.push('');
- }
-
- for (; i < cells.length; i++) {
- cells[i] = cells[i].replace(/\\\|/g, '|');
- }
- return cells;
-}
-
-/**
- * Marked
- */
-
-function marked(src, opt, callback) {
- // throw error in case of non string input
- if (typeof src === 'undefined' || src === null) {
- throw new Error('marked(): input parameter is undefined or null');
- }
- if (typeof src !== 'string') {
- throw new Error('marked(): input parameter is of type '
- + Object.prototype.toString.call(src) + ', string expected');
- }
-
- if (callback || typeof opt === 'function') {
- if (!callback) {
- callback = opt;
- opt = null;
- }
-
- opt = merge({}, marked.defaults, opt || {});
-
- var highlight = opt.highlight,
- tokens,
- pending,
- i = 0;
-
- try {
- tokens = Lexer.lex(src, opt)
- } catch (e) {
- return callback(e);
- }
-
- pending = tokens.length;
-
- var done = function(err) {
- if (err) {
- opt.highlight = highlight;
- return callback(err);
- }
-
- var out;
-
- try {
- out = Parser.parse(tokens, opt);
- } catch (e) {
- err = e;
- }
-
- opt.highlight = highlight;
-
- return err
- ? callback(err)
- : callback(null, out);
- };
-
- if (!highlight || highlight.length < 3) {
- return done();
- }
-
- delete opt.highlight;
-
- if (!pending) return done();
-
- for (; i < tokens.length; i++) {
- (function(token) {
- if (token.type !== 'code') {
- return --pending || done();
- }
- return highlight(token.text, token.lang, function(err, code) {
- if (err) return done(err);
- if (code == null || code === token.text) {
- return --pending || done();
- }
- token.text = code;
- token.escaped = true;
- --pending || done();
- });
- })(tokens[i]);
- }
-
- return;
- }
- try {
- if (opt) opt = merge({}, marked.defaults, opt);
- return Parser.parse(Lexer.lex(src, opt), opt);
- } catch (e) {
- e.message += '\nPlease report this to https://github.com/markedjs/marked.';
- if ((opt || marked.defaults).silent) {
- return '<p>An error occurred:</p><pre>'
- + escape(e.message + '', true)
- + '</pre>';
- }
- throw e;
- }
-}
-
-/**
- * Options
- */
-
-marked.options =
-marked.setOptions = function(opt) {
- merge(marked.defaults, opt);
- return marked;
-};
-
-marked.getDefaults = function () {
- return {
- baseUrl: null,
- breaks: false,
- gfm: true,
- headerIds: true,
- headerPrefix: '',
- highlight: null,
- langPrefix: 'language-',
- mangle: true,
- pedantic: false,
- renderer: new Renderer(),
- sanitize: false,
- sanitizer: null,
- silent: false,
- smartLists: false,
- smartypants: false,
- tables: true,
- xhtml: false
- };
-}
-
-marked.defaults = marked.getDefaults();
-
-/**
- * Expose
- */
-
-marked.Parser = Parser;
-marked.parser = Parser.parse;
-
-marked.Renderer = Renderer;
-marked.TextRenderer = TextRenderer;
-
-marked.Lexer = Lexer;
-marked.lexer = Lexer.lex;
-
-marked.InlineLexer = InlineLexer;
-marked.inlineLexer = InlineLexer.output;
-
-marked.parse = marked;
-
-if (typeof module !== 'undefined' && typeof exports === 'object') {
- module.exports = marked;
-} else if (typeof define === 'function' && define.amd) {
- define(function() { return marked; });
-} else {
- root.marked = marked;
-}
-})(this || (typeof window !== 'undefined' ? window : global));
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json b/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json
deleted file mode 100644
index d51ac744b..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json
+++ /dev/null
@@ -1,34 +0,0 @@
-[
- {
- "Id": "markdowneditor-marked",
- "Name": "Marked (WebEngine Markdown Editor example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "Marked is used in the WebEngine MarkDown Editor example",
- "QtParts": [ "examples" ],
- "Files": "marked.js",
- "Description": "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
- "Homepage": "https://github.com/chjj/marked",
- "Version": "0.4.0",
- "DownloadLocation": "https://github.com/markedjs/marked/blob/0.4.0/lib/marked.js",
- "Copyright": "Copyright (c) 2011-2018, Christopher Jeffrey",
- "License": "MIT License",
- "LicenseId": "MIT",
- "LicenseFile": "MARKED-LICENSE.txt"
- },
- {
- "Id": "markdowneditor-markdowncss",
- "Name": "Markdown.css (WebEngine Markdown Editor example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "markdown.css is used in the WebEngine MarkDown Editor example",
- "QtParts": [ "examples" ],
- "Files": "markdown.css",
- "Description": "Markdown.css is better default styling for your Markdown files.",
- "Version": "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
- "DownloadLocation": "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
- "Copyright": "Copyright 2011 Kevin Burke
- Copyright Twitter Inc.",
- "License": "Apache License 2.0",
- "LicenseId": "Apache-2.0",
- "LicenseFile": "MARKDOWN-LICENSE.txt"
- }
-]
diff --git a/examples/webenginewidgets/markdowneditor/resources/default.md b/examples/webenginewidgets/markdowneditor/resources/default.md
deleted file mode 100644
index af835fa4d..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/default.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## WebEngine Markdown Editor Example
-
-This example uses [QWebEngineView](http://doc.qt.io/qt-5/qwebengineview.html)
-to preview text written using the [Markdown](https://en.wikipedia.org/wiki/Markdown)
-syntax.
-
-### Acknowledgments
-
-The conversion from Markdown to HTML is done with the help of the
-[marked JavaScript library](https://github.com/chjj/marked) by _Christopher Jeffrey_.
-The [style sheet](https://kevinburke.bitbucket.io/markdowncss/)
-was created by _Kevin Burke_.
diff --git a/examples/webenginewidgets/markdowneditor/resources/index.html b/examples/webenginewidgets/markdowneditor/resources/index.html
deleted file mode 100644
index 289a2110b..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/index.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!doctype html>
-<html lang="en">
-<meta charset="utf-8">
-<head>
- <link rel="stylesheet" type="text/css" href="3rdparty/markdown.css">
- <script src="3rdparty/marked.js"></script>
- <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
-</head>
-<body>
- <div id="placeholder"></div>
- <script>
- 'use strict';
-
- var placeholder = document.getElementById('placeholder');
-
- var updateText = function(text) {
- placeholder.innerHTML = marked(text);
- }
-
- new QWebChannel(qt.webChannelTransport,
- function(channel) {
- var content = channel.objects.content;
- updateText(content.text);
- content.textChanged.connect(updateText);
- }
- );
- </script>
-</body>
-</html>
-
-
-
diff --git a/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
deleted file mode 100644
index bc738f1cf..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>default.md</file>
- <file>index.html</file>
- <file>3rdparty/markdown.css</file>
- <file>3rdparty/marked.js</file>
- </qresource>
-</RCC>
diff --git a/examples/webenginewidgets/minimal/CMakeLists.txt b/examples/webenginewidgets/minimal/CMakeLists.txt
deleted file mode 100644
index 7c1cac1d8..000000000
--- a/examples/webenginewidgets/minimal/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(minimal LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/minimal-widgets")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
-
-qt_add_executable(minimal-widgets
- main.cpp
-)
-
-set_target_properties(minimal-widgets PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(minimal-widgets PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineWidgets
-)
-
-install(TARGETS minimal-widgets
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginewidgets/minimal/doc/images/minimal-example.png b/examples/webenginewidgets/minimal/doc/images/minimal-example.png
deleted file mode 100644
index 18ac9b177..000000000
--- a/examples/webenginewidgets/minimal/doc/images/minimal-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
deleted file mode 100644
index 5fb5f8be3..000000000
--- a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginewidgets/minimal
- \title WebEngine Widgets Minimal Example
- \ingroup webengine-widgetexamples
- \brief Displays a web page using \QWE Widgets.
-
- \image minimal-example.png
-
- \e {WebEngine Widgets Minimal Example} demonstrates how to use
- \l{QWebEngineView} to render a web page. It shows the minimum amount of code
- needed to load and display an HTML page, and can be used as a basis for
- further experimentation.
-
- \include examples-run.qdocinc
-
- \section1 The Code
-
- We first define a \c commandLineUrlArgument function that returns the URL to open.
- This is either the first positional argument given on the command line, or
- \c https://www.qt.io as a fallback.
-
- \quotefromfile webenginewidgets/minimal/main.cpp
- \skipto #include
-
- \printto int main
-
- In the \c main function we first set the
- \l{QCoreApplication::organizationName} property. This affects the locations
- where \QWE stores persistent and cached data (see also
- \l{QWebEngineProfile::cachePath} and
- \l{QWebEngineProfile::persistentStoragePath}).
-
- Next, we instantiate a QApplication and a QWebEngineView. The URL
- to load is taken from \c commandLineUrlArgument and
- loaded by calling \l QWebEngineView::setUrl. The view widget is
- given a reasonable default size, and shown.
- Finally, QApplication::exec() launches the main event loop.
-
- \printuntil }
-
- \section1 Requirements
-
- The example requires a working internet connection to render
- the \l{Qt Homepage}.
- An optional system proxy should be picked up automatically.
- However, for proxies that require a username or password,
- you need to connect to
- QWebEnginePage::proxyAuthenticationRequired.
-
- \l{Qt WebEngine Widgets} uses the \l{Qt Quick Scene Graph} to compose the
- page. Therefore, OpenGL support is required.
-*/
diff --git a/examples/webenginewidgets/notifications/CMakeLists.txt b/examples/webenginewidgets/notifications/CMakeLists.txt
index 17d4f343b..688d06eb2 100644
--- a/examples/webenginewidgets/notifications/CMakeLists.txt
+++ b/examples/webenginewidgets/notifications/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(notifications LANGUAGES CXX)
diff --git a/examples/webenginewidgets/printme/CMakeLists.txt b/examples/webenginewidgets/printme/CMakeLists.txt
index 2c38103c1..013ba48ca 100644
--- a/examples/webenginewidgets/printme/CMakeLists.txt
+++ b/examples/webenginewidgets/printme/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(printme LANGUAGES CXX)
diff --git a/examples/webenginewidgets/webui/CMakeLists.txt b/examples/webenginewidgets/push-notifications/CMakeLists.txt
index e736a2cde..8ea2e25d1 100644
--- a/examples/webenginewidgets/webui/CMakeLists.txt
+++ b/examples/webenginewidgets/push-notifications/CMakeLists.txt
@@ -1,5 +1,8 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
-project(webui LANGUAGES CXX)
+project(notifications LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
@@ -7,39 +10,36 @@ if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/webui")
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/push-notifications")
find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
-qt_add_executable(webui
+qt_add_executable(push-notifications
main.cpp
- webuihandler.cpp webuihandler.h
+ notificationpopup.h
)
-set_target_properties(webui PROPERTIES
+set_target_properties(push-notifications PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
-target_link_libraries(webui PUBLIC
+target_link_libraries(push-notifications PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
-# Resources:
-set(webui_resource_files
- "about.html"
-)
-
-qt_add_resources(webui "webui"
+qt_add_resources(push-notifications "data"
PREFIX
"/"
+ BASE
+ "data"
FILES
- ${webui_resource_files}
+ "data/icon.png"
)
-install(TARGETS webui
+install(TARGETS push-notifications
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
diff --git a/examples/webenginewidgets/push-notifications/content/index.html b/examples/webenginewidgets/push-notifications/content/index.html
new file mode 100644
index 000000000..cce3055cd
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/index.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Push Notification Using Node and FCM</title>
+ <link rel="stylesheet" href="style.css">
+</head>
+<body>
+ <h1>Push Notification Using NodeJS and QtWebEngine</h1>
+ <div id="app">
+ <div id="ping-setup">
+ <form>
+ <div>
+ Ping Me Every [sec]:
+ </div>
+ <div class="ping-input">
+ <input type="number" name="seconds" min="0" max="3600" required="">
+ </div><button>Ping Me</button>
+ </form>
+ </div>
+ <div id="ping-clear">
+ <div id="ping-text"></div><button id="ping-clear-button">Clear</button>
+ </div>
+ </div>
+ <script src="ping.js"></script>
+</body>
+</html>
diff --git a/examples/webenginewidgets/push-notifications/content/ping.js b/examples/webenginewidgets/push-notifications/content/ping.js
new file mode 100644
index 000000000..285a57019
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/ping.js
@@ -0,0 +1,84 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+const publicVapidKey =
+ "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg";
+
+async function setup(delay)
+{
+ console.log('>> register service worker...');
+ const register = await navigator.serviceWorker.register('/worker.js', { scope : '/' });
+ console.log('>> service worker registered...');
+
+ console.log('>> subscribe push subscription to FCM');
+ var subscription = await register.pushManager.subscribe(
+ { userVisibleOnly : true, applicationServerKey : publicVapidKey });
+ console.log('>> subscription created...');
+
+ console.log('>> subscribe to push service...');
+ await fetch('/subscribe', {
+ method : 'POST',
+ body : JSON.stringify(subscription),
+ headers : { 'content-type' : 'application/json', 'ping-time' : delay }
+ });
+ console.log('>> push subscription created...')
+}
+
+async function clear()
+{
+ const register = await navigator.serviceWorker.getRegistration();
+ var subscription = await register.pushManager.getSubscription();
+ console.log('>> unsubscribe to push service...');
+ await fetch('/unsubscribe', {
+ method : 'POST',
+ body : JSON.stringify(subscription),
+ headers : { 'content-type' : 'application/json' }
+ });
+ console.log('>> push unsubscription removed...')
+
+ console.log('>> unsubscribe push subscription to FCM');
+ await subscription.unsubscribe();
+ console.log('>> subscription removed...');
+}
+
+function displaySetup(delay = null)
+{
+ const pingSetup = document.getElementById('ping-setup');
+ const pingClear = document.getElementById('ping-clear');
+ const pingText = document.getElementById('ping-text');
+ if (delay) {
+ pingClear.style.display = 'block';
+ pingSetup.style.display = 'none';
+ pingText.innerHTML = 'Ping Me Every ' + delay + ' seconds';
+ } else {
+ pingClear.style.display = 'none';
+ pingSetup.style.display = 'block';
+ pingText.innerHTML = "";
+ }
+}
+
+function handleSetupPing(event)
+{
+ event.preventDefault();
+
+ const seconds = document.forms[0].seconds.value;
+ document.forms[0].reset();
+
+ // check for service worker support
+ if ('serviceWorker' in navigator) {
+ setup(seconds).catch(err => console.error(err));
+ }
+
+ displaySetup(seconds);
+};
+
+function handleClearPing(event)
+{
+ event.preventDefault();
+ clear();
+ displaySetup();
+};
+
+document.forms[0].addEventListener('submit', handleSetupPing);
+const clearButton = document.getElementById('ping-clear-button');
+clearButton.addEventListener('click', handleClearPing);
diff --git a/examples/webenginewidgets/push-notifications/content/style.css b/examples/webenginewidgets/push-notifications/content/style.css
new file mode 100644
index 000000000..8176462a2
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/style.css
@@ -0,0 +1,29 @@
+body {
+ font-family: monaco;
+ height: 100vh;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ display: flex;
+}
+#ping-clear,
+#ping-setup {
+ font-size: 32px;
+ text-align: center;
+}
+.form-inputs{
+ margin-top: 20px;
+}
+input {
+ width: 100px;
+ height: 30px;
+}
+button {
+ font-size: 16px;
+}
+#ping-text {
+ margin-bottom: 30px;
+}
+#ping-clear {
+ display: none;
+}
diff --git a/examples/webenginewidgets/push-notifications/content/worker.js b/examples/webenginewidgets/push-notifications/content/worker.js
new file mode 100644
index 000000000..ed660a6e9
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/worker.js
@@ -0,0 +1,7 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+self.addEventListener('push', event => {
+ const data = event.data.json();
+ self.registration.showNotification(data.title, { body : data.text });
+});
diff --git a/examples/webenginewidgets/webui/webui.qrc b/examples/webenginewidgets/push-notifications/data/data.qrc
index 6ddf01fa2..619648d1b 100644
--- a/examples/webenginewidgets/webui/webui.qrc
+++ b/examples/webenginewidgets/push-notifications/data/data.qrc
@@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/">
- <file>about.html</file>
+ <file>icon.png</file>
</qresource>
</RCC>
diff --git a/examples/webenginewidgets/push-notifications/data/icon.png b/examples/webenginewidgets/push-notifications/data/icon.png
new file mode 100644
index 000000000..4c3870c06
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/data/icon.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/notification.png b/examples/webenginewidgets/push-notifications/doc/images/notification.png
new file mode 100644
index 000000000..ec5c67457
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/notification.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/permissions.png b/examples/webenginewidgets/push-notifications/doc/images/permissions.png
new file mode 100644
index 000000000..dedb6e472
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/permissions.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png b/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png
new file mode 100644
index 000000000..c5ba5f589
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/website.png b/examples/webenginewidgets/push-notifications/doc/images/website.png
new file mode 100644
index 000000000..10a4a6150
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/website.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc
new file mode 100644
index 000000000..2f234c1e0
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc
@@ -0,0 +1,202 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+
+\example webenginewidgets/push-notifications
+\title WebEngine Push Notifications Example
+\ingroup webengine-widgetexamples
+\brief Demonstrates how to subscribe to and unsubscribe from push notifications.
+
+In this example we are going to send push notifications from a web push service to the user.
+This is the typical scenario where messages are sent from the application server i.e. website
+back-end through a 3rd-party push service, to finally arrive at the user's browser in form of
+notifications. To demonstrate this flow, we will implement a simple push service server
+application, to which the user can subscribe to receive \e ping messages.
+
+As already mentioned, in such a workflow there are three different parties involved:
+
+\list
+ \li the user's web browser where they receive push notifications
+ \li 3rd-party push service, which is defined by a subscription endpoint and is a part
+ of a browser's push service implementation
+ \li application server, which will store user's subscriptions and initiate push messages
+ using a subscription endpoint
+\endlist
+
+The user visits a website, where a JavaScript web application uses the JavaScript Push API
+to create a push notification subscription. The user is then asked to grant a permission
+to receive and display push notifications. Once accepted, the Push API establishes a push channel
+with a 3rd-party push service, which in case of QtWebEngine is \l {https://firebase.google.com}
+{Firebase Cloud Messaging (FCM)}. The unique push subscription is created that
+includes the subscription endpoint URL. The browser then sends a subscription message
+to the application server forwarding the endpoint setup. The application server can now
+use the subscription endpoint to send notifications to the browser. The browser push service
+implementation will deliver a push message. However, to show it, a service worker must
+be registered. As the service worker runs in the background, it allows displaying notifications
+even if a website, which has installed it, is no longer opened.
+
+\image push-notifications.png
+
+Let's go more into implementation details. We start with implementing our custom
+push service using NodeJS with two modules:
+
+\list
+ \li \l {https://github.com/web-push-libs/web-push} {web-push} - provides the web-push protocol
+ implementation
+ \li \l {https://github.com/expressjs/express} {express} - provides the web application framework
+\endlist
+
+Let's initialize a new project and install the required modules in the root directory of this
+example:
+
+\snippet /push-notifications/commands 0
+
+These commands should create package.js, which defines the start command:
+
+\snippet /push-notifications/commands 1
+
+Now let's move on to the push service back-end implementation in server.js.
+
+We start by including the required modules and doing basic \e express framework setup, which
+we use to create our custom push server. For simplicity we are going to handle only one
+subscription at a time. To do that we need to create \e VAPID keys which we are going to
+generate with \e web-push libs. The public key is going to be used by the front-end and authenticate
+to the service.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto const express
+\printto add subscribe route
+
+\note We are not going to cover the encryption of messages in this example.
+
+To generate keys, we can use the tool shipped with \e web-push lib, that is installed by
+\c npm in our example's root directory.
+
+\snippet /push-notifications/commands 2
+
+Now we add two \c routes to the push server. One to \c subscribe and one to \c unsubscribe,
+so that our front-end can send an HTTP POST request to handle the push subscription.
+In the subscribe request we will get \c subscription in the request body and we also retrieve
+the custom header \c ping-time that defines how often the ping messages should be pushed to
+the user. We keep around the \c subscription to be able to send push notifications later.
+As a confirmation, we send the 201 status code and schedule the first push notification based on
+the \c ping-time value. The \c unsubscribe request simply removes a subscription.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto add subscribe route
+\printto function sendNotification
+
+The \c sendNotication() function sends push messages using the web-push lib. We create the payload
+with the message we want to present to a user and schedule the next push message.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto function sendNotification
+\printto server.listen
+
+In the end we start the server to listen on the given port.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto server.listen
+\printline started
+
+Let's move now to our front-end. We create a simple page index.html, where the user can enter how
+often they want to receive ping notification messages. We will have two buttons:
+\e {Ping Me} to subscribe for push notifications and \e Clear to unsubscribe.
+In the end we load ping.js, which we cover next.
+
+\quotefromfile webenginewidgets/push-notifications/content/index.html
+\skipto <body>
+\printuntil </body>
+
+The last piece is creating the logic for the push subscription within the front-end. Here we have two
+functions, \c setup and \c clear, to handle subscriptions. When the user clicks on the \e {Ping Me}
+button, \c setup is called. To be able to receive notifications, the service worker is needed.
+This way the user can leave the website and still get notified as the service worker works
+in the background and handles incoming messages. To achieve that, we have to first register
+one with:
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipto const register
+\printline worker.js
+
+The call to \c cpushManager.subscribe() will trigger a permission prompt, which is displayed to the
+user. If the permission is granted, the push subscription is returned. It includes a URL endpoint
+that allows sending notifications to the browser, where the registered service worker waits for
+push messages.
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipto var subscription
+\printto console.log
+
+As mentioned the subscription is created for FCM and should be now sent to our custom server
+with an HTTP POST request. In addition, we add to the post request the HTTP header with the
+\c ping-time the user entered on our website.
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipto await fetch
+\printto console.log
+
+The function \c clear call unsubscribes first from our push server by sending an HTTP POST request
+and later from the 3rd-party push service (FCM).
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipuntil async function clear()
+\skipuntil {
+\printto console.log
+\dots
+\skipto await fetch
+\printto console.log
+\dots
+\skipto await subscription
+\printto console.log
+
+The rest of code in ping.js is just boilerplate code to read a user provided value
+and call \c setup() or \c clear().
+
+As the last part of the front-end let's look inside a service worker script, where we simply
+register an event listener for \e push events.
+
+\quotefromfile webenginewidgets/push-notifications/content/worker.js
+\skipto self
+\printuntil });
+\printuntil });
+
+When a push event comes we simply use the Notification JavaScript API to display a notification.
+
+\note QtWebEngine Notification Example shows how to provide your own handler and customize
+the look and feel of a notification message.
+
+Having the implementation in place, we can start the server on localhost at the port 5000.
+To do that, we can simply enter in the console in the project's root directory:
+
+\snippet /push-notifications/commands 3
+
+Now we can look into the \e push-notification browser application, which is based on
+\l {WebEngine Notifications Example}:
+
+\quotefromfile webenginewidgets/push-notifications/main.cpp
+\skipto main
+\printuntil app.exec
+\printuntil }
+
+This application simply opens the page at \c http:\\localhost:5000. We are not going into detail
+about how to open a notification as it is documented \l {WebEngine Notifications Example}{here}.
+However, you need to modify the application in two ways. First, \c QWebEngineProfile cannot be
+set to \e off-the-record because push messaging would be disabled. Therefore, as you can see
+above, \c QWebEngineProfile is initialized with the name. Second, you need to enable push
+messaging with the call QWebEngineProfile::setPushServiceEnabled for the created \c profile.
+
+When the application runs it displays:
+
+\image website.png
+
+After granting the permission we can send our ping request:
+
+\image permissions.png
+
+We should see the coming push notification:
+
+\image notification.png
+
+*/
diff --git a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel
new file mode 100644
index 000000000..048a55911
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel
@@ -0,0 +1,837 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<qmt>
+ <project>
+ <uid>{9fd14f7e-7b67-4e13-9980-ef8fbe24b780}</uid>
+ <root-package>
+ <instance>
+ <MPackage>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{a26e0efd-1b21-4fba-96ce-a607bbcdb4f7}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push_notifications</name>
+ <children>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{6b1a06e9-960b-4a10-872e-5504d8c0b127}</uid>
+ <target>
+ <instance type="MCanvasDiagram">
+ <MCanvasDiagram>
+ <base-MDiagram>
+ <MDiagram>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{6b1a06e9-960b-4a10-872e-5504d8c0b127}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push_notifications</name>
+ </MObject>
+ </base-MObject>
+ <elements>
+ <qlist>
+ <item>
+ <instance type="DBoundary">
+ <DBoundary>
+ <base-DElement>
+ <DElement>
+ <uid>{d50762f2-c7f4-4d52-9592-8bcc07274ba1}</uid>
+ </DElement>
+ </base-DElement>
+ <text>Browser / User Agent</text>
+ <pos>x:415;y:390</pos>
+ <rect>x:-105;y:-125;w:210;h:250</rect>
+ </DBoundary>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{121189af-36df-4efa-b451-3f1f85ef339f}</object>
+ <name>JavaScript Web Application</name>
+ <pos>x:410;y:395</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{8bde1815-304a-41f6-8528-c754dc3d1eda}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{13c69399-5587-4169-a012-8d86216139fd}</object>
+ <name>Push Manager API</name>
+ <pos>x:410;y:320</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</object>
+ <name>Service Worker</name>
+ <pos>x:410;y:470</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{0a7b0146-d34b-4c39-a1af-df15a1b4108d}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d}</object>
+ <a>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</a>
+ <b>{8bde1815-304a-41f6-8528-c754dc3d1eda}</b>
+ <name>subscribe</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{e7d4a675-ddbd-41aa-a802-32221a56dae2}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{afae2401-ea81-4514-aa80-da53d61a8516}</object>
+ <a>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</a>
+ <b>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</b>
+ <name>register</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{998e7d36-3416-4b2f-843a-a437449f09f1}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</object>
+ <name>Firebase Cloud Messaging </name>
+ <pos>x:770;y:320</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <visual-role>6</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{28c1fccd-c50e-458c-865d-4ba41d55690b}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{d9959769-74a4-40ad-bf00-904c12a67309}</object>
+ <a>{8bde1815-304a-41f6-8528-c754dc3d1eda}</a>
+ <b>{998e7d36-3416-4b2f-843a-a437449f09f1}</b>
+ <name>create subscription</name>
+ </DRelation>
+ </base-DRelation>
+ <direction>2</direction>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{ba581e41-cc00-4129-adae-0a1208bb3222}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</object>
+ <name>Push Application Server</name>
+ <pos>x:770;y:390</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>6</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{e796d1cc-f574-45db-a440-7e47d7560d71}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{373c492c-0b9a-4032-9ff4-b3a7cc442883}</object>
+ <a>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</a>
+ <b>{ba581e41-cc00-4129-adae-0a1208bb3222}</b>
+ <name>subscribe with endpoint</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{6332f8ae-ef9d-4c15-9fbf-d6ee06ba3f84}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{94241d64-4e88-4855-8e78-365be237108b}</object>
+ <a>{ba581e41-cc00-4129-adae-0a1208bb3222}</a>
+ <b>{998e7d36-3416-4b2f-843a-a437449f09f1}</b>
+ <name>push notification</name>
+ <points>
+ <qlist>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:770;y:335</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ </qlist>
+ </points>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{582af542-5f2d-4660-a6d0-a3bd983d9682}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{00b8f12d-e08b-426a-83b8-83fea8907fab}</object>
+ <name>User</name>
+ <pos>x:185;y:395</pos>
+ <rect>x:-10;y:-20;w:20;h:40</rect>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <variety>actor</variety>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{66ca12e1-84a1-4247-82e5-ae6891f3f376}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{6d0ce78f-28e1-4a82-a443-59f4efcb8e66}</object>
+ <a>{582af542-5f2d-4660-a6d0-a3bd983d9682}</a>
+ <b>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</b>
+ <name>subscribe</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{7657479a-a855-4d97-8c61-098690da9023}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{eef542f5-e2cf-40a8-92c9-9892f3d06e1f}</object>
+ <a>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</a>
+ <b>{582af542-5f2d-4660-a6d0-a3bd983d9682}</b>
+ <name>notify</name>
+ <points>
+ <qlist>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:340;y:430</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ </qlist>
+ </points>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{97f3e5b0-93ca-4351-98d6-ad88567979f7}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{963ad9f9-ecad-430f-8233-b7897fa630bd}</object>
+ <a>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</a>
+ <b>{998e7d36-3416-4b2f-843a-a437449f09f1}</b>
+ <name>push notification</name>
+ <points>
+ <qlist>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:535;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:590;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:615;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:670;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:670;y:365</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ </qlist>
+ </points>
+ </DRelation>
+ </base-DRelation>
+ <direction>1</direction>
+ </DDependency>
+ </instance>
+ </item>
+ </qlist>
+ </elements>
+ <last-modified>1665083804306</last-modified>
+ <toolbarid>UseCases</toolbarid>
+ </MDiagram>
+ </base-MDiagram>
+ </MCanvasDiagram>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{121189af-36df-4efa-b451-3f1f85ef339f}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{121189af-36df-4efa-b451-3f1f85ef339f}</uid>
+ </MElement>
+ </base-MElement>
+ <name>JavaScript Web Application</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d}</uid>
+ </MElement>
+ </base-MElement>
+ <name>subscribe</name>
+ <a>{121189af-36df-4efa-b451-3f1f85ef339f}</a>
+ <b>{13c69399-5587-4169-a012-8d86216139fd}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{afae2401-ea81-4514-aa80-da53d61a8516}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{afae2401-ea81-4514-aa80-da53d61a8516}</uid>
+ </MElement>
+ </base-MElement>
+ <name>register</name>
+ <a>{121189af-36df-4efa-b451-3f1f85ef339f}</a>
+ <b>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{373c492c-0b9a-4032-9ff4-b3a7cc442883}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{373c492c-0b9a-4032-9ff4-b3a7cc442883}</uid>
+ </MElement>
+ </base-MElement>
+ <name>subscribe with endpoint</name>
+ <a>{121189af-36df-4efa-b451-3f1f85ef339f}</a>
+ <b>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{13c69399-5587-4169-a012-8d86216139fd}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{13c69399-5587-4169-a012-8d86216139fd}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Push Manager API</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{d9959769-74a4-40ad-bf00-904c12a67309}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{d9959769-74a4-40ad-bf00-904c12a67309}</uid>
+ </MElement>
+ </base-MElement>
+ <name>create subscription</name>
+ <a>{13c69399-5587-4169-a012-8d86216139fd}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ <direction>2</direction>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Service Worker</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{bfebbc32-3541-4c1a-b3c6-a3652f700767}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{bfebbc32-3541-4c1a-b3c6-a3652f700767}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push notification</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ <direction>1</direction>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{89d5f886-1913-4bb7-be32-cdd5cb61eebc}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{89d5f886-1913-4bb7-be32-cdd5cb61eebc}</uid>
+ </MElement>
+ </base-MElement>
+ <name>notify</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{00b8f12d-e08b-426a-83b8-83fea8907fab}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{eef542f5-e2cf-40a8-92c9-9892f3d06e1f}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{eef542f5-e2cf-40a8-92c9-9892f3d06e1f}</uid>
+ </MElement>
+ </base-MElement>
+ <name>notify</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{00b8f12d-e08b-426a-83b8-83fea8907fab}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{963ad9f9-ecad-430f-8233-b7897fa630bd}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{963ad9f9-ecad-430f-8233-b7897fa630bd}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push notification</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ <direction>1</direction>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Firebase Cloud Messaging </name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{560fb941-261e-4f45-8909-2106283fdb3e}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{560fb941-261e-4f45-8909-2106283fdb3e}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</a>
+ <b>{13c69399-5587-4169-a012-8d86216139fd}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Push Application Server</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{94241d64-4e88-4855-8e78-365be237108b}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{94241d64-4e88-4855-8e78-365be237108b}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push notification</name>
+ <a>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{00b8f12d-e08b-426a-83b8-83fea8907fab}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{00b8f12d-e08b-426a-83b8-83fea8907fab}</uid>
+ </MElement>
+ </base-MElement>
+ <name>User</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{6d0ce78f-28e1-4a82-a443-59f4efcb8e66}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{6d0ce78f-28e1-4a82-a443-59f4efcb8e66}</uid>
+ </MElement>
+ </base-MElement>
+ <name>subscribe</name>
+ <a>{00b8f12d-e08b-426a-83b8-83fea8907fab}</a>
+ <b>{121189af-36df-4efa-b451-3f1f85ef339f}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ <variety-editable>false</variety-editable>
+ <variety>actor</variety>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </children>
+ </MObject>
+ </base-MObject>
+ </MPackage>
+ </instance>
+ </root-package>
+ </project>
+</qmt>
diff --git a/examples/webenginewidgets/push-notifications/main.cpp b/examples/webenginewidgets/push-notifications/main.cpp
new file mode 100644
index 000000000..18a862182
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/main.cpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "notificationpopup.h"
+
+#include <QApplication>
+#include <QWebEngineProfile>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QApplication app(argc, argv);
+
+ const QString name =
+ QString::fromLatin1("push-notifications.%1").arg(qWebEngineChromiumVersion());
+
+ QScopedPointer<QWebEngineProfile> profile(new QWebEngineProfile(name));
+ QWebEngineView view(profile.data());
+ auto popup = new NotificationPopup(&view);
+
+ QObject::connect(view.page(), &QWebEnginePage::featurePermissionRequested,
+ [&](const QUrl &origin, QWebEnginePage::Feature feature) {
+ if (feature != QWebEnginePage::Notifications)
+ return;
+
+ view.page()->setFeaturePermission(origin, feature,
+ QWebEnginePage::PermissionGrantedByUser);
+ });
+
+ profile->setPushServiceEnabled(true);
+ profile->setNotificationPresenter([&](std::unique_ptr<QWebEngineNotification> notification) {
+ popup->present(notification);
+ });
+
+ view.resize(640, 480);
+ view.setUrl(QUrl("http://localhost:5000"));
+ view.show();
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/push-notifications/notificationpopup.h b/examples/webenginewidgets/push-notifications/notificationpopup.h
new file mode 100644
index 000000000..cf53ded45
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/notificationpopup.h
@@ -0,0 +1,91 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#pragma once
+
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QMouseEvent>
+#include <QPushButton>
+#include <QSpacerItem>
+#include <QTimer>
+#include <QVBoxLayout>
+#include <QWebEngineNotification>
+
+#include <memory>
+
+class NotificationPopup : public QWidget
+{
+ Q_OBJECT
+
+ QLabel m_icon, m_title, m_message;
+ std::unique_ptr<QWebEngineNotification> notification;
+
+public:
+ NotificationPopup(QWidget *parent) : QWidget(parent)
+ {
+ setWindowFlags(Qt::ToolTip);
+ auto rootLayout = new QHBoxLayout(this);
+
+ rootLayout->addWidget(&m_icon);
+
+ auto bodyLayout = new QVBoxLayout;
+ rootLayout->addLayout(bodyLayout);
+
+ auto titleLayout = new QHBoxLayout;
+ bodyLayout->addLayout(titleLayout);
+
+ titleLayout->addWidget(&m_title);
+ titleLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
+
+ auto close = new QPushButton(tr("Close"));
+ titleLayout->addWidget(close);
+ connect(close, &QPushButton::clicked, this, &NotificationPopup::onClosed);
+
+ bodyLayout->addWidget(&m_message);
+ adjustSize();
+ }
+
+ void present(std::unique_ptr<QWebEngineNotification> &newNotification)
+ {
+ if (notification) {
+ notification->close();
+ notification.reset();
+ }
+
+ notification.swap(newNotification);
+
+ m_title.setText("<b>" + notification->title() + "</b>");
+ m_message.setText(notification->message());
+ m_icon.setPixmap(QPixmap(":/icon.png").scaledToHeight(m_icon.height()));
+
+ show();
+ notification->show();
+
+ connect(notification.get(), &QWebEngineNotification::closed, this,
+ &NotificationPopup::onClosed);
+ QTimer::singleShot(10000, notification.get(), [&]() { onClosed(); });
+
+ // position our popup in the right corner of its parent widget
+ move(parentWidget()->mapToGlobal(parentWidget()->rect().bottomRight()
+ - QPoint(width() + 10, height() + 10)));
+ }
+
+protected slots:
+ void onClosed()
+ {
+ hide();
+ notification->close();
+ notification.reset();
+ }
+
+protected:
+ void mouseReleaseEvent(QMouseEvent *event) override
+ {
+ QWidget::mouseReleaseEvent(event);
+ if (notification && event->button() == Qt::LeftButton) {
+ notification->click();
+ onClosed();
+ }
+ }
+};
diff --git a/examples/webenginewidgets/push-notifications/push-notifications.pro b/examples/webenginewidgets/push-notifications/push-notifications.pro
new file mode 100644
index 000000000..5ffb85fd7
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/push-notifications.pro
@@ -0,0 +1,10 @@
+QT += webenginewidgets
+
+HEADERS = notificationpopup.h
+
+SOURCES = main.cpp
+
+RESOURCES = data/data.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/push-notifications
+INSTALLS += target
diff --git a/examples/webenginewidgets/push-notifications/server.js b/examples/webenginewidgets/push-notifications/server.js
new file mode 100644
index 000000000..fc7deb08a
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/server.js
@@ -0,0 +1,65 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+const express = require('express');
+const webpush = require('web-push');
+
+// setup server
+const port = 5000;
+const server = express();
+server.use(express.json());
+server.use(express.static('content'));
+
+// we support only one subscription at the time
+var subscription = null;
+
+// setup vapid keys
+const vapidKeys = {
+ publicKey :
+ "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg",
+ privateKey : "HqhrzsRfG5-SB3j45lyUmV7cYZuy-71r2Bb0tgaOefk"
+};
+
+// set vapid keys for webpush libs
+webpush.setVapidDetails('mailto:push@qt.io', vapidKeys.publicKey, vapidKeys.privateKey);
+
+// add subscribe route
+server.post('/subscribe', (req, res) => {
+
+ // subscription request
+ subscription = req.body;
+ const delay = req.headers['ping-time'];
+ console.log('Got subscription with endpoint: ' + subscription.endpoint);
+ console.log('Ping delay is at: ' + delay);
+
+ // confirm resource created
+ res.status(201).json({});
+
+ // schedule notification
+ setTimeout(() => { sendNotification(delay) }, delay * 1000);
+});
+
+// add unsubscribe route
+server.post('/unsubscribe', (req, res) => {
+ console.log('Got unsubscribe with endpoint: ' + req.body.endpoint);
+ subscription = null;
+ res.status(201).json({});
+});
+
+function sendNotification(delay)
+{
+ if (!subscription)
+ return;
+
+ // create payload text
+ const payload = JSON.stringify({ title : 'Ping !', text : 'Visit qt.io', url : 'www.qt.io' });
+
+ // send notification
+ console.log('Sending notification !');
+ webpush.sendNotification(subscription, payload).catch(err => console.error(err));
+
+ // schedule next notification
+ setTimeout(() => { sendNotification(delay) }, delay * 1000);
+}
+
+server.listen(port, () => console.log(`Push server started at port ${port}`));
diff --git a/examples/webenginewidgets/recipebrowser/CMakeLists.txt b/examples/webenginewidgets/recipebrowser/CMakeLists.txt
new file mode 100644
index 000000000..d10409c09
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/CMakeLists.txt
@@ -0,0 +1,71 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(recipebrowser LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/recipebrowser")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
+
+qt_add_executable(recipebrowser
+ main.cpp
+ mainwindow.cpp mainwindow.h mainwindow.ui
+ stylesheetdialog.cpp stylesheetdialog.h stylesheetdialog.ui
+ document.cpp document.h
+)
+
+set_target_properties(recipebrowser PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(recipebrowser PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+)
+
+# Resources:
+set(recipebrowser_resource_files
+ "assets/3rdparty/markdown.css"
+ "assets/3rdparty/marked.js"
+ "assets/custom.css"
+ "assets/custom.js"
+ "assets/pages/burger.html"
+ "assets/pages/cupcakes.html"
+ "assets/pages/images/burger.jpg"
+ "assets/pages/images/cupcakes.jpg"
+ "assets/pages/images/pasta.jpg"
+ "assets/pages/images/pizza.jpg"
+ "assets/pages/images/skewers.jpg"
+ "assets/pages/images/soup.jpg"
+ "assets/pages/images/steak.jpg"
+ "assets/pages/pasta.html"
+ "assets/pages/pizza.html"
+ "assets/pages/skewers.html"
+ "assets/pages/soup.html"
+ "assets/pages/steak.html"
+)
+
+qt_add_resources(recipebrowser "recipebrowser"
+ PREFIX
+ "/"
+ BASE
+ "assets"
+ FILES
+ ${recipebrowser_resource_files}
+)
+
+install(TARGETS recipebrowser
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKDOWN-LICENSE.txt
index 23c52cc43..23c52cc43 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKDOWN-LICENSE.txt
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKED-LICENSE.txt
index 8e3ba0e0a..8e3ba0e0a 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKED-LICENSE.txt
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/markdown.css b/examples/webenginewidgets/recipebrowser/assets/3rdparty/markdown.css
index 24fc2ffe2..24fc2ffe2 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/markdown.css
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/markdown.css
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/marked.js b/examples/webenginewidgets/recipebrowser/assets/3rdparty/marked.js
index 33c02d9cf..33c02d9cf 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/marked.js
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/marked.js
diff --git a/examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json b/examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json
new file mode 100644
index 000000000..f8b0fd023
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json
@@ -0,0 +1,34 @@
+[
+ {
+ "Id" : "recipebrowser-marked",
+ "Name" : "Marked (WebEngine Recipe Browser example)",
+ "QDocModule" : "qtwebengine",
+ "QtUsage" : "Marked is used in the WebEngine Recipe Browser example",
+ "QtParts" : ["examples"],
+ "Files" : "marked.js",
+ "Description" :
+ "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
+ "Homepage" : "https://github.com/chjj/marked",
+ "Version" : "0.4.0",
+ "DownloadLocation" : "https://github.com/markedjs/marked/blob/0.4.0/lib/marked.js",
+ "Copyright" : "Copyright (c) 2011-2018, Christopher Jeffrey",
+ "License" : "MIT License",
+ "LicenseId" : "MIT",
+ "LicenseFile" : "MARKED-LICENSE.txt"
+ },
+ {
+ "Id" : "recipebrowser-markdowncss",
+ "Name" : "Markdown.css (WebEngine Recipe Browser example)",
+ "QDocModule" : "qtwebengine",
+ "QtUsage" : "markdown.css is used in the WebEngine Recipe Browser example",
+ "QtParts" : ["examples"],
+ "Files" : "markdown.css",
+ "Description" : "Markdown.css is better default styling for your Markdown files.",
+ "Version" : "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
+ "DownloadLocation" : "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
+ "Copyright" : "Copyright 2011 Kevin Burke Copyright Twitter Inc.",
+ "License" : "Apache License 2.0",
+ "LicenseId" : "Apache-2.0",
+ "LicenseFile" : "MARKDOWN-LICENSE.txt"
+ }
+ ]
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.css b/examples/webenginewidgets/recipebrowser/assets/custom.css
index 8d2f6cb0b..cc1106af3 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.css
+++ b/examples/webenginewidgets/recipebrowser/assets/custom.css
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
body {
diff --git a/examples/webenginewidgets/recipebrowser/assets/custom.js b/examples/webenginewidgets/recipebrowser/assets/custom.js
new file mode 100644
index 000000000..34470164e
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/custom.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+marked.setOptions({
+ renderer : new marked.Renderer(),
+ gfm : true,
+ tables : true,
+ breaks : false,
+ pedantic : false,
+ sanitize : false,
+ smartLists : true,
+ smartypants : false
+});
diff --git a/examples/webenginequick/recipebrowser/resources/pages/burger.html b/examples/webenginewidgets/recipebrowser/assets/pages/burger.html
index 6651cc0f0..99497959f 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/burger.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/burger.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Insanity Burger</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -68,8 +71,24 @@ give it a minute to go gorgeous and sloppy.
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/cupcakes.html b/examples/webenginewidgets/recipebrowser/assets/pages/cupcakes.html
index 4791c7ffa..e8e14a9b6 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/cupcakes.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/cupcakes.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Cupcakes</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -46,8 +49,25 @@ Cupcakes
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/burger.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/burger.jpg
index edc0c65de..edc0c65de 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/burger.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/burger.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/cupcakes.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/cupcakes.jpg
index cce52ba23..cce52ba23 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/cupcakes.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/cupcakes.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/pasta.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/pasta.jpg
index 7ac924b79..7ac924b79 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/pasta.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/pasta.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/pizza.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/pizza.jpg
index 8d8f756af..8d8f756af 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/pizza.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/pizza.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/skewers.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/skewers.jpg
index 6bb2f1172..6bb2f1172 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/skewers.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/skewers.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/soup.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/soup.jpg
index fc9dff906..fc9dff906 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/soup.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/soup.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/steak.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/steak.jpg
index 240b72eb4..240b72eb4 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/steak.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/steak.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/pasta.html b/examples/webenginewidgets/recipebrowser/assets/pages/pasta.html
index 41ed1a756..c2b3d840a 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/pasta.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/pasta.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Pasta</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -49,8 +52,25 @@ Pasta
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/pizza.html b/examples/webenginewidgets/recipebrowser/assets/pages/pizza.html
index 348d809e8..7e390a373 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/pizza.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/pizza.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Pizza Diavola</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -40,8 +43,25 @@ Pizza Diavola
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/skewers.html b/examples/webenginewidgets/recipebrowser/assets/pages/skewers.html
index aca4c4859..db2df5472 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/skewers.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/skewers.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Grilled skewers</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -46,8 +49,24 @@ Grilled skewers
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/soup.html b/examples/webenginewidgets/recipebrowser/assets/pages/soup.html
index 1b7027e5d..ea51fc8a5 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/soup.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/soup.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Soup</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -34,8 +37,25 @@ Soup
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/steak.html b/examples/webenginewidgets/recipebrowser/assets/pages/steak.html
index a56313e27..26391b409 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/steak.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/steak.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Grilled steak and rice</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -60,8 +63,24 @@ Grilled steak and rice
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webp b/examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webp
new file mode 100644
index 000000000..8446bcde3
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webp
Binary files differ
diff --git a/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc b/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc
new file mode 100644
index 000000000..dd701f1f2
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc
@@ -0,0 +1,197 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example webenginewidgets/recipebrowser
+ \title Recipe Browser
+ \examplecategory {Application Examples}
+ \meta tag {widgets, webengine, webchannel, webenginescript}
+ \ingroup webengine-widgetexamples
+ \brief Injecting custom stylsheets into web pages and providing a rich text preview
+ tool for a custom markup language.
+
+ \image recipebrowser.webp
+
+ \e {Recipe Browser} is a small hybrid web browser application. It demonstrates how to
+ use the \l{Qt WebEngine Widgets C++ Classes} {Qt WebEngine C++ classes} to combine
+ C++ and JavaScript logic in the following ways.
+
+ \list
+ \li Running arbitrary JavaScript code via \c QWebEnginePage::runJavaScript() to
+ inject custom CSS stylesheets
+ \li Using QWebEngineScript and QWebEngineScriptCollection to persist the JavaScript
+ code and inject it to every page
+ \li Using QWebChannel to interact with and provide a rich text preview for a custom
+ markup language
+ \endlist
+
+ \l{http://daringfireball.net/projects/markdown/}{Markdown} is a lightweight
+ markup language with a plain text formatting syntax.
+ Some services, such as \l{http://github.com}{github}, acknowledge the
+ format, and render the content as rich text when viewed in a browser.
+
+ The Recipe Browser main window is split into a navigation on the left and
+ a preview area on the right. The preview area on the right switches to an
+ editor when the user clicks the Edit button on the top left of the main window.
+ The editor supports the Markdown syntax and is implemented by using
+ QPlainTextEdit. The document is rendered as rich text in the preview area,
+ once the user clicks the View button,to which the Edit button transforms to.
+ This rendering is implemented by using QWebEngineView. To render the text,
+ a JavaScript library inside the web engine converts the Markdown text to HTML.
+ The preview is updated from the editor through QWebChannel.
+
+ \include examples-run.qdocinc
+
+ \section1 Exposing Document Text
+
+ To render the current Markdown text it needs to be exposed to the web engine through
+ QWebChannel. To achieve this it has to be part of Qt metatype system. This is done
+ by using a dedicated \c Document class that exposes the document text as a
+ \c {Q_PROPERTY}:
+
+ \quotefromfile webenginewidgets/recipebrowser/document.h
+ \skipto class Document
+ \printto #endif
+
+ The \c Document class wraps a QString \c m_currentText to be set on the C++
+ side with the \c setText() method and exposes it at runtime as a \c text
+ property with a \c textChanged signal. We define the \c setText method as
+ follows:
+
+ \quotefromfile webenginewidgets/recipebrowser/document.cpp
+ \skipto Document::setText(const QString &text)
+ \printuntil /^\}/
+
+ Additionally, the \c Document class keeps track of the current recipe via
+ \c m_currentPage. We call the recipes pages here, because each recipe has
+ its distinct HTML document that contains the initial text content.
+ Furthermore, \c m_textCollection is a QMap<QString, QString> that contains
+ the key/value pairs \{page, text\}, so that changes made to the text content
+ of a page is persisted between navigation. Nevertheless, we do not write the
+ modified text contents to the drive, but instead we persist them between
+ application start and shutdown via QSettings.
+
+ \section1 Creating the Main Window
+
+ The \c MainWindow class inherits the QMainWindow class:
+
+ \quotefromfile webenginewidgets/recipebrowser/mainwindow.h
+ \skipto class MainWindow :
+ \printto endif
+
+ The class declares private slots that match the two buttons on the
+ top left, over the navigation list view. Additionally, helper
+ methods for custom CSS stylesheets are declared.
+
+ The actual layout of the main window is specified in a \c .ui file.
+ The widgets and actions are available at runtime in the \c ui member
+ variable.
+
+ \c m_isEditMode is a boolean that toggles between the editor and the
+ preview area.
+ \c m_content is an instance of the \c Document class.
+
+ The actual setup of the different objects is done in the \c MainWindow
+ constructor:
+
+ \quotefromfile webenginewidgets/recipebrowser/mainwindow.cpp
+ \skipto MainWindow::MainWindow
+ \printto connect
+
+ The constructor first calls \c setupUi to construct the widgets and menu
+ actions according to the UI file. The text editor font is set to one
+ with a fixed character width, and the QWebEngineView widget is told not
+ to show a context menu. Furthermore, the editor is hidden away.
+
+ \printto ui->recipes
+
+ Here the \c clicked signals of QPushButton are connected to respective functions
+ that show the stylesheets dialog or toggle between edit and view mode, that is,
+ hide and show the editor and preview area respectively.
+
+ \printto m_content.setTextEdit
+
+ Here the navigation QListWidget on the left is setup with the 7 recipes.
+ Also, the currentItemChanged signal of QListWidget is connected to a lambda
+ that loads the new, current recipe page and updates the page in \c m_content.
+
+ \printto connect
+
+ Next, the pointer to the ui editor, a QPlainTextEdit, is passed to \c m_content to ensure that
+ calls to \c Document::setInitialText() work properly.
+
+ \printto QSettings
+
+ Here the \c textChanged signal of the editor is connected to a lambda that
+ updates the text in \c m_content. This object is then exposed to the JS side
+ by \c QWebChannel under the name \c{content}.
+
+ \printto ui->recipes
+
+ By using QSettings we persist stylesheets between application runs. If there
+ should be no stylesheets configured, for example, because the user deleted all of them
+ in a previous run, we load default ones.
+
+ \printto }
+
+ Finally, we set the currently selected list item to the first contained in the
+ navigation list widget. This triggers the previously mentioned
+ QListWidget::currentItemChanged signal and navigates to the page of the list item.
+
+ \section1 Working With Stylesheets
+
+ We use JavaScript to create and append CSS elements to the documents.
+ After declaring the script source, QWebEnginePage::runJavaScript() can run it
+ immediately and apply newly created styles on the current content of the web view.
+ Encapsulating the script into a QWebEngineScript and adding it to the script collection
+ of QWebEnginePage makes its effect permanent.
+
+ \quotefromfile webenginewidgets/recipebrowser/mainwindow.cpp
+ \skipto MainWindow::insertStyleSheet
+ \printuntil /^\}/
+
+ Removing stylesheets can be done similarly:
+
+ \quotefromfile webenginewidgets/recipebrowser/mainwindow.cpp
+ \skipto MainWindow::removeStyleSheet
+ \printuntil /^\}/
+
+ \section1 Creating a recipe file
+
+ \quotefile webenginewidgets/recipebrowser/assets/pages/burger.html
+
+ All the different recipe pages are set up the same way.
+
+ In the \c <head> part they
+ include two CSS files: \c markdown.css, that styles the markdown, and
+ custom.css, that does some further styling but most importantly hides the
+ \c <div> with id \e content, as this \c <div> only contains the unmodified,
+ initial content text. Also, three JS scripts are included. \c marked.js
+ is responsible for parsing the markdown and transforming it into HTML.
+ \c custom.js does some configuration of \c marked.js, and \c qwebchannel.js
+ exposes the QWebChannel JavaScript API.
+
+ In the body there are two \c <div> elements. The \c <div> with id \e placeholder
+ gets the markdown text injected that is rendered and visible. The \c <div> with id
+ \e content is hidden by \c custom.css and only contains the original, unmodified
+ text content of the recipe.
+
+ Finally, on the bottom of each recipe HTML file is a script that is responsible for
+ the communication between the C++ and JavaScript side via QWebChannel. The original,
+ unmodified text content inside the \c <div> with id \e content is passed to the C++
+ side and a callback is setup that is invoked when the \c textChanged signal of
+ \c m_content is emitted. The callback then updates the contents of the \c <div>
+ \e placeholder with the parsed markdown.
+
+ \section1 Files and Attributions
+
+ The example bundles the following code with third-party licenses:
+ \table
+ \row
+ \li \l{recipebrowser-marked}{Marked}
+ \li MIT License
+ \row
+ \li \l{recipebrowser-markdowncss}{Markdown.css}
+ \li Apache License 2.0
+ \endtable
+*/
diff --git a/examples/webenginewidgets/recipebrowser/document.cpp b/examples/webenginewidgets/recipebrowser/document.cpp
new file mode 100644
index 000000000..c991e14f8
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/document.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "document.h"
+
+#include <QSettings>
+
+Document::Document(QObject *parent) : QObject(parent)
+{
+ QSettings settings;
+ settings.beginGroup("textCollection");
+ QStringList pageTexts = settings.allKeys();
+ for (const QString &name : std::as_const(pageTexts)) {
+ QString pageText = settings.value(name).value<QString>();
+ if (!pageText.isEmpty())
+ m_textCollection.insert(name, pageText);
+ }
+ settings.endGroup();
+}
+
+void Document::setTextEdit(QPlainTextEdit *textEdit)
+{
+ m_textEdit = textEdit;
+}
+
+void Document::setCurrentPage(const QString &page)
+{
+ m_currentPage = page;
+}
+
+void Document::setInitialText(const QString &text)
+{
+ m_textEdit->setPlainText(m_textCollection.value(m_currentPage, text));
+}
+
+void Document::setText(const QString &text)
+{
+ if (text == m_currentText)
+ return;
+ m_currentText = text;
+ emit textChanged(m_currentText);
+
+ QSettings settings;
+ settings.beginGroup("textCollection");
+ settings.setValue(m_currentPage, text);
+ m_textCollection.insert(m_currentPage, text);
+ settings.endGroup();
+}
diff --git a/examples/webenginewidgets/recipebrowser/document.h b/examples/webenginewidgets/recipebrowser/document.h
new file mode 100644
index 000000000..f6b537eb8
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/document.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef DOCUMENT_H
+#define DOCUMENT_H
+
+#include <QObject>
+#include <QString>
+#include <QPlainTextEdit>
+
+class Document : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text MEMBER m_currentText NOTIFY textChanged FINAL)
+public:
+ explicit Document(QObject *parent = nullptr);
+
+ void setTextEdit(QPlainTextEdit *textEdit);
+ void setCurrentPage(const QString &page);
+
+public slots:
+ void setInitialText(const QString &text);
+ void setText(const QString &text);
+
+signals:
+ void textChanged(const QString &text);
+
+private:
+ QPlainTextEdit *m_textEdit;
+
+ QString m_currentText;
+ QString m_currentPage;
+ QMap<QString, QString> m_textCollection;
+};
+
+#endif // DOCUMENT_H
diff --git a/examples/webenginewidgets/stylesheetbrowser/main.cpp b/examples/webenginewidgets/recipebrowser/main.cpp
index cf1e5f718..b0b42d16b 100644
--- a/examples/webenginewidgets/stylesheetbrowser/main.cpp
+++ b/examples/webenginewidgets/recipebrowser/main.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationName("QtExamples");
QApplication a(argc, argv);
- MainWindow w(QUrl("http://qt.io"));
+ MainWindow w;
w.show();
return a.exec();
}
diff --git a/examples/webenginewidgets/recipebrowser/mainwindow.cpp b/examples/webenginewidgets/recipebrowser/mainwindow.cpp
new file mode 100644
index 000000000..7288fe4ce
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/mainwindow.cpp
@@ -0,0 +1,153 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include "stylesheetdialog.h"
+#include "ui_mainwindow.h"
+
+#include <QWebChannel>
+
+static QMap<QString, QString> defaultStyleSheets = {
+ { "Upside down", "body { -webkit-transform: rotate(180deg); }" },
+ { "Darkmode",
+ "body { color: #FFF; background-color: #000 }"
+ "h1, h2, h3, h4, h5 { color: #FFF }" }
+};
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent), ui(new Ui::MainWindow), m_isEditMode(false)
+{
+ ui->setupUi(this);
+ ui->textEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
+ ui->textEdit->hide();
+ ui->webEngineView->setContextMenuPolicy(Qt::NoContextMenu);
+
+ connect(ui->stylesheetsButton, &QPushButton::clicked, this, &MainWindow::showStyleSheetsDialog);
+ connect(ui->editViewButton, &QPushButton::clicked, this, &MainWindow::toggleEditView);
+
+ ui->recipes->insertItem(0, "Burger");
+ ui->recipes->insertItem(1, "Cupcakes");
+ ui->recipes->insertItem(2, "Pasta");
+ ui->recipes->insertItem(3, "Pizza");
+ ui->recipes->insertItem(4, "Skewers");
+ ui->recipes->insertItem(5, "Soup");
+ ui->recipes->insertItem(6, "Steak");
+ connect(ui->recipes, &QListWidget::currentItemChanged, this,
+ [this](QListWidgetItem *current, QListWidgetItem * /* previous */) {
+ const QString page = current->text().toLower();
+ const QString url = QStringLiteral("qrc:/pages/") + page + QStringLiteral(".html");
+ ui->webEngineView->setUrl(QUrl(url));
+ m_content.setCurrentPage(page);
+ });
+
+ m_content.setTextEdit(ui->textEdit);
+
+ connect(ui->textEdit, &QPlainTextEdit::textChanged, this,
+ [this]() { m_content.setText(ui->textEdit->toPlainText()); });
+
+ QWebChannel *channel = new QWebChannel(this);
+ channel->registerObject(QStringLiteral("content"), &m_content);
+ ui->webEngineView->page()->setWebChannel(channel);
+
+ QSettings settings;
+ settings.beginGroup("styleSheets");
+ QStringList styleSheets = settings.allKeys();
+ if (styleSheets.empty()) {
+ // Add back default style sheets if the user cleared them out
+ loadDefaultStyleSheets();
+ } else {
+ for (const auto &name : std::as_const(styleSheets)) {
+ StyleSheet styleSheet = settings.value(name).value<StyleSheet>();
+ if (styleSheet.second)
+ insertStyleSheet(name, styleSheet.first, false);
+ }
+ }
+ settings.endGroup();
+
+ ui->recipes->setCurrentItem(ui->recipes->item(0));
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::insertStyleSheet(const QString &name, const QString &source, bool immediately)
+{
+ QWebEngineScript script;
+ QString s = QString::fromLatin1("(function() {"
+ " css = document.createElement('style');"
+ " css.type = 'text/css';"
+ " css.id = '%1';"
+ " document.head.appendChild(css);"
+ " css.innerText = '%2';"
+ "})()")
+ .arg(name, source.simplified());
+ if (immediately)
+ ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
+
+ script.setName(name);
+ script.setSourceCode(s);
+ script.setInjectionPoint(QWebEngineScript::DocumentReady);
+ script.setRunsOnSubFrames(true);
+ script.setWorldId(QWebEngineScript::ApplicationWorld);
+ ui->webEngineView->page()->scripts().insert(script);
+}
+
+void MainWindow::removeStyleSheet(const QString &name, bool immediately)
+{
+ QString s = QString::fromLatin1("(function() {"
+ " var element = document.getElementById('%1');"
+ " element.outerHTML = '';"
+ " delete element;"
+ "})()")
+ .arg(name);
+ if (immediately)
+ ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
+
+ const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
+ if (!scripts.isEmpty())
+ ui->webEngineView->page()->scripts().remove(scripts.first());
+}
+
+bool MainWindow::hasStyleSheet(const QString &name)
+{
+ const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
+ return !scripts.isEmpty();
+}
+
+void MainWindow::loadDefaultStyleSheets()
+{
+ QSettings settings;
+ settings.beginGroup("styleSheets");
+
+ for (auto it = defaultStyleSheets.constBegin(); it != defaultStyleSheets.constEnd(); ++it) {
+ settings.setValue(it.key(), QVariant::fromValue(qMakePair(it.value(), true)));
+ insertStyleSheet(it.key(), it.value(), false);
+ }
+
+ settings.endGroup();
+}
+
+void MainWindow::showStyleSheetsDialog()
+{
+ StylesheetDialog *dialog = new StylesheetDialog(this);
+ dialog->show();
+}
+
+void MainWindow::toggleEditView()
+{
+ m_isEditMode = !m_isEditMode;
+
+ if (m_isEditMode) {
+ ui->webEngineView->hide();
+ ui->textEdit->show();
+
+ ui->editViewButton->setText(QStringLiteral("View"));
+ } else {
+ ui->textEdit->hide();
+ ui->webEngineView->show();
+
+ ui->editViewButton->setText(QStringLiteral("Edit"));
+ }
+}
diff --git a/examples/webenginewidgets/stylesheetbrowser/mainwindow.h b/examples/webenginewidgets/recipebrowser/mainwindow.h
index 92d6d02fe..959c82af8 100644
--- a/examples/webenginewidgets/stylesheetbrowser/mainwindow.h
+++ b/examples/webenginewidgets/recipebrowser/mainwindow.h
@@ -1,12 +1,15 @@
-// Copyright (C) 2017 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
+#include "document.h"
#include <QMainWindow>
#include <QSettings>
#include <QWebEngineScriptCollection>
+#include <QWebEngineView>
+#include <QPlainTextEdit>
QT_BEGIN_NAMESPACE
namespace Ui {
@@ -19,7 +22,7 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
- explicit MainWindow(const QUrl &url);
+ explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void insertStyleSheet(const QString &name, const QString &source, bool immediately);
@@ -28,13 +31,14 @@ public:
void loadDefaultStyleSheets();
private slots:
- void urlEntered();
- void urlChanged(const QUrl &url);
void showStyleSheetsDialog();
- void reloadRequested();
+ void toggleEditView();
private:
Ui::MainWindow *ui;
+
+ bool m_isEditMode;
+ Document m_content;
};
#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/recipebrowser/mainwindow.ui b/examples/webenginewidgets/recipebrowser/mainwindow.ui
new file mode 100644
index 000000000..b7c29f1b8
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/mainwindow.ui
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>713</width>
+ <height>455</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Recipe Browser</string>
+ </property>
+ <property name="unifiedTitleAndToolBarOnMac">
+ <bool>false</bool>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="navigation">
+ <item>
+ <layout class="QHBoxLayout" name="navigationBar">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Recipes</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="editViewButton">
+ <property name="text">
+ <string>Edit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="stylesheetsButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Stylesheets</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListWidget" name="recipes">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QWebEngineView" name="webEngineView" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="textEdit"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>QWebEngineView</class>
+ <extends>QWidget</extends>
+ <header>qwebengineview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.pro b/examples/webenginewidgets/recipebrowser/recipebrowser.pro
index a9ff54400..8f8895b52 100644
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.pro
+++ b/examples/webenginewidgets/recipebrowser/recipebrowser.pro
@@ -1,22 +1,24 @@
TEMPLATE = app
-TARGET = stylesheetbrowser
+TARGET = recipebrowser
QT += webenginewidgets
HEADERS += \
mainwindow.h \
- stylesheetdialog.h
+ stylesheetdialog.h \
+ document.h
SOURCES += \
main.cpp \
mainwindow.cpp \
- stylesheetdialog.cpp
+ stylesheetdialog.cpp \
+ document.cpp
FORMS += \
mainwindow.ui \
stylesheetdialog.ui
-RESOURCES += stylesheetbrowser.qrc
+RESOURCES += recipebrowser.qrc
# install
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/stylesheetbrowser
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/recipebrowser
INSTALLS += target
diff --git a/examples/webenginewidgets/recipebrowser/recipebrowser.qrc b/examples/webenginewidgets/recipebrowser/recipebrowser.qrc
new file mode 100644
index 000000000..2dc003f30
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/recipebrowser.qrc
@@ -0,0 +1,15 @@
+<RCC>
+ <qresource prefix="/">
+ <file>assets/3rdparty/markdown.css</file>
+ <file>assets/3rdparty/marked.js</file>
+ <file>assets/custom.js</file>
+ <file>assets/custom.css</file>
+ <file>assets/pages/burger.html</file>
+ <file>assets/pages/cupcakes.html</file>
+ <file>assets/pages/pasta.html</file>
+ <file>assets/pages/pizza.html</file>
+ <file>assets/pages/skewers.html</file>
+ <file>assets/pages/soup.html</file>
+ <file>assets/pages/steak.html</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.cpp b/examples/webenginewidgets/recipebrowser/stylesheetdialog.cpp
index 30409f107..2137617c3 100644
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.cpp
+++ b/examples/webenginewidgets/recipebrowser/stylesheetdialog.cpp
@@ -1,18 +1,18 @@
-// Copyright (C) 2017 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include "stylesheetdialog.h"
#include "ui_stylesheetdialog.h"
-StylesheetDialog::StylesheetDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::StylesheetDialog)
+StylesheetDialog::StylesheetDialog(QWidget *parent) : QDialog(parent), ui(new Ui::StylesheetDialog)
{
ui->setupUi(this);
- connect(ui->styleSheetList, &QListWidget::currentItemChanged, this, &StylesheetDialog::currentStyleSheetChanged);
- connect(ui->styleSheetList, &QListWidget::itemClicked, this, &StylesheetDialog::listItemClicked);
+ connect(ui->styleSheetList, &QListWidget::currentItemChanged, this,
+ &StylesheetDialog::currentStyleSheetChanged);
+ connect(ui->styleSheetList, &QListWidget::itemClicked, this,
+ &StylesheetDialog::listItemClicked);
connect(ui->fileNameEdit, &QLineEdit::textChanged, this, &StylesheetDialog::fileNameChanged);
connect(ui->addButton, &QPushButton::clicked, this, &StylesheetDialog::addButtonClicked);
@@ -20,8 +20,8 @@ StylesheetDialog::StylesheetDialog(QWidget *parent) :
QSettings settings;
settings.beginGroup("styleSheets");
- for (auto name : settings.allKeys()) {
- QListWidgetItem *listItem = new QListWidgetItem(name, ui->styleSheetList);
+ for (const auto &name : settings.allKeys()) {
+ QListWidgetItem *listItem = new QListWidgetItem(name, ui->styleSheetList);
listItem->setFlags(listItem->flags() | Qt::ItemIsUserCheckable);
bool checked = settings.value(name).value<StyleSheet>().second;
listItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
@@ -59,9 +59,8 @@ void StylesheetDialog::listItemClicked(QListWidgetItem *item)
{
MainWindow *window = static_cast<MainWindow *>(parent());
const QString name = item->text();
- bool checkedStateChanged =
- (item->checkState() == Qt::Checked && !window->hasStyleSheet(name)) ||
- (item->checkState() == Qt::Unchecked && window->hasStyleSheet(name));
+ bool checkedStateChanged = (item->checkState() == Qt::Checked && !window->hasStyleSheet(name))
+ || (item->checkState() == Qt::Unchecked && window->hasStyleSheet(name));
if (!checkedStateChanged)
return;
@@ -96,7 +95,7 @@ void StylesheetDialog::addButtonClicked()
if (name.isEmpty() || source.isEmpty())
return;
- QListWidgetItem *listItem = new QListWidgetItem(ui->fileNameEdit->text(), ui->styleSheetList);
+ QListWidgetItem *listItem = new QListWidgetItem(ui->fileNameEdit->text(), ui->styleSheetList);
listItem->setFlags(listItem->flags() | Qt::ItemIsUserCheckable);
listItem->setCheckState(Qt::Checked);
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.h b/examples/webenginewidgets/recipebrowser/stylesheetdialog.h
index 7bebff74f..ca1b4ae99 100644
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.h
+++ b/examples/webenginewidgets/recipebrowser/stylesheetdialog.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef STYLESHEETDIALOG_H
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.ui b/examples/webenginewidgets/recipebrowser/stylesheetdialog.ui
index 19db267e8..19db267e8 100644
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.ui
+++ b/examples/webenginewidgets/recipebrowser/stylesheetdialog.ui
diff --git a/examples/webenginewidgets/simplebrowser/CMakeLists.txt b/examples/webenginewidgets/simplebrowser/CMakeLists.txt
index f23bce709..2dd4fd57a 100644
--- a/examples/webenginewidgets/simplebrowser/CMakeLists.txt
+++ b/examples/webenginewidgets/simplebrowser/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(simplebrowser LANGUAGES CXX)
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
index 0458cd1f4..d5b097b22 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
@@ -25,14 +25,6 @@ BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool
: m_browser(browser)
, m_profile(profile)
, m_tabWidget(new TabWidget(profile, this))
- , m_progressBar(nullptr)
- , m_historyBackAction(nullptr)
- , m_historyForwardAction(nullptr)
- , m_stopAction(nullptr)
- , m_reloadAction(nullptr)
- , m_stopReloadAction(nullptr)
- , m_urlLineEdit(nullptr)
- , m_favAction(nullptr)
{
setAttribute(Qt::WA_DeleteOnClose, true);
setFocusPolicy(Qt::ClickFocus);
@@ -58,7 +50,8 @@ BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool
m_progressBar->setMaximumHeight(1);
m_progressBar->setTextVisible(false);
- m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}"));
+ m_progressBar->setStyleSheet(QStringLiteral(
+ "QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}"));
layout->addWidget(m_progressBar);
}
@@ -266,11 +259,19 @@ QMenu *BrowserWindow::createWindowMenu(TabWidget *tabWidget)
previousTabAction->setShortcuts(shortcuts);
connect(previousTabAction, &QAction::triggered, tabWidget, &TabWidget::previousTab);
- connect(menu, &QMenu::aboutToShow, [this, menu, nextTabAction, previousTabAction]() {
+ QAction *inspectorAction = new QAction(tr("Open inspector in new window"), this);
+ shortcuts.clear();
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_I));
+ inspectorAction->setShortcuts(shortcuts);
+ connect(inspectorAction, &QAction::triggered, [this]() { emit currentTab()->devToolsRequested(currentTab()->page()); });
+
+ connect(menu, &QMenu::aboutToShow, [this, menu, nextTabAction, previousTabAction, inspectorAction]() {
menu->clear();
menu->addAction(nextTabAction);
menu->addAction(previousTabAction);
menu->addSeparator();
+ menu->addAction(inspectorAction);
+ menu->addSeparator();
QList<BrowserWindow*> windows = m_browser->windows();
int index(-1);
@@ -292,6 +293,20 @@ QMenu *BrowserWindow::createHelpMenu()
return helpMenu;
}
+static bool isBackspace(const QKeySequence &k)
+{
+ return (k[0].key() & Qt::Key_unknown) == Qt::Key_Backspace;
+}
+
+// Chromium already handles navigate on backspace when appropriate.
+static QList<QKeySequence> removeBackspace(QList<QKeySequence> keys)
+{
+ const auto it = std::find_if(keys.begin(), keys.end(), isBackspace);
+ if (it != keys.end())
+ keys.erase(it);
+ return keys;
+}
+
QToolBar *BrowserWindow::createToolBar()
{
QToolBar *navigationBar = new QToolBar(tr("Navigation"));
@@ -299,14 +314,7 @@ QToolBar *BrowserWindow::createToolBar()
navigationBar->toggleViewAction()->setEnabled(false);
m_historyBackAction = new QAction(this);
- QList<QKeySequence> backShortcuts = QKeySequence::keyBindings(QKeySequence::Back);
- for (auto it = backShortcuts.begin(); it != backShortcuts.end();) {
- // Chromium already handles navigate on backspace when appropriate.
- if ((*it)[0].key() == Qt::Key_Backspace)
- it = backShortcuts.erase(it);
- else
- ++it;
- }
+ auto backShortcuts = removeBackspace(QKeySequence::keyBindings(QKeySequence::Back));
// For some reason Qt doesn't bind the dedicated Back key to Back.
backShortcuts.append(QKeySequence(Qt::Key_Back));
m_historyBackAction->setShortcuts(backShortcuts);
@@ -319,13 +327,7 @@ QToolBar *BrowserWindow::createToolBar()
navigationBar->addAction(m_historyBackAction);
m_historyForwardAction = new QAction(this);
- QList<QKeySequence> fwdShortcuts = QKeySequence::keyBindings(QKeySequence::Forward);
- for (auto it = fwdShortcuts.begin(); it != fwdShortcuts.end();) {
- if (((*it)[0].key() & Qt::Key_unknown) == Qt::Key_Backspace)
- it = fwdShortcuts.erase(it);
- else
- ++it;
- }
+ auto fwdShortcuts = removeBackspace(QKeySequence::keyBindings(QKeySequence::Forward));
fwdShortcuts.append(QKeySequence(Qt::Key_Forward));
m_historyForwardAction->setShortcuts(fwdShortcuts);
m_historyForwardAction->setIconVisibleInMenu(false);
@@ -352,9 +354,8 @@ QToolBar *BrowserWindow::createToolBar()
downloadsAction->setIcon(QIcon(QStringLiteral(":go-bottom.png")));
downloadsAction->setToolTip(tr("Show downloads"));
navigationBar->addAction(downloadsAction);
- connect(downloadsAction, &QAction::triggered, [this]() {
- m_browser->downloadManagerWidget().show();
- });
+ connect(downloadsAction, &QAction::triggered,
+ &m_browser->downloadManagerWidget(), &QWidget::show);
return navigationBar;
}
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.h b/examples/webenginewidgets/simplebrowser/browserwindow.h
index 47fdf6314..55eeb46c2 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.h
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.h
@@ -22,7 +22,8 @@ class BrowserWindow : public QMainWindow
Q_OBJECT
public:
- BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool forDevTools = false);
+ explicit BrowserWindow(Browser *browser, QWebEngineProfile *profile,
+ bool forDevTools = false);
QSize sizeHint() const override;
TabWidget *tabWidget() const;
WebView *currentTab() const;
@@ -55,14 +56,14 @@ private:
Browser *m_browser;
QWebEngineProfile *m_profile;
TabWidget *m_tabWidget;
- QProgressBar *m_progressBar;
- QAction *m_historyBackAction;
- QAction *m_historyForwardAction;
- QAction *m_stopAction;
- QAction *m_reloadAction;
- QAction *m_stopReloadAction;
- QLineEdit *m_urlLineEdit;
- QAction *m_favAction;
+ QProgressBar *m_progressBar = nullptr;
+ QAction *m_historyBackAction = nullptr;
+ QAction *m_historyForwardAction = nullptr;
+ QAction *m_stopAction = nullptr;
+ QAction *m_reloadAction = nullptr;
+ QAction *m_stopReloadAction = nullptr;
+ QLineEdit *m_urlLineEdit = nullptr;
+ QAction *m_favAction = nullptr;
QString m_lastSearch;
};
diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
index bfb857cd8..fdddc4fb0 100644
--- a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
@@ -13,7 +13,6 @@
DownloadManagerWidget::DownloadManagerWidget(QWidget *parent)
: QWidget(parent)
- , m_numDownloads(0)
{
setupUi(this);
}
diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
index b9d5e9bd7..67df492b9 100644
--- a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
+++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
@@ -30,7 +30,7 @@ private:
void add(DownloadWidget *downloadWidget);
void remove(DownloadWidget *downloadWidget);
- int m_numDownloads;
+ int m_numDownloads = 0;
};
#endif // DOWNLOADMANAGERWIDGET_H
diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
index d4998853e..f8b96c6e6 100644
--- a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
@@ -38,12 +38,11 @@ inline QString DownloadWidget::withUnit(qreal bytes)
{
if (bytes < (1 << 10))
return tr("%L1 B").arg(bytes);
- else if (bytes < (1 << 20))
+ if (bytes < (1 << 20))
return tr("%L1 KiB").arg(bytes / (1 << 10), 0, 'f', 2);
- else if (bytes < (1 << 30))
+ if (bytes < (1 << 30))
return tr("%L1 MiB").arg(bytes / (1 << 20), 0, 'f', 2);
- else
- return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2);
+ return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2);
}
void DownloadWidget::updateWidget()
@@ -63,16 +62,14 @@ void DownloadWidget::updateWidget()
m_progressBar->setDisabled(false);
m_progressBar->setFormat(
tr("%p% - %1 of %2 downloaded - %3/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(totalBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(totalBytes),
+ withUnit(bytesPerSecond)));
} else {
m_progressBar->setValue(0);
m_progressBar->setDisabled(false);
m_progressBar->setFormat(
tr("unknown size - %1 downloaded - %2/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
}
break;
case QWebEngineDownloadRequest::DownloadCompleted:
@@ -80,16 +77,14 @@ void DownloadWidget::updateWidget()
m_progressBar->setDisabled(true);
m_progressBar->setFormat(
tr("completed - %1 downloaded - %2/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
break;
case QWebEngineDownloadRequest::DownloadCancelled:
m_progressBar->setValue(0);
m_progressBar->setDisabled(true);
m_progressBar->setFormat(
tr("cancelled - %1 downloaded - %2/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
break;
case QWebEngineDownloadRequest::DownloadInterrupted:
m_progressBar->setValue(0);
diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp
index 477a8171b..b945ef27e 100644
--- a/examples/webenginewidgets/simplebrowser/main.cpp
+++ b/examples/webenginewidgets/simplebrowser/main.cpp
@@ -5,6 +5,7 @@
#include "browserwindow.h"
#include "tabwidget.h"
#include <QApplication>
+#include <QLoggingCategory>
#include <QWebEngineProfile>
#include <QWebEngineSettings>
@@ -24,6 +25,7 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
app.setWindowIcon(QIcon(QStringLiteral(":AppLogoColor.png")));
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.webenginecontext.debug=true"));
QWebEngineProfile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
QWebEngineProfile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, true);
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
index 9e19cf782..e4e204ce9 100644
--- a/examples/webenginewidgets/simplebrowser/tabwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
@@ -34,8 +34,8 @@ TabWidget::TabWidget(QWebEngineProfile *profile, QWidget *parent)
QLabel *icon = new QLabel(this);
QPixmap pixmap(QStringLiteral(":ninja.png"));
icon->setPixmap(pixmap.scaledToHeight(tabBar->height()));
- setStyleSheet(QStringLiteral("QTabWidget::tab-bar { left: %1px; }").
- arg(icon->pixmap().width()));
+ setStyleSheet(
+ QStringLiteral("QTabWidget::tab-bar { left: %1px; }").arg(icon->pixmap().width()));
}
}
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.h b/examples/webenginewidgets/simplebrowser/tabwidget.h
index 08caab52c..a1a893b62 100644
--- a/examples/webenginewidgets/simplebrowser/tabwidget.h
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.h
@@ -19,7 +19,7 @@ class TabWidget : public QTabWidget
Q_OBJECT
public:
- TabWidget(QWebEngineProfile *profile, QWidget *parent = nullptr);
+ explicit TabWidget(QWebEngineProfile *profile, QWidget *parent = nullptr);
WebView *currentWebView() const;
diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp
index 66de5d6d9..699e3d2ed 100644
--- a/examples/webenginewidgets/simplebrowser/webpage.cpp
+++ b/examples/webenginewidgets/simplebrowser/webpage.cpp
@@ -22,29 +22,6 @@ void WebPage::handleCertificateError(QWebEngineCertificateError error)
[this, error]() mutable { emit createCertificateErrorDialog(error); });
}
-inline QString questionForFeature(QWebEnginePage::Feature feature)
-{
- switch (feature) {
- case QWebEnginePage::Geolocation:
- return WebPage::tr("Allow %1 to access your location information?");
- case QWebEnginePage::MediaAudioCapture:
- return WebPage::tr("Allow %1 to access your microphone?");
- case QWebEnginePage::MediaVideoCapture:
- return WebPage::tr("Allow %1 to access your webcam?");
- case QWebEnginePage::MediaAudioVideoCapture:
- return WebPage::tr("Allow %1 to access your microphone and webcam?");
- case QWebEnginePage::MouseLock:
- return WebPage::tr("Allow %1 to lock your mouse cursor?");
- case QWebEnginePage::DesktopVideoCapture:
- return WebPage::tr("Allow %1 to capture video of your desktop?");
- case QWebEnginePage::DesktopAudioVideoCapture:
- return WebPage::tr("Allow %1 to capture audio and video of your desktop?");
- case QWebEnginePage::Notifications:
- return WebPage::tr("Allow %1 to show notification on your desktop?");
- }
- return QString();
-}
-
void WebPage::handleSelectClientCertificate(QWebEngineClientCertificateSelection selection)
{
// Just select one.
diff --git a/examples/webenginewidgets/simplebrowser/webpage.h b/examples/webenginewidgets/simplebrowser/webpage.h
index 7fa2be335..83a4e833f 100644
--- a/examples/webenginewidgets/simplebrowser/webpage.h
+++ b/examples/webenginewidgets/simplebrowser/webpage.h
@@ -13,7 +13,7 @@ class WebPage : public QWebEnginePage
Q_OBJECT
public:
- WebPage(QWebEngineProfile *profile, QObject *parent = nullptr);
+ explicit WebPage(QWebEngineProfile *profile, QObject *parent = nullptr);
signals:
void createCertificateErrorDialog(QWebEngineCertificateError error);
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.h b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
index d13f5f183..0726bf0c2 100644
--- a/examples/webenginewidgets/simplebrowser/webpopupwindow.h
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
@@ -19,7 +19,7 @@ class WebPopupWindow : public QWidget
Q_OBJECT
public:
- WebPopupWindow(QWebEngineProfile *profile);
+ explicit WebPopupWindow(QWebEngineProfile *profile);
WebView *view() const;
private slots:
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
index 16a58ce6c..e41d4334e 100644
--- a/examples/webenginewidgets/simplebrowser/webview.cpp
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -19,7 +19,6 @@
WebView::WebView(QWidget *parent)
: QWebEngineView(parent)
- , m_loadProgress(100)
{
connect(this, &QWebEngineView::loadStarted, [this]() {
m_loadProgress = 0;
@@ -57,7 +56,7 @@ WebView::WebView(QWidget *parent)
tr("Render process exited with code: %1\n"
"Do you want to reload the page ?").arg(statusCode));
if (btn == QMessageBox::Yes)
- QTimer::singleShot(0, [this] { reload(); });
+ QTimer::singleShot(0, this, &WebView::reload);
});
}
@@ -149,13 +148,15 @@ QIcon WebView::favIcon() const
if (m_loadProgress < 0) {
static QIcon errorIcon(QStringLiteral(":dialog-error.png"));
return errorIcon;
- } else if (m_loadProgress < 100) {
+ }
+
+ if (m_loadProgress < 100) {
static QIcon loadingIcon(QStringLiteral(":view-refresh.png"));
return loadingIcon;
- } else {
- static QIcon defaultIcon(QStringLiteral(":text-html.png"));
- return defaultIcon;
}
+
+ static QIcon defaultIcon(":text-html.png");
+ return defaultIcon;
}
QWebEngineView *WebView::createWindow(QWebEnginePage::WebWindowType type)
@@ -193,12 +194,8 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
if (viewSource == actions.cend())
menu->addSeparator();
- QAction *action = new QAction(menu);
- action->setText("Open inspector in new window");
+ QAction *action = menu->addAction("Open inspector in new window");
connect(action, &QAction::triggered, [this]() { emit devToolsRequested(page()); });
-
- QAction *before(inspectElement == actions.cend() ? nullptr : *inspectElement);
- menu->insertAction(before, action);
} else {
(*inspectElement)->setText(tr("Inspect element"));
}
@@ -239,8 +236,8 @@ void WebView::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticato
passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
QString introMessage(tr("Enter username and password for \"%1\" at %2")
- .arg(auth->realm())
- .arg(requestUrl.toString().toHtmlEscaped()));
+ .arg(auth->realm(),
+ requestUrl.toString().toHtmlEscaped()));
passwordDialog.m_infoLabel->setText(introMessage);
passwordDialog.m_infoLabel->setWordWrap(true);
diff --git a/examples/webenginewidgets/simplebrowser/webview.h b/examples/webenginewidgets/simplebrowser/webview.h
index 63f82c3c9..41bc04ac0 100644
--- a/examples/webenginewidgets/simplebrowser/webview.h
+++ b/examples/webenginewidgets/simplebrowser/webview.h
@@ -20,7 +20,7 @@ class WebView : public QWebEngineView
Q_OBJECT
public:
- WebView(QWidget *parent = nullptr);
+ explicit WebView(QWidget *parent = nullptr);
void setPage(WebPage *page);
int loadProgress() const;
@@ -51,7 +51,7 @@ private:
void createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction);
private:
- int m_loadProgress;
+ int m_loadProgress = 100;
};
#endif
diff --git a/examples/webenginewidgets/spellchecker/CMakeLists.txt b/examples/webenginewidgets/spellchecker/CMakeLists.txt
index d76881c65..74cb626e1 100644
--- a/examples/webenginewidgets/spellchecker/CMakeLists.txt
+++ b/examples/webenginewidgets/spellchecker/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(spellchecker LANGUAGES CXX)
diff --git a/examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING b/examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING
deleted file mode 100644
index 220881da6..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING
+++ /dev/null
@@ -1 +0,0 @@
-The icons in this repository are herefore released into the Public Domain.
diff --git a/examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json b/examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json
deleted file mode 100644
index f779da7e2..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "Id": "stylesheetbrowser-tango",
- "Name": "Tango Icon Library",
- "QDocModule": "qtwebengine",
- "QtUsage": "Used in WebEngine StyleSheet Browser example.",
-
- "QtParts": [ "examples" ],
- "Description": "Selected icons from the Tango Icon Library",
- "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
- "Version": "0.8.90",
- "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
- "LicenseId": "urn:dje:license:public-domain",
- "License": "Public Domain",
- "LicenseFile": "COPYING",
- "Copyright": "Ulisse Perusin <uli.peru@gmail.com>
-Steven Garrity <sgarrity@silverorange.com>
-Lapo Calamandrei <calamandrei@gmail.com>
-Ryan Collier <rcollier@novell.com>
-Rodney Dawes <dobey@novell.com>
-Andreas Nilsson <nisses.mail@home.se>
-Tuomas Kuosmanen <tigert@tigert.com>
-Garrett LeSage <garrett@novell.com>
-Jakub Steiner <jimmac@novell.com>"
-}
diff --git a/examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.png b/examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.png
deleted file mode 100644
index cab4d02c7..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt b/examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt
deleted file mode 100644
index 55bd6715e..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(stylesheetbrowser LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/stylesheetbrowser")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
-
-qt_add_executable(stylesheetbrowser
- main.cpp
- mainwindow.cpp mainwindow.h mainwindow.ui
- stylesheetdialog.cpp stylesheetdialog.h stylesheetdialog.ui
-)
-
-set_target_properties(stylesheetbrowser PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(stylesheetbrowser PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineWidgets
-)
-
-# Resources:
-set(stylesheetbrowser_resource_files
- "3rdparty/view-refresh.png"
-)
-
-qt_add_resources(stylesheetbrowser "stylesheetbrowser"
- PREFIX
- "/"
- BASE
- "3rdparty"
- FILES
- ${stylesheetbrowser_resource_files}
-)
-
-install(TARGETS stylesheetbrowser
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.png b/examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.png
deleted file mode 100644
index 32c7c43ed..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc
deleted file mode 100644
index 80f333323..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginewidgets/stylesheetbrowser
- \title WebEngine StyleSheet Browser Example
- \ingroup webengine-widgetexamples
- \brief Demonstrates how to inject CSS into web pages using user scripts.
-
- \image stylesheetbrowser.png
-
- \e {StyleSheet Browser} demonstrates how to use the \l{Qt WebEngine Widgets C++ Classes}
- {Qt WebEngine C++ classes} to inject user stylesheets into web pages.
-
- \include examples-run.qdocinc
-
- \section1 Working With Stylesheets
-
- We use JavaScript to create and append CSS elements to the documents.
- After declaring the script source, QWebEnginePage::runJavaScript() can run it
- immediately and apply newly created styles on the current content of the web view.
- Encapsulating the script into a QWebEngineScript and adding it to the script collection
- of QWebEnginePage makes its effect permanent.
-
- \quotefromfile webenginewidgets/stylesheetbrowser/mainwindow.cpp
- \skipto MainWindow::insertStyleSheet
- \printuntil /^\}/
-
- Removing stylesheets can be done similarly:
-
- \quotefromfile webenginewidgets/stylesheetbrowser/mainwindow.cpp
- \skipto MainWindow::removeStyleSheet
- \printuntil /^\}/
-
- \section1 Files and Attributions
-
- The example uses icons from the Tango Icon Library:
-
- \table
- \row
- \li \l{stylesheetbrowser-tango}{Tango Icon Library}
- \li Public Domain
- \endtable
-*/
diff --git a/examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp b/examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp
deleted file mode 100644
index ab786d5c9..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "mainwindow.h"
-#include "stylesheetdialog.h"
-#include "ui_mainwindow.h"
-
-static QMap<QString, QString> defaultStyleSheets = {
- {"Upside down", "body { -webkit-transform: rotate(180deg); }"}
-};
-
-MainWindow::MainWindow(const QUrl &url) :
- QMainWindow(),
- ui(new Ui::MainWindow)
-{
- ui->setupUi(this);
-
- connect(ui->urlBar, &QLineEdit::returnPressed, this, &MainWindow::urlEntered);
- connect(ui->webEngineView, &QWebEngineView::urlChanged, this, &MainWindow::urlChanged);
- connect(ui->settingsButton, &QPushButton::clicked, this, &MainWindow::showStyleSheetsDialog);
- connect(ui->reloadButton, &QPushButton::clicked, this, &MainWindow::reloadRequested);
-
- QSettings settings;
- settings.beginGroup("styleSheets");
- QStringList styleSheets = settings.allKeys();
- if (styleSheets.empty()) {
- // Add back default style sheets if the user cleared them out
- loadDefaultStyleSheets();
- } else {
- for (auto name : std::as_const(styleSheets)) {
- StyleSheet styleSheet = settings.value(name).value<StyleSheet>();
- if (styleSheet.second)
- insertStyleSheet(name, styleSheet.first, false);
- }
- }
- settings.endGroup();
-
- ui->webEngineView->setUrl(url);
-}
-
-MainWindow::~MainWindow()
-{
- delete ui;
-}
-
-void MainWindow::insertStyleSheet(const QString &name, const QString &source, bool immediately)
-{
- QWebEngineScript script;
- QString s = QString::fromLatin1("(function() {"\
- " css = document.createElement('style');"\
- " css.type = 'text/css';"\
- " css.id = '%1';"\
- " document.head.appendChild(css);"\
- " css.innerText = '%2';"\
- "})()").arg(name).arg(source.simplified());
- if (immediately)
- ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
-
- script.setName(name);
- script.setSourceCode(s);
- script.setInjectionPoint(QWebEngineScript::DocumentReady);
- script.setRunsOnSubFrames(true);
- script.setWorldId(QWebEngineScript::ApplicationWorld);
- ui->webEngineView->page()->scripts().insert(script);
-}
-
-void MainWindow::removeStyleSheet(const QString &name, bool immediately)
-{
- QString s = QString::fromLatin1("(function() {"\
- " var element = document.getElementById('%1');"\
- " element.outerHTML = '';"\
- " delete element;"\
- "})()").arg(name);
- if (immediately)
- ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
-
- const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
- if (!scripts.isEmpty())
- ui->webEngineView->page()->scripts().remove(scripts.first());
-}
-
-bool MainWindow::hasStyleSheet(const QString &name)
-{
- const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
- return !scripts.isEmpty();
-}
-
-void MainWindow::loadDefaultStyleSheets()
-{
- QSettings settings;
- settings.beginGroup("styleSheets");
-
- auto it = defaultStyleSheets.constBegin();
- while (it != defaultStyleSheets.constEnd()) {
- settings.setValue(it.key(), QVariant::fromValue(qMakePair(it.value(), true)));
- insertStyleSheet(it.key(), it.value(), false);
- ++it;
- }
-
- settings.endGroup();
-}
-
-void MainWindow::urlEntered()
-{
- ui->webEngineView->setUrl(QUrl::fromUserInput(ui->urlBar->text()));
-}
-
-void MainWindow::urlChanged(const QUrl &url)
-{
- ui->urlBar->setText(url.toString());
-}
-
-void MainWindow::showStyleSheetsDialog()
-{
- StylesheetDialog *dialog = new StylesheetDialog(this);
- dialog->show();
-}
-
-void MainWindow::reloadRequested()
-{
- ui->webEngineView->reload();
-}
diff --git a/examples/webenginewidgets/stylesheetbrowser/mainwindow.ui b/examples/webenginewidgets/stylesheetbrowser/mainwindow.ui
deleted file mode 100644
index bc68c16bb..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/mainwindow.ui
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>713</width>
- <height>455</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>StyleSheet Browser</string>
- </property>
- <property name="unifiedTitleAndToolBarOnMac">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="centralWidget">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QWidget" name="webContentsWidget" native="true">
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QWidget" name="urlBarWidget" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLineEdit" name="urlBar"/>
- </item>
- <item>
- <widget class="QPushButton" name="reloadButton">
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="stylesheetbrowser.qrc">
- <normaloff>:/view-refresh.png</normaloff>:/view-refresh.png</iconset>
- </property>
- <property name="shortcut">
- <string>Ctrl+R</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="settingsButton">
- <property name="text">
- <string>Settings</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QWebEngineView" name="webEngineView" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="url" stdset="0">
- <url>
- <string>about:blank</string>
- </url>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QMenuBar" name="menuBar">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>713</width>
- <height>20</height>
- </rect>
- </property>
- </widget>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <customwidgets>
- <customwidget>
- <class>QWebEngineView</class>
- <extends>QWidget</extends>
- <header location="global">QtWebEngineWidgets/QWebEngineView</header>
- </customwidget>
- </customwidgets>
- <resources>
- <include location="stylesheetbrowser.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc b/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc
deleted file mode 100644
index a1cebd6a7..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file alias="view-refresh.png">3rdparty/view-refresh.png</file>
- </qresource>
-</RCC>
diff --git a/examples/webenginewidgets/videoplayer/CMakeLists.txt b/examples/webenginewidgets/videoplayer/CMakeLists.txt
index 4e3e3cc2c..87ec9b086 100644
--- a/examples/webenginewidgets/videoplayer/CMakeLists.txt
+++ b/examples/webenginewidgets/videoplayer/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(videoplayer LANGUAGES CXX)
diff --git a/examples/webenginewidgets/webenginewidgets.pro b/examples/webenginewidgets/webenginewidgets.pro
index b99dd5f74..0d65d6b95 100644
--- a/examples/webenginewidgets/webenginewidgets.pro
+++ b/examples/webenginewidgets/webenginewidgets.pro
@@ -3,17 +3,15 @@ QT_FOR_CONFIG += webenginecore webenginecore-private network-private
TEMPLATE=subdirs
SUBDIRS += \
- minimal \
contentmanipulation \
cookiebrowser \
notifications \
simplebrowser \
- stylesheetbrowser \
- videoplayer \
- webui
+ push-notifications \
+ videoplayer
qtConfig(webengine-geolocation): SUBDIRS += maps
-qtConfig(webengine-webchannel): SUBDIRS += markdowneditor
+qtConfig(webengine-webchannel): SUBDIRS += recipebrowser
qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printme html2pdf
diff --git a/examples/webenginewidgets/webui/about.html b/examples/webenginewidgets/webui/about.html
deleted file mode 100644
index 7b5a58969..000000000
--- a/examples/webenginewidgets/webui/about.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Qt WebEngine WebUI Example</title>
- <style>
- html {
- background: #f0f0f0;
- color: #303030;
- font: 16px system-ui;
- height: 100%;
- }
-
- body {
- margin: 0;
- padding: 0;
- height: 100%;
- display: flex;
- flex-direction: column;
- align-items: stretch;
- }
-
- body > * {
- padding-left: 20px;
- padding-right: 20px;
- }
-
- header {
- flex: none;
- display: flex;
- align-items: center;
- background: #f0fff0;
- border-bottom: 1px solid #e0e0e0;
- padding-top: 20px;
- padding-bottom: 20px;
- }
-
- header > h1 {
- font: bold 20px system-ui;
- margin-left: 18px;
- }
-
- main {
- flex: auto;
- }
-
- footer {
- flex: none;
- display: flex;
- justify-content: center;
- padding-bottom: 20px;
- }
-
- button {
- background: #41cd52;
- color: #f0f0f0;
- font: 16px system-ui;
- border: 0;
- box-shadow: 0px 1px 3px rgb(0,0,0,0.5);
- cursor: pointer;
- margin: 0 0 1px;
- padding: 10px 24px;
- }
-
- button:hover {
- background: #50dc61;
- }
-
- button:active {
- background: #50dc61;
- box-shadow: 0px 1px 2px rgb(0,0,0,0.5);
- margin: 1px 0 0;
- }
-
- button:focus {
- outline: 0;
- }
-
- </style>
- </head>
- <body>
- <header>
- <img width="48px" height="48px"
- src="qrc:/qt-project.org/qmessagebox/images/qtlogo-64.png">
- <h1>WebEngine Widgets<br>WebUI Example</h1>
- </header>
- <main>
- <p>
- Aside from the built-in schemes, such as <code>http</code> and
- <code>qrc</code>, Qt WebEngine may be extended with <em>custom
- schemes</em> by creating <em>custom scheme handlers</em>.
- </p>
-
- <p>
- This is a simple HTML page loaded from a custom scheme and
- displayed by a <code>QWebEngineView</code>. Even the Quit button
- below is a standard HTML <code>&lt;button&gt;</code> element.
- </p>
-
- <p>
- Read the documentation to find out
- </p>
- <ul>
- <li>
- <p>
- How to create a custom scheme handler which serves HTML
- and handles HTML form submissions.
- </p>
- </li>
- <li>
- <p>
- How to prevent ordinary web content from accessing the
- custom scheme.
- </p>
- </li>
- <li>
- <p>
- How to prevent any other scheme from submitting HTML
- form data.
- </p>
- </li>
- </ul>
- </main>
- <footer>
- <form action="" method="post">
- <button name="quit">Quit</button>
- </form>
- </footer>
- </body>
-</html>
diff --git a/examples/webenginewidgets/webui/doc/images/webui-example.png b/examples/webenginewidgets/webui/doc/images/webui-example.png
deleted file mode 100644
index 84e2c7fc3..000000000
--- a/examples/webenginewidgets/webui/doc/images/webui-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/webui/doc/src/webui.qdoc b/examples/webenginewidgets/webui/doc/src/webui.qdoc
deleted file mode 100644
index c8ab43ea8..000000000
--- a/examples/webenginewidgets/webui/doc/src/webui.qdoc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example webenginewidgets/webui
- \title WebEngine Widgets WebUI Example
- \ingroup webengine-widgetexamples
- \brief Displays HTML over a custom scheme.
-
- \image webui-example.png
-
- \e {WebUI} demonstrates how to implement a custom scheme in a secure way.
-
- Aside from the built-in URL schemes, such as \c {http} and \c {qrc},
- \QWE may be extended with \e {custom schemes} by creating \e {custom
- scheme handlers}. This example shows:
-
- \list
- \li How to create a custom scheme handler which serves HTML and handles
- HTML form submissions.
- \li How to prevent ordinary web content from accessing the custom scheme.
- \li How to prevent any other scheme from submitting HTML form data.
- \endlist
-
- \include examples-run.qdocinc
-
- \section1 Overview
-
- The example program consists of a single \l {QWebEngineView} showing a
- simple HTML page loaded from the URL \c {webui:about}, over our custom
- scheme. Pressing the button at the bottom of the page will trigger an HTML
- form submission via POST to the same URL, at which point our custom scheme
- handler will cause the application to exit.
-
- The program is divided into two parts, the \c {main} function for setting
- everything up, and the \c {WebUiHandler} class for implementing our custom
- scheme handler. The \c {main} function is quite short:
-
- \quotefromfile webenginewidgets/webui/main.cpp
- \skipto int main
- \printuntil /^\}/
-
- Aside from the relatively standard setup of widgets, two points are
- noteworthy. First, we call the static method \c
- {WebUiHandler::registerUrlScheme()} to register our custom scheme with the
- web engine. Second, we create and install our custom scheme handler \c
- {WebUiHandler} using \l
- {QWebEngineProfile::installUrlSchemeHandler()}{installUrlSchemeHandler()}.
- The following sections describe these aspects in more detail.
-
- \section1 Registering the Scheme
-
- As custom schemes are integrated directly into the web engine, they do not
- necessarily need to follow the standard security rules which apply to
- ordinary web content. Depending on the chosen configuration, content served
- over a custom scheme may be given access to local resources, be set to
- ignore Content-Security-Policy rules, or conversely, be denied access to any
- other content entirely.
-
- In order to take advantage of these possibilities, the custom scheme must
- first be registered. This means creating and configuring a \l
- {QWebEngineUrlScheme} object and then handing it over to \l
- {QWebEngineUrlScheme::registerScheme()}. The example program does exactly this in
- the static method \c {WebUiHandler::registerUrlScheme()}:
-
- \quotefromfile webenginewidgets/webui/webuihandler.cpp
- \skipto void WebUiHandler::registerUrlScheme
- \printuntil /^\}/
-
- A custom scheme needs a name, which can be set by passing it to
- the constructor of \c {QWebEngineUrlScheme} or by calling \l
- {QWebEngineUrlScheme::setName}. In the above, the name \c {webui} is set
- through the constructor. Additionally, we activate the flags \l
- {QWebEngineUrlScheme::SecureScheme}{SecureScheme}, \l
- {QWebEngineUrlScheme::LocalScheme}{LocalScheme} and \l
- {QWebEngineUrlScheme::LocalAccessAllowed}{LocalAccessAllowed}. Since our
- custom scheme handler will not deliver resources received from insecure
- network connections, we can safely mark it as a \c {SecureScheme}. The \c {LocalScheme}
- flag prevents content from non-local schemes (such as \c {http}) from
- interacting with our custom scheme. Without this flag it would be possible,
- for example, to embed the \c {webui:about} page in an \c <iframe> element on
- a remotely loaded HTML page, perhaps to attempt a phishing attack. We also
- need the \c {LocalAccessAllowed} flag without which we would not be able to
- access the \c {webui} scheme from our \c {webui:about} page.
-
- Earlier we saw that the call to \c {WebUiHandler::registerUrlScheme()} is
- made already at the top of the \c {main} function. This is so because custom
- schemes need to be registered as early as possible so that that they can be
- passed to all subprocesses. Specifically, custom schemes need to be registered
- before any other \QWE classes are instantiated by the application.
-
- \section1 Handling Requests
-
- A custom scheme handler is, broadly speaking, similar to a web application
- served over HTTP. However, because custom schemes are integrated directly
- into the web engine, they have the advantage in terms of efficiency: there's
- no need for generating and parsing HTTP messages or for transferring data
- over sockets.
-
- Implementing a handler means creating a subclass of \l
- {QWebEngineUrlSchemeHandler}, which is just what is done by the \c
- {WebUiHandler} class of the example program:
-
- \quotefromfile webenginewidgets/webui/webuihandler.h
- \skipto class WebUiHandler
- \printuntil /^\}/
-
- For each request to a \c {webui} URL, the \c
- {WebUiHandler::requestStarted()} method will be called:
-
- \quotefromfile webenginewidgets/webui/webuihandler.cpp
- \skipto void WebUiHandler::requestStarted
- \printuntil /^\}/
-
- The \l {QWebEngineUrlRequestJob} object \c {job} contains the request's
- attributes and provides methods for replying to the request with a response.
- Responses are generated asynchronously by reading them from the \l
- {QIODevice} that the application passes to \l
- {QWebEngineUrlRequestJob::reply()}{reply()}.
-
- \warning The \c requestStarted() method is not called from the main thread,
- but from the web engine's IO thread. Care must be taken to synchronize
- access to any resources on the main thread.
-
- Aside from the usual fare of \l
- {QWebEngineUrlRequestJob::requestMethod()}{requestMethod} and \l
- {QWebEngineUrlRequestJob::requestUrl()}{requestUrl}, there is also the \l
- {QWebEngineUrlRequestJob::initiator()}{initiator}, holding the origin of the
- content which initiated the request. An empty \c initiator means the request
- was initiated directly by the application (via \l
- {QWebEnginePage::setUrl()}, for example). The special value \c "null"
- corresponds to an opaque origin (a sandboxed \c {<iframe>} element, for
- example). Otherwise, the \c initiator will contain the URL scheme, hostname,
- and port of the content which initiated the request.
-
- In this example, the \c initiator is used to ensure that \c {POST} requests
- to \c {webui:about} will only trigger the application's exit if they
- originate from the \c {webui} scheme. This prevents content loaded over
- other schemes from triggering the application's exit.
-
-*/
diff --git a/examples/webenginewidgets/webui/main.cpp b/examples/webenginewidgets/webui/main.cpp
deleted file mode 100644
index cbbb9ad25..000000000
--- a/examples/webenginewidgets/webui/main.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "webuihandler.h"
-
-#include <QApplication>
-#include <QWebEnginePage>
-#include <QWebEngineProfile>
-#include <QWebEngineView>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
-
- WebUiHandler::registerUrlScheme();
-
- QApplication app(argc, argv);
-
- QWebEngineProfile profile;
-
- WebUiHandler handler;
- profile.installUrlSchemeHandler(WebUiHandler::schemeName, &handler);
-
- QWebEnginePage page(&profile);
- QWebEngineView view;
- view.setPage(&page);
- page.load(WebUiHandler::aboutUrl);
- view.setContextMenuPolicy(Qt::NoContextMenu);
- view.resize(500, 600);
- view.show();
-
- return app.exec();
-}
diff --git a/examples/webenginewidgets/webui/webui.pro b/examples/webenginewidgets/webui/webui.pro
deleted file mode 100644
index 714833587..000000000
--- a/examples/webenginewidgets/webui/webui.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TEMPLATE = app
-
-QT += webenginewidgets
-
-HEADERS += \
- webuihandler.h
-
-SOURCES += \
- main.cpp \
- webuihandler.cpp
-
-RESOURCES += \
- webui.qrc
-
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/webui
-INSTALLS += target
diff --git a/examples/webenginewidgets/webui/webuihandler.cpp b/examples/webenginewidgets/webui/webuihandler.cpp
deleted file mode 100644
index 932d622e5..000000000
--- a/examples/webenginewidgets/webui/webuihandler.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "webuihandler.h"
-
-#include <QApplication>
-#include <QFile>
-#include <QWebEngineUrlRequestJob>
-#include <QWebEngineUrlScheme>
-
-#define SCHEMENAME "webui"
-
-const QByteArray WebUiHandler::schemeName = QByteArrayLiteral(SCHEMENAME);
-const QUrl WebUiHandler::aboutUrl = QUrl(QStringLiteral(SCHEMENAME ":about"));
-
-WebUiHandler::WebUiHandler(QObject *parent)
- : QWebEngineUrlSchemeHandler(parent)
-{
-}
-
-void WebUiHandler::requestStarted(QWebEngineUrlRequestJob *job)
-{
- static const QUrl webUiOrigin(QStringLiteral(SCHEMENAME ":"));
- static const QByteArray GET(QByteArrayLiteral("GET"));
- static const QByteArray POST(QByteArrayLiteral("POST"));
-
- QByteArray method = job->requestMethod();
- QUrl url = job->requestUrl();
- QUrl initiator = job->initiator();
-
- if (method == GET && url == aboutUrl) {
- QFile *file = new QFile(QStringLiteral(":/about.html"), job);
- file->open(QIODevice::ReadOnly);
- job->reply(QByteArrayLiteral("text/html"), file);
- } else if (method == POST && url == aboutUrl && initiator == webUiOrigin) {
- job->fail(QWebEngineUrlRequestJob::RequestAborted);
- QApplication::exit();
- } else {
- job->fail(QWebEngineUrlRequestJob::UrlNotFound);
- }
-}
-
-// static
-void WebUiHandler::registerUrlScheme()
-{
- QWebEngineUrlScheme webUiScheme(schemeName);
- webUiScheme.setFlags(QWebEngineUrlScheme::SecureScheme |
- QWebEngineUrlScheme::LocalScheme |
- QWebEngineUrlScheme::LocalAccessAllowed);
- QWebEngineUrlScheme::registerScheme(webUiScheme);
-}
diff --git a/examples/webenginewidgets/webui/webuihandler.h b/examples/webenginewidgets/webui/webuihandler.h
deleted file mode 100644
index 072c0809c..000000000
--- a/examples/webenginewidgets/webui/webuihandler.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef WEBUIHANDLER_H
-#define WEBUIHANDLER_H
-
-#include <QWebEngineUrlSchemeHandler>
-
-class WebUiHandler : public QWebEngineUrlSchemeHandler
-{
- Q_OBJECT
-public:
- explicit WebUiHandler(QObject *parent = nullptr);
-
- void requestStarted(QWebEngineUrlRequestJob *job) override;
-
- static void registerUrlScheme();
-
- const static QByteArray schemeName;
- const static QUrl aboutUrl;
-};
-
-#endif // !WEBUIHANDLER_H
diff --git a/qt_cmdline.cmake b/qt_cmdline.cmake
index 568580c63..f89692711 100644
--- a/qt_cmdline.cmake
+++ b/qt_cmdline.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_commandline_option(build-qtpdf TYPE boolean NAME qtpdf-build)
qt_commandline_option(webengine-developer-build TYPE boolean)
diff --git a/src/3rdparty b/src/3rdparty
-Subproject c885ec409f9b6ffa25e03851729b1bc2ad2005b
+Subproject 08741ef38efb3754c1f244ea175d5a4c98b69fa
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index eef368ddb..59eb27e73 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
##
# MAIN CONFIGURE
##
@@ -73,13 +76,13 @@ if(QT_FEATURE_qtpdf_build)
add_subdirectory(pdf)
# keep log order, pdf build after webengine
if(QT_FEATURE_qtwebengine_core_build)
- add_dependencies(run_pdf_GnReady WebEngineCore)
+ add_dependencies(run_pdf_NinjaReady WebEngineCore)
endif()
if(QT_FEATURE_qtwebengine_widgets_build)
- add_dependencies(run_pdf_GnReady WebEngineWidgets)
+ add_dependencies(run_pdf_NinjaReady WebEngineWidgets)
endif()
if(QT_FEATURE_qtwebengine_quick_build)
- add_dependencies(run_pdf_GnReady WebEngineQuick)
+ add_dependencies(run_pdf_NinjaReady WebEngineQuick)
endif()
if(QT_FEATURE_qtpdf_widgets_build)
add_subdirectory(pdfwidgets)
@@ -166,7 +169,7 @@ if(CMAKE_CROSSCOMPILING AND NOT IOS AND NOT MACOS)
PREFIX host
USES_TERMINAL_BUILD TRUE
EXCLUDE_FROM_ALL TRUE
- CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${QT_HOST_PATH}/lib/cmake/Qt6/qt.toolchain.cmake
+ CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${QT_HOST_PATH_CMAKE_DIR}/Qt6/qt.toolchain.cmake
-DWEBENGINE_ROOT_BUILD_DIR=${PROJECT_BINARY_DIR}
-DWEBENGINE_ROOT_SOURCE_DIR=${WEBENGINE_ROOT_SOURCE_DIR}
-DGN_TARGET_CPU=${TEST_architecture_arch}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index b861a45c8..1d183573f 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,7 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
find_package(Ninja 1.7.2 REQUIRED)
find_package(Nodejs 12 REQUIRED)
+find_package(Perl)
find_package(PkgConfig)
if(PkgConfig_FOUND)
create_pkg_config_host_wrapper(${CMAKE_CURRENT_BINARY_DIR})
@@ -66,20 +70,18 @@ foreach(arch ${archs})
DEFINES
QT_NO_KEYWORDS
QT_USE_QSTRINGBUILDER
- QTWEBENGINECORE_VERSION_STR=\\\\\\\\\"${QT_REPO_MODULE_VERSION}\\\\\\\\\"
- QTWEBENGINEPROCESS_NAME=\\\\\\\\\"${qtWebEngineProcessName}\\\\\\\\\"
+ QTWEBENGINECORE_VERSION_STR=${QT_REPO_MODULE_VERSION}
+ QTWEBENGINEPROCESS_NAME=${qtWebEngineProcessName}
BUILDING_CHROMIUM
"${forwardDeclarationMacro}"
CXX_COMPILE_OPTIONS
${gnCxxCompileOptions}
SOURCES
- accessibility_activation_observer.cpp accessibility_activation_observer.h
accessibility_tree_formatter_qt.cpp
authentication_dialog_controller.cpp authentication_dialog_controller.h authentication_dialog_controller_p.h
autofill_client_qt.cpp autofill_client_qt.h
autofill_popup_controller.cpp autofill_popup_controller.h autofill_popup_controller_p.h
browser_accessibility_manager_qt.cpp browser_accessibility_manager_qt.h
- browser_accessibility_qt.cpp browser_accessibility_qt.h
browser_main_parts_qt.cpp browser_main_parts_qt.h
browser_message_filter_qt.cpp browser_message_filter_qt.h
browsing_data_remover_delegate_qt.cpp browsing_data_remover_delegate_qt.h
@@ -87,6 +89,7 @@ foreach(arch ${archs})
certificate_error_controller.cpp certificate_error_controller.h
chromium_overrides.cpp
client_cert_select_controller.cpp client_cert_select_controller.h
+ client_hints.cpp client_hints.h
clipboard_change_observer.h
clipboard_qt.cpp clipboard_qt.h
color_chooser_controller.cpp color_chooser_controller.h color_chooser_controller_p.h
@@ -96,6 +99,7 @@ foreach(arch ${archs})
compositor/content_gpu_client_qt.cpp compositor/content_gpu_client_qt.h
compositor/display_overrides.cpp
compositor/display_software_output_surface.cpp compositor/display_software_output_surface.h
+ compositor/native_skia_output_device.cpp compositor/native_skia_output_device.h
content_browser_client_qt.cpp content_browser_client_qt.h
content_client_qt.cpp content_client_qt.h
content_main_delegate_qt.cpp content_main_delegate_qt.h
@@ -149,15 +153,13 @@ foreach(arch ${archs})
ozone/surface_factory_qt.cpp ozone/surface_factory_qt.h
permission_manager_qt.cpp permission_manager_qt.h
platform_notification_service_qt.cpp platform_notification_service_qt.h
+ pointer_device_qt.cpp
pref_service_adapter.cpp pref_service_adapter.h
process_main.cpp
profile_adapter.cpp profile_adapter.h
profile_adapter_client.cpp profile_adapter_client.h
profile_io_data_qt.cpp profile_io_data_qt.h
profile_qt.cpp profile_qt.h
- quota_permission_context_qt.cpp quota_permission_context_qt.h
- quota_request_controller.h
- quota_request_controller_impl.cpp quota_request_controller_impl.h
render_view_context_menu_qt.cpp render_view_context_menu_qt.h
render_widget_host_view_qt.cpp render_widget_host_view_qt.h
render_widget_host_view_qt_delegate.h
@@ -195,19 +197,35 @@ foreach(arch ${archs})
web_usb_detector_qt.cpp web_usb_detector_qt.h
)
+ extend_gn_target(${buildGn} CONDITION QT_FEATURE_accessibility
+ SOURCES
+ accessibility_activation_observer.cpp accessibility_activation_observer.h
+ browser_accessibility_qt.cpp browser_accessibility_qt.h
+ )
+
extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_ozone_x11
SOURCES
ozone/gl_ozone_glx_qt.cpp ozone/gl_ozone_glx_qt.h
ozone/gl_surface_glx_qt.cpp ozone/gl_surface_glx_qt.h
)
+ extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_vulkan
+ SOURCES
+ compositor/vulkan_implementation_qt.cpp compositor/vulkan_implementation_qt.h
+ )
+
extend_gn_target(${buildGn} CONDITION QT_FEATURE_opengl
SOURCES
compositor/compositor_resource_fence.cpp compositor/compositor_resource_fence.h
- compositor/display_gl_output_surface.cpp compositor/display_gl_output_surface.h
compositor/display_skia_output_device.cpp compositor/display_skia_output_device.h
)
+ extend_gn_target(${buildGn} CONDITION MACOS
+ SOURCES
+ compositor/native_skia_output_device_mac.mm
+ compositor/native_skia_output_device_mac2.mm
+ )
+
extend_gn_target(${buildGn} CONDITION MACOS AND QT_FEATURE_opengl
SOURCES
macos_context_type_helper.mm macos_context_type_helper.h
@@ -286,20 +304,31 @@ foreach(arch ${archs})
list(APPEND gnArgArg
qtwebengine_target="${buildDir}/${config}/${arch}:QtWebEngineCore"
+ build_with_tflite_lib=false
+ enable_background_contents=false
+ enable_background_mode=false
enable_ipc_fuzzer=false
enable_ipc_logging=false
+ enable_js_type_check=false
enable_media_remoting=false
enable_message_center=false
enable_nacl=false
+ enable_oop_printing=false
enable_remoting=false
enable_reporting=false
enable_resource_allowlist_generation=false
+ enable_screen_ai_service=false
+ enable_session_service=false
enable_swiftshader=false
enable_swiftshader_vulkan=false
angle_enable_swiftshader=false
dawn_use_swiftshader=false
+ use_dawn=false
+ build_dawn_tests=false
+ enable_vr=false
enable_web_speech=false
enable_widevine=true
+ enable_library_cdms=true
fatal_linker_warnings=false
has_native_accessibility=false
safe_browsing_mode=0
@@ -307,12 +336,11 @@ foreach(arch ${archs})
toolkit_views=false
chrome_pgo_phase=0
optimize_webui=false
- enable_js_type_check=false
v8_use_external_startup_data=false
strip_absolute_paths_from_debug_symbols=false
- enable_oop_printing=false
devtools_fast_bundle=false
devtools_skip_typecheck=false
+ enable_jxl_decoder=false # temporarily because libjxl causes internal compiler error on armv7
)
extend_gn_list(gnArgArg
@@ -348,6 +376,10 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_extensions
)
extend_gn_list(gnArgArg
+ ARGS enable_vulkan
+ CONDITION QT_FEATURE_webengine_vulkan
+ )
+ extend_gn_list(gnArgArg
ARGS use_kerberos
CONDITION QT_FEATURE_webengine_kerberos
)
@@ -369,12 +401,16 @@ foreach(arch ${archs})
if(LINUX)
list(APPEND gnArgArg
+ use_gtk=false # GTK toolkit bindings
+ use_qt=false # Qt5 toolkit bindings
use_cups=false
use_gio=false
use_gnome_keyring=false
- use_udev=true
use_bundled_fontconfig=false
- enable_session_service=false
+ use_glib=false
+ use_bluez=false
+ use_vaapi=false
+ use_udev=true
is_cfi=false
use_ozone=true
ozone_auto_platforms=false
@@ -382,12 +418,9 @@ foreach(arch ${archs})
ozone_platform_external=true
ozone_platform="qt"
ozone_extra_path="${CMAKE_CURRENT_LIST_DIR}/ozone/ozone_extra.gni"
- use_glib=false
- use_bluez=false
- use_vaapi=false
)
set(systemLibs libjpeg libpng freetype harfbuzz libevent libwebp libxml
- opus snappy libvpx icu ffmpeg re2 lcms2
+ opus snappy libvpx icu ffmpeg re2 lcms2 libopenjpeg2
)
foreach(slib ${systemLibs})
extend_gn_list(gnArgArg
@@ -395,6 +428,12 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_system_${slib}
)
endforeach()
+ if(NOT QT_FEATURE_webengine_system_opus)
+ extend_gn_list(gnArgArg
+ ARGS has_perl
+ CONDITION Perl_FOUND
+ )
+ endif()
extend_gn_list(gnArgArg
ARGS use_system_libxslt
CONDITION QT_FEATURE_webengine_system_libxml
@@ -442,24 +481,27 @@ foreach(arch ${archs})
)
endif()
- if(QT_FEATURE_webengine_kerberos)
- list(APPEND gnArgArg
- external_gssapi_include_dir="${GSSAPI_INCLUDE_DIRS}/gssapi"
- )
- endif()
-
if(CMAKE_CROSSCOMPILING AND cpu STREQUAL "arm")
check_thumb(armThumb)
- if(NOT armThumb AND NOT QT_FEATURE_system_ffmpeg)
+ if(NOT armThumb AND NOT QT_FEATURE_webengine_system_ffmpeg)
list(APPEND gnArgArg media_use_ffmpeg=false use_webaudio_ffmpeg=false)
endif()
endif()
+
+ if(CMAKE_CROSSCOMPILING AND cpu STREQUAL "arm64")
+ # V8 sandbox initialization is slow in QEMU.
+ # This is a workaround to avoid auto test timeouts on the QEMU arm64 CI.
+ if ("$ENV{TARGET_OSVERSION_COIN}" STREQUAL "qemu")
+ list(APPEND gnArgArg v8_enable_sandbox=false)
+ endif()
+ endif()
endif()
if(MACOS)
list(APPEND gnArgArg
use_external_popup_menu=false
angle_enable_vulkan=false
+ use_static_angle=true
)
endif()
@@ -470,11 +512,10 @@ foreach(arch ${archs})
if(WIN32)
list(APPEND gnArgArg
- enable_session_service=false
ninja_use_custom_environment_files=false
com_init_check_hook_disabled=true
heterogeneous_executables=true
- enable_vr=false
+ use_static_angle=true
)
endif()
@@ -482,7 +523,7 @@ foreach(arch ${archs})
CMAKE_TARGET WebEngineCore
NINJA_TARGETS QtWebEngineCore convert_dict
GN_TARGET ${buildGn}
- GN_ARGS "${gnArgArg}"
+ GN_ARGS ${gnArgArg}
BUILDDIR ${buildDir}/${config}/${arch}
MODULE core
)
@@ -550,3 +591,11 @@ if(QT_FEATURE_webengine_spellchecker AND NOT CMAKE_CROSSCOMPILING)
add_dependencies(${dict_target_name} WebEngineCore)
endif()
+##
+# CHROMIUM UPDATE
+##
+
+add_custom_target(update-chromium
+ COMMAND ${CMAKE_COMMAND} -P ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/SubmoduleUpdate.cmake
+ DEPENDS ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/SubmoduleUpdate.cmake
+)
diff --git a/src/core/accessibility_activation_observer.cpp b/src/core/accessibility_activation_observer.cpp
index 53a5e87fd..179a780d0 100644
--- a/src/core/accessibility_activation_observer.cpp
+++ b/src/core/accessibility_activation_observer.cpp
@@ -3,8 +3,6 @@
#include "accessibility_activation_observer.h"
-#if QT_CONFIG(accessibility)
-
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
namespace QtWebEngineCore {
@@ -49,5 +47,3 @@ void AccessibilityActivationObserver::accessibilityActiveChanged(bool active)
}
} // namespace QtWebEngineCore
-
-#endif // QT_CONFIG(accessibility)
diff --git a/src/core/accessibility_activation_observer.h b/src/core/accessibility_activation_observer.h
index 20063c577..81d8b843c 100644
--- a/src/core/accessibility_activation_observer.h
+++ b/src/core/accessibility_activation_observer.h
@@ -6,12 +6,8 @@
#include <QtGui/qaccessible.h>
-#if QT_CONFIG(accessibility)
-
namespace QtWebEngineCore {
-class RenderWidgetHostViewQt;
-
class AccessibilityActivationObserver : public QAccessible::ActivationObserver
{
public:
@@ -23,6 +19,4 @@ public:
} // namespace QtWebEngineCore
-#endif // QT_CONFIG(accessibility)
-
#endif // ACCESSIBILITY_ACTIVATION_OBSERVER_H
diff --git a/src/core/accessibility_tree_formatter_qt.cpp b/src/core/accessibility_tree_formatter_qt.cpp
index 6167bc73b..3a3b30cb4 100644
--- a/src/core/accessibility_tree_formatter_qt.cpp
+++ b/src/core/accessibility_tree_formatter_qt.cpp
@@ -1,20 +1,27 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "ui/accessibility/platform/inspect/ax_tree_formatter_base.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
+#include "content/public/browser/ax_inspect_factory.h"
+#include "ui/accessibility/platform/inspect/ax_event_recorder.h"
+#include <QtGui/qtguiglobal.h>
+
+#include <memory>
+#include <string>
#include <utility>
+#if QT_CONFIG(accessibility)
+#include "browser_accessibility_qt.h"
+
#include "base/strings/stringprintf.h"
#include "base/values.h"
-#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
#include "content/browser/accessibility/browser_accessibility.h"
-#include "content/public/browser/ax_inspect_factory.h"
-#include "ui/accessibility/platform/inspect/ax_event_recorder.h"
-
-#include "browser_accessibility_qt.h"
+#include "ui/accessibility/platform/inspect/ax_tree_formatter_base.h"
#include <QtGui/qaccessible.h>
+#endif
namespace content {
@@ -24,16 +31,16 @@ public:
explicit AccessibilityTreeFormatterQt();
~AccessibilityTreeFormatterQt() override;
- base::Value BuildTree(ui::AXPlatformNodeDelegate *start) const override;
- base::Value BuildTreeForSelector(const AXTreeSelector &selector) const override
+ base::Value::Dict BuildTree(ui::AXPlatformNodeDelegate *start) const override;
+ base::Value::Dict BuildTreeForSelector(const AXTreeSelector &selector) const override
{
- return base::Value{};
+ return base::Value::Dict{};
}
private:
- void RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::DictionaryValue *dict) const;
- void AddProperties(const BrowserAccessibility &node, base::DictionaryValue *dict) const;
- std::string ProcessTreeForOutput(const base::DictionaryValue &node) const override;
+ void RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::Value::Dict *dict) const;
+ void AddProperties(const BrowserAccessibility &node, base::Value::Dict *dict) const;
+ std::string ProcessTreeForOutput(const base::Value::Dict &node) const override;
};
AccessibilityTreeFormatterQt::AccessibilityTreeFormatterQt()
@@ -44,127 +51,124 @@ AccessibilityTreeFormatterQt::~AccessibilityTreeFormatterQt()
{
}
-base::Value AccessibilityTreeFormatterQt::BuildTree(ui::AXPlatformNodeDelegate *start) const
+base::Value::Dict AccessibilityTreeFormatterQt::BuildTree(ui::AXPlatformNodeDelegate *start) const
{
BrowserAccessibility *root_internal =
BrowserAccessibility::FromAXPlatformNodeDelegate(start);
- base::Value dict(base::Value::Type::DICTIONARY);
- RecursiveBuildAccessibilityTree(*root_internal, static_cast<base::DictionaryValue *>(&dict));
+ base::Value::Dict dict;
+ RecursiveBuildAccessibilityTree(*root_internal, &dict);
return dict;
}
-void AccessibilityTreeFormatterQt::RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::DictionaryValue *dict) const
+void AccessibilityTreeFormatterQt::RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::Value::Dict *dict) const
{
AddProperties(node, dict);
- auto children = std::make_unique<base::ListValue>();
+ base::Value::List children;
for (size_t i = 0; i < node.PlatformChildCount(); ++i) {
- std::unique_ptr<base::DictionaryValue> child_dict(new base::DictionaryValue);
+ base::Value::Dict child_dict;
content::BrowserAccessibility *child_node = node.PlatformGetChild(i);
- RecursiveBuildAccessibilityTree(*child_node, child_dict.get());
- children->Append(std::move(child_dict));
+ RecursiveBuildAccessibilityTree(*child_node, &child_dict);
+ children.Append(std::move(child_dict));
}
dict->Set(kChildrenDictAttr, std::move(children));
}
-void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &node, base::DictionaryValue *dict) const
+void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &node, base::Value::Dict *dict) const
{
- dict->SetInteger("id", node.GetId());
+ dict->Set("id", node.GetId());
const QAccessibleInterface *iface = toQAccessibleInterface(&node);
- dict->SetString("role", qAccessibleRoleString(iface->role()));
+ dict->Set("role", qAccessibleRoleString(iface->role()));
QAccessible::State state = iface->state();
- std::vector<base::Value> states;
+ base::Value::List states;
if (state.busy)
- states.push_back(base::Value("busy"));
+ states.Append(base::Value("busy"));
if (state.checkable)
- states.push_back(base::Value("checkable"));
+ states.Append(base::Value("checkable"));
if (state.checked)
- states.push_back(base::Value("checked"));
+ states.Append(base::Value("checked"));
if (node.IsClickable())
- states.push_back(base::Value("clickable"));
+ states.Append(base::Value("clickable"));
if (state.collapsed)
- states.push_back(base::Value("collapsed"));
+ states.Append(base::Value("collapsed"));
if (state.disabled)
- states.push_back(base::Value("disabled"));
+ states.Append(base::Value("disabled"));
if (state.editable)
- states.push_back(base::Value("editable"));
+ states.Append(base::Value("editable"));
if (state.expandable)
- states.push_back(base::Value("expandable"));
+ states.Append(base::Value("expandable"));
if (state.expanded)
- states.push_back(base::Value("expanded"));
+ states.Append(base::Value("expanded"));
if (state.focusable)
- states.push_back(base::Value("focusable"));
+ states.Append(base::Value("focusable"));
if (state.focused)
- states.push_back(base::Value("focused"));
+ states.Append(base::Value("focused"));
if (state.hasPopup)
- states.push_back(base::Value("hasPopup"));
+ states.Append(base::Value("hasPopup"));
if (state.hotTracked)
- states.push_back(base::Value("hotTracked"));
+ states.Append(base::Value("hotTracked"));
if (state.invisible)
- states.push_back(base::Value("invisible"));
+ states.Append(base::Value("invisible"));
if (state.linked)
- states.push_back(base::Value("linked"));
+ states.Append(base::Value("linked"));
if (state.multiLine)
- states.push_back(base::Value("multiLine"));
+ states.Append(base::Value("multiLine"));
if (state.multiSelectable)
- states.push_back(base::Value("multiSelectable"));
+ states.Append(base::Value("multiSelectable"));
if (state.modal)
- states.push_back(base::Value("modal"));
+ states.Append(base::Value("modal"));
if (state.offscreen)
- states.push_back(base::Value("offscreen"));
+ states.Append(base::Value("offscreen"));
if (state.passwordEdit)
- states.push_back(base::Value("password"));
+ states.Append(base::Value("password"));
if (state.pressed)
- states.push_back(base::Value("pressed"));
+ states.Append(base::Value("pressed"));
if (state.readOnly)
- states.push_back(base::Value("readOnly"));
+ states.Append(base::Value("readOnly"));
if (state.selectable)
- states.push_back(base::Value("selectable"));
+ states.Append(base::Value("selectable"));
if (state.selected)
- states.push_back(base::Value("selected"));
+ states.Append(base::Value("selected"));
if (state.traversed)
- states.push_back(base::Value("traversed"));
- dict->SetKey("states", base::Value(states));
+ states.Append(base::Value("traversed"));
+ dict->Set("states", std::move(states));
- dict->SetString("name", iface->text(QAccessible::Name).toStdString());
- dict->SetString("description", iface->text(QAccessible::Description).toStdString());
+ dict->Set("name", iface->text(QAccessible::Name).toStdString());
+ dict->Set("description", iface->text(QAccessible::Description).toStdString());
}
-std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::DictionaryValue &node) const
+std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::Value::Dict &node) const
{
std::string error_value;
- if (node.GetString("error", &error_value))
- return error_value;
+ if (auto error_value = node.FindString("error"))
+ return *error_value;
std::string line;
std::string role_value;
- node.GetString("role", &role_value);
- if (!role_value.empty())
- WriteAttribute(true, base::StringPrintf("%s", role_value.c_str()), &line);
+ if (auto role_value = node.FindString("role"))
+ WriteAttribute(true, base::StringPrintf("%s", role_value->c_str()), &line);
- const base::ListValue *states_value = nullptr;
- if (node.GetList("states", &states_value)) {
- for (const auto &state : states_value->GetList()) {
+ if (const auto states_value = node.FindList("states")) {
+ for (const auto &state : *states_value) {
if (auto *state_value = state.GetIfString())
WriteAttribute(false, *state_value, &line);
}
}
- std::string name_value;
- if (node.GetString("name", &name_value))
- WriteAttribute(true, base::StringPrintf("name='%s'", name_value.c_str()), &line);
+ if (auto name_value = node.FindString("name"))
+ WriteAttribute(true, base::StringPrintf("name='%s'", name_value->c_str()), &line);
- std::string description_value;
- if (node.GetString("description", &description_value))
- WriteAttribute(false, base::StringPrintf("description='%s'", description_value.c_str()), &line);
+ if (auto description_value = node.FindString("description"))
+ WriteAttribute(false, base::StringPrintf("description='%s'", description_value->c_str()), &line);
int id_value;
- node.GetInteger("id", &id_value);
+ if (auto maybe_id = node.FindInt("id"))
+ id_value = *maybe_id;
WriteAttribute(false, base::StringPrintf("id=%d", id_value), &line);
return line + "\n";
diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index 2d493c04c..922adfd8c 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_package(Qt6 ${PROJECT_VERSION} REQUIRED COMPONENTS Gui Network Quick)
find_package(Qt6 ${PROJECT_VERSION} QUIET OPTIONAL_COMPONENTS WebChannel Positioning)
@@ -71,6 +74,10 @@ qt_internal_extend_target(WebEngineCore CONDITION QT_FEATURE_webengine_geolocati
Qt::Positioning
)
+get_install_config(config)
+get_architectures(archs)
+list(GET archs 0 arch)
+
##
# DOCS
##
@@ -79,18 +86,16 @@ qt_internal_add_docs(WebEngineCore
../doc/qtwebengine.qdocconf
)
-add_custom_command(
- OUTPUT chromium_attributions.qdoc
- COMMAND ${Python3_EXECUTABLE} chromium/tools/licenses.py
- --file-template ../core/doc/about_credits.tmpl
- --entry-template ../core/doc/about_credits_entry.tmpl
- credits ${CMAKE_CURRENT_BINARY_DIR}/chromium_attributions.qdoc
- DEPENDS ../doc/about_credits.tmpl ../doc/about_credits_entry.tmpl
- WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty
- USES_TERMINAL
+add_code_attributions_target(
+ TARGET generate_chromium_attributions
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/chromium_attributions.qdoc
+ GN_TARGET :QtWebEngineCore
+ FILE_TEMPLATE ../doc/about_credits.tmpl
+ ENTRY_TEMPLATE ../doc/about_credits_entry.tmpl
+ BUILDDIR ${buildDir}/${config}/${arch}
)
-add_custom_target(generate_chromium_attributions DEPENDS chromium_attributions.qdoc)
-add_dependencies(generate_docs_WebEngineCore generate_chromium_attributions)
+add_dependencies(generate_chromium_attributions run_core_GnDone)
+add_dependencies(docs generate_chromium_attributions)
##
# WEBENGINECORE RESOURCES
@@ -106,9 +111,7 @@ set(resourceList qtwebengine_resources.pak
qtwebengine_resources_200p.pak
qtwebengine_devtools_resources.pak)
-get_install_config(config)
-get_architectures(archs)
-list(GET archs 0 arch)
+
foreach(loc ${localeList})
get_filename_component(locSourcePath ${buildDir}/${config}/${arch}/qtwebengine_locales/${loc}.pak REALPATH)
diff --git a/src/core/api/Qt6WebEngineCoreMacros.cmake b/src/core/api/Qt6WebEngineCoreMacros.cmake
index efb34882b..7e23f377e 100644
--- a/src/core/api/Qt6WebEngineCoreMacros.cmake
+++ b/src/core/api/Qt6WebEngineCoreMacros.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
function(qt6_add_webengine_dictionary)
set(options)
set(oneValueArgs TARGET SOURCE OUTPUT_DIRECTORY)
diff --git a/src/core/api/configure.cmake b/src/core/api/configure.cmake
index d712f1c2a..a35651b8b 100644
--- a/src/core/api/configure.cmake
+++ b/src/core/api/configure.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
#### Libraries
if(NOT QT_CONFIGURE_RUNNING)
@@ -59,10 +62,6 @@ qt_feature("webengine-system-alsa" PRIVATE
LABEL "Use ALSA"
CONDITION UNIX AND TEST_alsa
)
-qt_feature("webengine-v8-snapshot-support" PRIVATE
- LABEL "Building v8 snapshot supported"
- CONDITION NOT UNIX OR NOT QT_FEATURE_cross_compile OR ( TEST_architecture_arch STREQUAL arm64 ) OR TEST_webengine_host_compiler
-)
qt_feature("webengine-geolocation" PUBLIC
LABEL "Geolocation"
CONDITION TARGET Qt::Positioning
@@ -147,6 +146,12 @@ qt_feature("webengine-sanitizer" PRIVATE
AUTODETECT CLANG
CONDITION CLANG AND ECM_ENABLE_SANITIZERS
)
+qt_feature("webengine-vulkan" PRIVATE
+ SECTION "WebEngine"
+ LABEL "Vulkan support"
+ PURPOSE "Enables support for Vulkan rendering"
+ CONDITION QT_FEATURE_vulkan
+)
# internal testing feature
qt_feature("webengine-system-poppler" PRIVATE
LABEL "popler"
@@ -175,8 +180,8 @@ qt_configure_add_summary_entry(
CONDITION UNIX
)
qt_configure_add_summary_entry(
- ARGS "webengine-v8-snapshot-support"
- CONDITION UNIX AND cross_compile
+ ARGS "webengine-vulkan"
+ CONDITION QT_FEATURE_vulkan
)
qt_configure_add_summary_entry(
ARGS "webengine-system-alsa"
@@ -200,11 +205,6 @@ if(CMAKE_CROSSCOMPILING)
endif()
qt_configure_add_report_entry(
TYPE WARNING
- MESSAGE "V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work. Please make sure you have 32-bit devel environment installed."
- CONDITION UNIX AND cross_compile AND NOT QT_FEATURE_webengine_v8_snapshot_support
-)
-qt_configure_add_report_entry(
- TYPE WARNING
MESSAGE "WebRTC requires XDamage with qpa_xcb."
CONDITION QT_FEATURE_webengine_ozone_x11 AND NOT XDAMAGE_FOUND
)
diff --git a/src/core/api/qt_cmdline.cmake b/src/core/api/qt_cmdline.cmake
index 42dd6b240..fe7092b8c 100644
--- a/src/core/api/qt_cmdline.cmake
+++ b/src/core/api/qt_cmdline.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_commandline_option(webengine-embedded-build TYPE boolean)
qt_commandline_option(webengine-pepper-plugins TYPE boolean)
qt_commandline_option(webengine-printing-and-pdf TYPE boolean)
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index 3c2eefdf5..2736e1a33 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -195,22 +195,25 @@ sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterf
static void initialize()
{
#if QT_CONFIG(opengl)
- if (QCoreApplication::instance()) {
- // On window/ANGLE, calling QtWebEngineQuick::initialize from DllMain will result in a crash.
- if (!qt_gl_global_share_context() &&
- !(QCoreApplication::testAttribute(Qt::AA_ShareOpenGLContexts) &&
- QQuickWindow::graphicsApi() == QSGRendererInterface::OpenGLRhi)
- ) {
- qWarning("Qt WebEngine seems to be initialized from a plugin. Please "
- "set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute and "
- "QSGRendererInterface::OpenGLRhi using QQuickWindow::setGraphicsApi "
- "before constructing QGuiApplication.");
+ if (QCoreApplication::instance()) {
+ // On Windows/ANGLE, calling QtWebEngineQuick::initialize from DllMain will result in a
+ // crash.
+ if (!qt_gl_global_share_context()
+ && !(QCoreApplication::testAttribute(Qt::AA_ShareOpenGLContexts)
+ && QQuickWindow::graphicsApi() == QSGRendererInterface::OpenGLRhi)) {
+ qWarning("Qt WebEngine seems to be initialized from a plugin. Please "
+ "set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute and "
+ "QSGRendererInterface::OpenGLRhi using QQuickWindow::setGraphicsApi "
+ "before constructing QGuiApplication.");
+ }
+ return;
}
- return;
- }
- // QCoreApplication is not yet instantiated, ensuring the call will be deferred
- qAddPreRoutine(QtWebEngineCore::initialize);
- QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
+
+ // QCoreApplication is not yet instantiated, ensuring the call will be deferred
+ qAddPreRoutine(QtWebEngineCore::initialize);
+ auto api = QQuickWindow::graphicsApi();
+ if (api != QSGRendererInterface::OpenGL && api != QSGRendererInterface::Vulkan)
+ QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
#endif // QT_CONFIG(opengl)
}
diff --git a/src/core/api/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal.h
index 305040808..3583e0848 100644
--- a/src/core/api/qtwebenginecoreglobal.h
+++ b/src/core/api/qtwebenginecoreglobal.h
@@ -18,6 +18,7 @@ QT_BEGIN_NAMESPACE
#define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match");
Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineVersion() noexcept;
+Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineProcessName() noexcept;
Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineChromiumVersion() noexcept;
Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineChromiumSecurityPatchVersion() noexcept;
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 072b39650..dff2418b5 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -17,7 +17,6 @@
#include "qwebenginenewwindowrequest_p.h"
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
-#include "qwebenginequotarequest.h"
#include "qwebengineregisterprotocolhandlerrequest.h"
#include "qwebenginescript.h"
#include "qwebenginescriptcollection_p.h"
@@ -34,6 +33,7 @@
#include "render_widget_host_view_qt_delegate.h"
#include "render_widget_host_view_qt_delegate_client.h"
#include "render_widget_host_view_qt_delegate_item.h"
+#include "touch_selection_menu_controller.h"
#include "web_contents_adapter.h"
#include <QAction>
@@ -502,12 +502,6 @@ void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOr
Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock);
}
-void QWebEnginePagePrivate::runQuotaRequest(QWebEngineQuotaRequest request)
-{
- Q_Q(QWebEnginePage);
- Q_EMIT q->quotaRequested(request);
-}
-
void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
{
Q_Q(QWebEnginePage);
@@ -742,12 +736,13 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
/*!
\fn QWebEnginePage::quotaRequested(QWebEngineQuotaRequest quotaRequest)
\since 5.11
+ \deprecated [6.5] This signal is no longer emitted.
- This signal is emitted when the web page requests larger persistent storage
- than the application's current allocation in File System API. The default quota
- is 0 bytes.
+ Requesting host quota is no longer supported by Chromium.
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
- The request object \a quotaRequest can be used to accept or reject the request.
+ For further details, see https://crbug.com/1233525
*/
/*!
@@ -1658,6 +1653,31 @@ void QWebEnginePagePrivate::printRequested()
view->printRequested();
}
+QtWebEngineCore::TouchHandleDrawableDelegate *
+QWebEnginePagePrivate::createTouchHandleDelegate(const QMap<int, QImage> &images)
+{
+ return view->createTouchHandleDelegate(images);
+}
+
+void QWebEnginePagePrivate::showTouchSelectionMenu(
+ QtWebEngineCore::TouchSelectionMenuController *controller, const QRect &selectionBounds,
+ const QSize &handleSize)
+{
+ Q_UNUSED(handleSize);
+
+ if (controller->buttonCount() == 1) {
+ controller->runContextMenu();
+ return;
+ }
+
+ view->showTouchSelectionMenu(controller, selectionBounds);
+}
+
+void QWebEnginePagePrivate::hideTouchSelectionMenu()
+{
+ view->hideTouchSelectionMenu();
+}
+
void QWebEnginePagePrivate::lifecycleStateChanged(LifecycleState state)
{
Q_Q(QWebEnginePage);
@@ -1979,7 +1999,10 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, const std::funct
return;
}
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, QWebEngineScript::MainWorld);
- d->m_variantCallbacks.insert(requestId, resultCallback);
+ if (requestId)
+ d->m_variantCallbacks.insert(requestId, resultCallback);
+ else if (resultCallback)
+ resultCallback(QVariant());
}
void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId, const std::function<void(const QVariant &)> &resultCallback)
@@ -1994,7 +2017,10 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId,
}
if (resultCallback) {
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, worldId);
- d->m_variantCallbacks.insert(requestId, resultCallback);
+ if (requestId)
+ d->m_variantCallbacks.insert(requestId, resultCallback);
+ else
+ resultCallback(QVariant());
} else {
d->adapter->runJavaScript(scriptSource, worldId);
}
@@ -2228,6 +2254,9 @@ QSizeF QWebEnginePage::contentsSize() const
To be informed about the result of the request, connect to the signal
pdfPrintingFinished().
+ \note The \l QWebEnginePage::Stop web action can be used to interrupt
+ this asynchronous operation.
+
If a file already exists at the provided file path, it will be overwritten.
\sa pdfPrintingFinished()
*/
@@ -2253,6 +2282,8 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &layo
The \a resultCallback must take a const reference to a QByteArray as parameter. If printing was successful, this byte array
will contain the PDF data, otherwise, the byte array will be empty.
+ \note The \l QWebEnginePage::Stop web action can be used to interrupt this operation.
+
\warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
index f4cca0582..c60feb3ab 100644
--- a/src/core/api/qwebenginepage.h
+++ b/src/core/api/qwebenginepage.h
@@ -7,6 +7,7 @@
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
#include <QtWebEngineCore/qwebengineclientcertificateselection.h>
#include <QtWebEngineCore/qwebenginedownloadrequest.h>
+#include <QtWebEngineCore/qwebenginequotarequest.h>
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
@@ -35,7 +36,6 @@ class QWebEngineNavigationRequest;
class QWebEngineNewWindowRequest;
class QWebEnginePagePrivate;
class QWebEngineProfile;
-class QWebEngineQuotaRequest;
class QWebEngineRegisterProtocolHandlerRequest;
class QWebEngineScriptCollection;
class QWebEngineSettings;
@@ -309,7 +309,10 @@ Q_SIGNALS:
void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);
+#if QT_DEPRECATED_SINCE(6, 5)
+ QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.")
void quotaRequested(QWebEngineQuotaRequest quotaRequest);
+#endif
void registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request);
void fileSystemAccessRequested(QWebEngineFileSystemAccessRequest request);
void selectClientCertificate(QWebEngineClientCertificateSelection clientCertSelection);
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 8bdf6de5c..bb33c7e98 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -77,6 +77,11 @@ public:
virtual void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
const QRect &bounds, bool autoselectFirstSuggestion) = 0;
virtual void hideAutofillPopup() = 0;
+ virtual QtWebEngineCore::TouchHandleDrawableDelegate *
+ createTouchHandleDelegate(const QMap<int, QImage> &) = 0;
+ virtual void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *,
+ const QRect &) = 0;
+ virtual void hideTouchSelectionMenu() = 0;
};
class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient
@@ -138,7 +143,6 @@ public:
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin) override;
void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
- void runQuotaRequest(QWebEngineQuotaRequest) override;
void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) override;
QObject *accessibilityParentObject() override;
@@ -157,9 +161,10 @@ public:
void setToolTip(const QString &toolTipText) override;
void printRequested() override;
QtWebEngineCore::TouchHandleDrawableDelegate *
- createTouchHandleDelegate(const QMap<int, QImage> &) override { return nullptr; }
- void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &, const QSize &) override { }
- void hideTouchSelectionMenu() override { }
+ createTouchHandleDelegate(const QMap<int, QImage> &) override;
+ void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &,
+ const QSize &) override;
+ void hideTouchSelectionMenu() override;
const QObject *holdingQObject() const override;
ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; }
void findTextFinished(const QWebEngineFindTextResult &result) override;
@@ -195,7 +200,6 @@ public:
QWebChannel *webChannel;
unsigned int webChannelWorldId;
QUrl iconUrl;
- bool m_navigationActionTriggered;
QPointer<QWebEnginePage> inspectedPage;
QPointer<QWebEnginePage> devToolsPage;
bool defaultAudioMuted;
diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index 445df4b52..ab873e345 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -393,6 +393,37 @@ void QWebEngineProfile::setDownloadPath(const QString &path)
}
/*!
+ \since 6.5
+
+ Returns \c true if the push messaging service is enabled.
+ \note By default the push messaging service is disabled.
+
+ \sa setPushServiceEnabled()
+*/
+bool QWebEngineProfile::isPushServiceEnabled() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->profileAdapter()->pushServiceEnabled();
+}
+
+/*!
+ \since 6.5
+
+ Enables the push messaging service if \a enable is \c true, otherwise disables it.
+
+ \note \QWE uses \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)}
+ as a browser push service. Therefore, all push messages will go through the
+ Google push service and its respective servers.
+
+ \sa isPushServiceEnabled()
+*/
+void QWebEngineProfile::setPushServiceEnabled(bool enable)
+{
+ Q_D(QWebEngineProfile);
+ d->profileAdapter()->setPushServiceEnabled(enable);
+}
+
+/*!
Returns the path used for caches.
By default, this is below StandardPaths::CacheLocation in a QtWebengine/StorageName specific
diff --git a/src/core/api/qwebengineprofile.h b/src/core/api/qwebengineprofile.h
index c29202973..9fb4c8e74 100644
--- a/src/core/api/qwebengineprofile.h
+++ b/src/core/api/qwebengineprofile.h
@@ -98,6 +98,9 @@ public:
QString downloadPath() const;
void setDownloadPath(const QString &path);
+ bool isPushServiceEnabled() const;
+ void setPushServiceEnabled(bool enabled);
+
void setNotificationPresenter(std::function<void(std::unique_ptr<QWebEngineNotification>)> notificationPresenter);
QWebEngineClientCertificateStore *clientCertificateStore();
diff --git a/src/core/api/qwebenginequotarequest.cpp b/src/core/api/qwebenginequotarequest.cpp
index ca1289625..3c312216d 100644
--- a/src/core/api/qwebenginequotarequest.cpp
+++ b/src/core/api/qwebenginequotarequest.cpp
@@ -3,76 +3,54 @@
#include "qwebenginequotarequest.h"
-#include "quota_request_controller.h"
+#if QT_DEPRECATED_SINCE(6, 5)
QT_BEGIN_NAMESPACE
/*!
\class QWebEngineQuotaRequest
- \brief The QWebEngineQuotaRequest class enables accepting or rejecting
- requests for larger persistent storage than the application's current
- allocation in File System API.
-
\since 5.11
\inmodule QtWebEngineCore
+ \deprecated [6.5] Requesting host quota is no longer supported by Chromium.
+
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
- This class is used by the QWebEnginePage::quotaRequested() signal to \l
- accept() or \l reject() a request for an increase in the persistent storage
- allocated to the application. The default quota is 0 bytes.
+ For further details, see https://crbug.com/1233525
*/
/*! \fn QWebEngineQuotaRequest::QWebEngineQuotaRequest()
\internal
*/
-/*! \internal */
-QWebEngineQuotaRequest::QWebEngineQuotaRequest(QSharedPointer<QtWebEngineCore::QuotaRequestController> controller)
- : d_ptr(controller)
-{}
-
-/*!
- Rejects a request for larger persistent storage.
-*/
void QWebEngineQuotaRequest::reject()
{
- d_ptr->reject();
}
-/*!
- Accepts a request for larger persistent storage.
-*/
void QWebEngineQuotaRequest::accept()
{
- d_ptr->accept();
}
/*!
\property QWebEngineQuotaRequest::origin
- \brief The URL of the web page that issued the quota request.
*/
QUrl QWebEngineQuotaRequest::origin() const
{
- return d_ptr->origin();
+ return QUrl();
}
/*!
\property QWebEngineQuotaRequest::requestedSize
- \brief Contains the size of the requested disk space in bytes.
*/
qint64 QWebEngineQuotaRequest::requestedSize() const
{
- return d_ptr->requestedSize();
+ return 0;
}
-/*! \fn bool QWebEngineQuotaRequest::operator==(const QWebEngineQuotaRequest &that) const
- Returns \c true if \a that points to the same object as this quota request.
-*/
+QT_END_NAMESPACE
-/*! \fn bool QWebEngineQuotaRequest::operator!=(const QWebEngineQuotaRequest &that) const
- Returns \c true if \a that points to a different object than this request.
-*/
+#endif // QT_DEPRECATED_SINCE(6, 5)
-QT_END_NAMESPACE
#include "moc_qwebenginequotarequest.cpp"
diff --git a/src/core/api/qwebenginequotarequest.h b/src/core/api/qwebenginequotarequest.h
index c10789360..f542f5576 100644
--- a/src/core/api/qwebenginequotarequest.h
+++ b/src/core/api/qwebenginequotarequest.h
@@ -6,13 +6,9 @@
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
-#include <QtCore/qsharedpointer.h>
#include <QtCore/qurl.h>
-namespace QtWebEngineCore {
-class QuotaPermissionContextQt;
-class QuotaRequestController;
-} // namespace QtWebEngineCore
+#if QT_DEPRECATED_SINCE(6, 5)
QT_BEGIN_NAMESPACE
@@ -22,20 +18,18 @@ class Q_WEBENGINECORE_EXPORT QWebEngineQuotaRequest
Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
Q_PROPERTY(qint64 requestedSize READ requestedSize CONSTANT FINAL)
public:
+ QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.")
QWebEngineQuotaRequest() {}
Q_INVOKABLE void accept();
Q_INVOKABLE void reject();
QUrl origin() const;
qint64 requestedSize() const;
- bool operator==(const QWebEngineQuotaRequest &that) const { return d_ptr == that.d_ptr; }
- bool operator!=(const QWebEngineQuotaRequest &that) const { return d_ptr != that.d_ptr; }
-
-private:
- QWebEngineQuotaRequest(QSharedPointer<QtWebEngineCore::QuotaRequestController>);
- friend QtWebEngineCore::QuotaPermissionContextQt;
- QSharedPointer<QtWebEngineCore::QuotaRequestController> d_ptr;
+ bool operator==(const QWebEngineQuotaRequest &) const { Q_UNREACHABLE(); }
+ bool operator!=(const QWebEngineQuotaRequest &) const { Q_UNREACHABLE(); }
};
QT_END_NAMESPACE
+#endif // QT_DEPRECATED_SINCE(6, 5)
+
#endif // QWEBENGINEQUOTAREQUEST_H
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 716f53e73..162ae7daf 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -76,10 +76,10 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::RedirectNavigation
execution of this function is finished.
*/
-QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
- QWebEngineUrlRequestInfo::NavigationType navigation,
- const QUrl &u, const QUrl &fpu, const QUrl &i,
- const QByteArray &m)
+QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(
+ QWebEngineUrlRequestInfo::ResourceType resource,
+ QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu,
+ const QUrl &i, const QByteArray &m, const QHash<QByteArray, QByteArray> &h)
: resourceType(resource)
, navigationType(navigation)
, shouldBlockRequest(false)
@@ -89,6 +89,7 @@ QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRe
, initiator(i)
, method(m)
, changed(false)
+ , extraHeaders(h)
{}
/*!
@@ -285,7 +286,28 @@ void QWebEngineUrlRequestInfo::block(bool shouldBlock)
void QWebEngineUrlRequestInfo::setHttpHeader(const QByteArray &name, const QByteArray &value)
{
d_ptr->changed = true;
+
+ // Headers are case insentive, so we need to compare manually
+ for (auto it = d_ptr->extraHeaders.begin(); it != d_ptr->extraHeaders.end(); ++it) {
+ if (it.key().compare(name, Qt::CaseInsensitive) == 0) {
+ d_ptr->extraHeaders.erase(it);
+ break;
+ }
+ }
+
d_ptr->extraHeaders.insert(name, value);
}
+/*!
+ Returns the request headers.
+ \since 6.5
+ \note Not all headers are visible at this stage as Chromium will add
+ security and proxy headers at a later stage.
+*/
+
+QHash<QByteArray, QByteArray> QWebEngineUrlRequestInfo::httpHeaders() const
+{
+ return d_ptr->extraHeaders;
+}
+
QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
index 5d27bcb7a..3678b52f4 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -73,6 +73,7 @@ public:
void block(bool shouldBlock);
void redirect(const QUrl &url);
void setHttpHeader(const QByteArray &name, const QByteArray &value);
+ QHash<QByteArray, QByteArray> httpHeaders() const;
private:
friend class QtWebEngineCore::ContentBrowserClientQt;
diff --git a/src/core/api/qwebengineurlrequestinfo_p.h b/src/core/api/qwebengineurlrequestinfo_p.h
index ec9cdda69..08faf8323 100644
--- a/src/core/api/qwebengineurlrequestinfo_p.h
+++ b/src/core/api/qwebengineurlrequestinfo_p.h
@@ -34,8 +34,10 @@ class QWebEngineUrlRequestInfoPrivate
Q_DECLARE_PUBLIC(QWebEngineUrlRequestInfo)
public:
QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
- QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu,
- const QUrl &i, const QByteArray &m);
+ QWebEngineUrlRequestInfo::NavigationType navigation,
+ const QUrl &u, const QUrl &fpu, const QUrl &i,
+ const QByteArray &m,
+ const QHash<QByteArray, QByteArray> &h = {});
QWebEngineUrlRequestInfo::ResourceType resourceType;
QWebEngineUrlRequestInfo::NavigationType navigationType;
diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
index e78a206d6..e01ecef49 100644
--- a/src/core/api/qwebengineurlschemehandler.cpp
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -12,9 +12,23 @@ QT_BEGIN_NAMESPACE
\brief The QWebEngineUrlSchemeHandler class is a base class for handling custom URL schemes.
\since 5.6
+ A custom scheme handler is, broadly speaking, similar to a web application
+ served over HTTP. However, because custom schemes are integrated directly
+ into the web engine, they have the advantage in terms of efficiency and security:
+ There is no need for generating and parsing HTTP messages or for transferring data
+ over sockets, nor any way to intercept or monitor the traffic.
+
To implement a custom URL scheme for QtWebEngine, you first have to create an instance of
QWebEngineUrlScheme and register it using QWebEngineUrlScheme::registerScheme().
+ As custom schemes are integrated directly into the web engine, they do not
+ necessarily need to follow the standard security rules which apply to
+ ordinary web content. Depending on the chosen configuration, content served
+ over a custom scheme may be given access to local resources, be set to
+ ignore Content-Security-Policy rules, or conversely, be denied access to any
+ other content entirely. If it is to be accessed by normal content, ensure cross-origin
+ access is enabled, and if accessed from HTTPS that it is marked as secure.
+
\note Make sure that you create and register the scheme object \e before the QGuiApplication
or QApplication object is instantiated.
@@ -30,10 +44,23 @@ QT_BEGIN_NAMESPACE
{
public:
MySchemeHandler(QObject *parent = nullptr);
- void requestStarted(QWebEngineUrlRequestJob *request)
+ void requestStarted(QWebEngineUrlRequestJob *job)
{
- // ....
+ const QByteArray method = job->requestMethod();
+ const QUrl url = job->requestUrl();
+
+ if (isValidUrl(url)) {
+ if (method == QByteArrayLiteral("GET")) {
+ job->reply(QByteArrayLiteral("text/html"), makeReply(url));
+ else // Unsupported method
+ job->fail(QWebEngineUrlRequestJob::RequestDenied);
+ } else {
+ // Invalid URL
+ job->fail(QWebEngineUrlRequestJob::UrlNotFound);
+ }
}
+ bool isValidUrl(const QUrl &url) const // ....
+ QIODevice *makeReply(const QUrl &url) // ....
};
int main(int argc, char **argv)
@@ -56,7 +83,7 @@ QT_BEGIN_NAMESPACE
\inmodule QtWebEngineCore
- \sa {QWebEngineUrlScheme}, {WebEngine Widgets WebUI Example}
+ \sa {QWebEngineUrlScheme}
*/
/*!
diff --git a/src/core/authentication_dialog_controller.cpp b/src/core/authentication_dialog_controller.cpp
index 5ed38ecbd..4efd5dad3 100644
--- a/src/core/authentication_dialog_controller.cpp
+++ b/src/core/authentication_dialog_controller.cpp
@@ -4,7 +4,6 @@
#include "authentication_dialog_controller.h"
#include "authentication_dialog_controller_p.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browser_task_traits.h"
@@ -17,7 +16,7 @@ AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(bas
void AuthenticationDialogControllerPrivate::dialogFinished(bool accepted, const QString &user, const QString &password)
{
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&LoginDelegateQt::sendAuthToRequester,
loginDelegate, accepted, user, password));
}
diff --git a/src/core/autofill_client_qt.cpp b/src/core/autofill_client_qt.cpp
index fb3f726ae..aaf775d60 100644
--- a/src/core/autofill_client_qt.cpp
+++ b/src/core/autofill_client_qt.cpp
@@ -39,7 +39,7 @@ autofill::AutocompleteHistoryManager *AutofillClientQt::GetAutocompleteHistoryMa
PrefService *AutofillClientQt::GetPrefs()
{
- return const_cast<PrefService *>(base::as_const(*this).GetPrefs());
+ return const_cast<PrefService *>(std::as_const(*this).GetPrefs());
}
const PrefService *AutofillClientQt::GetPrefs() const
@@ -113,7 +113,7 @@ bool AutofillClientQt::IsPasswordManagerEnabled()
return false;
}
-void AutofillClientQt::PropagateAutofillPredictions(content::RenderFrameHost *,
+void AutofillClientQt::PropagateAutofillPredictions(autofill::AutofillDriver *,
const std::vector<autofill::FormStructure *> &)
{
// For testing purposes only.
diff --git a/src/core/autofill_client_qt.h b/src/core/autofill_client_qt.h
index 967c4b227..95ae460f2 100644
--- a/src/core/autofill_client_qt.h
+++ b/src/core/autofill_client_qt.h
@@ -54,7 +54,7 @@ public:
void HideAutofillPopup(autofill::PopupHidingReason reason) override;
bool IsAutocompleteEnabled() override;
bool IsPasswordManagerEnabled() override;
- void PropagateAutofillPredictions(content::RenderFrameHost *,
+ void PropagateAutofillPredictions(autofill::AutofillDriver *,
const std::vector<autofill::FormStructure *> &) override;
diff --git a/src/core/autofill_popup_controller.cpp b/src/core/autofill_popup_controller.cpp
index 260b1ca8a..6e5890e47 100644
--- a/src/core/autofill_popup_controller.cpp
+++ b/src/core/autofill_popup_controller.cpp
@@ -26,7 +26,7 @@ void AutofillPopupController::setCurrentIndex(const QModelIndex &index)
if (m_currentIndex.isValid()) {
const autofill::Suggestion &suggestion = d->suggestions[m_currentIndex.row()];
- d->delegate->DidSelectSuggestion(suggestion.value, suggestion.frontend_id, suggestion.backend_id);
+ d->delegate->DidSelectSuggestion(suggestion.main_text.value, suggestion.frontend_id, autofill::Suggestion::BackendId());
}
Q_EMIT currentIndexChanged(index);
@@ -79,8 +79,7 @@ void AutofillPopupController::acceptSuggestion()
const int index = m_currentIndex.row();
const autofill::Suggestion &suggestion = d->suggestions[index];
- d->delegate->DidAcceptSuggestion(suggestion.value, suggestion.frontend_id,
- suggestion.backend_id, index);
+ d->delegate->DidAcceptSuggestion(suggestion, index);
}
void AutofillPopupController::notifyPopupShown()
@@ -105,7 +104,7 @@ void AutofillPopupController::updateModel()
{
QStringList values;
for (size_t i = 0; i < d->suggestions.size(); ++i) {
- values.append(QString::fromStdU16String(d->suggestions[i].value));
+ values.append(QString::fromStdU16String(d->suggestions[i].main_text.value));
}
m_model.setStringList(values);
setCurrentIndex(QModelIndex());
diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp
index b5f978b89..49a193b05 100644
--- a/src/core/browser_accessibility_manager_qt.cpp
+++ b/src/core/browser_accessibility_manager_qt.cpp
@@ -1,30 +1,33 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qtwebenginecoreglobal.h"
+
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+
+#include <QtGui/qtguiglobal.h>
+
+#if QT_CONFIG(accessibility)
+#include "browser_accessibility_qt.h"
#include "browser_accessibility_manager_qt.h"
-#include "qtwebenginecoreglobal_p.h"
+#include "render_widget_host_view_qt.h" // WebContentsAccessibilityQt
#include "content/browser/accessibility/browser_accessibility.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-
#if QT_CONFIG(webengine_extensions)
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/web_contents.h"
#endif // QT_CONFIG(webengine_extensions)
-
-#include "browser_accessibility_qt.h"
-#include "render_widget_host_view_qt.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include <QtGui/qaccessible.h>
-
-using namespace blink;
+#endif // QT_CONFIG(accessibility)
namespace content {
// static
BrowserAccessibilityManager *BrowserAccessibilityManager::Create(
const ui::AXTreeUpdate &initialTree,
- BrowserAccessibilityDelegate *delegate)
+ WebAXPlatformTreeManagerDelegate *delegate)
{
#if QT_CONFIG(accessibility)
Q_ASSERT(delegate);
@@ -34,26 +37,26 @@ BrowserAccessibilityManager *BrowserAccessibilityManager::Create(
#if QT_CONFIG(webengine_extensions)
// Accessibility is not supported for guest views.
if (!access) {
- Q_ASSERT(content::WebContents::FromRenderFrameHost(
- static_cast<content::RenderFrameHostImpl *>(delegate))
- ->GetOuterWebContents());
return nullptr;
}
#endif // QT_CONFIG(webengine_extensions)
return new BrowserAccessibilityManagerQt(access, initialTree, delegate);
#else
+ Q_UNUSED(initialTree);
+ Q_UNUSED(delegate);
return nullptr;
#endif // QT_CONFIG(accessibility)
}
// static
BrowserAccessibilityManager *BrowserAccessibilityManager::Create(
- BrowserAccessibilityDelegate *delegate)
+ WebAXPlatformTreeManagerDelegate *delegate)
{
#if QT_CONFIG(accessibility)
return BrowserAccessibilityManager::Create(BrowserAccessibilityManagerQt::GetEmptyDocument(), delegate);
#else
+ Q_UNUSED(delegate);
return nullptr;
#endif
}
@@ -62,7 +65,7 @@ BrowserAccessibilityManager *BrowserAccessibilityManager::Create(
BrowserAccessibilityManagerQt::BrowserAccessibilityManagerQt(
QtWebEngineCore::WebContentsAccessibilityQt *webContentsAccessibility,
const ui::AXTreeUpdate &initialTree,
- BrowserAccessibilityDelegate* delegate)
+ WebAXPlatformTreeManagerDelegate* delegate)
: BrowserAccessibilityManager(delegate)
, m_webContentsAccessibility(webContentsAccessibility)
{
@@ -160,9 +163,13 @@ void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type,
}
void BrowserAccessibilityManagerQt::FireGeneratedEvent(ui::AXEventGenerator::Event event_type,
- BrowserAccessibility* node)
+ const ui::AXNode *node)
{
- auto *iface = toQAccessibleInterface(node);
+ BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
+
+ BrowserAccessibility *wrapper = GetFromAXNode(node);
+ DCHECK(wrapper);
+ auto *iface = toQAccessibleInterface(wrapper);
switch (event_type) {
case ui::AXEventGenerator::Event::VALUE_IN_TEXT_FIELD_CHANGED:
diff --git a/src/core/browser_accessibility_manager_qt.h b/src/core/browser_accessibility_manager_qt.h
index 6cd3c84de..2b1989d7c 100644
--- a/src/core/browser_accessibility_manager_qt.h
+++ b/src/core/browser_accessibility_manager_qt.h
@@ -6,10 +6,7 @@
#include "content/browser/accessibility/browser_accessibility_manager.h"
-#include <QtCore/qobject.h>
-#include <QtGui/qtgui-config.h>
-
-#if QT_CONFIG(accessibility)
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
QT_FORWARD_DECLARE_CLASS(QAccessibleInterface)
@@ -24,13 +21,13 @@ class BrowserAccessibilityManagerQt : public BrowserAccessibilityManager
public:
BrowserAccessibilityManagerQt(QtWebEngineCore::WebContentsAccessibilityQt *webContentsAccessibility,
const ui::AXTreeUpdate &initialTree,
- BrowserAccessibilityDelegate *delegate);
+ WebAXPlatformTreeManagerDelegate *delegate);
~BrowserAccessibilityManagerQt() override;
void FireBlinkEvent(ax::mojom::Event event_type,
BrowserAccessibility *node,
int action_request_id) override;
void FireGeneratedEvent(ui::AXEventGenerator::Event event_type,
- BrowserAccessibility* node) override;
+ const ui::AXNode *node) override;
QAccessibleInterface *rootParentAccessible();
bool isValid() const { return m_valid; }
@@ -43,5 +40,4 @@ private:
}
-#endif // QT_CONFIG(accessibility)
-#endif
+#endif // BROWSER_ACCESSIBILITY_MANAGER_QT_H
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index 35d5b49d4..d1cdd4b20 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -6,16 +6,13 @@
// found in the LICENSE.Chromium file.
#include "browser_accessibility_qt.h"
-
-#if QT_CONFIG(accessibility)
-
-#include "content/browser/accessibility/browser_accessibility.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-
#include "browser_accessibility_manager_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "type_conversion.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+
#include <QtGui/qaccessible.h>
namespace QtWebEngineCore {
@@ -129,6 +126,8 @@ public:
void modelChange(QAccessibleTableModelChangeEvent *event) override;
private:
+ content::BrowserAccessibility *findTable() const;
+
QObject *m_object = nullptr;
QAccessible::Id m_id = 0;
BrowserAccessibilityQt *q;
@@ -215,10 +214,14 @@ void *BrowserAccessibilityInterface::interface_cast(QAccessible::InterfaceType t
}
case QAccessible::TableCellInterface: {
QAccessible::Role r = role();
- if (r == QAccessible::Cell ||
- r == QAccessible::ListItem ||
- r == QAccessible::TreeItem)
- return static_cast<QAccessibleTableCellInterface*>(this);
+ if (r == QAccessible::Cell) {
+ Q_ASSERT(findTable());
+ return static_cast<QAccessibleTableCellInterface *>(this);
+ }
+ if (r == QAccessible::ListItem || r == QAccessible::TreeItem) {
+ if (findTable())
+ return static_cast<QAccessibleTableCellInterface *>(this);
+ }
break;
}
default:
@@ -263,7 +266,7 @@ int BrowserAccessibilityInterface::indexOfChild(const QAccessibleInterface *ifac
{
const BrowserAccessibilityInterface *child = static_cast<const BrowserAccessibilityInterface *>(iface);
- return const_cast<BrowserAccessibilityInterface *>(child)->q->GetIndexInParent();
+ return const_cast<BrowserAccessibilityInterface *>(child)->q->GetIndexInParent().value();
}
QString BrowserAccessibilityInterface::text(QAccessible::Text t) const
@@ -357,6 +360,8 @@ QAccessible::Role BrowserAccessibilityInterface::role() const
case ax::mojom::Role::kComboBoxMenuButton:
case ax::mojom::Role::kTextFieldWithComboBox:
return QAccessible::ComboBox;
+ case ax::mojom::Role::kComboBoxSelect:
+ return QAccessible::PopupMenu;
case ax::mojom::Role::kComplementary:
return QAccessible::ComplementaryContent;
case ax::mojom::Role::kComment:
@@ -800,7 +805,8 @@ void BrowserAccessibilityInterface::doAction(const QString &actionName)
q->manager()->SetFocus(*q);
}
-QStringList BrowserAccessibilityInterface::keyBindingsForAction(const QString &actionName) const
+QStringList
+BrowserAccessibilityInterface::keyBindingsForAction(const QString & /*actionName*/) const
{
QT_NOT_YET_IMPLEMENTED
return QStringList();
@@ -1102,14 +1108,20 @@ bool BrowserAccessibilityInterface::isSelected() const
return false;
}
+content::BrowserAccessibility *BrowserAccessibilityInterface::findTable() const
+{
+ content::BrowserAccessibility *parent = q->PlatformGetParent();
+ while (parent && parent->GetRole() != ax::mojom::Role::kTable)
+ parent = parent->PlatformGetParent();
+
+ return parent;
+}
+
QAccessibleInterface *BrowserAccessibilityInterface::table() const
{
- content::BrowserAccessibility *find_table = q->PlatformGetParent();
- while (find_table && find_table->GetRole() != ax::mojom::Role::kTable)
- find_table = find_table->PlatformGetParent();
- if (!find_table)
- return nullptr;
- return content::toQAccessibleInterface(find_table);
+ content::BrowserAccessibility *table = findTable();
+ Q_ASSERT(table);
+ return content::toQAccessibleInterface(table);
}
void BrowserAccessibilityInterface::modelChange(QAccessibleTableModelChangeEvent *)
@@ -1137,6 +1149,3 @@ const QAccessibleInterface *toQAccessibleInterface(const BrowserAccessibility *o
}
} // namespace content
-
-
-#endif // QT_CONFIG(accessibility)
diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h
index 478ce0f62..b61338ce3 100644
--- a/src/core/browser_accessibility_qt.h
+++ b/src/core/browser_accessibility_qt.h
@@ -4,9 +4,8 @@
#ifndef BROWSER_ACCESSIBILITY_QT_H
#define BROWSER_ACCESSIBILITY_QT_H
-#include <QtGui/qtguiglobal.h>
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
-#if QT_CONFIG(accessibility)
QT_FORWARD_DECLARE_CLASS(QAccessibleInterface)
namespace content {
@@ -17,6 +16,4 @@ const QAccessibleInterface *toQAccessibleInterface(const BrowserAccessibility *o
} // namespace content
-#endif // QT_CONFIG(accessibility)
-
#endif // BROWSER_ACCESSIBILITY_QT_H
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index 62ad4f635..e58822c29 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -31,6 +31,7 @@
#include "select_file_dialog_factory_qt.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h"
+#include "type_conversion.h"
#include "ui/display/screen.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -50,6 +51,7 @@
#include "web_usb_detector_qt.h"
#include <QtGui/qtgui-config.h>
+#include <QStandardPaths>
#if QT_CONFIG(opengl)
#include "ui/gl/gl_context.h"
@@ -68,6 +70,10 @@
#include "desktop_screen_qt.h"
#endif
+#if defined(Q_OS_LINUX)
+#include "components/os_crypt/key_storage_config_linux.h"
+#include "components/os_crypt/os_crypt.h"
+#endif
namespace QtWebEngineCore {
@@ -252,6 +258,15 @@ void BrowserMainPartsQt::PostCreateMainMessageLoop()
{
if (!device_event_log::IsInitialized())
device_event_log::Initialize(0 /* default max entries */);
+
+#if defined(Q_OS_LINUX)
+ std::unique_ptr<os_crypt::Config> config = std::make_unique<os_crypt::Config>();
+ config->product_name = "Qt WebEngine";
+ config->main_thread_runner = content::GetUIThreadTaskRunner({});
+ config->should_use_preference = false;
+ config->user_data_path = toFilePath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
+ OSCrypt::SetConfig(std::move(config));
+#endif
}
int BrowserMainPartsQt::PreMainMessageLoopRun()
diff --git a/src/core/browsing_data_remover_delegate_qt.h b/src/core/browsing_data_remover_delegate_qt.h
index 4e690ffb1..a611a710c 100644
--- a/src/core/browsing_data_remover_delegate_qt.h
+++ b/src/core/browsing_data_remover_delegate_qt.h
@@ -4,6 +4,8 @@
#ifndef BROWSING_DATA_REMOVER_DELEGATE_QT_H
#define BROWSING_DATA_REMOVER_DELEGATE_QT_H
+#include <cstdint>
+
#include "content/public/browser/browsing_data_remover_delegate.h"
namespace QtWebEngineCore {
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 3830c8683..b75e5a5e6 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -9,10 +9,12 @@
#include "base/values.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/font_list.h"
-#include "gpu/vulkan/buildflags.h"
+#include "content/public/browser/web_contents_view_delegate.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/constants.h"
+#include "gpu/vulkan/buildflags.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
@@ -20,43 +22,36 @@
#include <QFontDatabase>
#include <QLibraryInfo>
-#if BUILDFLAG(ENABLE_VULKAN)
-#include "gpu/vulkan/init/vulkan_factory.h"
-#endif
-
#if !QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
#include "chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h"
#endif
+#if BUILDFLAG(ENABLE_VULKAN)
+#include "compositor/vulkan_implementation_qt.h"
+
+#include "gpu/vulkan/init/vulkan_factory.h"
+
+#if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/surface_factory_ozone.h"
+#endif // defined(USE_OZONE)
+#endif // defined(ENABLE_VULKAN)
+
void *GetQtXDisplay()
{
return GLContextHelper::getXDisplay();
}
-#if BUILDFLAG(ENABLE_VULKAN)
-namespace gpu {
-std::unique_ptr<VulkanImplementation> CreateVulkanImplementation(bool use_swiftshader,
- bool allow_protected_memory)
-{
- NOTIMPLEMENTED();
- return nullptr;
-}
-} // namespace gpu
-
-#endif
-
namespace content {
-class WebContentsView;
-class WebContentsViewDelegate;
class RenderViewHostDelegateView;
-WebContentsView* CreateWebContentsView(WebContentsImpl *web_contents,
- WebContentsViewDelegate *,
+std::unique_ptr<WebContentsView> CreateWebContentsView(WebContentsImpl *web_contents,
+ std::unique_ptr<WebContentsViewDelegate> delegate,
RenderViewHostDelegateView **render_view_host_delegate_view)
{
QtWebEngineCore::WebContentsViewQt* rv = new QtWebEngineCore::WebContentsViewQt(web_contents);
*render_view_host_delegate_view = rv;
- return rv;
+ return std::unique_ptr<WebContentsView>(rv);
}
#if defined(Q_OS_DARWIN)
@@ -79,36 +74,58 @@ base::FilePath getSandboxPath()
namespace content {
// content/common/font_list.h
-std::unique_ptr<base::ListValue> GetFontList_SlowBlocking()
+base::Value::List GetFontList_SlowBlocking()
{
- std::unique_ptr<base::ListValue> font_list(new base::ListValue);
+ base::Value::List font_list;
for (auto family : QFontDatabase::families()){
- std::unique_ptr<base::ListValue> font_item(new base::ListValue());
- font_item->Append(family.toStdString());
- font_item->Append(family.toStdString()); // localized name.
+ base::Value::List font_item;
+ font_item.Append(family.toStdString());
+ font_item.Append(family.toStdString()); // localized name.
// TODO(yusukes): Support localized family names.
- font_list->Append(std::move(font_item));
+ font_list.Append(std::move(font_item));
}
return font_list;
}
} // namespace content
+#endif // defined(USE_AURA) || defined(USE_OZONE)
-namespace aura {
-class Window;
-}
+#if BUILDFLAG(ENABLE_VULKAN)
+namespace gpu {
+std::unique_ptr<VulkanImplementation> CreateVulkanImplementation(bool use_swiftshader,
+ bool allow_protected_memory)
+{
+#if QT_CONFIG(webengine_vulkan)
+#if BUILDFLAG(IS_APPLE)
+ // TODO: Investigate if we can support MoltenVK.
+ NOTIMPLEMENTED();
+ return nullptr;
+#else
+#if defined(USE_OZONE)
+ return ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone()->CreateVulkanImplementation(
+ use_swiftshader, allow_protected_memory);
+#endif
-namespace wm {
-class ActivationClient;
+#if !BUILDFLAG(IS_WIN)
+ // TODO(samans): Support Swiftshader on more platforms.
+ // https://crbug.com/963988
+ DCHECK(!use_swiftshader) << "Vulkan Swiftshader is not supported on this platform.";
+#endif // !BUILDFLAG(IS_WIN)
-ActivationClient *GetActivationClient(aura::Window *)
-{
+ // Protected memory is supported only on Fuchsia, which uses Ozone, i.e.
+ // VulkanImplementation is initialized above.
+ DCHECK(!allow_protected_memory) << "Protected memory is not supported on this platform.";
+
+ return std::make_unique<VulkanImplementationQt>();
+#endif // BUILDFLAG(IS_APPLE)
+#else
+ NOTREACHED();
return nullptr;
+#endif // QT_CONFIG(webengine_vulkan)
}
-
-} // namespace wm
-#endif // defined(USE_AURA) || defined(USE_OZONE)
+} // namespace gpu
+#endif // BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<ui::OSExchangeDataProvider> ui::OSExchangeDataProviderFactory::CreateProvider()
{
diff --git a/src/core/client_hints.cpp b/src/core/client_hints.cpp
new file mode 100644
index 000000000..2a30bb51b
--- /dev/null
+++ b/src/core/client_hints.cpp
@@ -0,0 +1,173 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "client_hints.h"
+
+#include "web_contents_delegate_qt.h"
+#include "web_engine_settings.h"
+
+#include "components/embedder_support/user_agent_utils.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/network_service_instance.h"
+#include "extensions/buildflags/buildflags.h"
+#include "services/network/public/cpp/is_potentially_trustworthy.h"
+#include "services/network/public/cpp/network_quality_tracker.h"
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "components/guest_view/browser/guest_view_base.h"
+#endif
+
+namespace QtWebEngineCore {
+
+// based on weblayer/browser/client_hints_factory.cc:
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// static
+ClientHints *ClientHintsFactory::GetForBrowserContext(content::BrowserContext *browser_context)
+{
+ return static_cast<ClientHints*>(GetInstance()->GetServiceForBrowserContext(browser_context, true));
+}
+
+// static
+ClientHintsFactory *ClientHintsFactory::GetInstance()
+{
+ static base::NoDestructor<ClientHintsFactory> factory;
+ return factory.get();
+}
+
+ClientHintsFactory::ClientHintsFactory()
+ : BrowserContextKeyedServiceFactory("ClientHints", BrowserContextDependencyManager::GetInstance())
+{
+}
+
+ClientHintsFactory::~ClientHintsFactory() = default;
+
+KeyedService *ClientHintsFactory::BuildServiceInstanceFor(content::BrowserContext *context) const
+{
+ return new ClientHints(context);
+}
+
+content::BrowserContext *ClientHintsFactory::GetBrowserContextToUse(content::BrowserContext *context) const
+{
+ return context;
+}
+
+// based on components/client_hints/browser/in_memory_client_hints_controller_delegate.cc:
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+ClientHints::ClientHints(content::BrowserContext *context)
+{
+}
+
+ClientHints::~ClientHints() = default;
+
+// Enabled Client Hints are only cached and not persisted in this
+// implementation.
+void ClientHints::PersistClientHints(const url::Origin &primary_origin,
+ content::RenderFrameHost *parent_rfh,
+ const std::vector<network::mojom::WebClientHintsType> &client_hints)
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ const GURL primary_url = primary_origin.GetURL();
+ DCHECK(primary_url.is_valid());
+ if (!network::IsUrlPotentiallyTrustworthy(primary_url))
+ return;
+
+ // Client hints should only be enabled when JavaScript is enabled.
+ if (!IsJavaScriptAllowed(primary_url, parent_rfh))
+ return;
+
+ blink::EnabledClientHints enabled_hints;
+ for (auto hint : client_hints) {
+ enabled_hints.SetIsEnabled(hint, true);
+ }
+ accept_ch_cache_[primary_origin] = enabled_hints;
+}
+
+// Looks up enabled Client Hints for the URL origin, and adds additional Client
+// Hints if set.
+void ClientHints::GetAllowedClientHintsFromSource(const url::Origin &origin,
+ blink::EnabledClientHints *client_hints)
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(client_hints);
+ // Can not assert this, as we get here for unregistered custom schemes:
+ if (!network::IsOriginPotentiallyTrustworthy(origin))
+ return;
+
+ const auto &it = accept_ch_cache_.find(origin);
+ if (it != accept_ch_cache_.end()) {
+ *client_hints = it->second;
+ }
+
+ for (auto hint : additional_hints_)
+ client_hints->SetIsEnabled(hint, true);
+}
+
+void ClientHints::SetAdditionalClientHints(const std::vector<network::mojom::WebClientHintsType> &hints)
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ additional_hints_ = hints;
+}
+
+void ClientHints::ClearAdditionalClientHints()
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ additional_hints_.clear();
+}
+
+network::NetworkQualityTracker *ClientHints::GetNetworkQualityTracker()
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!network_quality_tracker_) {
+ network_quality_tracker_ =
+ std::make_unique<network::NetworkQualityTracker>(
+ base::BindRepeating(&content::GetNetworkService));
+ }
+ return network_quality_tracker_.get();
+}
+
+bool ClientHints::IsJavaScriptAllowed(const GURL &url, content::RenderFrameHost *parent_rfh)
+{
+ content::WebContents *webContents = content::WebContents::FromRenderFrameHost(parent_rfh);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (webContents && guest_view::GuestViewBase::IsGuest(webContents))
+ webContents = guest_view::GuestViewBase::GetTopLevelWebContents(webContents);
+#endif
+
+ if (webContents) {
+ WebContentsDelegateQt* delegate =
+ static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+ if (delegate) {
+ WebEngineSettings *settings = delegate->webEngineSettings();
+ if (settings)
+ return settings->testAttribute(QWebEngineSettings::JavascriptEnabled);
+ }
+ }
+ return true;
+}
+
+bool ClientHints::AreThirdPartyCookiesBlocked(const GURL &url)
+{
+ return false; // we probably can not report anything more specific
+}
+
+blink::UserAgentMetadata ClientHints::GetUserAgentMetadata()
+{
+ return embedder_support::GetUserAgentMetadata();
+}
+
+void ClientHints::SetMostRecentMainFrameViewportSize(
+ const gfx::Size& viewport_size) {
+ viewport_size_ = viewport_size;
+}
+
+gfx::Size
+ClientHints::GetMostRecentMainFrameViewportSize() {
+ return viewport_size_;
+}
+} // namespace
diff --git a/src/core/client_hints.h b/src/core/client_hints.h
new file mode 100644
index 000000000..a80629fc9
--- /dev/null
+++ b/src/core/client_hints.h
@@ -0,0 +1,102 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef CLIENT_HINTS_H_
+#define CLIENT_HINTS_H_
+
+// based on components/client_hints/browser/client_hints.h:
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/raw_ptr.h"
+#include "base/no_destructor.h"
+#include "base/sequence_checker.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/client_hints_controller_delegate.h"
+#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
+
+namespace QtWebEngineCore {
+
+class ClientHints;
+
+class ClientHintsFactory : public BrowserContextKeyedServiceFactory
+{
+public:
+ ClientHintsFactory(const ClientHintsFactory &) = delete;
+ ClientHintsFactory &operator=(const ClientHintsFactory &) = delete;
+
+ static ClientHints *GetForBrowserContext(content::BrowserContext *browser_context);
+ static ClientHintsFactory *GetInstance();
+
+private:
+ friend class base::NoDestructor<ClientHintsFactory>;
+
+ ClientHintsFactory();
+ ~ClientHintsFactory() override;
+
+ // BrowserContextKeyedServiceFactory methods:
+ KeyedService *BuildServiceInstanceFor(content::BrowserContext *profile) const override;
+ content::BrowserContext *GetBrowserContextToUse(content::BrowserContext *context) const override;
+};
+
+class ClientHints : public KeyedService, public content::ClientHintsControllerDelegate
+{
+public:
+ ClientHints(content::BrowserContext *context);
+
+ ClientHints(const ClientHints &) = delete;
+ ClientHints &operator=(const ClientHints &) = delete;
+
+ ~ClientHints() override;
+
+ // content::ClientHintsControllerDelegate:
+ network::NetworkQualityTracker *GetNetworkQualityTracker() override;
+
+ void GetAllowedClientHintsFromSource(const url::Origin &origin, blink::EnabledClientHints *client_hints) override;
+
+ bool IsJavaScriptAllowed(const GURL &url, content::RenderFrameHost *parent_rfh) override;
+
+ bool AreThirdPartyCookiesBlocked(const GURL &url) override;
+
+ blink::UserAgentMetadata GetUserAgentMetadata() override;
+
+ void PersistClientHints(const url::Origin &primary_origin,
+ content::RenderFrameHost *parent_rfh,
+ const std::vector<network::mojom::WebClientHintsType> &client_hints) override;
+
+ void SetAdditionalClientHints(const std::vector<network::mojom::WebClientHintsType> &) override;
+
+ void ClearAdditionalClientHints() override;
+
+ void SetMostRecentMainFrameViewportSize(const gfx::Size&) override;
+ gfx::Size GetMostRecentMainFrameViewportSize() override;
+
+private:
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ raw_ptr<content::BrowserContext> context_ = nullptr;
+
+ // Stores enabled Client Hint types for an origin.
+ std::map<url::Origin, blink::EnabledClientHints> accept_ch_cache_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ // Additional Client Hint types for Client Hints Reliability. If additional
+ // hints are set, they would be included by subsequent calls to
+ // GetAllowedClientHintsFromSource.
+ std::vector<network::mojom::WebClientHintsType> additional_hints_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ // This stores the viewport size of the most recent visible main frame tree
+ // node. This value is only used when the viewport size cannot be directly
+ // queried such as for prefetch requests and for tab restores.
+ gfx::Size viewport_size_;
+};
+
+} // namespace QtWebEngineCore
+
+#endif
diff --git a/src/core/common/extensions/extensions_client_qt.cpp b/src/core/common/extensions/extensions_client_qt.cpp
index 30d1836ca..9240e6528 100644
--- a/src/core/common/extensions/extensions_client_qt.cpp
+++ b/src/core/common/extensions/extensions_client_qt.cpp
@@ -122,6 +122,12 @@ bool ExtensionsClientQt::IsBlocklistUpdateURL(const GURL &url) const
return true;
}
+const GURL &ExtensionsClientQt::GetNewWebstoreBaseURL() const
+{
+ static GURL dummy;
+ return dummy;
+}
+
// Returns the set of file paths corresponding to any images within an
// extension's contents that may be displayed directly within the browser UI
// or WebUI, such as icons or theme images. This set of paths is used by the
diff --git a/src/core/common/extensions/extensions_client_qt.h b/src/core/common/extensions/extensions_client_qt.h
index b0069db22..b2d128bf9 100644
--- a/src/core/common/extensions/extensions_client_qt.h
+++ b/src/core/common/extensions/extensions_client_qt.h
@@ -74,6 +74,8 @@ public:
// extension blacklist URL.
bool IsBlocklistUpdateURL(const GURL &url) const override;
+ const GURL &GetNewWebstoreBaseURL() const override;
+
// Returns the set of file paths corresponding to any images within an
// extension's contents that may be displayed directly within the browser UI
// or WebUI, such as icons or theme images. This set of paths is used by the
diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
index ada039afc..c147f988b 100644
--- a/src/core/compositor/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -9,6 +9,7 @@
#include <QHash>
#include <QImage>
#include <QMutex>
+#include <QQuickWindow>
namespace QtWebEngineCore {
@@ -136,22 +137,32 @@ Compositor::Handle<Compositor::Observer> Compositor::observer()
return nullptr;
}
-QImage Compositor::image()
+void Compositor::waitForTexture()
+{
+}
+
+void Compositor::releaseTexture()
+{
+}
+
+QSGTexture *Compositor::texture(QQuickWindow *, uint32_t textureOptions)
{
Q_UNREACHABLE();
- return {};
+ return nullptr;
}
-void Compositor::waitForTexture()
+bool Compositor::textureIsFlipped()
{
Q_UNREACHABLE();
+ return false;
}
-int Compositor::textureId()
+#if QT_CONFIG(webengine_vulkan)
+void Compositor::releaseVulkanResources(QQuickWindow *)
{
Q_UNREACHABLE();
- return 0;
}
+#endif
// static
void Compositor::unlockBindings()
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
index 9cadab4d4..018d965ba 100644
--- a/src/core/compositor/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -4,11 +4,13 @@
#ifndef COMPOSITOR_H
#define COMPOSITOR_H
+#include <QtGui/qtguiglobal.h>
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
QT_BEGIN_NAMESPACE
-class QImage;
+class QQuickWindow;
class QSize;
+class QSGTexture;
QT_END_NAMESPACE
namespace viz {
@@ -19,9 +21,8 @@ namespace QtWebEngineCore {
// Produces composited frames for display.
//
-// Used by quick/widgets libraries for accessing the frame and
-// controlling frame swapping. Must be cast to a subclass to access
-// the frame as QImage or OpenGL texture, etc.
+// Used by quick/widgets libraries for accessing the frames and
+// controlling frame swapping.
class Q_WEBENGINECORE_PRIVATE_EXPORT Compositor
{
struct Binding;
@@ -31,6 +32,8 @@ public:
enum class Type {
Software,
OpenGL,
+ Vulkan,
+ NativeBuffer
};
// Identifies a compositor.
@@ -117,27 +120,24 @@ public:
virtual QSize size() = 0;
// Whether frame needs an alpha channel.
- //
- // In software mode, the image format can be either
- // QImage::Format_ARGB32_Premultiplied or
- // QImage::Format_RGBA8888_Premultiplied
- //
- // In OpenGL mode, the texture format is either GL_RGBA or GL_RGB.
- virtual bool hasAlphaChannel() = 0;
-
- // (Software) QImage of the frame.
- //
- // This is a big image so we should try not to make copies of it.
- // In particular, the client should drop its QImage reference
- // before calling swapFrame(), otherwise each swap will cause a
- // detach.
- virtual QImage image();
+ virtual bool requiresAlphaChannel() = 0;
- // (OpenGL) Wait on texture fence in Qt's current OpenGL context.
+ // Wait on texture to be ready aka. sync.
virtual void waitForTexture();
- // (OpenGL) Texture of the frame.
- virtual int textureId();
+ // Release any held texture resources
+ virtual void releaseTexture();
+
+ // QSGTexture of the frame.
+ virtual QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions);
+
+ // Is the texture produced upside down?
+ virtual bool textureIsFlipped();
+
+#if QT_CONFIG(webengine_vulkan)
+ // (Vulkan) Release Vulkan resources created by Qt's Vulkan instance.
+ virtual void releaseVulkanResources(QQuickWindow *win);
+#endif
protected:
Compositor(Type type) : m_type(type) { }
diff --git a/src/core/compositor/content_gpu_client_qt.cpp b/src/core/compositor/content_gpu_client_qt.cpp
index 9f3b00bb8..d12074d2e 100644
--- a/src/core/compositor/content_gpu_client_qt.cpp
+++ b/src/core/compositor/content_gpu_client_qt.cpp
@@ -15,11 +15,6 @@ ContentGpuClientQt::~ContentGpuClientQt()
{
}
-gpu::SyncPointManager *ContentGpuClientQt::GetSyncPointManager()
-{
- return WebEngineContext::syncPointManager();
-}
-
gl::GLShareGroup *ContentGpuClientQt::GetInProcessGpuShareGroup()
{
if (!m_shareGroupQt.get())
diff --git a/src/core/compositor/content_gpu_client_qt.h b/src/core/compositor/content_gpu_client_qt.h
index 150c257ae..33314e0bb 100644
--- a/src/core/compositor/content_gpu_client_qt.h
+++ b/src/core/compositor/content_gpu_client_qt.h
@@ -18,7 +18,6 @@ public:
~ContentGpuClientQt() override;
// content::ContentGpuClient implementation.
- gpu::SyncPointManager *GetSyncPointManager() override;
gl::GLShareGroup *GetInProcessGpuShareGroup() override;
private:
diff --git a/src/core/compositor/display_gl_output_surface.cpp b/src/core/compositor/display_gl_output_surface.cpp
deleted file mode 100644
index a13dc2f35..000000000
--- a/src/core/compositor/display_gl_output_surface.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "display_gl_output_surface.h"
-
-#include "type_conversion.h"
-
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/viz/service/display/display.h"
-#include "components/viz/service/display/output_surface_frame.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/texture_base.h"
-#include "gpu/ipc/in_process_command_buffer.h"
-#include "ui/gfx/buffer_format_util.h"
-
-namespace QtWebEngineCore {
-
-DisplayGLOutputSurface::DisplayGLOutputSurface(
- scoped_refptr<viz::VizProcessContextProvider> contextProvider)
- : OutputSurface(contextProvider)
- , Compositor(Compositor::Type::OpenGL)
- , m_commandBuffer(contextProvider->command_buffer())
- , m_gl(contextProvider->ContextGL())
- , m_vizContextProvider(contextProvider)
-{
- capabilities_.uses_default_gl_framebuffer = false;
- m_gl->GenFramebuffers(1, &m_fboId);
-}
-
-DisplayGLOutputSurface::~DisplayGLOutputSurface()
-{
- m_vizContextProvider->SetUpdateVSyncParametersCallback(viz::UpdateVSyncParametersCallback());
- m_gl->DeleteFramebuffers(1, &m_fboId);
-}
-
-// Called from viz::Display::Initialize.
-void DisplayGLOutputSurface::BindToClient(viz::OutputSurfaceClient *client)
-{
- m_client = client;
-}
-
-void DisplayGLOutputSurface::SetFrameSinkId(const viz::FrameSinkId &id)
-{
- bind(id);
-}
-
-// Triggered by ui::Compositor::SetVisible(true).
-void DisplayGLOutputSurface::EnsureBackbuffer()
-{
-}
-
-// Triggered by ui::Compositor::SetVisible(false). Framebuffer must be cleared.
-void DisplayGLOutputSurface::DiscardBackbuffer()
-{
- NOTIMPLEMENTED();
- // m_gl->DiscardBackbufferCHROMIUM();
-}
-
-// Called from viz::DirectRenderer::DrawFrame before rendering starts, but only
-// if the parameters differ from the previous Reshape call.
-//
-// Parameters:
-//
-// - sizeInPixels comes from ui::Compositor::SetScaleAndSize via
-// viz::HostContextFactoryPrivate::ResizeDisplay.
-//
-// - devicePixelRatio comes from viz::CompositorFrame::device_scale_factor()
-// via viz::RootCompositorFrameSinkImpl::SubmitCompositorFrame and
-// viz::Display::SetLocalSurfaceId.
-//
-// - colorSpace and hasAlpha correspond to the color_space and
-// has_transparent_background properties of the root viz::RenderPass.
-//
-// - useStencil should create a stencil buffer, but this is only needed for
-// overdraw feedback (--show-overdraw-feedback), so it's safe to ignore.
-// Accordingly, capabilities_.supports_stencil should be set to false.
-//
-void DisplayGLOutputSurface::Reshape(const gfx::Size &sizeInPixels,
- float devicePixelRatio,
- const gfx::ColorSpace &colorSpace,
- gfx::BufferFormat format,
- bool /*useStencil*/)
-{
- bool hasAlpha = gfx::AlphaBitsForBufferFormat(format) > 0;
- m_currentShape = Shape{sizeInPixels, devicePixelRatio, colorSpace, hasAlpha};
- m_gl->ResizeCHROMIUM(sizeInPixels.width(), sizeInPixels.height(), devicePixelRatio,
- colorSpace.AsGLColorSpace(), hasAlpha);
-}
-
-std::unique_ptr<DisplayGLOutputSurface::Buffer> DisplayGLOutputSurface::makeBuffer(const Shape &shape)
-{
- std::unique_ptr<Buffer> buffer = std::make_unique<Buffer>(this);
- buffer->shape = shape;
- m_gl->GenTextures(1, &buffer->clientId);
- m_gl->BindTexture(GL_TEXTURE_2D, buffer->clientId);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- uint32_t width = shape.sizeInPixels.width();
- uint32_t height = shape.sizeInPixels.height();
- uint32_t format = shape.hasAlpha ? GL_RGBA : GL_RGB;
- m_gl->TexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
- return buffer;
-}
-
-void DisplayGLOutputSurface::deleteBufferResources(Buffer *buffer)
-{
- m_gl->DeleteTextures(1, &buffer->clientId);
-}
-
-// Called by viz::GLRenderer during rendering whenever it switches to the root
-// render pass.
-void DisplayGLOutputSurface::BindFramebuffer()
-{
- if (!m_backBuffer || m_backBuffer->shape != m_currentShape)
- m_backBuffer = makeBuffer(m_currentShape);
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
- m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_backBuffer->clientId, 0);
-}
-
-// Called from viz::Display::DrawAndSwap after rendering.
-//
-// Parameters:
-//
-// - frame.size is the same as the size given to Reshape.
-//
-// - frame.sub_buffer_rect and frame.content_bounds are never used since these
-// are only enabled if gl::GLSurface::SupportsPostSubBuffer() or
-// gl::GLSurface::SupportsSwapBuffersWithBounds() are true, respectively,
-// but this not the case for any offscreen gl::GLSurface.
-//
-// - frame.latency_info is viz::CompositorFrame::metadata.latency_info.
-void DisplayGLOutputSurface::SwapBuffers(viz::OutputSurfaceFrame frame)
-{
- DCHECK(frame.size == m_currentShape.sizeInPixels);
- DCHECK(!frame.sub_buffer_rect.has_value());
- DCHECK(frame.content_bounds.empty());
- DCHECK(m_backBuffer);
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
- m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
- gpu::SyncToken syncToken;
- m_gl->GenSyncTokenCHROMIUM(syncToken.GetData());
-
- unsigned int clientId = m_backBuffer->clientId;
-
- // Now some thread-hopping:
- //
- // - We start here on the viz thread (client side of command buffer).
- //
- // - Then we'll jump to the gpu thread (service side of command buffer) to
- // get the real OpenGL texture id.
- //
- // - Then we'll get a call from the Qt Quick Scene Graph thread (could be
- // a separate thread or the main thread).
- //
- // - Finally we'll return to the viz thread to acknowledge the swap.
-
- {
- QMutexLocker locker(&m_mutex);
- m_taskRunner = base::ThreadTaskRunnerHandle::Get();
- m_middleBuffer = std::move(m_backBuffer);
- m_middleBuffer->serviceId = 0;
- }
-
- m_commandBuffer->GetTextureQt(
- clientId,
- base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnGpuThread, base::Unretained(this)),
- std::vector<gpu::SyncToken>{syncToken});
-}
-
-void DisplayGLOutputSurface::swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence)
-{
- {
- QMutexLocker locker(&m_mutex);
- m_middleBuffer->serviceId = id;
- m_middleBuffer->fence = CompositorResourceFence::create(std::move(fence));
- m_readyToUpdate = true;
- }
-
- if (auto obs = observer())
- obs->readyToSwap();
-}
-
-void DisplayGLOutputSurface::swapBuffersOnVizThread()
-{
- {
- QMutexLocker locker(&m_mutex);
- m_backBuffer = std::move(m_middleBuffer);
- }
-
- const auto now = base::TimeTicks::Now();
- m_client->DidReceiveSwapBuffersAck(gfx::SwapTimings{now, now, {}, {}, {}}, gfx::GpuFenceHandle());
- m_client->DidReceivePresentationFeedback(
- gfx::PresentationFeedback(now, base::TimeDelta(),
- gfx::PresentationFeedback::Flags::kVSync));
-}
-
-void DisplayGLOutputSurface::SetDrawRectangle(const gfx::Rect &)
-{
-}
-
-// Returning true here will cause viz::GLRenderer to try to render the output
-// surface as an overlay plane (see viz::DirectRenderer::DrawFrame and
-// viz::GLRenderer::ScheduleOverlays).
-bool DisplayGLOutputSurface::IsDisplayedAsOverlayPlane() const
-{
- return false;
-}
-
-// Only used if IsDisplayedAsOverlayPlane was true (called from
-// viz::GLRenderer::ScheduleOverlays).
-unsigned DisplayGLOutputSurface::GetOverlayTextureId() const
-{
- return 0;
-}
-
-// Called by viz::GLRenderer but always false in all implementations except for
-// android_webview::ParentOutputSurface.
-bool DisplayGLOutputSurface::HasExternalStencilTest() const
-{
- return false;
-}
-
-// Only called if HasExternalStencilTest was true. Dead code?
-void DisplayGLOutputSurface::ApplyExternalStencil()
-{
- NOTREACHED();
-}
-
-// Called from GLRenderer::GetFramebufferCopyTextureFormat when using
-// glCopyTexSubImage2D on our framebuffer.
-uint32_t DisplayGLOutputSurface::GetFramebufferCopyTextureFormat()
-{
- return m_currentShape.hasAlpha ? GL_RGBA : GL_RGB;
-}
-
-// Called from viz::DirectRenderer::DrawFrame, only used for overlays.
-unsigned DisplayGLOutputSurface::UpdateGpuFence()
-{
- NOTREACHED();
- return 0;
-}
-
-void DisplayGLOutputSurface::SetUpdateVSyncParametersCallback(viz::UpdateVSyncParametersCallback callback)
-{
- m_vizContextProvider->SetUpdateVSyncParametersCallback(std::move(callback));
-}
-
-void DisplayGLOutputSurface::SetDisplayTransformHint(gfx::OverlayTransform)
-{
-}
-
-gfx::OverlayTransform DisplayGLOutputSurface::GetDisplayTransform()
-{
- return gfx::OVERLAY_TRANSFORM_NONE;
-}
-
-void DisplayGLOutputSurface::swapFrame()
-{
- QMutexLocker locker(&m_mutex);
- if (m_readyToUpdate) {
- std::swap(m_middleBuffer, m_frontBuffer);
- m_taskRunner->PostTask(FROM_HERE,
- base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnVizThread,
- base::Unretained(this)));
- m_taskRunner.reset();
- m_readyToUpdate = false;
- }
-}
-
-void DisplayGLOutputSurface::waitForTexture()
-{
- if (m_frontBuffer && m_frontBuffer->fence) {
- m_frontBuffer->fence->wait();
- m_frontBuffer->fence.reset();
- }
-}
-
-int DisplayGLOutputSurface::textureId()
-{
- return m_frontBuffer ? m_frontBuffer->serviceId : 0;
-}
-
-QSize DisplayGLOutputSurface::size()
-{
- return m_frontBuffer ? toQt(m_frontBuffer->shape.sizeInPixels) : QSize();
-}
-
-bool DisplayGLOutputSurface::hasAlphaChannel()
-{
- return m_frontBuffer ? m_frontBuffer->shape.hasAlpha : false;
-}
-
-float DisplayGLOutputSurface::devicePixelRatio()
-{
- return m_frontBuffer ? m_frontBuffer->shape.devicePixelRatio : 1;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_gl_output_surface.h b/src/core/compositor/display_gl_output_surface.h
deleted file mode 100644
index 28625ef0e..000000000
--- a/src/core/compositor/display_gl_output_surface.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef DISPLAY_GL_OUTPUT_SURFACE_H
-#define DISPLAY_GL_OUTPUT_SURFACE_H
-
-#include "compositor_resource_fence.h"
-#include "compositor.h"
-
-#include "components/viz/common/display/update_vsync_parameters_callback.h"
-#include "components/viz/service/display/output_surface.h"
-#include "components/viz/service/display_embedder/viz_process_context_provider.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
-
-#include <QMutex>
-
-namespace QtWebEngineCore {
-
-class DisplayGLOutputSurface final : public viz::OutputSurface, public Compositor
-{
-public:
- DisplayGLOutputSurface(scoped_refptr<viz::VizProcessContextProvider> contextProvider);
- ~DisplayGLOutputSurface() override;
-
- // Overridden from viz::OutputSurface.
- void BindToClient(viz::OutputSurfaceClient *client) override;
- void EnsureBackbuffer() override;
- void DiscardBackbuffer() override;
- void BindFramebuffer() override;
- void SetDrawRectangle(const gfx::Rect &drawRect) override;
- bool IsDisplayedAsOverlayPlane() const override;
- unsigned GetOverlayTextureId() const override;
- void Reshape(const gfx::Size &size,
- float devicePixelRatio,
- const gfx::ColorSpace &colorSpace,
- gfx::BufferFormat format,
- bool useStencil) override;
- bool HasExternalStencilTest() const override;
- void ApplyExternalStencil() override;
- uint32_t GetFramebufferCopyTextureFormat() override;
- void SwapBuffers(viz::OutputSurfaceFrame frame) override;
- unsigned UpdateGpuFence() override;
- void SetUpdateVSyncParametersCallback(viz::UpdateVSyncParametersCallback callback) override;
- void SetDisplayTransformHint(gfx::OverlayTransform transform) override;
- gfx::OverlayTransform GetDisplayTransform() override;
- void SetFrameSinkId(const viz::FrameSinkId &id) override;
-
- // Overridden from Compositor.
- void swapFrame() override;
- void waitForTexture() override;
- int textureId() override;
- QSize size() override;
- bool hasAlphaChannel() override;
- float devicePixelRatio() override;
-
-private:
- struct Shape
- {
- gfx::Size sizeInPixels;
- float devicePixelRatio;
- gfx::ColorSpace colorSpace;
- bool hasAlpha;
-
- bool operator==(const Shape &that) const
- {
- return (sizeInPixels == that.sizeInPixels &&
- devicePixelRatio == that.devicePixelRatio &&
- colorSpace == that.colorSpace &&
- hasAlpha == that.hasAlpha);
- }
- bool operator!=(const Shape &that) const { return !(*this == that); }
- };
-
- struct Buffer
- {
- DisplayGLOutputSurface *parent;
- Shape shape;
- uint32_t clientId = 0;
- uint32_t serviceId = 0;
- scoped_refptr<CompositorResourceFence> fence;
-
- Buffer(DisplayGLOutputSurface *parent) : parent(parent) {}
- ~Buffer() { parent->deleteBufferResources(this); }
- };
-
- class Texture;
-
- void swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence);
- void swapBuffersOnVizThread();
-
- std::unique_ptr<Buffer> makeBuffer(const Shape &shape);
- void deleteBufferResources(Buffer *buffer);
- void attachBuffer();
- void detachBuffer();
-
- gpu::InProcessCommandBuffer *const m_commandBuffer;
- gpu::gles2::GLES2Interface *const m_gl;
- mutable QMutex m_mutex;
- uint32_t m_fboId = 0;
- viz::OutputSurfaceClient *m_client = nullptr;
- Shape m_currentShape;
- std::unique_ptr<Buffer> m_backBuffer;
- std::unique_ptr<Buffer> m_middleBuffer;
- std::unique_ptr<Buffer> m_frontBuffer;
- bool m_readyToUpdate = false;
- scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
- scoped_refptr<viz::VizProcessContextProvider> m_vizContextProvider;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // !DISPLAY_GL_OUTPUT_SURFACE_H
diff --git a/src/core/compositor/display_overrides.cpp b/src/core/compositor/display_overrides.cpp
index bf5daf8e5..2baff5d20 100644
--- a/src/core/compositor/display_overrides.cpp
+++ b/src/core/compositor/display_overrides.cpp
@@ -1,64 +1,42 @@
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "display_gl_output_surface.h"
#include "display_skia_output_device.h"
#include "display_software_output_surface.h"
+#include "native_skia_output_device.h"
#include "components/viz/service/display_embedder/output_surface_provider_impl.h"
#include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h"
#include "gpu/ipc/in_process_command_buffer.h"
-#include <qtgui-config.h>
-std::unique_ptr<viz::OutputSurface>
-viz::OutputSurfaceProviderImpl::CreateGLOutputSurface(
- scoped_refptr<VizProcessContextProvider> context_provider)
-{
-#if QT_CONFIG(opengl)
- return std::make_unique<QtWebEngineCore::DisplayGLOutputSurface>(std::move(context_provider));
-#else
- return nullptr;
-#endif // QT_CONFIG(opengl)
-}
+#include <qtgui-config.h>
std::unique_ptr<viz::OutputSurface>
-viz::OutputSurfaceProviderImpl::CreateSoftwareOutputSurface()
+viz::OutputSurfaceProviderImpl::CreateSoftwareOutputSurface(const RendererSettings &renderer_settings)
{
- return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>();
+ return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>(renderer_settings.requires_alpha_channel);
}
std::unique_ptr<viz::SkiaOutputDevice>
viz::SkiaOutputSurfaceImplOnGpu::CreateOutputDevice()
{
+ if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) {
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDevice>(
+ context_state_,
+ renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(),
+ dependency_.get(),
+ shared_image_factory_.get(),
+ shared_image_representation_factory_.get(),
+ GetDidSwapBuffersCompleteCallback());
+ }
#if QT_CONFIG(opengl)
return std::make_unique<QtWebEngineCore::DisplaySkiaOutputDevice>(
context_state_,
+ renderer_settings_.requires_alpha_channel,
shared_gpu_deps_->memory_tracker(),
GetDidSwapBuffersCompleteCallback());
#else
return nullptr;
#endif // QT_CONFIG(opengl)
}
-
-void gpu::InProcessCommandBuffer::GetTextureQt(
- unsigned int client_id,
- GetTextureCallback callback,
- const std::vector<SyncToken>& sync_token_fences)
-{
- ScheduleGpuTask(base::BindOnce(&InProcessCommandBuffer::GetTextureQtOnGpuThread,
- gpu_thread_weak_ptr_factory_.GetWeakPtr(),
- client_id,
- std::move(callback)),
- sync_token_fences);
-}
-
-void gpu::InProcessCommandBuffer::GetTextureQtOnGpuThread(
- unsigned int client_id, GetTextureCallback callback)
-{
- if (!MakeCurrent()) {
- LOG(ERROR) << "MakeCurrent failed for GetTextureQt";
- return;
- }
- gpu::TextureBase *texture = decoder_->GetTextureBase(client_id);
- std::move(callback).Run(texture ? texture->service_id() : 0, gl::GLFence::Create());
-}
diff --git a/src/core/compositor/display_skia_output_device.cpp b/src/core/compositor/display_skia_output_device.cpp
index ee693ed81..9f9462193 100644
--- a/src/core/compositor/display_skia_output_device.cpp
+++ b/src/core/compositor/display_skia_output_device.cpp
@@ -8,6 +8,32 @@
#include "gpu/command_buffer/service/skia_utils.h"
#include "third_party/skia/include/core/SkSurfaceProps.h"
+#if QT_CONFIG(webengine_vulkan)
+#if defined(USE_OZONE)
+#include "ui/ozone/buildflags.h"
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+// We need to define USE_VULKAN_XCB for proper vulkan function pointers.
+// Avoiding it may lead to call wrong vulkan functions.
+// This is originally defined in chromium/gpu/vulkan/BUILD.gn.
+#define USE_VULKAN_XCB
+#endif // BUILDFLAG(OZONE_PLATFORM_X11)
+#endif // defined(USE_OZONE)
+#include "gpu/vulkan/vulkan_function_pointers.h"
+
+#include "components/viz/common/gpu/vulkan_context_provider.h"
+#include "compositor/display_skia_output_device.h"
+#include "gpu/vulkan/vma_wrapper.h"
+#include "gpu/vulkan/vulkan_device_queue.h"
+#include "third_party/vulkan_memory_allocator/include/vk_mem_alloc.h"
+
+#include <QQuickWindow>
+#include <QVulkanInstance>
+#include <QVulkanFunctions>
+#include <QVulkanDeviceFunctions>
+#endif // QT_CONFIG(webengine_vulkan)
+
+#include <QSGTexture>
+
namespace QtWebEngineCore {
class DisplaySkiaOutputDevice::Buffer
@@ -17,6 +43,9 @@ public:
: m_parent(parent)
, m_shape(m_parent->m_shape)
{
+ }
+ void initialize()
+ {
const auto &colorType = m_shape.characterization.colorType();
DCHECK(colorType != kUnknown_SkColorType);
@@ -26,11 +55,8 @@ public:
DCHECK(m_texture.isValid());
if (m_texture.backend() == GrBackendApi::kVulkan) {
-#if BUILDFLAG(ENABLE_VULKAN)
- GrVkImageInfo info;
- bool result = m_texture.getVkImageInfo(&info);
- DCHECK(result);
- m_estimatedSize = info.fAlloc.fSize;
+#if QT_CONFIG(webengine_vulkan)
+ initVulkan();
#else
NOTREACHED();
#endif
@@ -53,8 +79,13 @@ public:
~Buffer()
{
- DeleteGrBackendTexture(m_parent->m_contextState.get(), &m_texture);
- m_parent->memory_type_tracker_->TrackMemFree(m_estimatedSize);
+#if QT_CONFIG(webengine_vulkan) && defined(Q_OS_WIN)
+ CloseHandle(m_win32Handle);
+#endif
+ if (m_texture.isValid()) {
+ DeleteGrBackendTexture(m_parent->m_contextState.get(), &m_texture);
+ m_parent->memory_type_tracker_->TrackMemFree(m_estimatedSize);
+ }
}
void createFence()
@@ -74,6 +105,42 @@ public:
const GrBackendTexture &texture() const { return m_texture; }
SkSurface *surface() const { return m_surface.get(); }
+#if QT_CONFIG(webengine_vulkan)
+ const VkImageCreateInfo *imageCreateInfo() const { return &m_imageCreateInfo; }
+ uint64_t allocationSize() const { return m_estimatedSize; }
+ VkImageLayout imageLayout() const { return m_imageLayout; }
+ uint32_t memoryTypeIndex() const { return m_memoryTypeIndex.value(); }
+
+#if defined(Q_OS_WIN)
+ const VkExternalMemoryHandleTypeFlagBits externalMemoryHandleType() const
+ {
+ return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+ }
+
+ HANDLE externalMemoryHandle() const { return m_win32Handle; }
+#else
+ const VkExternalMemoryHandleTypeFlagBits externalMemoryHandleType() const
+ {
+ return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+ }
+
+ int externalMemoryHandle() const
+ {
+ VkMemoryGetFdInfoKHR exportInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR };
+ exportInfo.pNext = nullptr;
+ exportInfo.memory = m_imageInfo.fAlloc.fMemory;
+ exportInfo.handleType = externalMemoryHandleType();
+
+ // Importing Vulkan memory object closes the file descriptor.
+ int fd = -1;
+ if (m_vfp->vkGetMemoryFdKHR(m_vulkanDevice, &exportInfo, &fd) != VK_SUCCESS)
+ qFatal("VULKAN: Unable to extract file descriptor out of external VkImage!");
+
+ return fd;
+ }
+#endif // defined(Q_OS_WIN)
+#endif // QT_CONFIG(webengine_vulkan)
+
private:
DisplaySkiaOutputDevice *m_parent;
Shape m_shape;
@@ -81,21 +148,135 @@ private:
sk_sp<SkSurface> m_surface;
uint64_t m_estimatedSize = 0;
scoped_refptr<CompositorResourceFence> m_fence;
+
+#if QT_CONFIG(webengine_vulkan)
+ static VkSampleCountFlagBits vkSampleCount(uint32_t sampleCount)
+ {
+ Q_ASSERT(sampleCount >= 1);
+ switch (sampleCount) {
+ case 1:
+ return VK_SAMPLE_COUNT_1_BIT;
+ case 2:
+ return VK_SAMPLE_COUNT_2_BIT;
+ case 4:
+ return VK_SAMPLE_COUNT_4_BIT;
+ case 8:
+ return VK_SAMPLE_COUNT_8_BIT;
+ case 16:
+ return VK_SAMPLE_COUNT_16_BIT;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ return VK_SAMPLE_COUNT_1_BIT;
+ }
+
+ void initVulkan()
+ {
+ bool success = m_texture.getVkImageInfo(&m_imageInfo);
+ if (!success)
+ qFatal("VULKAN: Failed to get external Vulkan resources from Skia!");
+
+ m_vfp = gpu::GetVulkanFunctionPointers();
+ gpu::VulkanDeviceQueue *vulkanDeviceQueue =
+ m_parent->m_contextState->vk_context_provider()->GetDeviceQueue();
+ m_vulkanDevice = vulkanDeviceQueue->GetVulkanDevice();
+
+ // Store allocation size for the external VkImage.
+ m_estimatedSize = m_imageInfo.fAlloc.fSize;
+
+ // Store initial layout for the imported image.
+ if (vulkanDeviceQueue->vk_physical_device_properties().vendorID == 0x10DE) {
+ // FIXME: This is a workaround for Nvidia driver.
+ // The imported image is empty if the initialLayout is not PREINITIALIZED.
+ m_imageLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+ } else {
+ // The initialLayout should be undefined for the external image.
+ // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkImageCreateInfo.html#VUID-VkImageCreateInfo-pNext-01443
+ m_imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ }
+
+ // Specify VkCreateImageInfo for the imported VkImage.
+ // The specification should match with the texture's VkImage.
+ m_externalMemoryImageCreateInfo.sType =
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR;
+ m_externalMemoryImageCreateInfo.pNext = nullptr;
+ m_externalMemoryImageCreateInfo.handleTypes = externalMemoryHandleType();
+
+ m_imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ m_imageCreateInfo.pNext = &m_externalMemoryImageCreateInfo;
+ m_imageCreateInfo.flags =
+ m_imageInfo.fProtected == GrProtected::kYes ? VK_IMAGE_CREATE_PROTECTED_BIT : 0;
+ m_imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
+ m_imageCreateInfo.format = m_imageInfo.fFormat;
+ m_imageCreateInfo.extent.width = static_cast<uint32_t>(m_shape.characterization.width());
+ m_imageCreateInfo.extent.height = static_cast<uint32_t>(m_shape.characterization.height());
+ m_imageCreateInfo.extent.depth = 1;
+ m_imageCreateInfo.mipLevels = m_imageInfo.fLevelCount;
+ m_imageCreateInfo.arrayLayers = 1;
+ m_imageCreateInfo.samples = vkSampleCount(m_imageInfo.fSampleCount);
+ m_imageCreateInfo.tiling = m_imageInfo.fImageTiling;
+ m_imageCreateInfo.usage = m_imageInfo.fImageUsageFlags;
+ m_imageCreateInfo.sharingMode = m_imageInfo.fSharingMode;
+ m_imageCreateInfo.queueFamilyIndexCount = 0;
+ m_imageCreateInfo.pQueueFamilyIndices = nullptr;
+ m_imageCreateInfo.initialLayout = m_imageLayout;
+
+#if defined(Q_OS_WIN)
+ // Extract Windows handle for the memory of the external VkImage.
+ // Ownership should be released at the destruction of the Buffer object.
+ // Multiple handles for the same memory cause issues on Windows even if one is
+ // released before extracting the other.
+ VkMemoryGetWin32HandleInfoKHR exportInfo = {
+ VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR
+ };
+ exportInfo.pNext = nullptr;
+ exportInfo.memory = m_imageInfo.fAlloc.fMemory;
+ exportInfo.handleType = externalMemoryHandleType();
+
+ if (m_vfp->vkGetMemoryWin32HandleKHR(m_vulkanDevice, &exportInfo, &m_win32Handle)
+ != VK_SUCCESS) {
+ qFatal("VULKAN: Unable to extract handle out of external VkImage!");
+ }
+#endif // defined(Q_OS_WIN)
+
+ VmaAllocator vmaAllocator = vulkanDeviceQueue->vma_allocator();
+ const VmaAllocation vmaAllocation =
+ reinterpret_cast<const VmaAllocation>(m_imageInfo.fAlloc.fBackendMemory);
+ VmaAllocationInfo vmaInfo;
+ gpu::vma::GetAllocationInfo(vmaAllocator, vmaAllocation, &vmaInfo);
+ m_memoryTypeIndex = vmaInfo.memoryType;
+ }
+
+ gpu::VulkanFunctionPointers *m_vfp = nullptr;
+ VkDevice m_vulkanDevice = VK_NULL_HANDLE;
+ VkImageLayout m_imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ GrVkImageInfo m_imageInfo;
+ VkExternalMemoryImageCreateInfoKHR m_externalMemoryImageCreateInfo = {};
+ VkImageCreateInfo m_imageCreateInfo = {};
+#if defined(Q_OS_WIN)
+ HANDLE m_win32Handle = nullptr;
+#endif
+ absl::optional<uint32_t> m_memoryTypeIndex;
+#endif // QT_CONFIG(webengine_vulkan)
};
DisplaySkiaOutputDevice::DisplaySkiaOutputDevice(
scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
gpu::MemoryTracker *memoryTracker,
DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
- : SkiaOutputDevice(
- contextState->gr_context(),
- memoryTracker,
- didSwapBufferCompleteCallback)
- , Compositor(Compositor::Type::OpenGL)
+ : SkiaOutputDevice(contextState->gr_context(), memoryTracker, didSwapBufferCompleteCallback)
+ , Compositor(contextState->GrContextIsVulkan() ? Compositor::Type::Vulkan
+ : Compositor::Type::OpenGL)
, m_contextState(contextState)
+ , m_requiresAlpha(requiresAlpha)
{
capabilities_.uses_default_gl_framebuffer = false;
capabilities_.supports_surfaceless = true;
+ capabilities_.preserve_buffer_content = true;
+ capabilities_.only_invalidates_damage_rect = false;
+ capabilities_.number_of_buffers = 3;
capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] =
kRGBA_8888_SkColorType;
@@ -138,7 +319,7 @@ void DisplaySkiaOutputDevice::SwapBuffers(BufferPresentedCallback feedback,
{
QMutexLocker locker(&m_mutex);
m_taskRunner = base::ThreadTaskRunnerHandle::Get();
- m_middleBuffer = std::move(m_backBuffer);
+ std::swap(m_middleBuffer, m_backBuffer);
m_readyToUpdate = true;
}
@@ -154,10 +335,12 @@ void DisplaySkiaOutputDevice::DiscardBackbuffer()
{
}
-SkSurface *DisplaySkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *)
+SkSurface *DisplaySkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *end_semaphores)
{
- if (!m_backBuffer || m_backBuffer->shape() != m_shape)
+ if (!m_backBuffer || m_backBuffer->shape() != m_shape) {
m_backBuffer = std::make_unique<Buffer>(this);
+ m_backBuffer->initialize();
+ }
return m_backBuffer->surface();
}
@@ -184,16 +367,32 @@ void DisplaySkiaOutputDevice::waitForTexture()
m_frontBuffer->consumeFence();
}
-int DisplaySkiaOutputDevice::textureId()
+QSGTexture *DisplaySkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureOptions)
{
if (!m_frontBuffer)
- return 0;
+ return nullptr;
- GrGLTextureInfo info;
- if (!m_frontBuffer->texture().getGLTextureInfo(&info))
- return 0;
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
- return info.fID;
+ QSGTexture *texture = nullptr;
+#if QT_CONFIG(webengine_vulkan)
+ if (type() == Type::Vulkan) {
+ VkImage image = vkImage(win);
+ VkImageLayout layout = vkImageLayout();
+ texture = QNativeInterface::QSGVulkanTexture::fromNative(image, layout, win, size(), texOpts);
+ } else
+#endif
+ {
+ GrGLTextureInfo info;
+ if (m_frontBuffer->texture().getGLTextureInfo(&info))
+ texture = QNativeInterface::QSGOpenGLTexture::fromNative(info.fID, win, size(), texOpts);
+ }
+ return texture;
+}
+
+bool DisplaySkiaOutputDevice::textureIsFlipped()
+{
+ return true;
}
QSize DisplaySkiaOutputDevice::size()
@@ -201,9 +400,9 @@ QSize DisplaySkiaOutputDevice::size()
return m_frontBuffer ? toQt(m_frontBuffer->shape().characterization.dimensions()) : QSize();
}
-bool DisplaySkiaOutputDevice::hasAlphaChannel()
+bool DisplaySkiaOutputDevice::requiresAlphaChannel()
{
- return true;
+ return m_requiresAlpha;
}
float DisplaySkiaOutputDevice::devicePixelRatio()
@@ -211,11 +410,97 @@ float DisplaySkiaOutputDevice::devicePixelRatio()
return m_frontBuffer ? m_frontBuffer->shape().devicePixelRatio : 1;
}
+#if QT_CONFIG(webengine_vulkan)
+VkImage DisplaySkiaOutputDevice::vkImage(QQuickWindow *win)
+{
+ if (!m_frontBuffer)
+ return VK_NULL_HANDLE;
+
+ QSGRendererInterface *ri = win->rendererInterface();
+ VkDevice qtVulkanDevice =
+ *static_cast<VkDevice *>(ri->getResource(win, QSGRendererInterface::DeviceResource));
+ QVulkanDeviceFunctions *df = win->vulkanInstance()->deviceFunctions(qtVulkanDevice);
+
+ df->vkDestroyImage(qtVulkanDevice, m_importedImage, nullptr);
+ df->vkFreeMemory(qtVulkanDevice, m_importedImageMemory, nullptr);
+
+ if (df->vkCreateImage(qtVulkanDevice, m_frontBuffer->imageCreateInfo(), nullptr,
+ &m_importedImage)
+ != VK_SUCCESS) {
+ qFatal("VULKAN: Failed to create imported image!");
+ }
+
+ VkMemoryDedicatedAllocateInfoKHR dedicatedAllocateInfo = {
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR
+ };
+ dedicatedAllocateInfo.pNext = nullptr;
+ dedicatedAllocateInfo.image = m_importedImage;
+ dedicatedAllocateInfo.buffer = VK_NULL_HANDLE;
+
+#if defined(Q_OS_WIN)
+ VkImportMemoryWin32HandleInfoKHR importInfo = {
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR
+ };
+ importInfo.handle = m_frontBuffer->externalMemoryHandle();
+#else
+ VkImportMemoryFdInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR };
+ importInfo.fd = m_frontBuffer->externalMemoryHandle();
+#endif // defined(Q_OS_WIN)
+ importInfo.pNext = &dedicatedAllocateInfo;
+ importInfo.handleType = m_frontBuffer->externalMemoryHandleType();
+
+ VkMemoryAllocateInfo allocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
+ allocateInfo.pNext = &importInfo;
+ allocateInfo.allocationSize = m_frontBuffer->allocationSize();
+ allocateInfo.memoryTypeIndex = m_frontBuffer->memoryTypeIndex();
+
+ if (df->vkAllocateMemory(qtVulkanDevice, &allocateInfo, nullptr, &m_importedImageMemory)
+ != VK_SUCCESS) {
+ qFatal("VULKAN: Failed to allocate memory for imported VkImage!");
+ }
+
+ df->vkBindImageMemory(qtVulkanDevice, m_importedImage, m_importedImageMemory, 0);
+
+ return m_importedImage;
+}
+
+VkImageLayout DisplaySkiaOutputDevice::vkImageLayout()
+{
+ if (!m_frontBuffer)
+ return VK_IMAGE_LAYOUT_UNDEFINED;
+
+ return m_frontBuffer->imageLayout();
+}
+
+void DisplaySkiaOutputDevice::releaseVulkanResources(QQuickWindow *win)
+{
+ VkDevice *vkDevicePtr = static_cast<VkDevice *>(
+ win->rendererInterface()->getResource(win, QSGRendererInterface::DeviceResource));
+
+ if (!vkDevicePtr) {
+ Q_ASSERT(m_importedImage == VK_NULL_HANDLE && m_importedImageMemory == VK_NULL_HANDLE);
+ return;
+ }
+
+ QVulkanDeviceFunctions *df = win->vulkanInstance()->deviceFunctions(*vkDevicePtr);
+
+ if (m_importedImage != VK_NULL_HANDLE) {
+ df->vkDestroyImage(*vkDevicePtr, m_importedImage, nullptr);
+ m_importedImage = VK_NULL_HANDLE;
+ }
+
+ if (m_importedImageMemory != VK_NULL_HANDLE) {
+ df->vkFreeMemory(*vkDevicePtr, m_importedImageMemory, nullptr);
+ m_importedImageMemory = VK_NULL_HANDLE;
+ }
+}
+#endif // QT_CONFIG(webengine_vulkan)
+
void DisplaySkiaOutputDevice::SwapBuffersFinished()
{
{
QMutexLocker locker(&m_mutex);
- m_backBuffer = std::move(m_middleBuffer);
+ std::swap(m_backBuffer, m_middleBuffer);
}
FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK),
diff --git a/src/core/compositor/display_skia_output_device.h b/src/core/compositor/display_skia_output_device.h
index 943d37214..27bee2d1d 100644
--- a/src/core/compositor/display_skia_output_device.h
+++ b/src/core/compositor/display_skia_output_device.h
@@ -13,12 +13,17 @@
#include <QMutex>
+QT_BEGIN_NAMESPACE
+class QQuickWindow;
+QT_END_NAMESPACE
+
namespace QtWebEngineCore {
class DisplaySkiaOutputDevice final : public viz::SkiaOutputDevice, public Compositor
{
public:
DisplaySkiaOutputDevice(scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
gpu::MemoryTracker *memoryTracker,
DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
~DisplaySkiaOutputDevice() override;
@@ -39,10 +44,16 @@ public:
// Overridden from Compositor.
void swapFrame() override;
void waitForTexture() override;
- int textureId() override;
+ QSGTexture *texture(QQuickWindow *win, uint32_t texOpts) override;
+ bool textureIsFlipped() override;
QSize size() override;
- bool hasAlphaChannel() override;
+ bool requiresAlphaChannel() override;
float devicePixelRatio() override;
+#if QT_CONFIG(webengine_vulkan)
+ VkImage vkImage(QQuickWindow *win);
+ VkImageLayout vkImageLayout();
+ void releaseVulkanResources(QQuickWindow *win) override;
+#endif
private:
struct Shape
@@ -72,7 +83,13 @@ private:
std::unique_ptr<Buffer> m_backBuffer;
viz::OutputSurfaceFrame m_frame;
bool m_readyToUpdate = false;
+ bool m_requiresAlpha;
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+
+#if QT_CONFIG(webengine_vulkan)
+ VkImage m_importedImage = VK_NULL_HANDLE;
+ VkDeviceMemory m_importedImageMemory = VK_NULL_HANDLE;
+#endif // QT_CONFIG(webengine_vulkan)
};
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_software_output_surface.cpp b/src/core/compositor/display_software_output_surface.cpp
index 2277dfea3..9d6534c28 100644
--- a/src/core/compositor/display_software_output_surface.cpp
+++ b/src/core/compositor/display_software_output_surface.cpp
@@ -13,6 +13,7 @@
#include <QMutex>
#include <QPainter>
+#include <QQuickWindow>
namespace QtWebEngineCore {
@@ -20,7 +21,7 @@ class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDev
public Compositor
{
public:
- Device();
+ Device(bool requiresAlpha);
// Overridden from viz::SoftwareOutputDevice.
void Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) override;
@@ -28,23 +29,27 @@ public:
// Overridden from Compositor.
void swapFrame() override;
- QImage image() override;
+ QSGTexture *texture(QQuickWindow *win, uint32_t) override;
+ bool textureIsFlipped() override;
float devicePixelRatio() override;
QSize size() override;
- bool hasAlphaChannel() override;
+ bool requiresAlphaChannel() override;
private:
mutable QMutex m_mutex;
float m_devicePixelRatio = 1.0;
+ bool m_requiresAlpha;
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
SwapBuffersCallback m_swapCompletionCallback;
QImage m_image;
float m_imageDevicePixelRatio = 1.0;
};
-DisplaySoftwareOutputSurface::Device::Device()
+DisplaySoftwareOutputSurface::Device::Device(bool requiresAlpha)
: Compositor(Type::Software)
-{}
+ , m_requiresAlpha(requiresAlpha)
+{
+}
void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels, float devicePixelRatio)
{
@@ -107,9 +112,14 @@ void DisplaySoftwareOutputSurface::Device::swapFrame()
m_taskRunner.reset();
}
-QImage DisplaySoftwareOutputSurface::Device::image()
+QSGTexture *DisplaySoftwareOutputSurface::Device::texture(QQuickWindow *win, uint32_t)
+{
+ return win->createTextureFromImage(m_image);
+}
+
+bool DisplaySoftwareOutputSurface::Device::textureIsFlipped()
{
- return m_image;
+ return false;
}
float DisplaySoftwareOutputSurface::Device::devicePixelRatio()
@@ -122,13 +132,13 @@ QSize DisplaySoftwareOutputSurface::Device::size()
return m_image.size();
}
-bool DisplaySoftwareOutputSurface::Device::hasAlphaChannel()
+bool DisplaySoftwareOutputSurface::Device::requiresAlphaChannel()
{
- return m_image.format() == QImage::Format_ARGB32_Premultiplied;
+ return m_requiresAlpha;
}
-DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface()
- : SoftwareOutputSurface(std::make_unique<Device>())
+DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface(bool requiresAlpha)
+ : SoftwareOutputSurface(std::make_unique<Device>(requiresAlpha))
{}
DisplaySoftwareOutputSurface::~DisplaySoftwareOutputSurface() {}
diff --git a/src/core/compositor/display_software_output_surface.h b/src/core/compositor/display_software_output_surface.h
index 5bb4e77c3..d23664d56 100644
--- a/src/core/compositor/display_software_output_surface.h
+++ b/src/core/compositor/display_software_output_surface.h
@@ -11,7 +11,7 @@ namespace QtWebEngineCore {
class DisplaySoftwareOutputSurface final : public viz::SoftwareOutputSurface
{
public:
- DisplaySoftwareOutputSurface();
+ DisplaySoftwareOutputSurface(bool requiresAlpha);
~DisplaySoftwareOutputSurface() override;
// Overridden from viz::OutputSurface.
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
new file mode 100644
index 000000000..aa0be8c26
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -0,0 +1,443 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "native_skia_output_device.h"
+
+#include "type_conversion.h"
+
+#include "components/viz/common/resources/shared_image_format.h"
+#include "components/viz/service/display_embedder/skia_output_surface_dependency.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "gpu/command_buffer/service/skia_utils.h"
+#include "third_party/skia/include/gpu/GrDirectContext.h"
+#include "third_party/skia/include/core/SkSurfaceProps.h"
+#include "ui/gl/gl_fence.h"
+
+#if defined(Q_OS_MACOS)
+#include "ui/gl/gl_image_io_surface.h"
+#elif defined(Q_OS_WIN)
+#include "ui/gl/gl_image_d3d.h"
+#include <QtQuick/qsgtexture.h>
+#include <d3d11_1.h>
+#endif
+
+#include <QQuickWindow>
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDevice::Buffer
+{
+public:
+ Buffer(NativeSkiaOutputDevice *parent)
+ : m_parent(parent)
+ , m_shape(m_parent->m_shape)
+ {
+ }
+ ~Buffer()
+ {
+ if (m_scopedSkiaWriteAccess)
+ endWriteSkia(false);
+
+ if (!m_mailbox.IsZero())
+ m_parent->m_factory->DestroySharedImage(m_mailbox);
+ }
+
+ // The following Buffer methods are based on components/viz/service/display_embedder/output_presenter.cc:
+ // Copyright 2020 The Chromium Authors
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ bool initialize()
+ {
+ static const uint32_t kDefaultSharedImageUsage =
+ gpu::SHARED_IMAGE_USAGE_SCANOUT | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ
+ | gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+ auto mailbox = gpu::Mailbox::GenerateForSharedImage();
+
+ if (!m_parent->m_factory->CreateSharedImage(mailbox,
+ viz::SharedImageFormat::SinglePlane(viz::RGBA_8888),
+ {m_parent->m_shape.characterization.width(), m_parent->m_shape.characterization.height()},
+ m_parent->m_shape.colorSpace,
+ m_parent->capabilities_.output_surface_origin == gfx::SurfaceOrigin::kTopLeft
+ ? kTopLeft_GrSurfaceOrigin
+ : kBottomLeft_GrSurfaceOrigin,
+ kPremul_SkAlphaType,
+ m_parent->m_deps->GetSurfaceHandle(), kDefaultSharedImageUsage)) {
+ LOG(ERROR) << "CreateSharedImage failed.";
+ return false;
+ }
+ m_mailbox = mailbox;
+
+ m_skiaRepresentation = m_parent->m_representationFactory->ProduceSkia(m_mailbox, m_parent->m_deps->GetSharedContextState());
+ if (!m_skiaRepresentation) {
+ LOG(ERROR) << "ProduceSkia() failed.";
+ return false;
+ }
+
+ m_overlayRepresentation = m_parent->m_representationFactory->ProduceOverlay(m_mailbox);
+ if (!m_overlayRepresentation) {
+ LOG(ERROR) << "ProduceOverlay() failed";
+ return false;
+ }
+
+ return true;
+ }
+ SkSurface *beginWriteSkia()
+ {
+ DCHECK(!m_scopedSkiaWriteAccess);
+ DCHECK(!m_presentCount);
+ DCHECK(m_endSemaphores.empty());
+
+ std::vector<GrBackendSemaphore> beginSemaphores;
+ SkSurfaceProps surface_props{0, kUnknown_SkPixelGeometry};
+
+ // Buffer queue is internal to GPU proc and handles texture initialization,
+ // so allow uncleared access.
+ m_scopedSkiaWriteAccess = m_skiaRepresentation->BeginScopedWriteAccess(
+ 0 /* sampleCount */, surface_props, &beginSemaphores, &m_endSemaphores,
+ gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
+ DCHECK(m_scopedSkiaWriteAccess);
+ if (!beginSemaphores.empty()) {
+ m_scopedSkiaWriteAccess->surface()->wait(
+ beginSemaphores.size(),
+ beginSemaphores.data(),
+ /*deleteSemaphoresAfterWait=*/false);
+ }
+ return m_scopedSkiaWriteAccess->surface();
+ }
+
+ void endWriteSkia(bool force_flush)
+ {
+ // The Flush now takes place in finishPaintCurrentBuffer on the CPU side.
+ // check if end_semaphores is not empty then flush here
+ DCHECK(m_scopedSkiaWriteAccess);
+ auto end_state = m_scopedSkiaWriteAccess->TakeEndState();
+ if (!m_endSemaphores.empty() || end_state || force_flush) {
+ GrFlushInfo flush_info = {};
+ flush_info.fNumSemaphores = m_endSemaphores.size();
+ flush_info.fSignalSemaphores = m_endSemaphores.data();
+ m_scopedSkiaWriteAccess->surface()->flush(flush_info, end_state.get());
+ auto *direct_context = m_scopedSkiaWriteAccess->surface()->recordingContext()->asDirectContext();
+ DCHECK(direct_context);
+ direct_context->submit();
+ }
+ m_scopedSkiaWriteAccess.reset();
+ m_endSemaphores.clear();
+
+ // SkiaRenderer always draws the full frame.
+ m_skiaRepresentation->SetCleared();
+ }
+
+ std::vector<GrBackendSemaphore> takeEndWriteSkiaSemaphores()
+ {
+ return std::exchange(m_endSemaphores, {});
+ }
+
+ void beginPresent()
+ {
+ if (++m_presentCount != 1) {
+ DCHECK(m_scopedOverlayReadAccess);
+ return;
+ }
+
+ DCHECK(!m_scopedSkiaWriteAccess);
+ DCHECK(!m_scopedOverlayReadAccess);
+
+ m_scopedOverlayReadAccess = m_overlayRepresentation->BeginScopedReadAccess(true);
+ DCHECK(m_scopedOverlayReadAccess);
+ m_acquireFence = TakeGpuFence(m_scopedOverlayReadAccess->TakeAcquireFence());
+ }
+
+ void endPresent()
+ {
+ if (!m_presentCount)
+ return;
+ DCHECK(m_scopedOverlayReadAccess);
+ if (--m_presentCount)
+ return;
+
+ m_scopedOverlayReadAccess.reset();
+ if (m_textureCleanup) {
+ m_textureCleanup();
+ m_textureCleanup = nullptr;
+ }
+ }
+ gl::GLImage *glImage()
+ {
+ DCHECK(m_presentCount);
+ return m_scopedOverlayReadAccess->gl_image();
+ }
+
+ void createFence()
+ {
+ // For some reason we still need to create this, but we do not need to wait on it.
+ m_fence = gl::GLFence::Create();
+ }
+
+ void consumeFence()
+ {
+ if (m_acquireFence) {
+ m_acquireFence->Wait();
+ m_acquireFence.reset();
+ }
+ }
+
+ const Shape &shape() const { return m_shape; }
+
+ std::function<void()> m_textureCleanup;
+private:
+ NativeSkiaOutputDevice *m_parent;
+ Shape m_shape;
+ uint64_t m_estimatedSize = 0; // FIXME: estimate size
+ static std::unique_ptr<gfx::GpuFence> TakeGpuFence(gfx::GpuFenceHandle fence)
+ {
+ return fence.is_null() ? nullptr
+ : std::make_unique<gfx::GpuFence>(std::move(fence));
+ }
+ std::unique_ptr<gfx::GpuFence> m_acquireFence;
+ std::unique_ptr<gl::GLFence> m_fence;
+ gpu::Mailbox m_mailbox;
+ std::unique_ptr<gpu::SkiaImageRepresentation> m_skiaRepresentation;
+ std::unique_ptr<gpu::SkiaImageRepresentation::ScopedWriteAccess> m_scopedSkiaWriteAccess;
+ std::unique_ptr<gpu::OverlayImageRepresentation> m_overlayRepresentation;
+ std::unique_ptr<gpu::OverlayImageRepresentation::ScopedReadAccess> m_scopedOverlayReadAccess;
+
+ std::vector<GrBackendSemaphore> m_endSemaphores;
+ int m_presentCount = 0;
+};
+
+NativeSkiaOutputDevice::NativeSkiaOutputDevice(
+ scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker,
+ viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : SkiaOutputDevice(contextState->gr_context(), memoryTracker, didSwapBufferCompleteCallback)
+ , Compositor(Compositor::Type::NativeBuffer)
+ , m_requiresAlpha(requiresAlpha)
+ , m_factory(shared_image_factory)
+ , m_representationFactory(shared_image_representation_factory)
+ , m_deps(dependency)
+{
+ capabilities_.uses_default_gl_framebuffer = false;
+ capabilities_.supports_surfaceless = true;
+ capabilities_.preserve_buffer_content = true;
+ capabilities_.only_invalidates_damage_rect = false;
+ capabilities_.number_of_buffers = 3;
+
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] =
+ kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] =
+ kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] =
+ kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] =
+ kRGBA_8888_SkColorType;
+}
+
+NativeSkiaOutputDevice::~NativeSkiaOutputDevice()
+{
+}
+
+void NativeSkiaOutputDevice::SetFrameSinkId(const viz::FrameSinkId &id)
+{
+ bind(id);
+}
+
+bool NativeSkiaOutputDevice::Reshape(const SkSurfaceCharacterization &characterization,
+ const gfx::ColorSpace &colorSpace,
+ float device_scale_factor,
+ gfx::OverlayTransform transform)
+{
+ m_shape = Shape{characterization, device_scale_factor, colorSpace};
+ DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
+ return true;
+}
+
+void NativeSkiaOutputDevice::SwapBuffers(BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame)
+{
+ DCHECK(m_backBuffer);
+
+ StartSwapBuffers(std::move(feedback));
+ m_frame = std::move(frame);
+ {
+ QMutexLocker locker(&m_mutex);
+ m_backBuffer->createFence();
+ m_taskRunner = base::ThreadTaskRunnerHandle::Get();
+ std::swap(m_middleBuffer, m_backBuffer);
+ m_readyToUpdate = true;
+ }
+
+ if (auto obs = observer())
+ obs->readyToSwap();
+}
+
+void NativeSkiaOutputDevice::EnsureBackbuffer()
+{
+}
+
+void NativeSkiaOutputDevice::DiscardBackbuffer()
+{
+}
+
+
+SkSurface *NativeSkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *end_semaphores)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ if (!m_backBuffer || m_backBuffer->shape() != m_shape) {
+ m_backBuffer = std::make_unique<Buffer>(this);
+ if (!m_backBuffer->initialize())
+ return nullptr;
+ }
+ }
+ auto surface = m_backBuffer->beginWriteSkia();
+ *end_semaphores = m_backBuffer->takeEndWriteSkiaSemaphores();
+ return surface;
+}
+
+void NativeSkiaOutputDevice::EndPaint()
+{
+ m_backBuffer->endWriteSkia(true);
+}
+
+void NativeSkiaOutputDevice::swapFrame()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_readyToUpdate) {
+ std::swap(m_frontBuffer, m_middleBuffer);
+ m_taskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&NativeSkiaOutputDevice::SwapBuffersFinished,
+ base::Unretained(this)));
+ m_taskRunner.reset();
+ m_readyToUpdate = false;
+ if (m_frontBuffer) {
+ m_readyWithTexture = true;
+ m_frontBuffer->beginPresent();
+ }
+ }
+}
+
+void NativeSkiaOutputDevice::waitForTexture()
+{
+ if (m_readyWithTexture)
+ m_frontBuffer->consumeFence();
+}
+
+void NativeSkiaOutputDevice::releaseTexture()
+{
+ if (m_readyWithTexture) {
+ m_frontBuffer->endPresent();
+ m_readyWithTexture = false;
+ }
+}
+
+#ifdef Q_OS_MACOS
+QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef io_surface, uint io_surface_plane, int width, int height, uint32_t textureOptions);
+
+QSGTexture *NativeSkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+ gl::GLImageIOSurface *gl_image_iosurface = gl::GLImageIOSurface::FromGLImage(m_frontBuffer->glImage());
+ QSGTexture *texture = nullptr;
+ if (gl_image_iosurface) {
+ texture = makeMetalTexture(win, gl_image_iosurface->io_surface().release(), /* plane */ 0,
+ m_shape.characterization.width(), m_shape.characterization.height(),
+ textureOptions);
+ } else {
+ qWarning() << "GLImage not an IOSURFACE";
+ }
+
+ return texture;
+}
+#elif defined(Q_OS_WIN)
+QSGTexture *NativeSkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+ Q_ASSERT(QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11);
+
+ QSGTexture *texture = nullptr;
+ gl::GLImageD3D *gl_image_d3d = gl::GLImageD3D::FromGLImage(m_frontBuffer->glImage());
+ if (gl_image_d3d) {
+ // Pass texture between two D3D devices:
+ HRESULT status = S_OK;
+ HANDLE sharedHandle;
+ sharedHandle = gl_image_d3d->shared_handle();
+ if (!sharedHandle) {
+ qWarning() << "No shared handle";
+ return nullptr;
+ }
+ Q_ASSERT(sharedHandle);
+
+ HANDLE sharedHandleDup;
+ DuplicateHandle(GetCurrentProcess(), sharedHandle, GetCurrentProcess(), &sharedHandleDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+
+ QSGRendererInterface *ri = win->rendererInterface();
+ ID3D11Device1 *device = static_cast<ID3D11Device1 *>(ri->getResource(win, QSGRendererInterface::DeviceResource));
+
+ ID3D11Texture2D *qtTexture;
+ status = device->OpenSharedResource1(sharedHandleDup, __uuidof(ID3D11Texture2D), (void**)&qtTexture);
+ Q_ASSERT(status == S_OK);
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ texture = QNativeInterface::QSGD3D11Texture::fromNative(qtTexture, win, size(), texOpts);
+
+ m_frontBuffer->m_textureCleanup = [qtTexture,sharedHandleDup]() {
+ qtTexture->Release();
+ ::CloseHandle(sharedHandleDup);
+ };
+ } else {
+ qWarning() << "GLImage is not D3D";
+ }
+
+ return texture;
+}
+#else
+QSGTexture *NativeSkiaOutputDevice::texture(QQuickWindow *, uint32_t)
+{
+ // Add Linux versions.
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+#endif
+
+bool NativeSkiaOutputDevice::textureIsFlipped()
+{
+ return true;
+}
+
+QSize NativeSkiaOutputDevice::size()
+{
+ return m_frontBuffer ? toQt(m_frontBuffer->shape().characterization.dimensions()) : QSize();
+}
+
+bool NativeSkiaOutputDevice::requiresAlphaChannel()
+{
+ return m_requiresAlpha;
+}
+
+float NativeSkiaOutputDevice::devicePixelRatio()
+{
+ return m_frontBuffer ? m_frontBuffer->shape().devicePixelRatio : 1;
+}
+
+void NativeSkiaOutputDevice::SwapBuffersFinished()
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ std::swap(m_backBuffer, m_middleBuffer);
+ }
+
+ FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK),
+ gfx::Size(m_shape.characterization.width(), m_shape.characterization.height()),
+ std::move(m_frame));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device.h b/src/core/compositor/native_skia_output_device.h
new file mode 100644
index 000000000..450f909b0
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device.h
@@ -0,0 +1,103 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_H
+
+#include "compositor.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/viz/service/display_embedder/skia_output_device.h"
+#include "gpu/command_buffer/service/shared_context_state.h"
+
+#include <QMutex>
+
+QT_BEGIN_NAMESPACE
+class QQuickWindow;
+QT_END_NAMESPACE
+
+namespace gpu {
+class SharedImageFactory;
+class SharedImageRepresentationFactory;
+}
+
+namespace viz {
+class SkiaOutputSurfaceDependency;
+}
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDevice final : public viz::SkiaOutputDevice, public Compositor
+{
+public:
+ NativeSkiaOutputDevice(scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker,
+ viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDevice() override;
+
+ // Overridden from SkiaOutputDevice.
+ void SetFrameSinkId(const viz::FrameSinkId &frame_sink_id) override;
+ bool Reshape(const SkSurfaceCharacterization &characterization,
+ const gfx::ColorSpace& colorSpace,
+ float device_scale_factor,
+ gfx::OverlayTransform transform) override;
+ void SwapBuffers(BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame) override;
+ void EnsureBackbuffer() override;
+ void DiscardBackbuffer() override;
+ SkSurface *BeginPaint(std::vector<GrBackendSemaphore> *semaphores) override;
+ void EndPaint() override;
+
+ // Overridden from Compositor.
+ void swapFrame() override;
+ void waitForTexture() override;
+ void releaseTexture() override;
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+ bool textureIsFlipped() override;
+ QSize size() override;
+ bool requiresAlphaChannel() override;
+ float devicePixelRatio() override;
+
+private:
+ struct Shape
+ {
+ SkSurfaceCharacterization characterization;
+ float devicePixelRatio;
+ gfx::ColorSpace colorSpace;
+
+ bool operator==(const Shape &that) const
+ {
+ return (characterization == that.characterization &&
+ devicePixelRatio == that.devicePixelRatio &&
+ colorSpace == that.colorSpace);
+ }
+ bool operator!=(const Shape &that) const { return !(*this == that); }
+ };
+
+ class Buffer;
+ friend class NativeSkiaOutputDevice::Buffer;
+ void SwapBuffersFinished();
+
+ mutable QMutex m_mutex;
+ Shape m_shape;
+ std::unique_ptr<Buffer> m_frontBuffer;
+ std::unique_ptr<Buffer> m_middleBuffer;
+ std::unique_ptr<Buffer> m_backBuffer;
+ viz::OutputSurfaceFrame m_frame;
+ bool m_readyToUpdate = false;
+ bool m_readyWithTexture = false;
+ bool m_requiresAlpha;
+ scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+
+ const raw_ptr<gpu::SharedImageFactory> m_factory;
+ const raw_ptr<gpu::SharedImageRepresentationFactory> m_representationFactory;
+ const raw_ptr<viz::SkiaOutputSurfaceDependency> m_deps;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !NATIVE_SKIA_OUTPUT_DEVICE_H
diff --git a/src/core/compositor/native_skia_output_device_mac.mm b/src/core/compositor/native_skia_output_device_mac.mm
new file mode 100644
index 000000000..0200a4a46
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_mac.mm
@@ -0,0 +1,30 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#import <IOSurface/IOSurface.h>
+#import <Metal/Metal.h>
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+QT_BEGIN_NAMESPACE
+class QSGTexture;
+class QQuickWindow;
+QT_END_NAMESPACE
+
+@class MTLDevice;
+
+namespace QtWebEngineCore {
+QSGTexture *makeMetalTexture2(QQuickWindow *win, id<MTLTexture> mtlTexture, int width, int height, uint32_t textureOptions);
+MTLDevice *getRhiDev(QQuickWindow *win);
+
+QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef io_surface, uint io_surface_plane, int width, int height, uint32_t textureOptions)
+{
+ auto desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
+ width:width height:height mipmapped:false];
+
+ auto device = getRhiDev(win);
+ auto texture = [device newTextureWithDescriptor:desc iosurface:io_surface plane:io_surface_plane];
+ return makeMetalTexture2(win, texture, width, height, textureOptions);
+}
+
+} // namespace
diff --git a/src/core/compositor/native_skia_output_device_mac2.mm b/src/core/compositor/native_skia_output_device_mac2.mm
new file mode 100644
index 000000000..645f26c61
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_mac2.mm
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <qquickwindow.h>
+#include <qsgrendererinterface.h>
+#include <qsgtexture.h>
+
+@class MTLDevice;
+@protocol MTLTexture;
+
+namespace QtWebEngineCore {
+
+MTLDevice *getRhiDev(QQuickWindow *win)
+{
+ QSGRendererInterface *ri = win->rendererInterface();
+ return static_cast<MTLDevice *>(ri->getResource(win, QSGRendererInterface::DeviceResource));
+}
+
+QSGTexture *makeMetalTexture2(QQuickWindow *win, id<MTLTexture> mtlTexture, int width, int height, uint32_t textureOptions)
+{
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ return QNativeInterface::QSGMetalTexture::fromNative(mtlTexture, win, {width, height}, texOpts);
+}
+
+} // namespace
diff --git a/src/core/compositor/vulkan_implementation_qt.cpp b/src/core/compositor/vulkan_implementation_qt.cpp
new file mode 100644
index 000000000..cdc68d3d4
--- /dev/null
+++ b/src/core/compositor/vulkan_implementation_qt.cpp
@@ -0,0 +1,156 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "vulkan_implementation_qt.h"
+
+#include "base/environment.h"
+#include "base/logging.h"
+#include "gpu/vulkan/vulkan_image.h"
+#include "gpu/vulkan/vulkan_surface.h"
+#include "gpu/vulkan/vulkan_util.h"
+#include "ui/gfx/gpu_fence.h"
+
+#include <vulkan/vulkan.h>
+
+namespace gpu {
+
+VulkanImplementationQt::VulkanImplementationQt() : VulkanImplementation(false) { }
+
+VulkanImplementationQt::~VulkanImplementationQt() = default;
+
+bool VulkanImplementationQt::InitializeVulkanInstance(bool /*using_surface*/)
+{
+ std::vector<const char *> required_extensions = {
+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
+ };
+
+ auto env = base::Environment::Create();
+ std::string vulkan_path;
+ if (!env->GetVar("QT_VULKAN_LIB", &vulkan_path)) {
+#if BUILDFLAG(IS_WIN)
+ vulkan_path = "vulkan-1.dll";
+#else
+ vulkan_path = "libvulkan.so.1";
+#endif
+ }
+
+ if (!vulkan_instance_.Initialize(base::FilePath::FromUTF8Unsafe(vulkan_path),
+ required_extensions, {})) {
+ LOG(ERROR) << "Failed to initialize vulkan instance";
+ return false;
+ }
+
+ return true;
+}
+
+VulkanInstance *VulkanImplementationQt::GetVulkanInstance()
+{
+ return &vulkan_instance_;
+}
+
+std::unique_ptr<VulkanSurface>
+VulkanImplementationQt::CreateViewSurface(gfx::AcceleratedWidget /*window*/)
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+bool VulkanImplementationQt::GetPhysicalDevicePresentationSupport(
+ VkPhysicalDevice /*device*/,
+ const std::vector<VkQueueFamilyProperties> & /*queue_family_properties*/,
+ uint32_t /*queue_family_index*/)
+{
+ NOTREACHED();
+ return true;
+}
+
+std::vector<const char *> VulkanImplementationQt::GetRequiredDeviceExtensions()
+{
+ return {
+ VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
+#if BUILDFLAG(IS_WIN)
+ VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
+#else
+ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
+#endif
+ };
+}
+
+std::vector<const char *> VulkanImplementationQt::GetOptionalDeviceExtensions()
+{
+ return {
+ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
+#if BUILDFLAG(IS_WIN)
+ VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
+#else
+ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
+#endif
+ };
+}
+
+VkFence VulkanImplementationQt::CreateVkFenceForGpuFence(VkDevice /*vk_device*/)
+{
+ NOTREACHED();
+ return VK_NULL_HANDLE;
+}
+
+std::unique_ptr<gfx::GpuFence>
+VulkanImplementationQt::ExportVkFenceToGpuFence(VkDevice /*vk_device*/, VkFence /*vk_fence*/)
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+VkSemaphore VulkanImplementationQt::CreateExternalSemaphore(VkDevice vk_device)
+{
+ return CreateExternalVkSemaphore(
+#if BUILDFLAG(IS_WIN)
+ vk_device, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT);
+#else
+ vk_device, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT);
+#endif
+}
+
+VkSemaphore VulkanImplementationQt::ImportSemaphoreHandle(VkDevice vk_device,
+ SemaphoreHandle sync_handle)
+{
+ return ImportVkSemaphoreHandle(vk_device, std::move(sync_handle));
+}
+
+SemaphoreHandle VulkanImplementationQt::GetSemaphoreHandle(VkDevice vk_device,
+ VkSemaphore vk_semaphore)
+{
+ return GetVkSemaphoreHandle(vk_device, vk_semaphore,
+#if BUILDFLAG(IS_WIN)
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT);
+#else
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT);
+#endif
+}
+
+VkExternalMemoryHandleTypeFlagBits VulkanImplementationQt::GetExternalImageHandleType()
+{
+#if BUILDFLAG(IS_WIN)
+ return VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
+#else
+ return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
+#endif
+}
+
+bool VulkanImplementationQt::CanImportGpuMemoryBuffer(
+ VulkanDeviceQueue* /*device_queue*/,
+ gfx::GpuMemoryBufferType /*memory_buffer_type*/)
+{
+ return false;
+}
+
+std::unique_ptr<VulkanImage> VulkanImplementationQt::CreateImageFromGpuMemoryHandle(VulkanDeviceQueue *, gfx::GpuMemoryBufferHandle,
+ gfx::Size, VkFormat,
+ const gfx::ColorSpace &)
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+} // namespace gpu
diff --git a/src/core/compositor/vulkan_implementation_qt.h b/src/core/compositor/vulkan_implementation_qt.h
new file mode 100644
index 000000000..56a61e086
--- /dev/null
+++ b/src/core/compositor/vulkan_implementation_qt.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef VULKAN_IMPLEMENTATION_QT_H
+#define VULKAN_IMPLEMENTATION_QT_H
+
+#include "gpu/vulkan/vulkan_implementation.h"
+#include "gpu/vulkan/vulkan_instance.h"
+
+namespace gpu {
+
+class VulkanImplementationQt : public VulkanImplementation
+{
+public:
+ VulkanImplementationQt();
+ ~VulkanImplementationQt() override;
+
+ // Overridden from VulkanImplementation.
+ bool InitializeVulkanInstance(bool using_surface) override;
+ VulkanInstance *GetVulkanInstance() override;
+ std::unique_ptr<VulkanSurface> CreateViewSurface(gfx::AcceleratedWidget window) override;
+ bool GetPhysicalDevicePresentationSupport(
+ VkPhysicalDevice device,
+ const std::vector<VkQueueFamilyProperties> &queue_family_properties,
+ uint32_t queue_family_index) override;
+ std::vector<const char *> GetRequiredDeviceExtensions() override;
+ std::vector<const char *> GetOptionalDeviceExtensions() override;
+ VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
+ std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(VkDevice vk_device,
+ VkFence vk_fence) override;
+ VkSemaphore CreateExternalSemaphore(VkDevice vk_device) override;
+ VkSemaphore ImportSemaphoreHandle(VkDevice vk_device, SemaphoreHandle handle) override;
+ SemaphoreHandle GetSemaphoreHandle(VkDevice vk_device, VkSemaphore vk_semaphore) override;
+ VkExternalMemoryHandleTypeFlagBits GetExternalImageHandleType() override;
+ bool CanImportGpuMemoryBuffer(VulkanDeviceQueue* device_queue,
+ gfx::GpuMemoryBufferType memory_buffer_type) override;
+ std::unique_ptr<VulkanImage> CreateImageFromGpuMemoryHandle(VulkanDeviceQueue *device_queue,
+ gfx::GpuMemoryBufferHandle gmb_handle,
+ gfx::Size size, VkFormat vk_format,
+ const gfx::ColorSpace &color_space) override;
+
+private:
+ VulkanInstance vulkan_instance_;
+};
+
+} // namespace gpu
+
+#endif // VULKAN_IMPLEMENTATION_QT_H
diff --git a/src/core/configure.json b/src/core/configure.json
deleted file mode 100644
index 9e39ae59a..000000000
--- a/src/core/configure.json
+++ /dev/null
@@ -1,303 +0,0 @@
-{
- "module": "webenginecore",
- "depends": [
- "buildtools-private",
- "core-private",
- "gui-private",
- "printsupport"
- ],
- "condition": "module.gui && features.build-qtwebengine-core && features.webengine-core-support",
- "testDir": "../../config.tests",
- "commandline": {
- "options": {
- "webengine-alsa": "boolean",
- "webengine-embedded-build": "boolean",
- "webengine-full-debug-info": "boolean",
- "webengine-icu": { "type": "enum", "name": "webengine-system-icu", "values": { "system": "yes", "qt": "no" } },
- "webengine-ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
- "webengine-opus": { "type": "enum", "name": "webengine-system-opus", "values": { "system": "yes", "qt": "no" } },
- "webengine-webp": { "type": "enum", "name": "webengine-system-libwebp", "values": { "system": "yes", "qt": "no" } },
- "webengine-pepper-plugins": "boolean",
- "webengine-printing-and-pdf": "boolean",
- "webengine-proprietary-codecs": "boolean",
- "webengine-pulseaudio": "boolean",
- "webengine-spellchecker": "boolean",
- "webengine-native-spellchecker": "boolean",
- "webengine-extensions": "boolean",
- "webengine-webrtc": "boolean",
- "webengine-webrtc-pipewire": "boolean",
- "webengine-geolocation": "boolean",
- "webengine-webchannel": "boolean",
- "webengine-kerberos": "boolean",
- "alsa": { "type": "boolean", "name": "webengine-alsa" },
- "pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" },
- "ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
- "opus": { "type": "enum", "name": "webengine-system-opus", "values": { "system": "yes", "qt": "no" } },
- "webp": { "type": "enum", "name": "webengine-system-libwebp", "values": { "system": "yes", "qt": "no" } },
- "pepper-plugins": { "type": "boolean", "name": "webengine-pepper-plugins" },
- "printing-and-pdf": { "type": "boolean", "name": "webengine-printing-and-pdf" },
- "proprietary-codecs": { "type": "boolean", "name": "webengine-proprietary-codecs" },
- "spellchecker": { "type": "boolean", "name": "webengine-spellchecker" },
- "extensions": { "type": "boolean", "name": "webengine-extensions" },
- "webrtc": { "type": "boolean", "name": "webengine-webrtc" }
- }
- },
-
- "libraries": {
- "webengine-alsa": {
- "label": "alsa",
- "test": {
- "tail": [
- "#if SND_LIB_VERSION < 0x1000a // 1.0.10",
- "#error Alsa version found too old, require >= 1.0.10",
- "#endif"
- ]
- },
- "headers" : ["alsa/asoundlib.h"],
- "sources" : [{ "type": "pkgConfig", "args": "alsa" }
- ]
- },
- "webengine-poppler-cpp": {
- "label": "poppler-cpp",
- "sources": [
- { "type": "pkgConfig", "args": "poppler-cpp" }
- ]
- },
- "webengine-pulseaudio": {
- "label": "pulseaudio >= 0.9.10",
- "sources": [
- { "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" }
- ]
- },
- "webengine-gio": {
- "label": "gio",
- "sources": [
- { "type": "pkgConfig", "args": "gio-2.0" }
- ]
- }
- },
- "tests" : {
- "webengine-host-compiler": {
- "label": "host compiler",
- "test": "hostcompiler",
- "host": "true",
- "type": "compile"
- },
- "webengine-host-pkg-config": {
- "label": "host pkg-config",
- "type": "detectHostPkgConfig",
- "log": "path"
- },
- "webengine-embedded-build": {
- "label": "embedded build",
- "type": "detectEmbedded"
- }
- },
- "features": {
- "webengine-embedded-build": {
- "label": "Embedded build",
- "purpose": "Enables the embedded build configuration.",
- "condition": "config.unix",
- "autoDetect": "tests.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-alsa": {
- "label": "Use ALSA",
- "condition": "config.unix && libs.webengine-alsa",
- "output": [ "privateFeature" ]
- },
- "webengine-v8-snapshot-support": {
- "label" : "Building v8 snapshot supported",
- "condition": "!config.unix || !features.cross_compile || arch.arm64 || tests.webengine-host-compiler",
- "output": [ "privateFeature" ]
- },
- "webengine-geolocation": {
- "label": "Geolocation",
- "condition": "module.positioning",
- "output": [ "publicFeature" ]
- },
- "webengine-pulseaudio": {
- "label": "Use PulseAudio",
- "autoDetect": "config.unix",
- "condition": "libs.webengine-pulseaudio",
- "output": [ "privateFeature" ]
- },
- "webengine-pepper-plugins": {
- "label": "Pepper Plugins",
- "purpose": "Enables use of Pepper Flash plugins.",
- "autoDetect": "!features.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-printing-and-pdf": {
- "label": "Printing and PDF",
- "purpose": "Provides printing and output to PDF.",
- "condition": "module.printsupport && features.printer",
- "autoDetect": "!features.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-webchannel": {
- "label": "WebChannel support",
- "purpose": "Provides QtWebChannel integration.",
- "section": "WebEngine",
- "condition": "module.webchannel",
- "output": [ "publicFeature" ]
- },
- "webengine-proprietary-codecs": {
- "label": "Proprietary Codecs",
- "purpose": "Enables the use of proprietary codecs such as h.264/h.265 and MP3.",
- "autoDetect": false,
- "output": [ "privateFeature" ]
- },
- "webengine-kerberos": {
- "label": "Kerberos Authentication",
- "purpose": "Enables Kerberos Authentication Support",
- "autoDetect": "config.win32",
- "section": "WebEngine",
- "output": [ "privateFeature" ]
- },
- "webengine-spellchecker": {
- "label": "Spellchecker",
- "purpose": "Provides a spellchecker.",
- "output": [ "publicFeature" ]
- },
- "webengine-native-spellchecker": {
- "label": "Native Spellchecker",
- "purpose": "Use the system's native spellchecking engine.",
- "autoDetect": false,
- "condition": "config.macos && features.webengine-spellchecker",
- "output": [ "publicFeature" ]
- },
- "webengine-extensions": {
- "label": "Extensions",
- "purpose": "Enables Chromium extensions within certain limits. Currently used for enabling the pdf viewer.",
- "section": "WebEngine",
- "condition": "features.webengine-printing-and-pdf",
- "autoDetect": "features.webengine-printing-and-pdf",
- "output": [ "publicFeature" ]
- },
- "webengine-webrtc": {
- "label": "WebRTC",
- "purpose": "Provides WebRTC support.",
- "autoDetect": "!features.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-webrtc-pipewire": {
- "label": "PipeWire over GIO",
- "purpose": "Provides PipeWire support in WebRTC using GIO.",
- "condition": "features.webengine-webrtc && libs.webengine-gio",
- "autoDetect": "false",
- "output": [ "privateFeature" ]
- },
- "webengine-ozone" : {
- "label": "Support qpa-xcb",
- "condition": "features.webengine-ozone-x11",
- "output": [ "privateFeature" ]
- },
- "webengine-poppler-cpp": {
- "label": "poppler-cpp",
- "autoDetect": "config.unix",
- "condition": "libs.webengine-poppler-cpp",
- "output": [ "privateFeature" ]
- },
- "webengine-full-debug-info": {
- "label": "Full debug information",
- "purpose": "Enables debug information for Blink and V8.",
- "autoDetect": false,
- "condition": "config.debug || features.debug_and_release || features.force_debug_info",
- "output": [
- { "type": "privateConfig", "name": "v8base_debug" },
- { "type": "privateConfig", "name": "webcore_debug" }
- ]
- }
- },
-
- "report": [
- {
- "type": "warning",
- "condition": "config.unix && !features.webengine-host-pkg-config",
- "message": "host pkg-config not found"
- },
- {
- "type": "warning",
- "condition": "config.linux && features.webengine-embedded-build && !features.webengine-system-ffmpeg && arch.arm && !features.webengine-arm-thumb",
- "message": "Thumb instruction set is required to build ffmpeg for QtWebEngine."
- },
- {
- "type": "warning",
- "condition": "config.unix && config.cross_compile && !features.webengine-v8-snapshot-support",
- "message": "V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work. Please make sure you have 32-bit devel environment installed."
- }
- ],
-
- "summary": [
- {
- "section": "Qt WebEngineCore",
- "condition": "features.build-qtwebengine-core",
- "entries": [
- "webengine-embedded-build",
- "webengine-full-debug-info",
- "webengine-pepper-plugins",
- "webengine-printing-and-pdf",
- "webengine-proprietary-codecs",
- "webengine-spellchecker",
- "webengine-native-spellchecker",
- "webengine-webrtc",
- "webengine-webrtc-pipewire",
- "webengine-geolocation",
- "webengine-webchannel",
- "webengine-kerberos",
- "webengine-extensions",
- {
- "type": "feature",
- "args": "webengine-ozone",
- "condition": "config.unix"
- },
- {
- "type": "feature",
- "args": "webengine-v8-snapshot-support",
- "condition": "config.unix && config.cross_compile"
- },
- {
- "type": "feature",
- "args": "webengine-alsa",
- "condition": "config.unix"
- },
- {
- "type": "feature",
- "args": "webengine-pulseaudio",
- "condition": "config.unix"
- },
- {
- "message": "macOS version",
- "type": "macosToolchainVersion",
- "args": "macosVersion",
- "condition": "config.macos"
- },
- {
- "message": "Xcode version",
- "type": "macosToolchainVersion",
- "args": "xcodeVersion",
- "condition": "config.macos"
- },
- {
- "message": "Clang version",
- "type": "macosToolchainVersion",
- "args": "clangVersion",
- "condition": "config.macos"
- },
- {
- "message": "macOS SDK version",
- "type": "macosToolchainVersion",
- "args": "sdkVersion",
- "condition": "config.macos"
- },
- {
- "message": "macOS minimum deployment target",
- "type": "macosToolchainVersion",
- "args": "deploymentTarget",
- "condition": "config.macos"
- }
- ]
- }
- ]
-}
diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index efbb28075..01bf84b70 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -97,7 +97,7 @@ config("cpp17_config") {
}
shared_library("QtWebEngineCore") {
- rsp_types = [ "objects", "archives", "libs" ]
+ rsp_types = [ "objects", "archives", "libs", "lflags"]
configs += [
":cpp17_config",
":QtWebEngineCore_config",
@@ -109,21 +109,25 @@ shared_library("QtWebEngineCore") {
"//third_party/boringssl/src/include",
"//third_party/skia/include/core"
]
- defines = [ "CHROMIUM_VERSION=\"" + chromium_version[0] + "\"" ]
+ defines = [ "CHROMIUM_VERSION=" + chromium_version[0] ]
deps = [
"//base",
"//components/autofill/content/browser",
"//components/autofill/content/renderer",
"//components/autofill/core/browser",
+ "//components/autofill/core/browser:buildflags",
"//components/cdm/renderer",
+ "//components/embedder_support/origin_trials",
"//components/error_page/common",
"//components/favicon/content",
+ "//components/gcm_driver",
"//components/history/content/browser",
"//components/keyed_service/content",
"//components/navigation_interception",
"//components/network_hints/browser",
"//components/network_hints/common:mojo_bindings",
"//components/network_hints/renderer",
+ "//components/signin/public/base",
"//components/visitedlink/browser",
"//components/visitedlink/renderer",
"//components/web_cache/browser",
@@ -135,6 +139,7 @@ shared_library("QtWebEngineCore") {
"//content/public/app",
"//content/public/browser",
"//content",
+ "//gpu/ipc:gl_in_process_context",
"//media:media_buildflags",
"//net",
"//services/proxy_resolver:lib",
@@ -212,6 +217,32 @@ source_set("qtwebengine_spellcheck_sources") {
}
}
+source_set("devtools_sources") {
+ configs += [ ":cpp17_config" ]
+ deps = [
+ "//components/zoom",
+ "//third_party/blink/public/mojom:mojom_platform",
+ ]
+ sources = [
+ "//chrome/browser/devtools/devtools_eye_dropper.cc",
+ "//chrome/browser/devtools/devtools_eye_dropper.h",
+ "//chrome/browser/devtools/devtools_file_helper.cc",
+ "//chrome/browser/devtools/devtools_file_helper.h",
+ "//chrome/browser/devtools/devtools_file_system_indexer.cc",
+ "//chrome/browser/devtools/devtools_file_system_indexer.h",
+ "//chrome/browser/devtools/devtools_file_watcher.cc",
+ "//chrome/browser/devtools/devtools_file_watcher.h",
+ "//chrome/browser/devtools/url_constants.cc",
+ "//chrome/browser/devtools/url_constants.h",
+ "//chrome/browser/devtools/devtools_ui_bindings.cc",
+ "//chrome/browser/devtools/devtools_ui_bindings.h",
+ "//chrome/browser/devtools/devtools_settings.cc",
+ "//chrome/browser/devtools/devtools_settings.h",
+ "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc",
+ "//chrome/browser/devtools/devtools_embedder_message_dispatcher.h",
+ ]
+}
+
source_set("qtwebengine_sources") {
configs += [
":cpp17_config",
@@ -219,12 +250,16 @@ source_set("qtwebengine_sources") {
"//third_party/boringssl:external_config",
]
deps = [
+ ":devtools_sources",
"//build:branding_buildflags",
+ "//build/config/chromebox_for_meetings:buildflags",
"//chrome/browser:dev_ui_browser_resources_grit",
"//chrome/browser/resources/net_internals:resources",
+ "//chrome/browser/signin:identity_manager_provider",
"//chrome/common:buildflags",
- "//chromeos/components/chromebox_for_meetings/buildflags",
+ "//chrome/common:version_header",
"//components/custom_handlers",
+ "//components/embedder_support:embedder_support",
"//components/nacl/common:buildflags",
"//components/performance_manager",
"//components/plugins/renderer/",
@@ -239,15 +274,51 @@ source_set("qtwebengine_sources") {
sources = [
"//chrome/browser/accessibility/accessibility_ui.cc",
"//chrome/browser/accessibility/accessibility_ui.h",
- "//chrome/browser/devtools/devtools_eye_dropper.cc",
- "//chrome/browser/devtools/devtools_eye_dropper.h",
+ "//chrome/browser/gcm/gcm_product_util.cc",
+ "//chrome/browser/gcm/gcm_product_util.h",
+ "//chrome/browser/gcm/gcm_profile_service_factory.cc",
+ "//chrome/browser/gcm/gcm_profile_service_factory.h",
+ "//chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc",
+ "//chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h",
"//chrome/browser/media/webrtc/desktop_media_list.h",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
"//chrome/browser/prefs/chrome_command_line_pref_store.cc",
"//chrome/browser/prefs/chrome_command_line_pref_store.h",
+ "//chrome/browser/profiles/incognito_helpers.cc",
+ "//chrome/browser/profiles/incognito_helpers.h",
+ "//chrome/browser/profiles/profile_keyed_service_factory.cc",
+ "//chrome/browser/profiles/profile_keyed_service_factory.h",
+ "//chrome/browser/profiles/profile_selections.cc",
+ "//chrome/browser/profiles/profile_selections.h",
"//chrome/browser/profiles/profile.cc",
"//chrome/browser/profiles/profile.h",
+ "//chrome/browser/push_messaging/push_messaging_app_identifier.cc",
+ "//chrome/browser/push_messaging/push_messaging_app_identifier.h",
+ "//chrome/browser/push_messaging/push_messaging_constants.cc",
+ "//chrome/browser/push_messaging/push_messaging_constants.h",
+ "//chrome/browser/push_messaging/push_messaging_features.cc",
+ "//chrome/browser/push_messaging/push_messaging_features.h",
+ "//chrome/browser/push_messaging/push_messaging_notification_manager.cc",
+ "//chrome/browser/push_messaging/push_messaging_notification_manager.h",
+ "//chrome/browser/push_messaging/push_messaging_refresher.cc",
+ "//chrome/browser/push_messaging/push_messaging_refresher.h",
+ "//chrome/browser/push_messaging/push_messaging_service_factory.cc",
+ "//chrome/browser/push_messaging/push_messaging_service_factory.h",
+ "//chrome/browser/push_messaging/push_messaging_service_impl.cc",
+ "//chrome/browser/push_messaging/push_messaging_service_impl.h",
+ "//chrome/browser/push_messaging/push_messaging_utils.cc",
+ "//chrome/browser/push_messaging/push_messaging_utils.h",
+ "//chrome/browser/signin/chrome_signin_client.cc",
+ "//chrome/browser/signin/chrome_signin_client.h",
+ "//chrome/browser/signin/chrome_signin_client_factory.cc",
+ "//chrome/browser/signin/chrome_signin_client_factory.h",
+ "//chrome/browser/signin/force_signin_verifier.cc",
+ "//chrome/browser/signin/force_signin_verifier.h",
+ "//chrome/browser/signin/identity_manager_factory.cc",
+ "//chrome/browser/signin/identity_manager_factory.h",
+ "//chrome/browser/signin/signin_util.cc",
+ "//chrome/browser/signin/signin_util.h",
"//chrome/browser/tab_contents/form_interaction_tab_helper.cc",
"//chrome/browser/tab_contents/form_interaction_tab_helper.h",
"//chrome/browser/tab_contents/web_contents_collection.cc",
@@ -274,6 +345,8 @@ source_set("qtwebengine_sources") {
"//chrome/common/url_constants.h",
"//chrome/common/webui_url_constants.cc",
"//chrome/common/webui_url_constants.h",
+ "//components/embedder_support/user_agent_utils.cc",
+ "//components/embedder_support/user_agent_utils.h",
]
if (enable_extensions) {
deps += [
@@ -317,12 +390,23 @@ source_set("qtwebengine_sources") {
"//extensions/common/url_pattern.h",
]
}
- if (is_linux) {
+ if (is_linux || is_win) {
sources += [
"//chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc",
"//chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h",
]
}
+ if (is_win) {
+ sources += [
+ "//chrome/browser/net/chrome_mojo_proxy_resolver_win.cc",
+ "//chrome/browser/net/chrome_mojo_proxy_resolver_win.h",
+ "//chrome/browser/ui/webui/sandbox/sandbox_handler.cc",
+ "//chrome/browser/ui/webui/sandbox/sandbox_handler.h",
+ ]
+ deps += [ "//services/proxy_resolver_win",
+ "//services/proxy_resolver_win/public/mojom",
+ ]
+ }
if (enable_spellcheck) {
deps += [
":qtwebengine_spellcheck_sources",
@@ -363,7 +447,7 @@ source_set("qtwebengine_sources") {
if (enable_webrtc && enable_extensions) {
deps += [
- "//chrome/browser/resources/media:webrtc_logs_resources",
+ "//chrome/browser/resources/media:resources",
"//components/upload_list",
"//components/webrtc_logging/browser",
"//components/webrtc_logging/common",
@@ -448,6 +532,7 @@ repack("qtwebengine_repack_resources") {
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/content/dev_ui_content_resources.pak",
+ "$root_gen_dir/content/indexed_db_resources.pak",
"$root_gen_dir/content/quota_internals_resources.pak",
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
"$root_gen_dir/net/net_resources.pak",
@@ -465,6 +550,7 @@ repack("qtwebengine_repack_resources") {
"//content/browser/resources/media:resources",
"//content/browser/tracing:resources",
"//content:content_resources",
+ "//content/browser/resources/indexed_db:resources",
"//content/browser/resources/quota:resources",
"//content:dev_ui_content_resources_grit",
"//mojo/public/js:resources",
@@ -494,10 +580,10 @@ repack("qtwebengine_repack_resources") {
}
if (enable_webrtc && enable_extensions) {
sources += [
- "$root_gen_dir/chrome/webrtc_logs_resources.pak",
+ "$root_gen_dir/chrome/media_resources.pak",
]
deps += [
- "//chrome/browser/resources/media:webrtc_logs_resources",
+ "//chrome/browser/resources/media:resources",
]
}
if (enable_pdf) {
@@ -514,7 +600,6 @@ repack("qtwebengine_repack_resources_100") {
sources = [
"$root_gen_dir/chrome/renderer_resources_100_percent.pak",
"$root_gen_dir/components/components_resources_100_percent.pak",
- "$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
"$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
]
@@ -522,7 +607,6 @@ repack("qtwebengine_repack_resources_100") {
deps = [
"//chrome/renderer:resources_grit",
"//components/resources:components_scaled_resources_grit",
- "//content/app/resources:resources_grit",
"//third_party/blink/public:scaled_resources_100_percent",
"//ui/resources:ui_resources_grd_grit"
]
@@ -540,7 +624,6 @@ repack("qtwebengine_repack_resources_200") {
sources = [
"$root_gen_dir/chrome/renderer_resources_200_percent.pak",
"$root_gen_dir/components/components_resources_200_percent.pak",
- "$root_gen_dir/content/app/resources/content_resources_200_percent.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_200_percent.pak",
"$root_gen_dir/ui/resources/ui_resources_200_percent.pak",
]
@@ -548,7 +631,6 @@ repack("qtwebengine_repack_resources_200") {
deps = [
"//chrome/renderer:resources_grit",
"//components/resources:components_scaled_resources_grit",
- "//content/app/resources:resources_grit",
"//third_party/blink/public:scaled_resources_200_percent",
"//ui/resources:ui_resources_grd_grit"
]
@@ -609,7 +691,7 @@ if (enable_extensions) {
if (enable_spellcheck) {
shared_library("convert_dict") {
- rsp_types = [ "objects", "archives", "libs" ]
+ rsp_types = [ "objects", "archives", "libs", "lflags" ]
configs += [ "//build/config/compiler:wexit_time_destructors" ]
deps = [
"//chrome/tools/convert_dict:lib",
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index f55e52eec..bf39ebe2f 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -4,10 +4,10 @@
#include "content_browser_client_qt.h"
#include "base/files/file_util.h"
-#include "base/task/post_task.h"
#include "chrome/browser/tab_contents/form_interaction_tab_helper.h"
#include "components/autofill/content/browser/content_autofill_driver_factory.h"
#include "components/custom_handlers/protocol_handler_registry.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "components/error_page/common/error.h"
#include "components/error_page/common/localized_error.h"
#include "components/navigation_interception/intercept_navigation_throttle.h"
@@ -30,9 +30,11 @@
#include "content/public/browser/url_loader_request_interceptor.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
+#include "content/public/browser/web_contents_view_delegate.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
+#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
@@ -71,7 +73,6 @@
#include "platform_notification_service_qt.h"
#include "profile_qt.h"
#include "profile_io_data_qt.h"
-#include "quota_permission_context_qt.h"
#include "renderer_host/user_resource_controller_host.h"
#include "select_file_dialog_factory_qt.h"
#include "type_conversion.h"
@@ -93,7 +94,11 @@
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
+#include "chrome/browser/spellchecker/spellcheck_factory.h"
+#include "chrome/browser/spellchecker/spellcheck_service.h"
+#include "components/spellcheck/browser/pref_names.h"
#include "components/spellcheck/common/spellcheck.mojom.h"
+#include "components/spellcheck/common/spellcheck_features.h"
#endif
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
@@ -107,6 +112,7 @@
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "common/extensions/extensions_client_qt.h"
#include "components/guest_view/browser/guest_view_base.h"
+#include "extensions/browser/api/messaging/messaging_api_message_filter.h"
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_message_filter.h"
@@ -200,7 +206,7 @@ ContentBrowserClientQt::~ContentBrowserClientQt()
{
}
-std::unique_ptr<content::BrowserMainParts> ContentBrowserClientQt::CreateBrowserMainParts(content::MainFunctionParams)
+std::unique_ptr<content::BrowserMainParts> ContentBrowserClientQt::CreateBrowserMainParts(bool)
{
Q_ASSERT(!m_browserMainParts);
auto browserMainParts = std::make_unique<BrowserMainPartsQt>();
@@ -213,6 +219,11 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
const int id = host->GetID();
Profile *profile = Profile::FromBrowserContext(host->GetBrowserContext());
+#if QT_CONFIG(webengine_spellchecker)
+ if (spellcheck::UseBrowserSpellChecker() && !profile->GetPrefs()->GetBoolean(spellcheck::prefs::kSpellCheckEnable))
+ SpellcheckServiceFactory::GetForContext(profile)->InitForRenderer(host);
+#endif
+
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
WebRtcLoggingController::AttachToRenderProcessHost(host, WebEngineContext::current()->webRtcLogUploader());
#endif
@@ -229,6 +240,7 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
host->AddFilter(new BrowserMessageFilterQt(id, profile));
#if BUILDFLAG(ENABLE_EXTENSIONS)
host->AddFilter(new extensions::ExtensionMessageFilter(id, profile));
+ host->AddFilter(new extensions::MessagingAPIMessageFilter(id, profile));
#endif //ENABLE_EXTENSIONS
bool is_incognito_process = profile->IsOffTheRecord();
@@ -257,11 +269,6 @@ void ContentBrowserClientQt::OverrideWebkitPrefs(content::WebContents *webConten
delegate->overrideWebPreferences(webContents, web_prefs);
}
-scoped_refptr<content::QuotaPermissionContext> ContentBrowserClientQt::CreateQuotaPermissionContext()
-{
- return new QuotaPermissionContextQt;
-}
-
void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webContents,
int cert_error,
const net::SSLInfo &ssl_info,
@@ -449,12 +456,12 @@ void ContentBrowserClientQt::ExposeInterfacesToRenderer(service_manager::BinderR
if (auto *manager = performance_manager::PerformanceManagerRegistry::GetInstance())
manager->CreateProcessNodeAndExposeInterfacesToRendererProcess(registry, render_process_host);
#if BUILDFLAG(ENABLE_EXTENSIONS)
- associated_registry->AddInterface(base::BindRepeating(&extensions::EventRouter::BindForRenderer,
- render_process_host->GetID()));
- associated_registry->AddInterface(base::BindRepeating(&extensions::ExtensionsGuestView::CreateForComponents,
- render_process_host->GetID()));
- associated_registry->AddInterface(base::BindRepeating(&extensions::ExtensionsGuestView::CreateForExtensions,
- render_process_host->GetID()));
+ associated_registry->AddInterface<extensions::mojom::EventRouter>(
+ base::BindRepeating(&extensions::EventRouter::BindForRenderer, render_process_host->GetID()));
+ associated_registry->AddInterface<guest_view::mojom::GuestViewHost>(
+ base::BindRepeating(&extensions::ExtensionsGuestView::CreateForComponents, render_process_host->GetID()));
+ associated_registry->AddInterface<extensions::mojom::GuestView>(
+ base::BindRepeating(&extensions::ExtensionsGuestView::CreateForExtensions, render_process_host->GetID()));
#else
Q_UNUSED(associated_registry);
#endif
@@ -465,7 +472,7 @@ void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHos
blink::AssociatedInterfaceRegistry &associated_registry)
{
#if QT_CONFIG(webengine_webchannel)
- associated_registry.AddInterface(
+ associated_registry.AddInterface<qtwebchannel::mojom::WebChannelTransportHost>(
base::BindRepeating(
[](content::RenderFrameHost *render_frame_host,
mojo::PendingAssociatedReceiver<qtwebchannel::mojom::WebChannelTransportHost> receiver) {
@@ -475,7 +482,7 @@ void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHos
}, &rfh));
#endif
#if BUILDFLAG(ENABLE_PRINTING) && BUILDFLAG(ENABLE_PRINT_PREVIEW)
- associated_registry.AddInterface(
+ associated_registry.AddInterface<printing::mojom::PrintManagerHost>(
base::BindRepeating(
[](content::RenderFrameHost* render_frame_host,
mojo::PendingAssociatedReceiver<printing::mojom::PrintManagerHost> receiver) {
@@ -483,21 +490,21 @@ void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHos
}, &rfh));
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
- associated_registry.AddInterface(
+ associated_registry.AddInterface<extensions::mojom::LocalFrameHost>(
base::BindRepeating(
[](content::RenderFrameHost *render_frame_host,
mojo::PendingAssociatedReceiver<extensions::mojom::LocalFrameHost> receiver) {
extensions::ExtensionWebContentsObserverQt::BindLocalFrameHost(std::move(receiver), render_frame_host);
}, &rfh));
#endif
- associated_registry.AddInterface(
+ associated_registry.AddInterface<autofill::mojom::AutofillDriver>(
base::BindRepeating(
[](content::RenderFrameHost *render_frame_host,
mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver> receiver) {
autofill::ContentAutofillDriverFactory::BindAutofillDriver(std::move(receiver), render_frame_host);
}, &rfh));
#if BUILDFLAG(ENABLE_PDF)
- associated_registry.AddInterface(
+ associated_registry.AddInterface<pdf::mojom::PdfService>(
base::BindRepeating(
[](content::RenderFrameHost *render_frame_host,
mojo::PendingAssociatedReceiver<pdf::mojom::PdfService> receiver) {
@@ -663,7 +670,7 @@ static void LaunchURL(const GURL& url,
has_user_gesture);
if (!allowed) {
- content::RenderFrameHost *rfh = webContents->GetMainFrame();
+ content::RenderFrameHost *rfh = webContents->GetPrimaryMainFrame();
if (!base::CommandLine::ForCurrentProcess()->HasSwitch("disable-sandbox-external-protocols")) {
rfh->AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kError,
"Navigation to external protocol blocked by sandbox.");
@@ -697,7 +704,7 @@ bool ContentBrowserClientQt::HandleExternalProtocol(const GURL &url,
Q_UNUSED(initiator_document);
Q_UNUSED(out_factory);
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&LaunchURL,
url,
std::move(web_contents_getter),
@@ -953,7 +960,15 @@ void ContentBrowserClientQt::OverrideURLLoaderFactoryParams(content::BrowserCont
std::string ContentBrowserClientQt::getUserAgent()
{
// Mention the Chromium version we're based on to get passed stupid UA-string-based feature detection (several WebRTC demos need this)
- return content::BuildUserAgentFromProduct("QtWebEngine/" QTWEBENGINECORE_VERSION_STR " Chrome/" CHROMIUM_VERSION);
+ return content::BuildUserAgentFromProduct("QtWebEngine/" + std::string(qWebEngineVersion())
+ + " Chrome/"
+ + std::string(qWebEngineChromiumVersion()));
+}
+
+blink::UserAgentMetadata ContentBrowserClientQt::getUserAgentMetadata()
+{
+ static blink::UserAgentMetadata userAgentMetadata(embedder_support::GetUserAgentMetadata());
+ return userAgentMetadata;
}
std::string ContentBrowserClientQt::GetProduct()
@@ -1200,8 +1215,7 @@ bool ContentBrowserClientQt::WillCreateURLLoaderFactory(
std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
ContentBrowserClientQt::WillCreateURLLoaderRequestInterceptors(content::NavigationUIData* navigation_ui_data,
- int frame_tree_node_id,
- const scoped_refptr<network::SharedURLLoaderFactory>& network_loader_factory)
+ int frame_tree_node_id)
{
std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>> interceptors;
#if BUILDFLAG(ENABLE_PDF) && BUILDFLAG(ENABLE_EXTENSIONS)
@@ -1274,7 +1288,7 @@ void ContentBrowserClientQt::CreateWebSocket(
to_url = toGurl(infoPrivate->url);
for (auto header = infoPrivate->extraHeaders.constBegin(); header != infoPrivate->extraHeaders.constEnd(); ++header) {
std::string h = header.key().toStdString();
- if (base::LowerCaseEqualsASCII(h, net::HttpRequestHeaders::kUserAgent))
+ if (base::EqualsCaseInsensitiveASCII(h, net::HttpRequestHeaders::kUserAgent))
addedUserAgent = true;
headers.push_back(network::mojom::HttpHeader::New(h, header.value().toStdString()));
}
@@ -1317,7 +1331,7 @@ void ContentBrowserClientQt::SiteInstanceDeleting(content::SiteInstance *site_in
#endif
}
-content::WebContentsViewDelegate *ContentBrowserClientQt::GetWebContentsViewDelegate(content::WebContents *web_contents)
+std::unique_ptr<content::WebContentsViewDelegate> ContentBrowserClientQt::GetWebContentsViewDelegate(content::WebContents *web_contents)
{
FormInteractionTabHelper::CreateForWebContents(web_contents);
FileSystemAccessPermissionRequestManagerQt::CreateForWebContents(web_contents);
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index ded346a34..87e48db5a 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -37,10 +37,9 @@ class ContentBrowserClientQt : public content::ContentBrowserClient
public:
ContentBrowserClientQt();
~ContentBrowserClientQt();
- std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(content::MainFunctionParams) override;
+ std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(bool is_integration_test) override;
void RenderProcessWillLaunch(content::RenderProcessHost *host) override;
content::MediaObserver* GetMediaObserver() override;
- scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override;
void OverrideWebkitPrefs(content::WebContents *web_contents,
blink::web_pref::WebPreferences *prefs) override;
void AllowCertificateError(content::WebContents *web_contents,
@@ -188,8 +187,7 @@ public:
const std::string &scheme) override;
std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
WillCreateURLLoaderRequestInterceptors(content::NavigationUIData *navigation_ui_data,
- int frame_tree_node_id,
- const scoped_refptr<network::SharedURLLoaderFactory> &network_loader_factory) override;
+ int frame_tree_node_id) override;
bool WillCreateURLLoaderFactory(content::BrowserContext *browser_context,
content::RenderFrameHost *frame,
int render_process_id,
@@ -226,11 +224,13 @@ public:
void SiteInstanceDeleting(content::SiteInstance *site_instance) override;
base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(content::BrowserContext *browser_context) override;
- content::WebContentsViewDelegate* GetWebContentsViewDelegate(content::WebContents* web_contents) override;
+ std::unique_ptr<content::WebContentsViewDelegate> GetWebContentsViewDelegate(content::WebContents *web_contents) override;
static std::string getUserAgent();
+ static blink::UserAgentMetadata getUserAgentMetadata();
std::string GetUserAgent() override { return getUserAgent(); }
+ blink::UserAgentMetadata GetUserAgentMetadata() override { return getUserAgentMetadata(); }
std::string GetProduct() override;
private:
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 67faabde8..fab8a5abb 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -50,8 +50,8 @@ const char kWidevineCdmFileName[] =
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if QT_CONFIG(webengine_printing_and_pdf)
+#include "components/pdf/common/internal_plugin_helpers.h"
#include "pdf/pdf.h"
-const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
const char kPdfPluginPath[] = "internal-pdf-viewer";
#endif // QT_CONFIG(webengine_printing_and_pdf)
@@ -98,7 +98,7 @@ static QString getProgramFilesDir(bool x86Dir = false)
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.Chromium file.
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
static QString ppapiPluginsPath()
@@ -114,16 +114,19 @@ static QString ppapiPluginsPath()
return potentialPluginsPath;
}
-void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins)
+void ComputeBuiltInPlugins(std::vector<content::ContentPluginInfo> *plugins)
{
#if QT_CONFIG(webengine_printing_and_pdf)
- content::PepperPluginInfo pdf_info;
+ static constexpr char kPDFPluginExtension[] = "pdf";
+ static constexpr char kPDFPluginDescription[] = "Portable Document Format";
+ content::ContentPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
pdf_info.name = "Chromium PDF Viewer";
- pdf_info.description = "Portable Document Format";
+ pdf_info.description = kPDFPluginDescription;
pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
- content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf", "Portable Document Format");
+ content::WebPluginMimeType pdf_mime_type(
+ pdf::kInternalPluginMimeType, kPDFPluginExtension, kPDFPluginDescription);
pdf_info.mime_types.push_back(pdf_mime_type);
plugins->push_back(pdf_info);
#endif // QT_CONFIG(webengine_printing_and_pdf)
@@ -131,7 +134,7 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins)
namespace QtWebEngineCore {
-void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins)
+void ContentClientQt::AddPlugins(std::vector<content::ContentPluginInfo> *plugins)
{
ComputeBuiltInPlugins(plugins);
}
@@ -417,4 +420,19 @@ std::u16string ContentClientQt::GetLocalizedString(int message_id)
return l10n_util::GetStringUTF16(message_id);
}
+// This method is a copy from chrome/common/chrome_content_client.cc:
+// Copyright 2012 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE.Chromium file.
+blink::OriginTrialPolicy *ContentClientQt::GetOriginTrialPolicy()
+{
+ // Prevent initialization race (see crbug.com/721144). There may be a
+ // race when the policy is needed for worker startup (which happens on a
+ // separate worker thread).
+ base::AutoLock auto_lock(origin_trial_policy_lock_);
+ if (!origin_trial_policy_)
+ origin_trial_policy_ = std::make_unique<embedder_support::OriginTrialPolicyImpl>();
+ return origin_trial_policy_.get();
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/content_client_qt.h b/src/core/content_client_qt.h
index f0afdcb58..f58e17f96 100644
--- a/src/core/content_client_qt.h
+++ b/src/core/content_client_qt.h
@@ -5,16 +5,21 @@
#define CONTENT_CLIENT_QT_H
#include "qtwebenginecoreglobal_p.h"
+
#include "base/strings/string_piece.h"
+#include "base/synchronization/lock.h"
+#include "components/embedder_support/origin_trials/origin_trial_policy_impl.h"
#include "content/public/common/content_client.h"
#include "ui/base/layout.h"
+#include <memory>
+
namespace QtWebEngineCore {
class ContentClientQt : public content::ContentClient {
public:
#if QT_CONFIG(webengine_pepper_plugins)
- void AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) override;
+ void AddPlugins(std::vector<content::ContentPluginInfo> *plugins) override;
#endif
void AddContentDecryptionModules(std::vector<content::CdmInfo> *cdms,
std::vector<media::CdmHostFilePath> *cdm_host_file_paths) override;
@@ -24,6 +29,12 @@ public:
base::RefCountedMemory* GetDataResourceBytes(int resource_id) override;
gfx::Image &GetNativeImageNamed(int resource_id) override;
std::u16string GetLocalizedString(int message_id) override;
+ blink::OriginTrialPolicy *GetOriginTrialPolicy() override;
+
+private:
+ // Used to lock when |origin_trial_policy_| is initialized.
+ base::Lock origin_trial_policy_lock_;
+ std::unique_ptr<embedder_support::OriginTrialPolicyImpl> origin_trial_policy_;
};
} // namespace QtWebEngineCore
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index bd7a23497..52e23399e 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -77,19 +77,18 @@ struct LazyDirectoryListerCacher
{
LazyDirectoryListerCacher()
{
- base::DictionaryValue dict;
- dict.SetString("header", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_HEADER));
- dict.SetString("parentDirText", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_PARENT));
- dict.SetString("headerName", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_NAME));
- dict.SetString("headerSize", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_SIZE));
- dict.SetString("headerDateModified",
- l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_DATE_MODIFIED));
- dict.SetString("language", l10n_util::GetLanguage(base::i18n::GetConfiguredLocale()));
- dict.SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
+ base::Value::Dict dict;
+ dict.Set("header", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_HEADER));
+ dict.Set("parentDirText", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_PARENT));
+ dict.Set("headerName", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_NAME));
+ dict.Set("headerSize", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_SIZE));
+ dict.Set("headerDateModified", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_DATE_MODIFIED));
+ dict.Set("language", l10n_util::GetLanguage(base::i18n::GetConfiguredLocale()));
+ dict.Set("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
std::string html =
webui::GetI18nTemplateHtml(
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_DIR_HEADER_HTML),
- &dict);
+ std::move(dict));
html_data = base::RefCountedString::TakeString(&html);
}
@@ -198,11 +197,6 @@ void ContentMainDelegateQt::PreSandboxStartup()
}
}
-void ContentMainDelegateQt::PostEarlyInitialization(bool)
-{
- PostFieldTrialInitialization();
-}
-
content::ContentClient *ContentMainDelegateQt::CreateContentClient()
{
return &m_contentClient;
@@ -264,7 +258,7 @@ static void SafeOverridePathImpl(const char *keyName, int key, const base::FileP
#define SafeOverridePath(KEY, PATH) SafeOverridePathImpl(#KEY, KEY, PATH)
-bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
+absl::optional<int> ContentMainDelegateQt::BasicStartupComplete()
{
SafeOverridePath(base::FILE_EXE, WebEngineLibraryInfo::getPath(base::FILE_EXE));
SafeOverridePath(base::DIR_QT_LIBRARY_DATA, WebEngineLibraryInfo::getPath(base::DIR_QT_LIBRARY_DATA));
@@ -275,7 +269,7 @@ bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
url::CustomScheme::LoadSchemes(base::CommandLine::ForCurrentProcess());
- return false;
+ return absl::nullopt;
}
} // namespace QtWebEngineCore
diff --git a/src/core/content_main_delegate_qt.h b/src/core/content_main_delegate_qt.h
index f88c3dea0..a177bd6df 100644
--- a/src/core/content_main_delegate_qt.h
+++ b/src/core/content_main_delegate_qt.h
@@ -20,14 +20,13 @@ public:
// This is where the embedder puts all of its startup code that needs to run
// before the sandbox is engaged.
void PreSandboxStartup() override;
- void PostEarlyInitialization(bool) override;
content::ContentClient *CreateContentClient() override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentGpuClient* CreateContentGpuClient() override;
content::ContentRendererClient* CreateContentRendererClient() override;
content::ContentUtilityClient* CreateContentUtilityClient() override;
- bool BasicStartupComplete(int* /*exit_code*/) override;
+ absl::optional<int> BasicStartupComplete() override;
private:
ContentClientQt m_contentClient;
diff --git a/src/core/content_utility_client_qt.cpp b/src/core/content_utility_client_qt.cpp
index c76cab2f9..7af90c7a1 100644
--- a/src/core/content_utility_client_qt.cpp
+++ b/src/core/content_utility_client_qt.cpp
@@ -3,10 +3,14 @@
#include "content_utility_client_qt.h"
-#include "base/no_destructor.h"
#include "mojo/public/cpp/bindings/service_factory.h"
#include "services/proxy_resolver/proxy_resolver_factory_impl.h"
+#if BUILDFLAG(IS_WIN)
+#include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
+#include "services/proxy_resolver_win/windows_system_proxy_resolver_impl.h"
+#endif
+
namespace QtWebEngineCore {
ContentUtilityClientQt::ContentUtilityClientQt()
@@ -20,9 +24,21 @@ auto RunProxyResolver(mojo::PendingReceiver<proxy_resolver::mojom::ProxyResolver
return std::make_unique<proxy_resolver::ProxyResolverFactoryImpl>(std::move(receiver));
}
+#if BUILDFLAG(IS_WIN)
+auto RunWindowsSystemProxyResolver(
+ mojo::PendingReceiver<proxy_resolver_win::mojom::WindowsSystemProxyResolver> receiver)
+{
+ return std::make_unique<proxy_resolver_win::WindowsSystemProxyResolverImpl>(
+ std::move(receiver));
+}
+#endif
+
void ContentUtilityClientQt::RegisterIOThreadServices(mojo::ServiceFactory &services)
{
services.Add(RunProxyResolver);
+#if BUILDFLAG(IS_WIN)
+ services.Add(RunWindowsSystemProxyResolver);
+#endif
}
} // namespace
diff --git a/src/core/desktop_screen_qt.cpp b/src/core/desktop_screen_qt.cpp
index 898b8a1cc..fb68f7b09 100644
--- a/src/core/desktop_screen_qt.cpp
+++ b/src/core/desktop_screen_qt.cpp
@@ -119,13 +119,27 @@ display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeWindow /*wi
return GetPrimaryDisplay();
}
+#if defined(USE_XSCREENSAVER)
+class XScreenSuspender : public display::Screen::ScreenSaverSuspender
+{
+public:
+ XScreenSuspender()
+ {
+ ui::SuspendX11ScreenSaver(true);
+ }
+ ~XScreenSuspender() override
+ {
+ ui::SuspendX11ScreenSaver(false);
+ }
+};
+#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
-bool DesktopScreenQt::SetScreenSaverSuspended(bool suspend)
+std::unique_ptr<display::Screen::ScreenSaverSuspender> DesktopScreenQt::SuspendScreenSaver()
{
#if defined(USE_XSCREENSAVER)
- return ui::SuspendX11ScreenSaver(suspend);
+ return std::make_unique<XScreenSuspender>();
#else
- return false;
+ return nullptr;
#endif
}
#endif
diff --git a/src/core/desktop_screen_qt.h b/src/core/desktop_screen_qt.h
index 33f0cf870..a322c4840 100644
--- a/src/core/desktop_screen_qt.h
+++ b/src/core/desktop_screen_qt.h
@@ -18,7 +18,7 @@ public:
display::Display GetDisplayNearestWindow(gfx::NativeWindow /*window*/) const override;
#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
- bool SetScreenSaverSuspended(bool suspend) override;
+ std::unique_ptr<ScreenSaverSuspender> SuspendScreenSaver() override;
#endif
bool IsScreenSaverActive() const override;
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index e706c680a..731414db9 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -8,161 +8,45 @@
#include "devtools_frontend_qt.h"
-#include "profile_adapter.h"
#include "profile_qt.h"
+#include "profile_adapter.h"
#include "web_contents_adapter.h"
+#include "web_contents_delegate_qt.h"
-#include "base/base64.h"
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/json/string_escape.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
-#include "base/values.h"
#include "chrome/browser/devtools/devtools_eye_dropper.h"
-#include "chrome/common/url_constants.h"
-#include "components/prefs/in_memory_pref_store.h"
-#include "components/prefs/json_pref_store.h"
+#include "chrome/browser/devtools/devtools_ui_bindings.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/devtools_frontend_host.h"
-#include "content/public/browser/file_url_loader.h"
+#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/shared_cors_origin_access_list.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/url_constants.h"
-#include "content/public/common/url_utils.h"
-#include "ipc/ipc_channel.h"
-#include "net/http/http_response_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/cpp/simple_url_loader.h"
-#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
+#include "content/public/browser/page_navigator.h"
+#include "content/public/browser/site_instance.h"
+#include "url/gurl.h"
using namespace QtWebEngineCore;
namespace {
-
-constexpr char kScreencastEnabled[] = "screencastEnabled";
-
-base::DictionaryValue BuildObjectForResponse(const net::HttpResponseHeaders *rh,
- bool success, int net_error)
-{
- base::DictionaryValue response;
- int responseCode = 200;
- if (rh) {
- responseCode = rh->response_code();
- } else if (!success) {
- // In case of no headers, assume file:// URL and failed to load
- responseCode = 404;
- }
- response.SetInteger("statusCode", responseCode);
- response.SetInteger("netError", net_error);
- response.SetString("netErrorName", net::ErrorToString(net_error));
-
- auto headers = std::make_unique<base::DictionaryValue>();
- size_t iterator = 0;
- std::string name;
- std::string value;
- // TODO(caseq): this probably needs to handle duplicate header names
- // correctly by folding them.
- while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value))
- headers->SetString(name, value);
-
- response.Set("headers", std::move(headers));
- return response;
-}
+static const char kScreencastEnabled[] = "screencastEnabled";
static std::string GetFrontendURL()
{
return "devtools://devtools/bundled/inspector.html";
}
-
-} // namespace
+} // namespace
namespace QtWebEngineCore {
-class DevToolsFrontendQt::NetworkResourceLoader
- : public network::SimpleURLLoaderStreamConsumer {
-public:
- NetworkResourceLoader(int stream_id,
- int request_id,
- DevToolsFrontendQt *bindings,
- std::unique_ptr<network::SimpleURLLoader> loader,
- network::mojom::URLLoaderFactory *url_loader_factory)
- : stream_id_(stream_id),
- request_id_(request_id),
- bindings_(bindings),
- loader_(std::move(loader))
- {
- loader_->SetOnResponseStartedCallback(base::BindOnce(
- &NetworkResourceLoader::OnResponseStarted, base::Unretained(this)));
- loader_->DownloadAsStream(url_loader_factory, this);
- }
-
-private:
- void OnResponseStarted(const GURL &final_url,
- const network::mojom::URLResponseHead &response_head)
- {
- response_headers_ = response_head.headers;
- }
-
- void OnDataReceived(base::StringPiece chunk, base::OnceClosure resume) override
- {
- base::Value chunkValue;
-
- bool encoded = !base::IsStringUTF8(chunk);
- if (encoded) {
- std::string encoded_string;
- base::Base64Encode(chunk, &encoded_string);
- chunkValue = base::Value(std::move(encoded_string));
- } else {
- chunkValue = base::Value(chunk);
- }
- base::Value id(stream_id_);
- base::Value encodedValue(encoded);
-
- bindings_->CallClientFunction("DevToolsAPI", "streamWrite", std::move(id), std::move(chunkValue), std::move(encodedValue));
- std::move(resume).Run();
- }
-
- void OnComplete(bool success) override
- {
- auto response = BuildObjectForResponse(response_headers_.get(), success, loader_->NetError());
- bindings_->SendMessageAck(request_id_, std::move(response));
- bindings_->m_loaders.erase(bindings_->m_loaders.find(this));
- }
-
- void OnRetry(base::OnceClosure start_retry) override { NOTREACHED(); }
-
- const int stream_id_;
- const int request_id_;
- DevToolsFrontendQt *const bindings_;
- std::unique_ptr<network::SimpleURLLoader> loader_;
- scoped_refptr<net::HttpResponseHeaders> response_headers_;
-};
-
-// This constant should be in sync with
-// the constant at devtools_ui_bindings.cc.
-const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
-
// static
-DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter> frontendAdapter, content::WebContents *inspectedContents)
+DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter> frontendAdapter,
+ content::WebContents *inspectedContents)
{
DCHECK(frontendAdapter);
DCHECK(inspectedContents);
if (!frontendAdapter->isInitialized()) {
- scoped_refptr<content::SiteInstance> site =
- content::SiteInstance::CreateForURL(frontendAdapter->profile(), GURL(GetFrontendURL()));
+ scoped_refptr<content::SiteInstance> site = content::SiteInstance::CreateForURL(
+ frontendAdapter->profile(), GURL(GetFrontendURL()));
frontendAdapter->initialize(site.get());
}
@@ -174,13 +58,15 @@ DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter>
return nullptr;
}
- DevToolsFrontendQt *devtoolsFrontend = new DevToolsFrontendQt(frontendAdapter, inspectedContents);
+ DevToolsFrontendQt *devtoolsFrontend =
+ new DevToolsFrontendQt(frontendAdapter, inspectedContents);
if (contents->GetURL() == GURL(GetFrontendURL())) {
contents->GetController().Reload(content::ReloadType::ORIGINAL_REQUEST_URL, false);
- } else {
+ } else {
content::NavigationController::LoadURLParams loadParams((GURL(GetFrontendURL())));
- loadParams.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_TOPLEVEL | ui::PAGE_TRANSITION_FROM_API);
+ loadParams.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_TOPLEVEL
+ | ui::PAGE_TRANSITION_FROM_API);
contents->GetController().LoadURLWithParams(loadParams);
}
@@ -191,24 +77,21 @@ DevToolsFrontendQt::DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webCon
content::WebContents *inspectedContents)
: content::WebContentsObserver(webContentsAdapter->webContents())
, m_frontendAdapter(webContentsAdapter)
- , m_inspectedAdapter(static_cast<WebContentsDelegateQt *>(inspectedContents->GetDelegate())
- ->webContentsAdapter())
, m_inspectedContents(inspectedContents)
- , m_inspect_element_at_x(-1)
- , m_inspect_element_at_y(-1)
- , m_prefStore(nullptr)
- , m_weakFactory(this)
+ , m_bindings(new DevToolsUIBindings(webContentsAdapter->webContents()))
{
- // We use a separate prefstore than one in ProfileQt, because that one is in-memory only, and this
- // needs to be stored or it will show introduction text on every load.
- if (webContentsAdapter->profileAdapter()->isOffTheRecord())
- m_prefStore = scoped_refptr<PersistentPrefStore>(new InMemoryPrefStore());
- else
- CreateJsonPreferences(false);
-
- m_frontendDelegate = static_cast<WebContentsDelegateQt *>(webContentsAdapter->webContents()->GetDelegate());
-}
+ // bindings take ownership over devtools
+ m_bindings->SetDelegate(this);
+ m_bindings->AttachTo(content::DevToolsAgentHost::GetOrCreateFor(m_inspectedContents));
+ auto *prefService = m_bindings->profile()->GetPrefs();
+ const auto &devtoolsPrefs = prefService->GetDict(prefs::kDevToolsPreferences);
+
+ if (!devtoolsPrefs.Find(kScreencastEnabled)) {
+ ScopedDictPrefUpdate update(prefService, prefs::kDevToolsPreferences);
+ update->Set(kScreencastEnabled, "false");
+ }
+}
DevToolsFrontendQt::~DevToolsFrontendQt()
{
@@ -218,7 +101,7 @@ DevToolsFrontendQt::~DevToolsFrontendQt()
void DevToolsFrontendQt::Activate()
{
- m_frontendDelegate->ActivateContents(web_contents());
+ web_contents()->GetDelegate()->ActivateContents(web_contents());
}
void DevToolsFrontendQt::Focus()
@@ -228,12 +111,11 @@ void DevToolsFrontendQt::Focus()
void DevToolsFrontendQt::InspectElementAt(int x, int y)
{
- if (m_agentHost)
- m_agentHost->InspectElement(m_inspectedContents->GetFocusedFrame(), x, y);
- else {
- m_inspect_element_at_x = x;
- m_inspect_element_at_y = y;
- }
+ if (!m_inspectedContents)
+ return;
+ scoped_refptr<content::DevToolsAgentHost> agent(
+ content::DevToolsAgentHost::GetOrCreateFor(m_inspectedContents));
+ agent->InspectElement(m_inspectedContents->GetFocusedFrame(), x, y);
}
void DevToolsFrontendQt::Close()
@@ -244,286 +126,54 @@ void DevToolsFrontendQt::Close()
void DevToolsFrontendQt::DisconnectFromTarget()
{
- if (!m_agentHost)
- return;
- m_agentHost->DetachClient(this);
- m_agentHost = nullptr;
+ m_bindings->Detach();
}
-void DevToolsFrontendQt::ReadyToCommitNavigation(content::NavigationHandle *navigationHandle)
+WebContentsDelegateQt *DevToolsFrontendQt::frontendDelegate() const
{
- // ShellDevToolsFrontend does this in RenderViewCreated,
- // but that doesn't work for us for some reason.
- content::RenderFrameHost *frame = navigationHandle->GetRenderFrameHost();
- if (navigationHandle->IsInMainFrame()) {
- // If the frontend for some reason goes to some place other than devtools, stop the bindings
- if (navigationHandle->GetURL() != GetFrontendURL())
- m_frontendHost.reset(nullptr);
- else if (!m_frontendHost)
- m_frontendHost = content::DevToolsFrontendHost::Create(
- frame,
- base::BindRepeating(&DevToolsFrontendQt::HandleMessageFromDevToolsFrontend,
- base::Unretained(this)));
- }
+ return static_cast<WebContentsDelegateQt *>(web_contents()->GetDelegate());
}
-void DevToolsFrontendQt::DocumentOnLoadCompletedInPrimaryMainFrame()
+void DevToolsFrontendQt::ColorPickedInEyeDropper(int r, int g, int b, int a)
{
- if (!m_inspectedContents)
- return;
- // Don't call AttachClient multiple times for the same DevToolsAgentHost.
- // Otherwise it will call AgentHostClosed which closes the DevTools window.
- // This may happen in cases where the DevTools content fails to load.
- scoped_refptr<content::DevToolsAgentHost> agent_host =
- content::DevToolsAgentHost::GetOrCreateFor(m_inspectedContents);
- if (agent_host != m_agentHost) {
- if (m_agentHost)
- m_agentHost->DetachClient(this);
- m_agentHost = agent_host;
- m_agentHost->AttachClient(this);
- if (m_inspect_element_at_x != -1) {
- m_agentHost->InspectElement(m_inspectedContents->GetFocusedFrame(), m_inspect_element_at_x, m_inspect_element_at_y);
- m_inspect_element_at_x = -1;
- m_inspect_element_at_y = -1;
- }
- }
+ base::DictionaryValue color;
+ color.SetInteger("r", r);
+ color.SetInteger("g", g);
+ color.SetInteger("b", b);
+ color.SetInteger("a", a);
+ m_bindings->CallClientMethod("DevToolsAPI", "eyeDropperPickedColor", std::move(color));
}
+// content::WebContentsObserver implementation
void DevToolsFrontendQt::WebContentsDestroyed()
{
- if (m_inspectedAdapter)
- m_inspectedAdapter->devToolsFrontendDestroyed(this);
+ WebContentsAdapter *inspectedAdapter =
+ static_cast<WebContentsDelegateQt *>(m_inspectedContents->GetDelegate())
+ ->webContentsAdapter();
+ if (inspectedAdapter)
+ inspectedAdapter->devToolsFrontendDestroyed(this);
- if (m_agentHost) {
- m_agentHost->DetachClient(this);
- m_agentHost = nullptr;
- }
- delete this;
+ delete m_bindings; // it will call ~DevToolsFrontendQt()
}
-void DevToolsFrontendQt::SetPreference(const std::string &name, const std::string &value)
+// DevToolsUIBindings::Delegate implementation
+void DevToolsFrontendQt::ActivateWindow()
{
- DCHECK(m_prefStore);
- m_prefStore->SetValue(name, base::WrapUnique(new base::Value(value)), 0);
+ web_contents()->Focus();
}
-void DevToolsFrontendQt::RemovePreference(const std::string &name)
+void DevToolsFrontendQt::InspectElementCompleted()
{
- DCHECK(m_prefStore);
- m_prefStore->RemoveValue(name, 0);
+ m_bindings->CallClientMethod("DevToolsAPI", "setUseSoftMenu", base::Value(true));
}
-void DevToolsFrontendQt::ClearPreferences()
+void DevToolsFrontendQt::OpenInNewTab(const std::string &url)
{
- ProfileQt *profile = static_cast<ProfileQt *>(web_contents()->GetBrowserContext());
- if (profile->IsOffTheRecord() || profile->profileAdapter()->storageName().isEmpty())
- m_prefStore = scoped_refptr<PersistentPrefStore>(new InMemoryPrefStore());
- else
- CreateJsonPreferences(true);
-}
+ content::OpenURLParams params(GURL(url), content::Referrer(),
+ WindowOpenDisposition::NEW_FOREGROUND_TAB,
+ ui::PAGE_TRANSITION_LINK, false);
-void DevToolsFrontendQt::CreateJsonPreferences(bool clear)
-{
- content::BrowserContext *browserContext = web_contents()->GetBrowserContext();
- DCHECK(!browserContext->IsOffTheRecord());
- JsonPrefStore *jsonPrefStore = new JsonPrefStore(
- browserContext->GetPath().Append(FILE_PATH_LITERAL("devtoolsprefs.json")));
- // We effectively clear the preferences by not calling ReadPrefs
- base::ScopedAllowBlockingForTesting allowBlocking;
- if (!clear)
- jsonPrefStore->ReadPrefs();
-
- m_prefStore = scoped_refptr<PersistentPrefStore>(jsonPrefStore);
-}
-
-void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(base::Value message)
-{
- const std::string *method_ptr = nullptr;
- base::Value *params_value = nullptr;
- if (message.is_dict()) {
- method_ptr = message.FindStringKey("method");
- params_value = message.FindKey("params");
- }
- if (!method_ptr || (params_value && !params_value->is_list())) {
- LOG(ERROR) << "Invalid message was sent to embedder: " << message;
- return;
- }
- base::Value empty_params(base::Value::Type::LIST);
- if (!params_value)
- params_value = &empty_params;
-
- int request_id = message.FindIntKey("id").value_or(0);
- const std::string &method = *method_ptr;
- base::Value::List *paramsPtr;
- if (params_value)
- paramsPtr = params_value->GetIfList();
- base::Value::List &params = *paramsPtr;
-
- if (method == "dispatchProtocolMessage" && params.size() == 1) {
- const std::string *protocol_message = params[0].GetIfString();
- if (!protocol_message)
- return;
- if (m_agentHost)
- m_agentHost->DispatchProtocolMessage(this, base::as_bytes(base::make_span(*protocol_message)));
- } else if (method == "loadCompleted") {
- web_contents()->GetMainFrame()->ExecuteJavaScript(u"DevToolsAPI.setUseSoftMenu(true);",
- base::NullCallback());
- } else if (method == "loadNetworkResource" && params.size() == 3) {
- // TODO(pfeldman): handle some of the embedder messages in content.
- const std::string *url = params[0].GetIfString();
- const std::string *headers = params[1].GetIfString();
- absl::optional<int> stream_id = params[2].GetIfInt();
- if (!url || !headers || !stream_id.has_value()) {
- return;
- }
-
- GURL gurl(*url);
- if (!gurl.is_valid()) {
- base::DictionaryValue response;
- response.SetInteger("statusCode", 404);
- response.SetBoolean("urlValid", false);
- SendMessageAck(request_id, std::move(response));
- return;
- }
-
- net::NetworkTrafficAnnotationTag traffic_annotation =
- net::DefineNetworkTrafficAnnotation(
- "devtools_handle_front_end_messages", R"(
- semantics {
- sender: "Developer Tools"
- description:
- "When user opens Developer Tools, the browser may fetch "
- "additional resources from the network to enrich the debugging "
- "experience (e.g. source map resources)."
- trigger: "User opens Developer Tools to debug a web page."
- data: "Any resources requested by Developer Tools."
- destination: OTHER
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user"
- setting:
- "It's not possible to disable this feature from settings."
- chrome_policy {
- DeveloperToolsAvailability {
- policy_options {mode: MANDATORY}
- DeveloperToolsAvailability: 2
- }
- }
- })");
- auto resource_request = std::make_unique<network::ResourceRequest>();
- resource_request->url = gurl;
- // TODO(caseq): this preserves behavior of URLFetcher-based implementation.
- // We really need to pass proper first party origin from the front-end.
- resource_request->site_for_cookies = net::SiteForCookies::FromUrl(gurl);
- resource_request->headers.AddHeadersFromString(*headers);
-
- mojo::Remote<network::mojom::URLLoaderFactory> file_url_loader_factory;
- scoped_refptr<network::SharedURLLoaderFactory> network_url_loader_factory;
- network::mojom::URLLoaderFactory *url_loader_factory;
- if (gurl.SchemeIsFile()) {
- file_url_loader_factory.Bind(content::CreateFileURLLoaderFactory(base::FilePath(), nullptr));
- url_loader_factory = file_url_loader_factory.get();
- } else if (content::HasWebUIScheme(gurl)) {
- base::DictionaryValue response;
- response.SetInteger("statusCode", 403);
- SendMessageAck(request_id, std::move(response));
- return;
- } else {
- auto *partition = web_contents()->GetBrowserContext()->GetStoragePartitionForUrl(gurl);
- network_url_loader_factory = partition->GetURLLoaderFactoryForBrowserProcess();
- url_loader_factory = network_url_loader_factory.get();
- }
- auto simple_url_loader = network::SimpleURLLoader::Create(
- std::move(resource_request), traffic_annotation);
- auto resource_loader = std::make_unique<NetworkResourceLoader>(
- *stream_id, request_id, this, std::move(simple_url_loader),
- url_loader_factory);
- m_loaders.insert(std::move(resource_loader));
- return;
- } else if (method == "getPreferences") {
- // Screencast is enabled by default if it's not present in the preference store.
- if (!m_prefStore->GetValue(kScreencastEnabled, NULL))
- SetPreference(kScreencastEnabled, "false");
-
- m_preferences = std::move(*m_prefStore->GetValues());
- SendMessageAck(request_id, m_preferences.Clone());
- return;
- } else if (method == "setPreference" && params.size() >= 2) {
- const std::string *name = params[0].GetIfString();
- const std::string *value = params[1].GetIfString();
- if (!name || !value)
- return;
- SetPreference(*name, *value);
- } else if (method == "removePreference" && params.size() >= 1) {
- const std::string *name = params[0].GetIfString();
- if (!name)
- return;
- RemovePreference(*name);
- } else if (method == "clearPreferences") {
- ClearPreferences();
- } else if (method == "requestFileSystems") {
- web_contents()->GetMainFrame()->ExecuteJavaScript(u"DevToolsAPI.fileSystemsLoaded([]);",
- base::NullCallback());
- } else if (method == "reattach") {
- if (!m_agentHost)
- return;
- m_agentHost->DetachClient(this);
- m_agentHost->AttachClient(this);
- } else if (method == "inspectedURLChanged" && params.size() >= 1) {
- const std::string *url = params[0].GetIfString();
- if (!url)
- return;
- const std::string kHttpPrefix = "http://";
- const std::string kHttpsPrefix = "https://";
- const std::string simplified_url =
- base::StartsWith(*url, kHttpsPrefix, base::CompareCase::SENSITIVE)
- ? url->substr(kHttpsPrefix.length())
- : base::StartsWith(*url, kHttpPrefix, base::CompareCase::SENSITIVE)
- ? url->substr(kHttpPrefix.length())
- : *url;
- // DevTools UI is not localized.
- web_contents()->UpdateTitleForEntry(web_contents()->GetController().GetActiveEntry(),
- base::UTF8ToUTF16(
- base::StringPrintf("DevTools - %s", simplified_url.c_str())));
- } else if (method == "openInNewTab" && params.size() >= 1) {
- const std::string *urlString = params[0].GetIfString();
- if (!urlString)
- return;
- GURL url(*urlString);
- if (!url.is_valid())
- return;
- content::OpenURLParams openParams(GURL(url),
- content::Referrer(),
- WindowOpenDisposition::NEW_FOREGROUND_TAB,
- ui::PAGE_TRANSITION_LINK,
- false);
- // OpenURL will (via WebContentsDelegateQt::OpenURLFromTab) call
- // application code, which may decide to close this devtools view (see
- // quicknanobrowser for example).
- //
- // Chromium always calls SendMessageAck through a callback bound to a
- // WeakPtr, we do the same here, except without the callback.
- base::WeakPtr<DevToolsFrontendQt> weakThis = m_weakFactory.GetWeakPtr();
- web_contents()->OpenURL(openParams);
- if (!weakThis)
- return;
- } else if (method == "bringToFront") {
- Activate();
- } else if (method == "closeWindow") {
- web_contents()->Close();
- } else if (method == "setEyeDropperActive" && params.size() == 1) {
- absl::optional<bool> active = params[0].GetIfBool();
- if (!active)
- return;
- SetEyeDropperActive(*active);
- } else {
- VLOG(1) << "Unimplemented devtools method: " << message;
- return;
- }
-
- if (request_id)
- SendMessageAck(request_id, base::Value());
+ m_inspectedContents->OpenURL(params);
}
void DevToolsFrontendQt::SetEyeDropperActive(bool active)
@@ -532,80 +182,26 @@ void DevToolsFrontendQt::SetEyeDropperActive(bool active)
return;
if (active) {
m_eyeDropper.reset(new DevToolsEyeDropper(
- m_inspectedContents,
- base::BindRepeating(&DevToolsFrontendQt::ColorPickedInEyeDropper,
- base::Unretained(this))));
+ m_inspectedContents,
+ base::BindRepeating(&DevToolsFrontendQt::ColorPickedInEyeDropper,
+ base::Unretained(this))));
} else {
m_eyeDropper.reset();
}
}
-void DevToolsFrontendQt::ColorPickedInEyeDropper(int r, int g, int b, int a)
-{
- base::DictionaryValue color;
- color.SetInteger("r", r);
- color.SetInteger("g", g);
- color.SetInteger("b", b);
- color.SetInteger("a", a);
- CallClientFunction("DevToolsAPI", "eyeDropperPickedColor", std::move(color));
-}
-
-void DevToolsFrontendQt::DispatchProtocolMessage(content::DevToolsAgentHost *agentHost, base::span<const uint8_t> message)
-{
- Q_UNUSED(agentHost);
- base::StringPiece str_message(reinterpret_cast<const char*>(message.data()), message.size());
-
- if (str_message.length() < kMaxMessageChunkSize) {
- CallClientFunction("DevToolsAPI", "dispatchMessage",
- base::Value(std::string(str_message)));
- } else {
- size_t total_size = str_message.length();
- for (size_t pos = 0; pos < str_message.length(); pos += kMaxMessageChunkSize) {
- base::StringPiece str_message_chunk = str_message.substr(pos, kMaxMessageChunkSize);
-
- CallClientFunction("DevToolsAPI", "dispatchMessageChunk",
- base::Value(std::string(str_message_chunk)),
- base::Value(base::NumberToString(pos ? 0 : total_size)));
- }
- }
-}
-
-void DevToolsFrontendQt::CallClientFunction(const std::string &object_name,
- const std::string &method_name,
- base::Value arg1, base::Value arg2, base::Value arg3,
- base::OnceCallback<void(base::Value)> cb)
-
-{
- base::Value::List arguments;
- if (!arg1.is_none()) {
- arguments.Append(std::move(arg1));
- if (!arg2.is_none()) {
- arguments.Append(std::move(arg2));
- if (!arg3.is_none()) {
- arguments.Append(std::move(arg3));
- }
- }
- }
- web_contents()->GetMainFrame()->ExecuteJavaScriptMethod(base::ASCIIToUTF16(object_name),
- base::ASCIIToUTF16(method_name),
- std::move(arguments),
- std::move(cb));
-
-}
-
-void DevToolsFrontendQt::SendMessageAck(int request_id, base::Value arg)
+// static
+bool DevToolsFrontendQt::IsValidFrontendURL(const GURL &url)
{
- base::Value id_value(request_id);
- CallClientFunction("DevToolsAPI", "embedderMessageAck", std::move(id_value), std::move(arg));
+ // NOTE: the inspector app does not change the frontend url.
+ // If we bring back the devtools_app, the url must be sanitized
+ // according to chrome/browser/devtools/devtools_ui_bindings.cc.
+ return url.spec() == GetFrontendURL();
}
-void DevToolsFrontendQt::AgentHostClosed(content::DevToolsAgentHost *agentHost)
+void DevToolsFrontendQt::InspectedContentsClosing()
{
- DCHECK(agentHost == m_agentHost.get());
- m_agentHost = nullptr;
- m_inspectedContents = nullptr;
- m_inspectedAdapter = nullptr;
- Close();
+ web_contents()->ClosePage();
}
} // namespace QtWebEngineCore
diff --git a/src/core/devtools_frontend_qt.h b/src/core/devtools_frontend_qt.h
index 78a3aaefc..3b722c9ad 100644
--- a/src/core/devtools_frontend_qt.h
+++ b/src/core/devtools_frontend_qt.h
@@ -11,28 +11,24 @@
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/weak_ptr.h"
-#include "content/public/browser/devtools_agent_host.h"
+#include "chrome/browser/devtools/devtools_ui_bindings.h"
#include "content/public/browser/web_contents_observer.h"
-namespace base {
-class Value;
-}
+class DevToolsEyeDropper;
namespace content {
-class DevToolsFrontendHost;
-class NavigationHandle;
+class DevToolsAgentHost;
class WebContents;
-} // namespace content
-
-class DevToolsEyeDropper;
-class PersistentPrefStore;
+} // namespace content
namespace QtWebEngineCore {
+class WebContentsAdapter;
-class DevToolsFrontendQt : public content::WebContentsObserver
- , public content::DevToolsAgentHostClient {
+class DevToolsFrontendQt : public DevToolsUIBindings::Delegate, public content::WebContentsObserver
+{
public:
- static DevToolsFrontendQt *Show(QSharedPointer<WebContentsAdapter> frontendAdapter, content::WebContents *inspectedContents);
+ static DevToolsFrontendQt *Show(QSharedPointer<WebContentsAdapter> frontendAdapter,
+ content::WebContents *inspectedContents);
void Activate();
void Focus();
@@ -41,62 +37,48 @@ public:
void DisconnectFromTarget();
- void CallClientFunction(const std::string &object_name,
- const std::string &method_name,
- base::Value arg1 = {},
- base::Value arg2 = {},
- base::Value arg3 = {},
- base::OnceCallback<void(base::Value)> cb = base::NullCallback());
+ WebContentsDelegateQt *frontendDelegate() const;
- WebContentsDelegateQt *frontendDelegate() const
- {
- return m_frontendDelegate;
- }
+ static bool IsValidFrontendURL(const GURL &url);
protected:
- DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webContentsAdapter, content::WebContents *inspectedContents);
+ DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webContentsAdapter,
+ content::WebContents *inspectedContents);
~DevToolsFrontendQt() override;
- // content::DevToolsAgentHostClient implementation.
- void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
- void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, base::span<const uint8_t> message) override;
-
- void SetPreferences(const std::string& json);
- void HandleMessageFromDevToolsFrontend(base::Value message);
-
private:
- // WebContentsObserver overrides
- void ReadyToCommitNavigation(content::NavigationHandle* navigation_handle) override;
- void DocumentOnLoadCompletedInPrimaryMainFrame() override;
+ void ColorPickedInEyeDropper(int r, int g, int b, int a);
+
+ // content::WebContentsObserver overrides
void WebContentsDestroyed() override;
- void SendMessageAck(int request_id, base::Value arg1);
- void SetPreference(const std::string &name, const std::string &value);
- void RemovePreference(const std::string &name);
- void ClearPreferences();
- void CreateJsonPreferences(bool clear);
- void SetEyeDropperActive(bool active);
- void ColorPickedInEyeDropper(int r, int g, int b, int a);
+ // DevToolsUIBindings::Delegate overrides
+ void ActivateWindow() override;
+ void InspectElementCompleted() override;
+ void SetEyeDropperActive(bool active) override;
+ void OpenInNewTab(const std::string &url) override;
+ void InspectedContentsClosing() override;
+
+ void CloseWindow() override{};
+ void Inspect(scoped_refptr<content::DevToolsAgentHost>) override{};
+ void SetInspectedPageBounds(const gfx::Rect &) override{};
+ void SetIsDocked(bool) override{};
+ void SetWhitelistedShortcuts(const std::string &) override{};
+ void OpenNodeFrontend() override{};
+ void OnLoadCompleted() override{};
+ void ReadyForTest() override{};
+ void ConnectionReady() override{};
+ void SetOpenNewWindowForPopups(bool) override{};
+ void RenderProcessGone(bool) override{};
+ void ShowCertificateViewer(const std::string &) override{};
// We shouldn't be keeping it alive
QWeakPointer<WebContentsAdapter> m_frontendAdapter;
- WebContentsAdapter *m_inspectedAdapter;
- WebContentsDelegateQt *m_frontendDelegate;
content::WebContents *m_inspectedContents;
- scoped_refptr<content::DevToolsAgentHost> m_agentHost;
- int m_inspect_element_at_x;
- int m_inspect_element_at_y;
- std::unique_ptr<content::DevToolsFrontendHost> m_frontendHost;
std::unique_ptr<DevToolsEyeDropper> m_eyeDropper;
-
- class NetworkResourceLoader;
- std::set<std::unique_ptr<NetworkResourceLoader>, base::UniquePtrComparator> m_loaders;
-
- base::DictionaryValue m_preferences;
- scoped_refptr<PersistentPrefStore> m_prefStore;
- base::WeakPtrFactory<DevToolsFrontendQt> m_weakFactory;
+ DevToolsUIBindings *m_bindings;
};
} // namespace QtWebEngineCore
-#endif // DEVTOOLS_FRONTEND_QT_H
+#endif // DEVTOOLS_FRONTEND_QT_H
diff --git a/src/core/doc/about_credits_entry.tmpl b/src/core/doc/about_credits_entry.tmpl
index 2bb9cff4e..aa94f2945 100644
--- a/src/core/doc/about_credits_entry.tmpl
+++ b/src/core/doc/about_credits_entry.tmpl
@@ -1,5 +1,6 @@
/*!
-\page qtwebengine-3rdparty-{{name-sanitized}}.html attribution
+\page qtwebengine-3rdparty-{{name-sanitized}}.html
+\attribution
\ingroup qtwebengine-licensing
\brief {{license-type}}
\title {{name}}
diff --git a/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc b/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc
index 74a3ecb48..6af681cc5 100644
--- a/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc
+++ b/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_add_webengine_dictionary.html
+\page qt-add-webengine-dictionary.html
\ingroup cmake-commands-qtwebenginecore
\title qt_add_webengine_dictionary
diff --git a/src/core/doc/src/qtwebengine-debugging.qdoc b/src/core/doc/src/qtwebengine-debugging.qdoc
index 3599ec55e..3bb6a7029 100644
--- a/src/core/doc/src/qtwebengine-debugging.qdoc
+++ b/src/core/doc/src/qtwebengine-debugging.qdoc
@@ -92,6 +92,15 @@
QTWEBENGINE_CHROMIUM_FLAGS="--disable-logging" mybrowser
\endcode
- QTWEBENGINE_CHROMIUM_FLAGS can also be set using {qputenv} from within the
+ QTWEBENGINE_CHROMIUM_FLAGS can also be set using \c qputenv from within the
application if called before QtWebEngineQuick::initialize().
+
+ \section1 Dump WebEngineContext Information
+
+ For dumping the WebEngineContext information, you can set the \c QT_LOGGING_RULES
+ environment variable to \c "qt.webenginecontext.debug=true".
+
+ The output contains information about the graphical backend, and the way how \QWE
+ is initialized for the application. This is particularly useful for reproducing
+ issues.
*/
diff --git a/src/core/doc/src/qtwebengine-deploying.qdoc b/src/core/doc/src/qtwebengine-deploying.qdoc
index 3fb46a672..7504965e3 100644
--- a/src/core/doc/src/qtwebengine-deploying.qdoc
+++ b/src/core/doc/src/qtwebengine-deploying.qdoc
@@ -138,4 +138,47 @@
QTQUICK_COMPILER_SKIPPED_RESOURCES += resources/my_resource.qrc
\endcode
+ \section2 \macos Specific Deployment Steps
+
+ To deploy a \QWE application that accesses the microphone or camera
+ on \macos, you will need to provide texts for the messages that will be shown to the user to
+ explain why the application asks for permission to access to the camera or microphone.
+ To do this, add the texts to the application's \c Info.plist file using the keys
+ described below.
+
+ For the camera usage message, provide a text using the following key:
+ \code
+ <key>NSCameraUsageDescription</key>
+ <string>Your message text for camera usage.</string>
+ \endcode
+
+ \sa \l{https://developer.apple.com/documentation/bundleresources/information_property_list/nscamerausagedescription} {Apple's property list file documentation}
+
+ For the microphone usage message, provide a text using the following key:
+ \code
+ <key>NSMicrophoneUsageDescription</key>
+ <string>Your message text for microphone usage.</string>
+ \endcode
+
+ \sa \l{https://developer.apple.com/documentation/bundleresources/information_property_list/nsmicrophoneusagedescription} {Apple's property list file documentation}
+
+ To notarize an application that accesses the camera or the microphone,
+ you will need to add the corresponding keys to your application's entitlements file used for
+ deployment and notarization.
+
+ To enable access to the camera, add:
+ \code
+ <key>com.apple.security.device.camera</key>
+ <true/>
+ \endcode
+
+ \sa \l{https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_camera} {Apple's camera entitlement documentation}.
+
+ To enable access to the microphone, add:
+ \code
+ <key>com.apple.security.device.microphone</key>
+ <true/>
+ \endcode
+
+ /sa \l{https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_microphone} {Apple's microphone entitlement documentation}.
*/
diff --git a/src/core/doc/src/qtwebengine-features.qdoc b/src/core/doc/src/qtwebengine-features.qdoc
index a564641a5..3d6d0fea8 100644
--- a/src/core/doc/src/qtwebengine-features.qdoc
+++ b/src/core/doc/src/qtwebengine-features.qdoc
@@ -298,6 +298,12 @@
tested by using \l{WebEngine Widgets Maps Example}{Maps} and allowing it to
find the current position of the user.
+ \note On Windows 11, enable settings to grant the maps example access to
+ Windows location services. In the Settings App under
+ \uicontrol {Privacy & Security} > \uicontrol {Location}, enable \uicontrol
+ {Location services}, \uicontrol {Let apps access your location} and \uicontrol
+ {Let desktop apps access your location}.
+
See \l{Qt Positioning} for a possible backend setup like the GPS or IP based positioning.
Support for this feature was added in Qt 5.5.0.
@@ -383,7 +389,6 @@
WebEngineView::colorDialogRequested(),
WebEngineView::fileDialogRequested(), and
WebEngineView::formValidationMessageRequested() signals. For an example,
- see \l{WebEngine Qt Quick Custom Dialogs Example}.
\section1 Pepper Plugin API
diff --git a/src/core/doc/src/qtwebengine-overview.qdoc b/src/core/doc/src/qtwebengine-overview.qdoc
index 2e1272404..b1e8ee3da 100644
--- a/src/core/doc/src/qtwebengine-overview.qdoc
+++ b/src/core/doc/src/qtwebengine-overview.qdoc
@@ -162,7 +162,7 @@
The following sample QML application loads a web page using the \l{WebEngineView::}{url}
property:
- \quotefromfile webenginequick/minimal/main.qml
+ \quotefromfile minimal/main.qml
\skipto import
\printuntil /^\}/
diff --git a/src/core/doc/src/qtwebengine-platform-notes.qdoc b/src/core/doc/src/qtwebengine-platform-notes.qdoc
index 76f5bbfda..98873a2aa 100644
--- a/src/core/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/core/doc/src/qtwebengine-platform-notes.qdoc
@@ -52,13 +52,7 @@
\li Windows 10 SDK version 10.0.20348.0 or later
\endlist
- \QWE can only be built on 64-bit Windows, with a x64-bit toolchain.
- For building \QWE for x86 applications, you need to configure
- and compile Qt with the Visual Studio x64 to x86 cross-compile
- toolchain. This toolchain can be set up on the command line by running
- \c{vcvarsall.bat amd64_x86}.
-
- \note It is not recommended to use tools form \c msys2 or \c cygwin to build \QWE as it may result in build errors.
+ \note It is not recommended to use tools from \c msys2 or \c cygwin to build \QWE as it may result in build errors.
\section2 Linux
diff --git a/src/core/doc/src/qwebengine-licensing.qdoc b/src/core/doc/src/qwebengine-licensing.qdoc
index 2b1bd2845..796a9664d 100644
--- a/src/core/doc/src/qwebengine-licensing.qdoc
+++ b/src/core/doc/src/qwebengine-licensing.qdoc
@@ -14,11 +14,16 @@ respect the licenses of Chromium, and third-party code included in
Chromium. The arguably most restrictive license to be respected by
all users is LGPLv2.1.
+\note Any GPL licenses listed below are only used to access Linux system
+resources. \QWE does not link to nor distribute GPL binary code, and
+it does not affect users of \QWE.
+
Third party licenses included in the sources are:
*/
/*!
-\page qtwebengine-3rdparty-chromium-global.html attribution
+\page qtwebengine-3rdparty-chromium-global.html
+\attribution
\ingroup qtwebengine-licensing
\title Chromium License
\brief BSD
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index d093c4e26..2838b59ff 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -55,7 +55,7 @@ void DownloadManagerDelegateQt::cancelDownload(content::DownloadTargetCallback c
download::DownloadItem::UNKNOWN,
base::FilePath(),
base::FilePath(),
- absl::nullopt,
+ std::string(),
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
}
@@ -97,7 +97,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
download::DownloadItem::VALIDATED,
item->GetForcedFilePath(),
item->GetFileNameToReportUser(),
- absl::nullopt,
+ item->GetMimeType(),
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
return true;
}
@@ -190,7 +190,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
download::DownloadItem::VALIDATED,
filePathForCallback.AddExtension(toFilePathString("download")),
base::FilePath(),
- absl::nullopt,
+ item->GetMimeType(),
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
} else
cancelDownload(std::move(*callback));
diff --git a/src/core/extensions/component_extension_resource_manager_qt.cpp b/src/core/extensions/component_extension_resource_manager_qt.cpp
index b2cb7e356..428f673d3 100644
--- a/src/core/extensions/component_extension_resource_manager_qt.cpp
+++ b/src/core/extensions/component_extension_resource_manager_qt.cpp
@@ -37,12 +37,12 @@ ComponentExtensionResourceManagerQt::ComponentExtensionResourceManagerQt()
AddComponentResourceEntries(kPdfResources, kPdfResourcesSize);
#endif
#if BUILDFLAG(ENABLE_PDF)
- base::Value dict(base::Value::Type::DICTIONARY);
+ base::Value::Dict dict;
pdf_extension_util::AddStrings(pdf_extension_util::PdfViewerContext::kPdfViewer, &dict);
- pdf_extension_util::AddAdditionalData(&dict);
+ pdf_extension_util::AddAdditionalData(/*enable_annotations=*/true, &dict);
ui::TemplateReplacements pdf_viewer_replacements;
- ui::TemplateReplacementsFromDictionaryValue(dict.GetDict(), &pdf_viewer_replacements);
+ ui::TemplateReplacementsFromDictionaryValue(dict, &pdf_viewer_replacements);
template_replacements_[extension_misc::kPdfExtensionId] = std::move(pdf_viewer_replacements);
#endif
}
diff --git a/src/core/extensions/extension_system_qt.cpp b/src/core/extensions/extension_system_qt.cpp
index 67750fa6a..0f44b8db3 100644
--- a/src/core/extensions/extension_system_qt.cpp
+++ b/src/core/extensions/extension_system_qt.cpp
@@ -21,7 +21,6 @@
#include "base/path_service.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -143,7 +142,7 @@ void ExtensionSystemQt::LoadExtension(std::string extension_id, std::unique_ptr<
if (!extension.get())
LOG(ERROR) << error;
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
+ content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&InfoMap::AddExtension,
base::Unretained(info_map()),
base::RetainedRef(extension),
@@ -378,8 +377,7 @@ void ExtensionSystemQt::RegisterExtensionWithRequestContexts(const Extension *ex
bool incognito_enabled = false;
bool notifications_disabled = false;
- base::PostTaskAndReply(
- FROM_HERE, {BrowserThread::IO},
+ content::GetIOThreadTaskRunner({})->PostTaskAndReply(FROM_HERE,
base::BindOnce(&InfoMap::AddExtension, info_map(),
base::RetainedRef(extension), install_time, incognito_enabled,
notifications_disabled),
@@ -388,8 +386,7 @@ void ExtensionSystemQt::RegisterExtensionWithRequestContexts(const Extension *ex
void ExtensionSystemQt::UnregisterExtensionWithRequestContexts(const std::string &extension_id)
{
- base::PostTask(
- FROM_HERE, {BrowserThread::IO},
+ content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&InfoMap::RemoveExtension, info_map(), extension_id));
}
diff --git a/src/core/extensions/extension_web_contents_observer_qt.cpp b/src/core/extensions/extension_web_contents_observer_qt.cpp
index 22092be30..a33954a20 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.cpp
+++ b/src/core/extensions/extension_web_contents_observer_qt.cpp
@@ -41,17 +41,8 @@ void ExtensionWebContentsObserverQt::CreateForWebContents(content::WebContents *
void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost *render_frame_host)
{
ExtensionWebContentsObserver::RenderFrameCreated(render_frame_host);
-
- if (web_contents()->IsInnerWebContentsForGuest() && static_cast<content::RenderFrameHostImpl *>(render_frame_host)->is_local_root_subframe()) {
- content::WebContents *parent = web_contents()->GetOutermostWebContents();
- QtWebEngineCore::RenderWidgetHostViewQt *main_rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent->GetRenderWidgetHostView());
- // Main frame of guest WebContents
- content::RenderWidgetHost *guest_render_widget_host = web_contents()->GetRenderViewHost()->GetWidget();
- main_rwhv->addGuest(guest_render_widget_host);
- // The frame which holds the actual PDF content inside the guest
- content::RenderWidgetHost *pdf_render_widget_host = render_frame_host->GetRenderWidgetHost();
- main_rwhv->addGuest(pdf_render_widget_host);
- }
+ QtWebEngineCore::RenderWidgetHostViewQt::registerInputEventObserver(web_contents(),
+ render_frame_host);
const Extension *extension = GetExtensionFromFrame(render_frame_host, false);
if (!extension)
diff --git a/src/core/extensions/extensions_browser_client_qt.cpp b/src/core/extensions/extensions_browser_client_qt.cpp
index f013c04a4..ab44c23eb 100644
--- a/src/core/extensions/extensions_browser_client_qt.cpp
+++ b/src/core/extensions/extensions_browser_client_qt.cpp
@@ -13,7 +13,6 @@
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
-#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/memory/ref_counted_memory.h"
#include "chrome/browser/extensions/api/generated_api_registration.h"
@@ -167,9 +166,7 @@ private:
if (!head->mime_type.empty()) {
head->headers->AddHeader(net::HttpRequestHeaders::kContentType, head->mime_type.c_str());
}
- client_->OnReceiveResponse(std::move(head),
- mojo::ScopedDataPipeConsumerHandle());
- client_->OnStartLoadingResponseBody(std::move(consumer_handle));
+ client_->OnReceiveResponse(std::move(head), std::move(consumer_handle), absl::nullopt);
uint32_t write_size = data->size();
MojoResult result = producer_handle->WriteData(data->front(), &write_size, MOJO_WRITE_DATA_FLAG_NONE);
@@ -294,6 +291,24 @@ BrowserContext *ExtensionsBrowserClientQt::GetOriginalContext(BrowserContext *co
return context;
}
+BrowserContext *ExtensionsBrowserClientQt::GetRedirectedContextInIncognito(BrowserContext *context, bool, bool)
+{
+ // like in ShellExtensionsBrowserClient:
+ return context;
+}
+
+BrowserContext *ExtensionsBrowserClientQt::GetContextForRegularAndIncognito(BrowserContext *context, bool, bool)
+{
+ // like in ShellExtensionsBrowserClient:
+ return context;
+}
+
+BrowserContext *ExtensionsBrowserClientQt::GetRegularProfile(BrowserContext *context, bool, bool)
+{
+ // like in ShellExtensionsBrowserClient:
+ return context;
+}
+
bool ExtensionsBrowserClientQt::IsGuestSession(BrowserContext *context) const
{
return context->IsOffTheRecord();
@@ -449,7 +464,8 @@ const ComponentExtensionResourceManager *ExtensionsBrowserClientQt::GetComponent
void ExtensionsBrowserClientQt::BroadcastEventToRenderers(events::HistogramValue histogram_value,
const std::string &event_name,
- std::unique_ptr<base::ListValue> args, bool dispatch_to_off_the_record_profiles)
+ base::Value::List args,
+ bool dispatch_to_off_the_record_profiles)
{
NOTIMPLEMENTED();
// TODO : do the event routing
diff --git a/src/core/extensions/extensions_browser_client_qt.h b/src/core/extensions/extensions_browser_client_qt.h
index e111c1283..78b56d920 100644
--- a/src/core/extensions/extensions_browser_client_qt.h
+++ b/src/core/extensions/extensions_browser_client_qt.h
@@ -35,6 +35,9 @@ public:
bool HasOffTheRecordContext(content::BrowserContext *context) override;
content::BrowserContext *GetOffTheRecordContext(content::BrowserContext *context) override;
content::BrowserContext *GetOriginalContext(content::BrowserContext *context) override;
+ content::BrowserContext *GetRedirectedContextInIncognito(content::BrowserContext *context, bool, bool) override;
+ content::BrowserContext *GetContextForRegularAndIncognito(content::BrowserContext *context, bool, bool) override;
+ content::BrowserContext *GetRegularProfile(content::BrowserContext *context, bool, bool) override;
bool IsGuestSession(content::BrowserContext *context) const override;
bool IsExtensionIncognitoEnabled(const std::string &extension_id, content::BrowserContext *context) const override;
bool CanExtensionCrossIncognito(const Extension *extension, content::BrowserContext *context) const override;
@@ -65,7 +68,7 @@ public:
GetComponentExtensionResourceManager() override;
void BroadcastEventToRenderers(events::HistogramValue histogram_value,
const std::string &event_name,
- std::unique_ptr<base::ListValue> args,
+ base::Value::List args,
bool dispatch_to_off_the_record_profiles) override;
ExtensionCache *GetExtensionCache() override;
bool IsBackgroundUpdateAllowed() override;
diff --git a/src/core/extensions/messaging_delegate_qt.cpp b/src/core/extensions/messaging_delegate_qt.cpp
index 791949cb5..b0089aea2 100644
--- a/src/core/extensions/messaging_delegate_qt.cpp
+++ b/src/core/extensions/messaging_delegate_qt.cpp
@@ -11,10 +11,10 @@ MessagingDelegateQt::MessagingDelegateQt()
{
}
-std::unique_ptr<base::DictionaryValue> MessagingDelegateQt::MaybeGetTabInfo(content::WebContents *web_contents)
+absl::optional<base::Value::Dict> MessagingDelegateQt::MaybeGetTabInfo(content::WebContents *web_contents)
{
Q_UNUSED(web_contents);
- return nullptr;
+ return absl::nullopt;
}
} // namespace extensions
diff --git a/src/core/extensions/messaging_delegate_qt.h b/src/core/extensions/messaging_delegate_qt.h
index f1d312544..c3c6244f5 100644
--- a/src/core/extensions/messaging_delegate_qt.h
+++ b/src/core/extensions/messaging_delegate_qt.h
@@ -22,7 +22,7 @@ public:
MessagingDelegateQt();
// MessagingDelegate implementation.
- std::unique_ptr<base::DictionaryValue> MaybeGetTabInfo(content::WebContents *web_contents) override;
+ absl::optional<base::Value::Dict> MaybeGetTabInfo(content::WebContents *web_contents) override;
};
} // namespace extensions
diff --git a/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp b/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
index a55294981..5a93b4b84 100644
--- a/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
+++ b/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
@@ -18,7 +18,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
#include "content/public/common/webplugininfo.h"
-#include "net/base/escape.h"
+#include "base/strings/escape.h"
#include "net/http/http_response_headers.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
@@ -69,12 +69,12 @@ bool IsPDFPluginEnabled(content::NavigationHandle *navigation_handle, bool *is_s
if (web_contents->IsInnerWebContentsForGuest())
web_contents = web_contents->GetOuterWebContents();
- int process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
- int routing_id = web_contents->GetMainFrame()->GetRoutingID();
+ int process_id = web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
+ int routing_id = web_contents->GetPrimaryMainFrame()->GetRoutingID();
content::WebPluginInfo plugin_info;
// Will check WebEngineSettings by PluginServiceFilterQt
return content::PluginService::GetInstance()->GetPluginInfo(
- process_id, routing_id, navigation_handle->GetURL(),
+ process_id, routing_id, nullptr, navigation_handle->GetURL(),
kPDFMimeType,
false /* allow_wildcard */, is_stale, &plugin_info,
nullptr /* actual_mime_type */);
@@ -85,12 +85,12 @@ std::string GetPDFPlaceholderHTML(const GURL &pdf_url)
std::string template_html = ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_PDF_PLUGIN_HTML);
webui::AppendWebUiCssTextDefaults(&template_html);
- base::DictionaryValue values;
- values.SetString("fileName", pdf_url.ExtractFileName());
- values.SetString("open", l10n_util::GetStringUTF8(IDS_ACCNAME_OPEN));
- values.SetString("pdfUrl", pdf_url.spec());
+ base::Value::Dict values;
+ values.Set("fileName", pdf_url.ExtractFileName());
+ values.Set("open", l10n_util::GetStringUTF8(IDS_ACCNAME_OPEN));
+ values.Set("pdfUrl", pdf_url.spec());
- return webui::GetI18nTemplateHtml(template_html, &values);
+ return webui::GetI18nTemplateHtml(template_html, std::move(values));
}
// static
@@ -167,7 +167,7 @@ void PDFIFrameNavigationThrottleQt::LoadPlaceholderHTML()
{
// Prepare the params to navigate to the placeholder.
std::string html = GetPDFPlaceholderHTML(navigation_handle()->GetURL());
- GURL data_url("data:text/html," + net::EscapePath(html));
+ GURL data_url("data:text/html," + base::EscapePath(html));
content::OpenURLParams params = content::OpenURLParams::FromNavigationHandle(navigation_handle());
params.url = data_url;
params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
diff --git a/src/core/extensions/plugin_service_filter_qt.cpp b/src/core/extensions/plugin_service_filter_qt.cpp
index 9c66ea6c3..1f6c606bc 100644
--- a/src/core/extensions/plugin_service_filter_qt.cpp
+++ b/src/core/extensions/plugin_service_filter_qt.cpp
@@ -18,11 +18,12 @@ PluginServiceFilterQt *PluginServiceFilterQt::GetInstance()
return base::Singleton<PluginServiceFilterQt>::get();
}
-bool PluginServiceFilterQt::IsPluginAvailable(int render_process_id,
- int render_frame_id,
+bool PluginServiceFilterQt::IsPluginAvailable(int render_process_id, int render_frame_id,
+ content::BrowserContext *browser_context,
const content::WebPluginInfo &plugin)
{
Q_UNUSED(plugin);
+ Q_UNUSED(browser_context);
content::RenderFrameHost *frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id);
content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(frame_host);
if (!web_contents) {
diff --git a/src/core/extensions/plugin_service_filter_qt.h b/src/core/extensions/plugin_service_filter_qt.h
index e26a71d68..d171edfde 100644
--- a/src/core/extensions/plugin_service_filter_qt.h
+++ b/src/core/extensions/plugin_service_filter_qt.h
@@ -14,8 +14,8 @@ class PluginServiceFilterQt : public content::PluginServiceFilter {
public:
static PluginServiceFilterQt* GetInstance();
- bool IsPluginAvailable(int render_process_id,
- int render_frame_id,
+ bool IsPluginAvailable(int render_process_id, int render_frame_id,
+ content::BrowserContext *browser_context,
const content::WebPluginInfo &plugin) override;
bool CanLoadPlugin(int render_process_id,
diff --git a/src/core/favicon_service_factory_qt.cpp b/src/core/favicon_service_factory_qt.cpp
index 6963f7e9b..d76bfab11 100644
--- a/src/core/favicon_service_factory_qt.cpp
+++ b/src/core/favicon_service_factory_qt.cpp
@@ -41,6 +41,10 @@ std::unique_ptr<history::HistoryBackendClient> HistoryClientQt::CreateBackendCli
return nullptr;
}
+void HistoryClientQt::UpdateBookmarkLastUsedTime(int64_t /*bookmark_node_id*/, base::Time /*time*/)
+{
+}
+
// static
history::HistoryService *
HistoryServiceFactoryQt::GetForBrowserContext(content::BrowserContext *context)
diff --git a/src/core/favicon_service_factory_qt.h b/src/core/favicon_service_factory_qt.h
index 2816140ba..44a43211e 100644
--- a/src/core/favicon_service_factory_qt.h
+++ b/src/core/favicon_service_factory_qt.h
@@ -51,6 +51,7 @@ public:
bool CanAddURL(const GURL &url) override;
void NotifyProfileError(sql::InitStatus init_status, const std::string &diagnostics) override;
std::unique_ptr<history::HistoryBackendClient> CreateBackendClient() override;
+ void UpdateBookmarkLastUsedTime(int64_t bookmark_node_id, base::Time time) override;
};
class HistoryServiceFactoryQt : public BrowserContextKeyedServiceFactory
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 1bfa0db20..6ec7258b9 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -179,11 +179,14 @@ void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
if (d_ptr->fileDialogListener) {
QStringList files(filesList);
base::FilePath baseDir;
- if (d_ptr->mode == UploadFolder && !filesList.isEmpty()
- && QFileInfo(filesList.first()).isDir()) {
- // Enumerate the directory
- files = listRecursively(QDir(filesList.first()));
- baseDir = toFilePath(filesList.first());
+ if (d_ptr->mode == UploadFolder && !filesList.isEmpty()) {
+ if (QFileInfo(filesList.first()).isDir()) {
+ // Enumerate the directory
+ files = listRecursively(QDir(filesList.first()));
+ baseDir = toFilePath(filesList.first());
+ } else {
+ baseDir = toFilePath(filesList.first()).DirName();
+ }
}
std::vector<blink::mojom::FileChooserFileInfoPtr> chooser_files;
diff --git a/src/core/file_system_access/file_system_access_permission_context_qt.cpp b/src/core/file_system_access/file_system_access_permission_context_qt.cpp
index 11a50e1c7..2fd710ad6 100644
--- a/src/core/file_system_access/file_system_access_permission_context_qt.cpp
+++ b/src/core/file_system_access/file_system_access_permission_context_qt.cpp
@@ -212,7 +212,7 @@ FileSystemAccessPermissionContextQt::GetReadPermissionGrant(const url::Origin &o
// |path| changed from being a directory to being a file or vice versa,
// don't just re-use the existing grant but revoke the old grant before
// creating a new grant.
- existing_grant->SetStatus(PermissionStatus::DENIED);
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::DENIED);
existing_grant = nullptr;
}
@@ -260,7 +260,7 @@ FileSystemAccessPermissionContextQt::GetWritePermissionGrant(const url::Origin &
// |path| changed from being a directory to being a file or vice versa,
// don't just re-use the existing grant but revoke the old grant before
// creating a new grant.
- existing_grant->SetStatus(PermissionStatus::DENIED);
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::DENIED);
existing_grant = nullptr;
}
@@ -290,13 +290,14 @@ FileSystemAccessPermissionContextQt::GetWritePermissionGrant(const url::Origin &
return existing_grant;
}
-void FileSystemAccessPermissionContextQt::ConfirmSensitiveDirectoryAccess(
+void FileSystemAccessPermissionContextQt::ConfirmSensitiveEntryAccess(
const url::Origin &origin, PathType path_type, const base::FilePath &path,
- HandleType handle_type, content::GlobalRenderFrameHostId frame_id,
- base::OnceCallback<void(SensitiveDirectoryResult)> callback)
+ HandleType handle_type, UserAction user_action,
+ content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(SensitiveEntryResult)> callback)
{
if (path_type == PathType::kExternal) {
- std::move(callback).Run(SensitiveDirectoryResult::kAllowed);
+ std::move(callback).Run(SensitiveEntryResult::kAllowed);
return;
}
@@ -304,7 +305,7 @@ void FileSystemAccessPermissionContextQt::ConfirmSensitiveDirectoryAccess(
FROM_HERE, { base::MayBlock(), base::TaskPriority::USER_VISIBLE },
base::BindOnce(&ShouldBlockAccessToPath, path, handle_type),
base::BindOnce(&FileSystemAccessPermissionContextQt::DidConfirmSensitiveDirectoryAccess,
- m_weakFactory.GetWeakPtr(), origin, path, handle_type, frame_id,
+ m_weakFactory.GetWeakPtr(), origin, path, handle_type, user_action, frame_id,
std::move(callback)));
}
@@ -355,7 +356,7 @@ FileSystemAccessPermissionContextQt::GetLastPickedDirectory(const url::Origin &o
}
base::FilePath FileSystemAccessPermissionContextQt::GetWellKnownDirectoryPath(
- blink::mojom::WellKnownDirectory directory)
+ blink::mojom::WellKnownDirectory directory, const url::Origin &origin)
{
QStandardPaths::StandardLocation location = QStandardPaths::DocumentsLocation;
switch (directory) {
@@ -405,25 +406,26 @@ void FileSystemAccessPermissionContextQt::NavigatedAwayFromOrigin(const url::Ori
OriginState &origin_state = it->second;
for (auto &grant : origin_state.read_grants)
- grant.second->SetStatus(PermissionStatus::ASK);
+ grant.second->SetStatus(blink::mojom::PermissionStatus::ASK);
for (auto &grant : origin_state.write_grants)
- grant.second->SetStatus(PermissionStatus::ASK);
+ grant.second->SetStatus(blink::mojom::PermissionStatus::ASK);
}
void FileSystemAccessPermissionContextQt::DidConfirmSensitiveDirectoryAccess(
- const url::Origin &origin, const base::FilePath &path, HandleType handle_type,
+ const url::Origin &origin, const base::FilePath &path, HandleType handle_type, UserAction user_action,
content::GlobalRenderFrameHostId frame_id,
- base::OnceCallback<void(SensitiveDirectoryResult)> callback, bool should_block)
+ base::OnceCallback<void(SensitiveEntryResult)> callback, bool should_block)
{
Q_UNUSED(origin);
Q_UNUSED(path);
Q_UNUSED(handle_type);
+ Q_UNUSED(user_action);
Q_UNUSED(frame_id);
if (should_block)
- std::move(callback).Run(SensitiveDirectoryResult::kAbort);
+ std::move(callback).Run(SensitiveEntryResult::kAbort);
else
- std::move(callback).Run(SensitiveDirectoryResult::kAllowed);
+ std::move(callback).Run(SensitiveEntryResult::kAllowed);
}
bool FileSystemAccessPermissionContextQt::AncestorHasActivePermission(
@@ -446,6 +448,11 @@ bool FileSystemAccessPermissionContextQt::AncestorHasActivePermission(
return false;
}
+std::u16string FileSystemAccessPermissionContextQt::GetPickerTitle(const blink::mojom::FilePickerOptionsPtr &)
+{
+ return {};
+}
+
void FileSystemAccessPermissionContextQt::PermissionGrantDestroyed(
FileSystemAccessPermissionGrantQt *grant)
{
diff --git a/src/core/file_system_access/file_system_access_permission_context_qt.h b/src/core/file_system_access/file_system_access_permission_context_qt.h
index 1e2843ce7..09e890038 100644
--- a/src/core/file_system_access/file_system_access_permission_context_qt.h
+++ b/src/core/file_system_access/file_system_access_permission_context_qt.h
@@ -36,10 +36,11 @@ public:
scoped_refptr<content::FileSystemAccessPermissionGrant>
GetWritePermissionGrant(const url::Origin &origin, const base::FilePath &path,
HandleType handle_type, UserAction user_action) override;
- void ConfirmSensitiveDirectoryAccess(
+ void ConfirmSensitiveEntryAccess(
const url::Origin &origin, PathType path_type, const base::FilePath &path,
- HandleType handle_type, content::GlobalRenderFrameHostId frame_id,
- base::OnceCallback<void(SensitiveDirectoryResult)> callback) override;
+ HandleType handle_type, UserAction user_action,
+ content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(SensitiveEntryResult)> callback) override;
void PerformAfterWriteChecks(std::unique_ptr<content::FileSystemAccessWriteItem> item,
content::GlobalRenderFrameHostId frame_id,
base::OnceCallback<void(AfterWriteCheckResult)> callback) override;
@@ -49,7 +50,8 @@ public:
const base::FilePath &path, const PathType type) override;
FileSystemAccessPermissionContextQt::PathInfo
GetLastPickedDirectory(const url::Origin &origin, const std::string &id) override;
- base::FilePath GetWellKnownDirectoryPath(blink::mojom::WellKnownDirectory directory) override;
+ base::FilePath GetWellKnownDirectoryPath(blink::mojom::WellKnownDirectory directory, const url::Origin &origin) override;
+ std::u16string GetPickerTitle(const blink::mojom::FilePickerOptionsPtr &) override;
void NavigatedAwayFromOrigin(const url::Origin &origin);
content::BrowserContext *profile() const { return m_profile; }
@@ -61,8 +63,8 @@ private:
void DidConfirmSensitiveDirectoryAccess(
const url::Origin &origin, const base::FilePath &path, HandleType handle_type,
- content::GlobalRenderFrameHostId frame_id,
- base::OnceCallback<void(SensitiveDirectoryResult)> callback, bool should_block);
+ UserAction user_action, content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(SensitiveEntryResult)> callback, bool should_block);
bool AncestorHasActivePermission(const url::Origin &origin,
const base::FilePath &path,
GrantType grant_type) const;
diff --git a/src/core/file_system_access/file_system_access_permission_grant_qt.cpp b/src/core/file_system_access/file_system_access_permission_grant_qt.cpp
index b9a8f5a26..67fa1c8cf 100644
--- a/src/core/file_system_access/file_system_access_permission_grant_qt.cpp
+++ b/src/core/file_system_access/file_system_access_permission_grant_qt.cpp
@@ -34,9 +34,9 @@ void FileSystemAccessPermissionGrantQt::RequestPermission(
// Check if a permission request has already been processed previously. This
// check is done first because we don't want to reset the status of a
// permission if it has already been granted.
- if (GetStatus() != PermissionStatus::ASK || !m_context) {
- if (GetStatus() == PermissionStatus::GRANTED)
- SetStatus(PermissionStatus::GRANTED);
+ if (GetStatus() != blink::mojom::PermissionStatus::ASK || !m_context) {
+ if (GetStatus() == blink::mojom::PermissionStatus::GRANTED)
+ SetStatus(blink::mojom::PermissionStatus::GRANTED);
std::move(callback).Run(PermissionRequestOutcome::kRequestAborted);
return;
}
@@ -111,7 +111,7 @@ void FileSystemAccessPermissionGrantQt::RequestPermission(
std::move(fullscreen_block));
}
-void FileSystemAccessPermissionGrantQt::SetStatus(PermissionStatus status)
+void FileSystemAccessPermissionGrantQt::SetStatus(blink::mojom::PermissionStatus status)
{
bool should_notify = m_status != status;
m_status = status;
@@ -120,24 +120,24 @@ void FileSystemAccessPermissionGrantQt::SetStatus(PermissionStatus status)
}
void FileSystemAccessPermissionGrantQt::OnPermissionRequestResult(
- base::OnceCallback<void(PermissionRequestOutcome)> callback, PermissionAction result)
+ base::OnceCallback<void(PermissionRequestOutcome)> callback, permissions::PermissionAction result)
{
switch (result) {
- case PermissionAction::GRANTED:
- SetStatus(PermissionStatus::GRANTED);
+ case permissions::PermissionAction::GRANTED:
+ SetStatus(blink::mojom::PermissionStatus::GRANTED);
std::move(callback).Run(PermissionRequestOutcome::kUserGranted);
break;
- case PermissionAction::DENIED:
- SetStatus(PermissionStatus::DENIED);
+ case permissions::PermissionAction::DENIED:
+ SetStatus(blink::mojom::PermissionStatus::DENIED);
std::move(callback).Run(PermissionRequestOutcome::kUserDenied);
break;
- case PermissionAction::DISMISSED:
- case PermissionAction::IGNORED:
+ case permissions::PermissionAction::DISMISSED:
+ case permissions::PermissionAction::IGNORED:
std::move(callback).Run(PermissionRequestOutcome::kUserDismissed);
break;
- case PermissionAction::REVOKED:
- case PermissionAction::GRANTED_ONCE:
- case PermissionAction::NUM:
+ case permissions::PermissionAction::REVOKED:
+ case permissions::PermissionAction::GRANTED_ONCE:
+ case permissions::PermissionAction::NUM:
NOTREACHED();
break;
}
diff --git a/src/core/file_system_access/file_system_access_permission_grant_qt.h b/src/core/file_system_access/file_system_access_permission_grant_qt.h
index e1d1ca7e9..829d2b889 100644
--- a/src/core/file_system_access/file_system_access_permission_grant_qt.h
+++ b/src/core/file_system_access/file_system_access_permission_grant_qt.h
@@ -14,8 +14,6 @@ namespace QtWebEngineCore {
using HandleType = content::FileSystemAccessPermissionContext::HandleType;
using GrantType = FileSystemAccessPermissionContextQt::GrantType;
-using blink::mojom::PermissionStatus;
-using permissions::PermissionAction;
class FileSystemAccessPermissionGrantQt : public content::FileSystemAccessPermissionGrant
{
@@ -25,7 +23,7 @@ public:
HandleType handle_type, GrantType type);
// content::FileSystemAccessPermissionGrant:
- PermissionStatus GetStatus() override { return m_status; }
+ blink::mojom::PermissionStatus GetStatus() override { return m_status; }
base::FilePath GetPath() override { return m_path; }
void RequestPermission(content::GlobalRenderFrameHostId frame_id,
UserActivationState user_activation_state,
@@ -36,14 +34,14 @@ public:
const base::FilePath &path() const { return m_path; }
GrantType type() const { return m_type; }
- void SetStatus(PermissionStatus status);
+ void SetStatus(blink::mojom::PermissionStatus status);
protected:
~FileSystemAccessPermissionGrantQt() override;
private:
void OnPermissionRequestResult(base::OnceCallback<void(PermissionRequestOutcome)> callback,
- PermissionAction result);
+ permissions::PermissionAction result);
base::WeakPtr<FileSystemAccessPermissionContextQt> const m_context;
const url::Origin m_origin;
@@ -53,7 +51,7 @@ private:
// This member should only be updated via SetStatus(), to make sure
// observers are properly notified about any change in status.
- PermissionStatus m_status = PermissionStatus::ASK;
+ blink::mojom::PermissionStatus m_status = blink::mojom::PermissionStatus::ASK;
};
} // namespace QtWebEngineCore
diff --git a/src/core/file_system_access/file_system_access_permission_request_controller.h b/src/core/file_system_access/file_system_access_permission_request_controller.h
index f1b446de6..e659f81a7 100644
--- a/src/core/file_system_access/file_system_access_permission_request_controller.h
+++ b/src/core/file_system_access/file_system_access_permission_request_controller.h
@@ -17,7 +17,7 @@ class FileSystemAccessPermissionRequestController : public RequestController
public:
FileSystemAccessPermissionRequestController(const QUrl &origin, const QUrl &filePath,
HandleType handleType, AccessFlags accessType)
- : RequestController(std::move(origin))
+ : RequestController(origin)
, m_filePath(filePath)
, m_handleType(handleType)
, m_accessType(accessType)
diff --git a/src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp b/src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp
index 423cdd777..c384dc7b3 100644
--- a/src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp
+++ b/src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp
@@ -153,7 +153,7 @@ void FileSystemAccessPermissionRequestManagerQt::DidFinishNavigation(
if (!navigation->IsInMainFrame() || !navigation->HasCommitted())
return;
- auto src_origin = url::Origin::Create(navigation->GetPreviousMainFrameURL());
+ auto src_origin = url::Origin::Create(navigation->GetPreviousPrimaryMainFrameURL());
auto dest_origin = url::Origin::Create(navigation->GetURL());
if (src_origin == dest_origin)
return;
@@ -168,7 +168,7 @@ void FileSystemAccessPermissionRequestManagerQt::DidFinishNavigation(
void FileSystemAccessPermissionRequestManagerQt::WebContentsDestroyed()
{
- auto src_origin = web_contents()->GetMainFrame()->GetLastCommittedOrigin();
+ auto src_origin = web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
// Navigated away from |src_origin|, tell permission context to check if
// permissions need to be revoked.
diff --git a/src/core/login_delegate_qt.cpp b/src/core/login_delegate_qt.cpp
index 845872012..140335735 100644
--- a/src/core/login_delegate_qt.cpp
+++ b/src/core/login_delegate_qt.cpp
@@ -7,7 +7,6 @@
#include "login_delegate_qt.h"
-#include "base/task/post_task.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
@@ -45,8 +44,7 @@ LoginDelegateQt::LoginDelegateQt(const net::AuthChallengeInfo &authInfo,
, m_auth_required_callback(std::move(auth_required_callback))
, m_weakFactory(this)
{
- base::PostTask(
- FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&LoginDelegateQt::triggerDialog, m_weakFactory.GetWeakPtr()));
}
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index cddb5a290..a6ac070af 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -12,8 +12,9 @@
#include "web_contents_view_qt.h"
#include "web_engine_settings.h"
-#include "base/task/post_task.h"
+#include "base/strings/strcat.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/desktop_streams_registry.h"
@@ -22,6 +23,8 @@
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_manager_base.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#if QT_CONFIG(webengine_webrtc)
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
@@ -54,26 +57,166 @@ const blink::MediaStreamDevice *findDeviceWithId(const blink::MediaStreamDevices
}
// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
-void getDevicesForDesktopCapture(blink::MediaStreamDevices *devices,
+media::mojom::CaptureHandlePtr CreateCaptureHandle(content::WebContents *capturer,
+ const url::Origin &capturer_origin,
+ const content::DesktopMediaID &captured_id)
+{
+ if (capturer_origin.opaque())
+ return nullptr;
+
+ content::RenderFrameHost *const captured_rfh =
+ content::RenderFrameHost::FromID(
+ captured_id.web_contents_id.render_process_id,
+ captured_id.web_contents_id.main_render_frame_id);
+ if (!captured_rfh || !captured_rfh->IsActive())
+ return nullptr;
+
+ content::WebContents *const captured = content::WebContents::FromRenderFrameHost(captured_rfh);
+ if (!captured)
+ return nullptr;
+
+ const auto &captured_config = captured->GetCaptureHandleConfig();
+ if (!captured_config.all_origins_permitted &&
+ std::none_of(captured_config.permitted_origins.begin(),
+ captured_config.permitted_origins.end(),
+ [capturer_origin](const url::Origin& permitted_origin) {
+ return capturer_origin.IsSameOriginWith(permitted_origin);
+ }))
+ {
+ return nullptr;
+ }
+
+ // Observing CaptureHandle when either the capturing or the captured party
+ // is incognito is disallowed, except for self-capture.
+ if (capturer->GetPrimaryMainFrame() != captured->GetPrimaryMainFrame()) {
+ if (capturer->GetBrowserContext()->IsOffTheRecord() ||
+ captured->GetBrowserContext()->IsOffTheRecord()) {
+ return nullptr;
+ }
+ }
+
+ if (!captured_config.expose_origin && captured_config.capture_handle.empty())
+ return nullptr;
+
+ auto result = media::mojom::CaptureHandle::New();
+ if (captured_config.expose_origin)
+ result->origin = captured->GetPrimaryMainFrame()->GetLastCommittedOrigin();
+
+ result->capture_handle = captured_config.capture_handle;
+
+ return result;
+}
+
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+media::mojom::DisplayMediaInformationPtr DesktopMediaIDToDisplayMediaInformation(content::WebContents *capturer,
+ const url::Origin &capturer_origin,
+ const content::DesktopMediaID &media_id)
+{
+ media::mojom::DisplayCaptureSurfaceType display_surface = media::mojom::DisplayCaptureSurfaceType::MONITOR;
+ bool logical_surface = true;
+ media::mojom::CursorCaptureType cursor = media::mojom::CursorCaptureType::NEVER;
+#if defined(USE_AURA)
+ const bool uses_aura = (media_id.window_id != content::DesktopMediaID::kNullId ? true : false);
+#else
+ const bool uses_aura = false;
+#endif // defined(USE_AURA)
+
+ media::mojom::CaptureHandlePtr capture_handle;
+ switch (media_id.type) {
+ case content::DesktopMediaID::TYPE_SCREEN:
+ display_surface = media::mojom::DisplayCaptureSurfaceType::MONITOR;
+ cursor = uses_aura ? media::mojom::CursorCaptureType::MOTION
+ : media::mojom::CursorCaptureType::ALWAYS;
+ break;
+ case content::DesktopMediaID::TYPE_WINDOW:
+ display_surface = media::mojom::DisplayCaptureSurfaceType::WINDOW;
+ cursor = uses_aura ? media::mojom::CursorCaptureType::MOTION
+ : media::mojom::CursorCaptureType::ALWAYS;
+ break;
+ case content::DesktopMediaID::TYPE_WEB_CONTENTS:
+ display_surface = media::mojom::DisplayCaptureSurfaceType::BROWSER;
+ cursor = media::mojom::CursorCaptureType::MOTION;
+ capture_handle = CreateCaptureHandle(capturer, capturer_origin, media_id);
+ break;
+ case content::DesktopMediaID::TYPE_NONE:
+ break;
+ }
+
+ return media::mojom::DisplayMediaInformation::New(display_surface, logical_surface, cursor, std::move(capture_handle));
+}
+
+
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+std::string DeviceNamePrefix(content::WebContents *web_contents,
+ blink::mojom::MediaStreamType requested_stream_type,
+ const content::DesktopMediaID &media_id)
+{
+ if (!web_contents || requested_stream_type != blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB) {
+ return std::string();
+ }
+
+ // Note that all of these must still be checked, as the explicit-selection
+ // dialog for DISPLAY_VIDEO_CAPTURE_THIS_TAB could still return something
+ // other than the current tab - be it a screen, window, or another tab.
+ if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS &&
+ web_contents->GetPrimaryMainFrame()->GetProcess()->GetID() ==
+ media_id.web_contents_id.render_process_id &&
+ web_contents->GetPrimaryMainFrame()->GetRoutingID() ==
+ media_id.web_contents_id.main_render_frame_id) {
+ return "current-";
+ }
+
+ return std::string();
+}
+
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+std::string DeviceName(content::WebContents *web_contents,
+ blink::mojom::MediaStreamType requested_stream_type,
+ const content::DesktopMediaID &media_id)
+{
+ const std::string prefix =
+ DeviceNamePrefix(web_contents, requested_stream_type, media_id);
+ if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
+ return base::StrCat({prefix, content::kWebContentsCaptureScheme,
+ base::UnguessableToken::Create().ToString()});
+ } else {
+ // TODO(crbug.com/1252682): MediaStreamTrack.label leaks internal state for
+ // screen/window
+ return base::StrCat({prefix, media_id.ToString()});
+ }
+}
+
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+void getDevicesForDesktopCapture(const content::MediaStreamRequest &request,
+ content::WebContents *web_contents,
content::DesktopMediaID mediaId,
bool captureAudio,
- MediaStreamType videoType,
- MediaStreamType audioType)
+ bool disableLocalEcho,
+ blink::mojom::StreamDevices &out_devices)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Add selected desktop source to the list.
- devices->push_back(blink::MediaStreamDevice(videoType, mediaId.ToString(), mediaId.ToString()));
+ blink::MediaStreamDevice device(request.video_type, mediaId.ToString(),
+ DeviceName(web_contents, request.video_type, mediaId));
+ device.display_media_info = DesktopMediaIDToDisplayMediaInformation(
+ web_contents, url::Origin::Create(request.security_origin), mediaId);
+ out_devices.video_device = device;
+
if (captureAudio) {
+ DCHECK_NE(request.audio_type, blink::mojom::MediaStreamType::NO_SERVICE);
+
if (mediaId.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
- devices->push_back(
- blink::MediaStreamDevice(audioType, mediaId.ToString(), "Tab audio"));
+ content::WebContentsMediaCaptureId web_id = mediaId.web_contents_id;
+ web_id.disable_local_echo = disableLocalEcho;
+ out_devices.audio_device = blink::MediaStreamDevice(request.audio_type, web_id.ToString(), "Tab audio");
} else {
// Use the special loopback device ID for system audio capture.
- devices->push_back(blink::MediaStreamDevice(
- audioType,
- media::AudioDeviceDescription::kLoopbackInputDeviceId,
- "System Audio"));
+ out_devices.audio_device = blink::MediaStreamDevice(
+ request.audio_type, (disableLocalEcho
+ ? media::AudioDeviceDescription::kLoopbackWithMuteDeviceId
+ : media::AudioDeviceDescription::kLoopbackInputDeviceId),
+ "System Audio");
}
}
}
@@ -201,11 +344,12 @@ WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const co
class MediaStreamUIQt : public content::MediaStreamUI
{
public:
- MediaStreamUIQt(content::WebContents *webContents, const blink::MediaStreamDevices &devices)
+ MediaStreamUIQt(content::WebContents *webContents, const blink::mojom::StreamDevices &devices)
: m_delegate(static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->AsWeakPtr())
, m_devices(devices)
{
- DCHECK(!m_devices.empty());
+ DCHECK(m_devices.audio_device.has_value() ||
+ m_devices.video_device.has_value());
}
~MediaStreamUIQt() override
@@ -238,9 +382,10 @@ private:
Q_UNUSED(label);
Q_UNUSED(media_id);
}
-
+ void OnDeviceStoppedForSourceChange(const std::string&, const content::DesktopMediaID&, const content::DesktopMediaID&) override
+ {}
base::WeakPtr<WebContentsDelegateQt> m_delegate;
- const blink::MediaStreamDevices m_devices;
+ const blink::mojom::StreamDevices m_devices;
bool m_started = false;
base::RepeatingClosure m_onStop; // currently unused
};
@@ -262,7 +407,7 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- blink::MediaStreamDevices devices;
+ blink::mojom::StreamDevicesSet deviceSet;
auto it = m_pendingRequests.find(webContents);
if (it == m_pendingRequests.end() || it->second.empty())
return;
@@ -289,20 +434,22 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
if (microphoneRequested || webcamRequested) {
switch (request.request_type) {
case blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
- getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices);
+ getDefaultDevices("", "", microphoneRequested, webcamRequested, deviceSet);
break;
case blink::MEDIA_DEVICE_ACCESS:
case blink::MEDIA_DEVICE_UPDATE:
case blink::MEDIA_GENERATE_STREAM:
case blink::MEDIA_GET_OPEN_DEVICE:
getDefaultDevices(request.requested_audio_device_id, request.requested_video_device_id,
- microphoneRequested, webcamRequested, &devices);
+ microphoneRequested, webcamRequested, deviceSet);
break;
}
} else if (desktopVideoRequested) {
+ deviceSet.stream_devices.emplace_back(blink::mojom::StreamDevices::New());
bool captureAudio = desktopAudioRequested && m_loopbackAudioSupported;
- getDevicesForDesktopCapture(&devices, getDefaultScreenId(), captureAudio,
- request.video_type, request.audio_type);
+ blink::mojom::StreamDevices &stream_devices = *deviceSet.stream_devices[0];
+ getDevicesForDesktopCapture(request, webContents, getDefaultScreenId(), captureAudio,
+ request.disable_local_echo, stream_devices);
}
}
@@ -313,17 +460,17 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
// Post a task to process next queued request. It has to be done
// asynchronously to make sure that calling infobar is not destroyed until
// after this function returns.
- base::PostTask(FROM_HERE, {BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest,
base::Unretained(this), webContents));
}
- if (devices.empty())
- std::move(callback).Run(devices, MediaStreamRequestResult::INVALID_STATE,
+ if (deviceSet.stream_devices.empty())
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::INVALID_STATE,
std::unique_ptr<content::MediaStreamUI>());
else
- std::move(callback).Run(devices, MediaStreamRequestResult::OK,
- std::make_unique<MediaStreamUIQt>(webContents, devices));
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::OK,
+ std::make_unique<MediaStreamUIQt>(webContents, *deviceSet.stream_devices[0]));
}
MediaCaptureDevicesDispatcher *MediaCaptureDevicesDispatcher::GetInstance()
@@ -358,7 +505,7 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebConten
WebContentsAdapterClient::MediaRequestFlags flags = mediaRequestFlagsForRequest(request);
if (!flags) {
- std::move(callback).Run(blink::MediaStreamDevices(), MediaStreamRequestResult::NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>());
+ std::move(callback).Run(blink::mojom::StreamDevicesSet(), MediaStreamRequestResult::NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -370,7 +517,7 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebConten
QWebEngineSettings::ScreenCaptureEnabled);
const bool originIsSecure = network::IsUrlPotentiallyTrustworthy(request.security_origin);
if (!screenCaptureEnabled || !originIsSecure) {
- std::move(callback).Run(blink::MediaStreamDevices(), MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
+ std::move(callback).Run(blink::mojom::StreamDevicesSet(), MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -388,11 +535,11 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebConten
void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
{
- blink::MediaStreamDevices devices;
+ blink::mojom::StreamDevicesSet deviceSet;
content::WebContents *const web_contents_for_stream = content::WebContents::FromRenderFrameHost(
content::RenderFrameHost::FromID(request.render_process_id, request.render_frame_id));
- content::RenderFrameHost *const main_frame = web_contents_for_stream ? web_contents_for_stream->GetMainFrame() : NULL;
+ content::RenderFrameHost *const main_frame = web_contents_for_stream ? web_contents_for_stream->GetPrimaryMainFrame() : nullptr;
content::DesktopMediaID mediaId;
if (main_frame) {
@@ -407,7 +554,7 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
// Received invalid device id.
if (mediaId.type == content::DesktopMediaID::TYPE_NONE) {
- std::move(callback).Run(devices, MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -417,14 +564,16 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
bool audioSupported = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && m_loopbackAudioSupported);
bool captureAudio = (audioRequested && audioSupported);
- getDevicesForDesktopCapture(&devices, mediaId, captureAudio, request.video_type, request.audio_type);
+ deviceSet.stream_devices.emplace_back(blink::mojom::StreamDevices::New());
+ blink::mojom::StreamDevices &stream_devices = *deviceSet.stream_devices[0];
+ getDevicesForDesktopCapture(request, webContents, mediaId, captureAudio, request.disable_local_echo, stream_devices);
- if (devices.empty())
- std::move(callback).Run(devices, MediaStreamRequestResult::INVALID_STATE,
+ if (deviceSet.stream_devices.empty())
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::INVALID_STATE,
std::unique_ptr<content::MediaStreamUI>());
else
- std::move(callback).Run(devices, MediaStreamRequestResult::OK,
- std::make_unique<MediaStreamUIQt>(webContents, devices));
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::OK,
+ std::make_unique<MediaStreamUIQt>(webContents, *deviceSet.stream_devices[0]));
}
void MediaCaptureDevicesDispatcher::enqueueMediaAccessRequest(content::WebContents *webContents,
@@ -453,18 +602,20 @@ void MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest(content::WebConte
}
void MediaCaptureDevicesDispatcher::getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId,
- bool audio, bool video, blink::MediaStreamDevices *devices)
+ bool audio, bool video, blink::mojom::StreamDevicesSet &devicesSet)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(audio || video);
+ devicesSet.stream_devices.emplace_back(blink::mojom::StreamDevices::New());
+ blink::mojom::StreamDevices& devices = *devicesSet.stream_devices[0];
if (audio) {
const blink::MediaStreamDevices &audioDevices = content::MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices();
const blink::MediaStreamDevice *device = findDeviceWithId(audioDevices, audioDeviceId);
if (!device && !audioDevices.empty())
device = &audioDevices.front();
if (device)
- devices->push_back(*device);
+ devices.audio_device = *device;
}
if (video) {
@@ -473,14 +624,14 @@ void MediaCaptureDevicesDispatcher::getDefaultDevices(const std::string &audioDe
if (!device && !videoDevices.empty())
device = &videoDevices.front();
if (device)
- devices->push_back(*device);
+ devices.video_device = *device;
}
}
void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(int render_process_id, int render_frame_id, int page_request_id, const GURL &security_origin, blink::mojom::MediaStreamType stream_type, content::MediaRequestState state)
{
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- base::PostTask(FROM_HERE, {BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&MediaCaptureDevicesDispatcher::updateMediaRequestStateOnUIThread,
base::Unretained(this), render_process_id, render_frame_id,
page_request_id, security_origin, stream_type, state));
diff --git a/src/core/media_capture_devices_dispatcher.h b/src/core/media_capture_devices_dispatcher.h
index cdb84ee24..37f41901b 100644
--- a/src/core/media_capture_devices_dispatcher.h
+++ b/src/core/media_capture_devices_dispatcher.h
@@ -30,7 +30,7 @@ public:
void handleMediaAccessPermissionResponse(content::WebContents *, const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags);
private:
- void getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId, bool audio, bool video, blink::MediaStreamDevices *);
+ void getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId, bool audio, bool video, blink::mojom::StreamDevicesSet &devices);
// Overridden from content::MediaObserver:
void OnAudioCaptureDevicesChanged() override {}
diff --git a/src/core/net/client_cert_qt.cpp b/src/core/net/client_cert_qt.cpp
index 1e7aa8b6a..d5ea1a776 100644
--- a/src/core/net/client_cert_qt.cpp
+++ b/src/core/net/client_cert_qt.cpp
@@ -4,7 +4,6 @@
#include "client_cert_qt.h"
#include "base/bind.h"
-#include "base/task/post_task.h"
#include "base/callback_forward.h"
#include "content/public/browser/browser_task_traits.h"
#include "crypto/crypto_buildflags.h"
@@ -118,8 +117,8 @@ void ClientCertStoreQt::GetClientCerts(const net::SSLCertRequestInfo &cert_reque
{
#if QT_CONFIG(ssl)
// Access the user-provided data from the UI thread, but return on whatever thread this is.
- bool ok = base::PostTaskAndReplyWithResult(
- FROM_HERE, { content::BrowserThread::UI },
+ bool ok = content::GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
base::BindOnce(&ClientCertStoreQt::GetClientCertsOnUIThread,
base::Unretained(this), std::cref(cert_request_info)),
base::BindOnce(&ClientCertStoreQt::GetClientCertsReturn,
diff --git a/src/core/net/custom_url_loader_factory.cpp b/src/core/net/custom_url_loader_factory.cpp
index bd7d7dc58..19a1a884f 100644
--- a/src/core/net/custom_url_loader_factory.cpp
+++ b/src/core/net/custom_url_loader_factory.cpp
@@ -4,7 +4,6 @@
#include "custom_url_loader_factory.h"
#include "base/strings/stringprintf.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -64,7 +63,7 @@ public:
scoped_refptr<URLRequestCustomJobProxy> proxy = new URLRequestCustomJobProxy(this, m_proxy->m_scheme, m_proxy->m_profileAdapter);
m_proxy->m_client = nullptr;
// m_taskRunner->PostTask(FROM_HERE, base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
- base::PostTask(FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
m_proxy = std::move(proxy);
if (new_url)
@@ -87,7 +86,7 @@ private:
mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote,
QPointer<ProfileAdapter> profileAdapter)
// ### We can opt to run the url-loader on the UI thread instead
- : m_taskRunner(base::CreateSingleThreadTaskRunner({ content::BrowserThread::IO }))
+ : m_taskRunner(content::GetIOThreadTaskRunner({}))
, m_proxy(new URLRequestCustomJobProxy(this, request.url.scheme(), profileAdapter))
, m_receiver(this, std::move(loader))
, m_client(std::move(client_remote))
@@ -151,7 +150,7 @@ private:
m_firstBytePosition = m_byteRange.first_byte_position();
// m_taskRunner->PostTask(FROM_HERE,
- base::PostTask(FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&URLRequestCustomJobProxy::initialize, m_proxy,
m_request.url, m_request.method, m_request.request_initiator, std::move(headers)));
}
@@ -204,7 +203,7 @@ private:
m_device->close();
m_device = nullptr;
// m_taskRunner->PostTask(FROM_HERE, base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
- base::PostTask(FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
if (!wait_for_loader_error || !m_receiver.is_bound())
delete this;
@@ -286,8 +285,7 @@ private:
m_head->mime_type = m_mimeType;
m_head->charset = m_charset;
m_headerBytesRead = m_head->headers->raw_headers().length();
- m_client->OnReceiveResponse(std::move(m_head), mojo::ScopedDataPipeConsumerHandle());
- m_client->OnStartLoadingResponseBody(std::move(m_pipeConsumerHandle));
+ m_client->OnReceiveResponse(std::move(m_head), std::move(m_pipeConsumerHandle), absl::nullopt);
m_head = nullptr;
m_watcher = std::make_unique<mojo::SimpleWatcher>(
@@ -337,7 +335,7 @@ private:
m_head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(net::HttpUtil::AssembleRawHeaders(headers));
m_head->encoded_data_length = m_head->headers->raw_headers().length();
m_head->content_length = m_head->encoded_body_length = -1;
- m_client->OnReceiveResponse(std::move(m_head), mojo::ScopedDataPipeConsumerHandle());
+ m_client->OnReceiveResponse(std::move(m_head), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
CompleteWithFailure(net::Error(error));
}
void notifyReadyRead() override
@@ -447,7 +445,7 @@ private:
class CustomURLLoaderFactory : public network::mojom::URLLoaderFactory {
public:
CustomURLLoaderFactory(ProfileAdapter *profileAdapter, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
- : m_taskRunner(base::CreateSequencedTaskRunner({ content::BrowserThread::IO }))
+ : m_taskRunner(content::GetIOThreadTaskRunner({}))
, m_profileAdapter(profileAdapter)
{
m_receivers.set_disconnect_handler(base::BindRepeating(
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index 1bcb3ddea..f61fb704a 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -10,7 +10,6 @@
#include "base/bind.h"
#include "base/guid.h"
-#include "base/task/post_task.h"
#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -151,16 +150,13 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
producer_handle->WriteData(
payload.c_str(), &len, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
-
- new_client->OnStartLoadingResponseBody(std::move(consumer_handle));
-
network::URLLoaderCompletionStatus status(net::OK);
status.decoded_body_length = len;
new_client->OnComplete(status);
mojo::PendingRemote<network::mojom::URLLoader> original_loader;
mojo::PendingReceiver<network::mojom::URLLoaderClient> original_client;
- mojo::ScopedDataPipeConsumerHandle body;
+ mojo::ScopedDataPipeConsumerHandle body = std::move(consumer_handle);
delegate_->InterceptResponse(std::move(dummy_new_loader),
std::move(new_client_receiver),
&original_loader, &original_client,
diff --git a/src/core/net/proxy_config_monitor.cpp b/src/core/net/proxy_config_monitor.cpp
index d4543947a..8315b7bf2 100644
--- a/src/core/net/proxy_config_monitor.cpp
+++ b/src/core/net/proxy_config_monitor.cpp
@@ -10,14 +10,11 @@
#include "proxy_config_monitor.h"
#include "proxy_config_service_qt.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
-#include "build/build_config.h"
-#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "content/public/browser/browser_task_traits.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "net/proxy_resolution/proxy_resolution_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include <utility>
@@ -28,9 +25,7 @@ ProxyConfigMonitor::ProxyConfigMonitor(PrefService *prefs)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- proxy_config_service_.reset(
- new ProxyConfigServiceQt(
- prefs, base::CreateSingleThreadTaskRunner({ BrowserThread::UI })));
+ proxy_config_service_.reset(new ProxyConfigServiceQt(prefs, content::GetUIThreadTaskRunner({})));
proxy_config_service_->AddObserver(this);
}
diff --git a/src/core/net/proxy_config_monitor.h b/src/core/net/proxy_config_monitor.h
index 69655b807..585e4b7ed 100644
--- a/src/core/net/proxy_config_monitor.h
+++ b/src/core/net/proxy_config_monitor.h
@@ -10,16 +10,11 @@
#define PROXY_CONFIG_MONITOR_H
#include <memory>
-#include <string>
-#include "build/buildflag.h"
-#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "services/network/public/mojom/network_context.mojom-forward.h"
-#include "services/network/public/mojom/network_service.mojom-forward.h"
-#include "services/network/public/mojom/proxy_config.mojom-forward.h"
#include "services/network/public/mojom/proxy_config_with_annotation.mojom.h"
namespace net {
@@ -61,4 +56,4 @@ private:
mojo::RemoteSet<network::mojom::ProxyConfigClient> proxy_config_client_set_;
};
-#endif // !PROXY_CONFIG_MONITOR_H
+#endif // PROXY_CONFIG_MONITOR_H
diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp
index 14514a615..70bcb59b4 100644
--- a/src/core/net/proxy_config_service_qt.cpp
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -9,12 +9,10 @@
#include "proxy_config_service_qt.h"
-#include "base/bind.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/proxy_resolution/configured_proxy_resolution_service.h"
+#include "net/base/proxy_server.h"
-using content::BrowserThread;
+#include <QNetworkProxy>
net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy)
{
@@ -36,7 +34,7 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
ProxyConfigServiceQt::ProxyConfigServiceQt(PrefService *prefService,
const scoped_refptr<base::SequencedTaskRunner> &taskRunner)
- : m_baseService(net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(taskRunner))
+ : m_baseService(net::ProxyConfigService::CreateSystemProxyConfigService(taskRunner))
, m_usesSystemConfiguration(false)
, m_registeredObserver(false)
, m_prefState(prefService
diff --git a/src/core/net/proxy_config_service_qt.h b/src/core/net/proxy_config_service_qt.h
index dcbc5074f..49c9877a5 100644
--- a/src/core/net/proxy_config_service_qt.h
+++ b/src/core/net/proxy_config_service_qt.h
@@ -4,10 +4,8 @@
#ifndef PROXY_CONFIG_SERVICE_QT_H
#define PROXY_CONFIG_SERVICE_QT_H
-#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "base/task/sequenced_task_runner.h"
-
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
index ab435f8e2..8608d35cd 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.cpp
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -15,7 +15,6 @@
#include "type_conversion.h"
#include "base/memory/ptr_util.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
@@ -29,7 +28,7 @@ void ProxyingRestrictedCookieManagerQt::CreateAndBind(ProfileIODataQt *profileIo
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
+ content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&ProxyingRestrictedCookieManagerQt::CreateAndBindOnIoThread,
profileIoData,
std::move(underlying_rcm),
@@ -121,7 +120,7 @@ void ProxyingRestrictedCookieManagerQt::SetCookieFromString(const GURL &url,
underlying_restricted_cookie_manager_->SetCookieFromString(url, site_for_cookies, top_frame_origin, cookie,
partitioned_cookies_runtime_feature_enabled, std::move(callback));
} else {
- std::move(callback).Run();
+ std::move(callback).Run(false, false); // FIXME: is true, true in aw_proxying_restricted_cookie_manager.cc though..
}
}
@@ -150,6 +149,11 @@ void ProxyingRestrictedCookieManagerQt::CookiesEnabledFor(const GURL &url,
std::move(callback).Run(allowCookies(url, site_for_cookies));
}
+void ProxyingRestrictedCookieManagerQt::ConvertPartitionedCookiesToUnpartitioned(const GURL&)
+{
+ NOTIMPLEMENTED();
+}
+
bool ProxyingRestrictedCookieManagerQt::allowCookies(const GURL &url, const net::SiteForCookies &site_for_cookies) const
{
if (!m_profileIoData)
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.h b/src/core/net/proxying_restricted_cookie_manager_qt.h
index 7ac6807ac..95e193f76 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.h
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.h
@@ -56,6 +56,7 @@ public:
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
CookiesEnabledForCallback callback) override;
+ void ConvertPartitionedCookiesToUnpartitioned(const GURL&) override;
// Internal:
bool allowCookies(const GURL &url, const net::SiteForCookies &site_for_cookies) const;
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index 1dc1b1577..70ec61b34 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -80,6 +80,18 @@ static QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::N
return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
}
+static QHash<QByteArray, QByteArray> toQt(const net::HttpRequestHeaders &headers)
+{
+ const auto vector = headers.GetHeaderVector();
+ QHash<QByteArray, QByteArray> hash;
+
+ for (const auto &header : vector) {
+ hash.insert(QByteArray::fromStdString(header.key), QByteArray::fromStdString(header.value));
+ }
+
+ return hash;
+}
+
// Handles intercepted, in-progress requests/responses, so that they can be
// controlled and modified accordingly.
class InterceptedRequest : public network::mojom::URLLoader
@@ -98,12 +110,10 @@ public:
void Restart();
// network::mojom::URLLoaderClient
- void OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle) override;
+ void OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle, absl::optional<mojo_base::BigBuffer>) override;
void OnReceiveRedirect(const net::RedirectInfo &redirect_info, network::mojom::URLResponseHeadPtr head) override;
void OnUploadProgress(int64_t current_position, int64_t total_size, OnUploadProgressCallback callback) override;
- void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
- void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus &status) override;
void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr) override {}
@@ -306,8 +316,14 @@ void InterceptedRequest::Restart()
else
firstPartyUrl = toQt(request_.site_for_cookies.first_party_url()); // m_topDocumentUrl can be empty for the main-frame.
- auto info = new QWebEngineUrlRequestInfoPrivate(resourceType, navigationType, originalUrl, firstPartyUrl,
- initiator, QByteArray::fromStdString(request_.method));
+ QHash<QByteArray, QByteArray> headers = toQt(request_.headers);
+
+ if (!request_.referrer.is_empty())
+ headers.insert("Referer", toQt(request_.referrer).toEncoded());
+
+ auto info = new QWebEngineUrlRequestInfoPrivate(
+ resourceType, navigationType, originalUrl, firstPartyUrl, initiator,
+ QByteArray::fromStdString(request_.method), headers);
Q_ASSERT(!request_info_);
request_info_.reset(new QWebEngineUrlRequestInfo(info));
@@ -342,7 +358,7 @@ void InterceptedRequest::ContinueAfterIntercept()
for (auto header = info.extraHeaders.constBegin(); header != info.extraHeaders.constEnd(); ++header) {
std::string h = header.key().toStdString();
- if (base::LowerCaseEqualsASCII(h, "referer")) {
+ if (base::EqualsCaseInsensitiveASCII(h, "referer")) {
request_.referrer = GURL(header.value().toStdString());
} else {
request_.headers.SetHeader(h, header.value().toStdString());
@@ -386,11 +402,11 @@ void InterceptedRequest::ContinueAfterIntercept()
// URLLoaderClient methods.
-void InterceptedRequest::OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle handle)
+void InterceptedRequest::OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle handle, absl::optional<mojo_base::BigBuffer> buffer)
{
current_response_ = head.Clone();
- target_client_->OnReceiveResponse(std::move(head), std::move(handle));
+ target_client_->OnReceiveResponse(std::move(head), std::move(handle), std::move(buffer));
}
void InterceptedRequest::OnReceiveRedirect(const net::RedirectInfo &redirect_info, network::mojom::URLResponseHeadPtr head)
@@ -410,21 +426,11 @@ void InterceptedRequest::OnUploadProgress(int64_t current_position, int64_t tota
target_client_->OnUploadProgress(current_position, total_size, std::move(callback));
}
-void InterceptedRequest::OnReceiveCachedMetadata(mojo_base::BigBuffer data)
-{
- target_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
void InterceptedRequest::OnTransferSizeUpdated(int32_t transfer_size_diff)
{
target_client_->OnTransferSizeUpdated(transfer_size_diff);
}
-void InterceptedRequest::OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body)
-{
- target_client_->OnStartLoadingResponseBody(std::move(body));
-}
-
void InterceptedRequest::OnComplete(const network::URLLoaderCompletionStatus &status)
{
// Only wait for the original loader to possibly have a custom error if the
diff --git a/src/core/net/ssl_host_state_delegate_qt.cpp b/src/core/net/ssl_host_state_delegate_qt.cpp
index 2c64132f3..d0308389d 100644
--- a/src/core/net/ssl_host_state_delegate_qt.cpp
+++ b/src/core/net/ssl_host_state_delegate_qt.cpp
@@ -39,7 +39,7 @@ SSLHostStateDelegateQt::SSLHostStateDelegateQt() {}
SSLHostStateDelegateQt::~SSLHostStateDelegateQt() {}
-void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, int error, content::WebContents *)
+void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, int error, content::StoragePartition *)
{
m_certPolicyforHost[host].Allow(cert, error);
}
@@ -67,7 +67,7 @@ void SSLHostStateDelegateQt::Clear(base::RepeatingCallback<bool(const std::strin
// prior to this query, otherwise false.
content::SSLHostStateDelegate::CertJudgment SSLHostStateDelegateQt::QueryPolicy(const std::string &host,
const net::X509Certificate &cert,
- int error, content::WebContents *)
+ int error, content::StoragePartition *)
{
return m_certPolicyforHost[host].Check(cert, error) ? SSLHostStateDelegate::ALLOWED : SSLHostStateDelegate::DENIED;
}
@@ -83,12 +83,12 @@ bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host,
return false;
}
-void SSLHostStateDelegateQt::AllowHttpForHost(const std::string &host, content::WebContents *web_contents)
+void SSLHostStateDelegateQt::AllowHttpForHost(const std::string &host, content::StoragePartition *web_contents)
{
// Intentional no-op see aw_ssl_host_state_delegate
}
-bool SSLHostStateDelegateQt::IsHttpAllowedForHost(const std::string &host, content::WebContents *web_contents)
+bool SSLHostStateDelegateQt::IsHttpAllowedForHost(const std::string &host, content::StoragePartition *web_contents)
{
return false;
}
@@ -104,7 +104,7 @@ void SSLHostStateDelegateQt::RevokeUserAllowExceptions(const std::string &host)
// |host|. This does not mean that *all* certificate errors are allowed, just
// that there exists an exception. To see if a particular certificate and
// error combination exception is allowed, use QueryPolicy().
-bool SSLHostStateDelegateQt::HasAllowException(const std::string &host, content::WebContents *)
+bool SSLHostStateDelegateQt::HasAllowException(const std::string &host, content::StoragePartition *)
{
auto policy_iterator = m_certPolicyforHost.find(host);
return policy_iterator != m_certPolicyforHost.end() &&
diff --git a/src/core/net/ssl_host_state_delegate_qt.h b/src/core/net/ssl_host_state_delegate_qt.h
index ff25a0587..380e59f2c 100644
--- a/src/core/net/ssl_host_state_delegate_qt.h
+++ b/src/core/net/ssl_host_state_delegate_qt.h
@@ -32,15 +32,15 @@ public:
~SSLHostStateDelegateQt();
// content::SSLHostStateDelegate implementation:
- void AllowCert(const std::string &, const net::X509Certificate &cert, int error, content::WebContents *web_contents) override;
+ void AllowCert(const std::string &, const net::X509Certificate &cert, int error, content::StoragePartition *storage_partition) override;
void Clear(base::RepeatingCallback<bool(const std::string&)> host_filter) override;
- CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert, int error, content::WebContents *web_contents) override;
+ CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert, int error, content::StoragePartition *web_contents) override;
void HostRanInsecureContent(const std::string &host, int child_id, InsecureContentType content_type) override;
bool DidHostRunInsecureContent(const std::string &host, int child_id, InsecureContentType content_type) override;
- void AllowHttpForHost(const std::string &host, content::WebContents *web_contents) override;
- bool IsHttpAllowedForHost(const std::string &host, content::WebContents *web_contents) override;
+ void AllowHttpForHost(const std::string &host, content::StoragePartition *web_contents) override;
+ bool IsHttpAllowedForHost(const std::string &host, content::StoragePartition *web_contents) override;
void RevokeUserAllowExceptions(const std::string &host) override;
- bool HasAllowException(const std::string &host, content::WebContents *web_contents) override;
+ bool HasAllowException(const std::string &host, content::StoragePartition *web_contents) override;
private:
std::map<std::string, CertPolicy> m_certPolicyforHost;
diff --git a/src/core/net/system_network_context_manager.cpp b/src/core/net/system_network_context_manager.cpp
index 3ee06b7c9..83e122aab 100644
--- a/src/core/net/system_network_context_manager.cpp
+++ b/src/core/net/system_network_context_manager.cpp
@@ -30,6 +30,12 @@
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
+#if BUILDFLAG(IS_WIN)
+#include "chrome/browser/net/chrome_mojo_proxy_resolver_win.h"
+#include "components/os_crypt/os_crypt.h"
+#include "content/public/common/network_service_util.h"
+#endif
+
namespace {
// The global instance of the SystemNetworkContextmanager.
@@ -186,6 +192,11 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(network::mojom::Networ
network_service->SetUpHttpAuth(CreateHttpAuthStaticParams());
network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams());
+#if BUILDFLAG(IS_WIN)
+ if (content::IsOutOfProcessNetworkService())
+ network_service->SetEncryptionKey(OSCrypt::GetRawEncryptionKey());
+#endif
+
// Configure the Certificate Transparency logs.
std::vector<std::pair<std::string, base::Time>> disqualified_logs =
certificate_transparency::GetDisqualifiedLogs();
@@ -270,13 +281,20 @@ void SystemNetworkContextManager::ConfigureDefaultNetworkContextParams(network::
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kSingleProcess)) {
- LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode.";
- } else {
- network_context_params->proxy_resolver_factory =
- ChromeMojoProxyResolverFactory::CreateWithSelfOwnedReceiver();
+ if (!command_line.HasSwitch(switches::kWinHttpProxyResolver)) {
+ if (command_line.HasSwitch(switches::kSingleProcess)) {
+ LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode.";
+ } else {
+ network_context_params->proxy_resolver_factory =
+ ChromeMojoProxyResolverFactory::CreateWithSelfOwnedReceiver();
+ }
}
-
+#if BUILDFLAG(IS_WIN)
+ if (command_line.HasSwitch(switches::kUseSystemProxyResolver)) {
+ network_context_params->windows_system_proxy_resolver =
+ ChromeMojoProxyResolverWin::CreateWithSelfOwnedReceiver();
+ }
+#endif
// Use the SystemNetworkContextManager to populate and update SSL
// configuration. The SystemNetworkContextManager is owned by the
// BrowserProcess itself, so will only be destroyed on shutdown, at which
diff --git a/src/core/net/url_request_custom_job_delegate.cpp b/src/core/net/url_request_custom_job_delegate.cpp
index d05b7d5a0..22d26f735 100644
--- a/src/core/net/url_request_custom_job_delegate.cpp
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -4,7 +4,6 @@
#include "url_request_custom_job_delegate.h"
#include "url_request_custom_job_proxy.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index 68bbb42fa..0551d9be7 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -9,6 +9,7 @@
#include "webui_controller_factory_qt.h"
#include "build_config_qt.h"
+#include "devtools_frontend_qt.h"
#include "base/bind.h"
#include "build/build_config.h"
@@ -93,8 +94,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
return &NewWebUI<NetInternalsUI>;
if (url.SchemeIs(content::kChromeDevToolsScheme)) {
- // if (!DevToolsUIBindings::IsValidFrontendURL(url))
- // return nullptr;
+ if (!QtWebEngineCore::DevToolsFrontendQt::IsValidFrontendURL(url))
+ return nullptr;
return &NewWebUI<DevToolsUI>;
}
if (url.host() == chrome::kChromeUIAccessibilityHost)
@@ -127,7 +128,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
if (url.host_piece() == chrome::kChromeUIWebRtcLogsHost)
return &NewWebUI<WebRtcLogsUI>;
#endif
-#if BUILDFLAG(IS_LINUX) // Consider enabling for BUILDFLAG(IS_WIN)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
if (url.host_piece() == chrome::kChromeUISandboxHost)
return &NewWebUI<SandboxInternalsUI>;
#endif
diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index 08d626063..40fa92b99 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -174,20 +174,15 @@ scoped_refptr<GLContext> CreateGLContext(GLShareGroup* share_group,
GLSurface* compatible_surface,
const GLContextAttribs& attribs)
{
- scoped_refptr<GLContext> context;
if (GetGLImplementation() == kGLImplementationDesktopGL) {
- context = new GLContextWGL(share_group);
+ scoped_refptr<GLContext> context = new GLContextWGL(share_group);
if (!context->Initialize(compatible_surface, attribs))
return nullptr;
return context;
- } else {
- context = new GLContextEGL(share_group);
}
- if (!GLContextHelper::initializeContext(context.get(), compatible_surface, attribs))
- return nullptr;
-
- return context;
+ return InitializeGLContext(new GLContextEGL(share_group),
+ compatible_surface, attribs);
}
} // namespace init
diff --git a/src/core/ozone/gl_ozone_egl_qt.cpp b/src/core/ozone/gl_ozone_egl_qt.cpp
index 02c3666b4..c0348e833 100644
--- a/src/core/ozone/gl_ozone_egl_qt.cpp
+++ b/src/core/ozone/gl_ozone_egl_qt.cpp
@@ -48,32 +48,31 @@ bool GLOzoneEGLQt::LoadGLES2Bindings(const gl::GLImplementationParts & /*impleme
return true;
}
-bool GLOzoneEGLQt::InitializeGLOneOffPlatform()
+gl::GLDisplay *GLOzoneEGLQt::InitializeGLOneOffPlatform(uint64_t system_device_id)
{
- if (!gl::GLSurfaceEGLQt::InitializeOneOff()) {
- LOG(ERROR) << "GLOzoneEGLQt::InitializeOneOff failed.";
- return false;
- }
- return true;
+ return gl::GLSurfaceEGLQt::InitializeOneOff(system_device_id);
}
-bool GLOzoneEGLQt::InitializeExtensionSettingsOneOffPlatform()
+bool GLOzoneEGLQt::InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display)
{
+ Q_UNUSED(display);
return gl::GLSurfaceEGLQt::InitializeExtensionSettingsOneOff();
}
-scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateViewGLSurface(gfx::AcceleratedWidget window)
+scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateViewGLSurface(gl::GLDisplay* display, gfx::AcceleratedWidget window)
{
+ Q_UNUSED(display);
+ Q_UNUSED(window);
return nullptr;
}
-scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(const gfx::Size &size)
+scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(gl::GLDisplay* display, const gfx::Size &size)
{
- scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceEGLQt(size);
+ scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceEGLQt(static_cast<gl::GLDisplayEGL*>(display), size);
if (surface->Initialize(gl::GLSurfaceFormat()))
return surface;
- surface = new gl::GLSurfacelessQtEGL(size);
+ surface = new gl::GLSurfacelessQtEGL(static_cast<gl::GLDisplayEGL*>(display), size);
if (surface->Initialize(gl::GLSurfaceFormat()))
return surface;
diff --git a/src/core/ozone/gl_ozone_egl_qt.h b/src/core/ozone/gl_ozone_egl_qt.h
index 089e6ba17..4619fc714 100644
--- a/src/core/ozone/gl_ozone_egl_qt.h
+++ b/src/core/ozone/gl_ozone_egl_qt.h
@@ -12,12 +12,14 @@ namespace ui {
class GLOzoneEGLQt : public GLOzoneEGL {
public:
- bool InitializeGLOneOffPlatform() override;
- bool InitializeExtensionSettingsOneOffPlatform() override;
+ gl::GLDisplay *InitializeGLOneOffPlatform(uint64_t system_device_id) override;
+ bool InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) override;
scoped_refptr<gl::GLSurface> CreateViewGLSurface(
+ gl::GLDisplay *display,
gfx::AcceleratedWidget window) override;
scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(
- const gfx::Size& size) override;
+ gl::GLDisplay *display,
+ const gfx::Size &size) override;
protected:
// Returns native platform display handle. This is used to obtain the EGL
diff --git a/src/core/ozone/gl_ozone_glx_qt.cpp b/src/core/ozone/gl_ozone_glx_qt.cpp
index 4c4822944..c610862f6 100644
--- a/src/core/ozone/gl_ozone_glx_qt.cpp
+++ b/src/core/ozone/gl_ozone_glx_qt.cpp
@@ -16,12 +16,8 @@
namespace ui {
-bool GLOzoneGLXQt::InitializeGLOneOffPlatform() {
- if (!gl::GLSurfaceGLXQt::InitializeOneOff()) {
- LOG(ERROR) << "GLSurfaceGLXQt::InitializeOneOff failed.";
- return false;
- }
- return true;
+gl::GLDisplay *GLOzoneGLXQt::InitializeGLOneOffPlatform(uint64_t system_device_id) {
+ return gl::GLSurfaceGLXQt::InitializeOneOff(system_device_id);
}
bool GLOzoneGLXQt::InitializeStaticGLBindings(
@@ -65,7 +61,7 @@ void GLOzoneGLXQt::SetDisabledExtensionsPlatform(
gl::SetDisabledExtensionsGLX(disabled_extensions);
}
-void GLOzoneGLXQt::ShutdownGL() {
+void GLOzoneGLXQt::ShutdownGL(gl::GLDisplay *) {
gl::ClearBindingsGL();
gl::ClearBindingsGLX();
}
@@ -86,16 +82,19 @@ scoped_refptr<gl::GLContext> GLOzoneGLXQt::CreateGLContext(
}
scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) {
return nullptr;
}
scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateSurfacelessViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) {
return nullptr;
}
scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateOffscreenGLSurface(
+ gl::GLDisplay* display,
const gfx::Size& size) {
scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceGLXQt(size);
if (surface->Initialize(gl::GLSurfaceFormat()))
@@ -104,7 +103,19 @@ scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateOffscreenGLSurface(
return nullptr;
}
-bool GLOzoneGLXQt::InitializeExtensionSettingsOneOffPlatform()
+bool GLOzoneGLXQt::CanImportNativePixmap()
+{
+ return false;
+}
+
+std::unique_ptr<ui::NativePixmapGLBinding> GLOzoneGLXQt::ImportNativePixmap(
+ scoped_refptr<gfx::NativePixmap>, gfx::BufferFormat, gfx::BufferPlane,
+ gfx::Size, const gfx::ColorSpace&, GLenum, GLuint)
+{
+ return nullptr;
+}
+
+bool GLOzoneGLXQt::InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *)
{
return gl::GLSurfaceGLXQt::InitializeExtensionSettingsOneOff();
}
diff --git a/src/core/ozone/gl_ozone_glx_qt.h b/src/core/ozone/gl_ozone_glx_qt.h
index 77d639a88..777de352e 100644
--- a/src/core/ozone/gl_ozone_glx_qt.h
+++ b/src/core/ozone/gl_ozone_glx_qt.h
@@ -15,28 +15,36 @@ public:
GLOzoneGLXQt() {}
~GLOzoneGLXQt() override {}
- bool InitializeGLOneOffPlatform() override;
+ gl::GLDisplay *InitializeGLOneOffPlatform(uint64_t system_device_id) override;
bool InitializeStaticGLBindings(const gl::GLImplementationParts &implementation) override;
- bool InitializeExtensionSettingsOneOffPlatform() override;
- void ShutdownGL() override;
+ bool InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) override;
+ void ShutdownGL(gl::GLDisplay *display) override;
void SetDisabledExtensionsPlatform(
const std::string& disabled_extensions) override;
bool GetGLWindowSystemBindingInfo(
const gl::GLVersionInfo &gl_info,
gl::GLWindowSystemBindingInfo *info) override;
+ bool CanImportNativePixmap() override;
+ std::unique_ptr<ui::NativePixmapGLBinding> ImportNativePixmap(
+ scoped_refptr<gfx::NativePixmap>, gfx::BufferFormat, gfx::BufferPlane,
+ gfx::Size, const gfx::ColorSpace&, GLenum, GLuint) override;
+
scoped_refptr<gl::GLContext> CreateGLContext(
gl::GLShareGroup* share_group,
gl::GLSurface* compatible_surface,
const gl::GLContextAttribs& attribs) override;
scoped_refptr<gl::GLSurface> CreateViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) override;
scoped_refptr<gl::GLSurface> CreateSurfacelessViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) override;
scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(
+ gl::GLDisplay* display,
const gfx::Size& size) override;
};
diff --git a/src/core/ozone/gl_share_context_qt.cpp b/src/core/ozone/gl_share_context_qt.cpp
index 086317b46..35bd18f22 100644
--- a/src/core/ozone/gl_share_context_qt.cpp
+++ b/src/core/ozone/gl_share_context_qt.cpp
@@ -5,6 +5,9 @@
#include <QtGui/qtgui-config.h>
#include <qpa/qplatformnativeinterface.h>
+#include "ui/gl/gl_context_egl.h"
+#include "ui/gl/gl_implementation.h"
+
#if QT_CONFIG(opengl)
#include <QtGui/qopenglcontext_platform.h>
#include <QOpenGLContext>
@@ -59,6 +62,11 @@ unsigned int QtShareGLContext::CheckStickyGraphicsResetStatusImpl()
void ShareGroupQt::AboutToAddFirstContext()
{
+ if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) {
+ m_shareContextQt = new gl::GLContextEGL(nullptr);
+ return;
+ }
+
#if QT_CONFIG(opengl)
// This currently has to be setup by ::main in all applications using QQuickWebEngineView with
// delegated rendering.
@@ -69,7 +77,7 @@ void ShareGroupQt::AboutToAddFirstContext()
"QCoreApplication is created.");
}
m_shareContextQt = new QtShareGLContext(shareContext);
-#endif
+#endif // QT_CONFIG(opengl)
}
} // namespace
diff --git a/src/core/ozone/gl_share_context_qt.h b/src/core/ozone/gl_share_context_qt.h
index ba66b222c..89be00421 100644
--- a/src/core/ozone/gl_share_context_qt.h
+++ b/src/core/ozone/gl_share_context_qt.h
@@ -57,7 +57,7 @@ public:
void AboutToAddFirstContext() override;
private:
- scoped_refptr<QtShareGLContext> m_shareContextQt;
+ scoped_refptr<gl::GLContext> m_shareContextQt;
};
} // namespace
#endif
diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp
index bd9ec060e..32e6db4e8 100644
--- a/src/core/ozone/gl_surface_egl_qt.cpp
+++ b/src/core/ozone/gl_surface_egl_qt.cpp
@@ -8,169 +8,82 @@
#include "gl_context_qt.h"
#include "ozone/gl_surface_egl_qt.h"
-#if !BUILDFLAG(IS_MAC)
#include "ui/gl/egl_util.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_display.h"
+#include "ui/gl/gl_display_manager.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/init/gl_factory.h"
-// From ANGLE's egl/eglext.h.
-#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
-#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
-#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
-#endif
+#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN)
using ui::GetLastEGLErrorString;
namespace gl {
-bool GLSurfaceEGL::InitializeExtensionSettingsOneOff()
+bool GLDisplayEGL::InitializeExtensionSettings()
{
return GLSurfaceEGLQt::InitializeExtensionSettingsOneOff();
}
-EGLDisplay GLSurfaceEGL::GetHardwareDisplay()
+GLDisplayEGL *GLDisplayEGL::GetDisplayForCurrentContext()
{
- return GLSurfaceQt::g_display ? static_cast<EGLDisplay>(GLSurfaceQt::g_display->GetDisplay()) : EGL_NO_DISPLAY;
+ GLContext *context = GLContext::GetCurrent();
+ return context ? context->GetGLDisplayEGL() : nullptr;
}
-bool GLSurfaceEGL::IsCreateContextRobustnessSupported()
-{
- return GLContextHelper::isCreateContextRobustnessSupported() && HasEGLExtension("EGL_EXT_create_context_robustness");
-}
-
-bool GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported()
-{
- return false;
-}
-bool GLSurfaceEGL::IsEGLSurfacelessContextSupported()
+bool GLDisplayEGL::IsEGLSurfacelessContextSupported()
{
return GLSurfaceEGLQt::g_egl_surfaceless_context_supported;
}
-bool GLSurfaceEGL::IsEGLContextPrioritySupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsRobustResourceInitSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsDisplayTextureShareGroupSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsCreateContextClientArraysSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsPixelFormatFloatSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsANGLEFeatureControlSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsANGLEPowerPreferenceSupported()
-{
- return false;
-}
-bool GLSurfaceEGL::IsANGLEExternalContextAndSurfaceSupported()
+bool GLDisplayEGL::IsEGLContextPrioritySupported()
{
return false;
}
-bool GLSurfaceEGL::IsDisplaySemaphoreShareGroupSupported()
+bool GLDisplayEGL::Initialize(gl::EGLDisplayPlatform native_display)
{
- return false;
-}
+ auto glDisplay = GLSurfaceEGLQt::InitializeOneOff(0);
-bool GLSurfaceEGL::IsRobustnessVideoMemoryPurgeSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsANGLEContextVirtualizationSupported()
-{
- return false;
-}
+ if (glDisplay) {
+ display_ = glDisplay->GetDisplay();
+ native_display_ = native_display;
+ }
-bool GLSurfaceEGL::IsANGLEVulkanImageSupported()
-{
- return false;
+ return glDisplay;
}
-bool GLSurfaceEGL::IsEGLQueryDeviceSupported()
+bool GLDisplayEGL::IsAndroidNativeFenceSyncSupported()
{
return false;
}
-void GLSurfaceEGL::ShutdownOneOff()
-{
-}
-
-const char *GLSurfaceEGL::GetEGLClientExtensions()
-{
- return GLSurfaceQt::g_client_extensions.c_str();
-}
-
-const char *GLSurfaceEGL::GetEGLExtensions()
-{
- return GLSurfaceQt::g_extensions.c_str();
-}
-
-bool GLSurfaceEGL::HasEGLClientExtension(const char *name)
+// static
+GLDisplayEGL *GLSurfaceEGL::GetGLDisplayEGL()
{
- return ExtensionsContain(GetEGLClientExtensions(), name);
+ return GLDisplayManagerEGL::GetInstance()->GetDisplay(GpuPreference::kDefault);
}
-bool GLSurfaceEGL::HasEGLExtension(const char *name)
+DisplayType GLDisplayEGL::GetDisplayType() const
{
- return ExtensionsContain(GetEGLExtensions(), name);
+ return DisplayType::DEFAULT;
}
-bool GLSurfaceEGL::InitializeOneOff(gl::EGLDisplayPlatform /*native_display*/, uint64_t)
+EGLDisplayPlatform GLDisplayEGL::GetNativeDisplay() const
{
- return GLSurfaceEGLQt::InitializeOneOff();
+ return native_display_;
}
-bool GLSurfaceEGL::IsEGLNoConfigContextSupported()
+GLSurface *GLSurfaceEGL::createSurfaceless(gl::GLDisplayEGL *display, const gfx::Size& size)
{
- return false;
-}
-
-bool GLSurfaceEGL::IsAndroidNativeFenceSyncSupported()
-{
- return false;
-}
-
-DisplayType GLSurfaceEGL::GetDisplayType()
-{
- return DisplayType::DEFAULT;
-}
-
-GLSurface *GLSurfaceEGL::createSurfaceless(const gfx::Size& size)
-{
- return new GLSurfacelessQtEGL(size);
+ return new GLSurfacelessQtEGL(display, size);
}
bool GLSurfaceEGLQt::g_egl_surfaceless_context_supported = false;
bool GLSurfaceEGLQt::s_initialized = false;
-GLSurfaceEGLQt::GLSurfaceEGLQt(const gfx::Size& size)
+GLSurfaceEGLQt::GLSurfaceEGLQt(gl::GLDisplayEGL *display, const gfx::Size& size)
: GLSurfaceQt(size),
m_surfaceBuffer(0)
{
@@ -181,38 +94,35 @@ GLSurfaceEGLQt::~GLSurfaceEGLQt()
Destroy();
}
-bool GLSurfaceEGLQt::InitializeOneOff()
+gl::GLDisplay *GLSurfaceEGLQt::InitializeOneOff(uint64_t system_device_id)
{
if (s_initialized)
- return true;
+ return g_display;
- // Must be called before initializing the display.
- g_driver_egl.InitializeClientExtensionBindings();
-
- auto *egl_display = new GLDisplayEGL();
+ auto *egl_display = GLDisplayManagerEGL::GetInstance()->GetDisplay(system_device_id);
g_display = egl_display;
egl_display->SetDisplay(GLContextHelper::getEGLDisplay());
- if (!g_display->GetDisplay()) {
+ if (!egl_display->GetDisplay()) {
LOG(ERROR) << "GLContextHelper::getEGLDisplay() failed.";
- return false;
+ return nullptr;
}
g_config = GLContextHelper::getEGLConfig();
if (!g_config) {
LOG(ERROR) << "GLContextHelper::getEGLConfig() failed.";
- return false;
+ return nullptr;
}
- if (!eglInitialize(g_display->GetDisplay(), NULL, NULL)) {
+ if (!eglInitialize(egl_display->GetDisplay(), NULL, NULL)) {
LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
- return false;
+ return nullptr;
}
g_client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
- g_extensions = eglQueryString(g_display->GetDisplay(), EGL_EXTENSIONS);
+ g_extensions = eglQueryString(egl_display->GetDisplay(), EGL_EXTENSIONS);
g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions.c_str(), "EGL_KHR_surfaceless_context");
if (g_egl_surfaceless_context_supported) {
- scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(gfx::Size(1, 1));
+ scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(egl_display, gfx::Size(1, 1));
gl::GLContextAttribs attribs;
scoped_refptr<GLContext> context = init::CreateGLContext(
NULL, surface.get(), attribs);
@@ -228,11 +138,8 @@ bool GLSurfaceEGLQt::InitializeOneOff()
}
}
- // Must be called after initializing the display.
- g_driver_egl.InitializeExtensionBindings();
-
s_initialized = true;
- return true;
+ return egl_display;
}
bool GLSurfaceEGLQt::InitializeExtensionSettingsOneOff()
@@ -245,7 +152,7 @@ bool GLSurfaceEGLQt::Initialize(GLSurfaceFormat format)
Q_ASSERT(!m_surfaceBuffer);
m_format = format;
- EGLDisplay display = g_display->GetDisplay();
+ EGLDisplay display = GLContextHelper::getEGLDisplay();
if (!display) {
LOG(ERROR) << "Trying to create surface with invalid display.";
return false;
@@ -273,7 +180,7 @@ bool GLSurfaceEGLQt::Initialize(GLSurfaceFormat format)
void GLSurfaceEGLQt::Destroy()
{
if (m_surfaceBuffer) {
- if (!eglDestroySurface(g_display->GetDisplay(), m_surfaceBuffer))
+ if (!eglDestroySurface(GLContextHelper::getEGLDisplay(), m_surfaceBuffer))
LOG(ERROR) << "eglDestroySurface failed with error " << GetLastEGLErrorString();
m_surfaceBuffer = 0;
@@ -311,7 +218,7 @@ void* GLSurfaceEGLQt::GetHandle()
return reinterpret_cast<void*>(m_surfaceBuffer);
}
-GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size)
+GLSurfacelessQtEGL::GLSurfacelessQtEGL(GLDisplayEGL *display, const gfx::Size& size)
: GLSurfaceQt(size)
{
}
@@ -348,26 +255,15 @@ void* GLSurfacelessQtEGL::GetShareHandle()
return NULL;
}
-std::string DriverEGL::GetPlatformExtensions()
+std::string DisplayExtensionsEGL::GetPlatformExtensions(EGLDisplay)
{
EGLDisplay display = GLContextHelper::getEGLDisplay();
if (display == EGL_NO_DISPLAY)
return "";
- DCHECK(g_driver_egl.fn.eglQueryStringFn);
- const char* str = g_driver_egl.fn.eglQueryStringFn(display, EGL_EXTENSIONS);
+ const char* str = eglQueryString(display, EGL_EXTENSIONS);
return str ? std::string(str) : "";
}
-} // namespace gl
-#else
-namespace gl {
-struct GL_EXPORT DriverEGL {
- static std::string GetPlatformExtensions();
-};
-std::string DriverEGL::GetPlatformExtensions()
-{
- return "";
-}
} // namespace gl
-#endif // !BUILDFLAG(IS_MAC)
+#endif // !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN)
diff --git a/src/core/ozone/gl_surface_egl_qt.h b/src/core/ozone/gl_surface_egl_qt.h
index 8a799b847..71992e700 100644
--- a/src/core/ozone/gl_surface_egl_qt.h
+++ b/src/core/ozone/gl_surface_egl_qt.h
@@ -10,11 +10,13 @@
namespace gl {
+class GLDisplayEGL;
+
class GLSurfaceEGLQt: public GLSurfaceQt {
public:
- explicit GLSurfaceEGLQt(const gfx::Size& size);
+ explicit GLSurfaceEGLQt(gl::GLDisplayEGL *display, const gfx::Size& size);
- static bool InitializeOneOff();
+ static gl::GLDisplay *InitializeOneOff(uint64_t system_device_id);
static bool InitializeExtensionSettingsOneOff();
bool Initialize(GLSurfaceFormat format) override;
@@ -42,7 +44,7 @@ private:
class GLSurfacelessQtEGL : public GLSurfaceQt {
public:
- explicit GLSurfacelessQtEGL(const gfx::Size& size);
+ explicit GLSurfacelessQtEGL(gl::GLDisplayEGL *display, const gfx::Size& size);
public:
bool Initialize(GLSurfaceFormat format) override;
diff --git a/src/core/ozone/gl_surface_glx_qt.cpp b/src/core/ozone/gl_surface_glx_qt.cpp
index f97f3de1e..21de815a8 100644
--- a/src/core/ozone/gl_surface_glx_qt.cpp
+++ b/src/core/ozone/gl_surface_glx_qt.cpp
@@ -7,8 +7,10 @@
#include "gl_context_qt.h"
#include "ozone/gl_surface_glx_qt.h"
+
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_display.h"
+#include "ui/gl/gl_display_manager.h"
#include "ui/gl/gl_surface_glx.h"
namespace gl {
@@ -86,37 +88,37 @@ GLSurfaceGLXQt::~GLSurfaceGLXQt()
Destroy();
}
-bool GLSurfaceGLXQt::InitializeOneOff()
+GLDisplay *GLSurfaceGLXQt::InitializeOneOff(uint64_t system_device_id)
{
if (s_initialized)
- return true;
+ return g_display;
- g_display = new GLDisplayX11();
+ g_display = GLDisplayManagerX11::GetInstance()->GetDisplay(system_device_id);
if (!g_display->GetDisplay()) {
LOG(ERROR) << "GLContextHelper::getXDisplay() failed.";
- return false;
+ return nullptr;
}
g_config = GLContextHelper::getGlXConfig();
if (!g_config) {
LOG(ERROR) << "GLContextHelper::getGlxConfig() failed.";
- return false;
+ return nullptr;
}
Display* display = static_cast<Display*>(g_display->GetDisplay());
int major, minor;
if (!glXQueryVersion(display, &major, &minor)) {
LOG(ERROR) << "glxQueryVersion failed.";
- return false;
+ return nullptr;
}
if (major == 1 && minor < 3) {
LOG(ERROR) << "GLX 1.3 or later is required.";
- return false;
+ return nullptr;
}
s_initialized = true;
- return true;
+ return g_display;
}
diff --git a/src/core/ozone/gl_surface_glx_qt.h b/src/core/ozone/gl_surface_glx_qt.h
index 6312f6b74..f81f6e9df 100644
--- a/src/core/ozone/gl_surface_glx_qt.h
+++ b/src/core/ozone/gl_surface_glx_qt.h
@@ -12,7 +12,7 @@ class GLSurfaceGLXQt: public GLSurfaceQt {
public:
explicit GLSurfaceGLXQt(const gfx::Size& size);
- static bool InitializeOneOff();
+ static gl::GLDisplay *InitializeOneOff(uint64_t system_device_id);
static bool InitializeExtensionSettingsOneOff();
bool Initialize(GLSurfaceFormat format) override;
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index 0d7f686e8..b6242b427 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -19,8 +19,11 @@
#include "ozone/gl_surface_egl_qt.h"
#include "gpu/ipc/service/image_transport_surface.h"
+#include "ui/gl/direct_composition_support.h"
+#include "ui/gl/gl_display.h"
#include "ui/gl/gl_implementation.h"
-#include "ui/gl/direct_composition_surface_win.h"
+#include "ui/gl/gl_surface_egl.h"
+#include "ui/gl/gl_utils.h"
#include "ui/gl/vsync_provider_win.h"
#endif
@@ -59,7 +62,7 @@ bool GLSurfaceQt::IsOffscreen()
return true;
}
-gfx::SwapResult GLSurfaceQt::SwapBuffers(PresentationCallback callback)
+gfx::SwapResult GLSurfaceQt::SwapBuffers(PresentationCallback callback, FrameData data)
{
LOG(ERROR) << "Attempted to call SwapBuffers on a pbuffer.";
Q_UNREACHABLE();
@@ -88,17 +91,31 @@ void* GLSurfaceQt::GetConfig()
#if BUILDFLAG(IS_WIN)
namespace init {
-bool InitializeGLOneOffPlatform(uint64_t system_device_id)
+
+gl::GLDisplay *InitializeGLOneOffPlatform(uint64_t system_device_id)
{
VSyncProviderWin::InitializeOneOff();
- if (GetGLImplementation() == kGLImplementationEGLGLES2 || GetGLImplementation() == kGLImplementationEGLANGLE)
- return GLSurfaceEGLQt::InitializeOneOff();
-
if (GetGLImplementation() == kGLImplementationDesktopGL || GetGLImplementation() == kGLImplementationDesktopGLCoreProfile)
- return GLSurfaceWGLQt::InitializeOneOff();
+ return GLSurfaceWGLQt::InitializeOneOff(system_device_id);
- return false;
+ GLDisplayEGL *display = GetDisplayEGL(system_device_id);
+ switch (GetGLImplementation()) {
+ case kGLImplementationEGLANGLE:
+ case kGLImplementationEGLGLES2:
+ if (!display->Initialize(EGLDisplayPlatform(GetDC(nullptr)))) {
+ LOG(ERROR) << "GLDisplayEGL::Initialize failed.";
+ return nullptr;
+ }
+ InitializeDirectComposition(display);
+ break;
+ case kGLImplementationMockGL:
+ case kGLImplementationStubGL:
+ break;
+ default:
+ NOTREACHED();
+ }
+ return display;
}
bool usingSoftwareDynamicGL()
@@ -111,7 +128,7 @@ bool usingSoftwareDynamicGL()
}
scoped_refptr<GLSurface>
-CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format)
+CreateOffscreenGLSurfaceWithFormat(GLDisplay *display, const gfx::Size& size, GLSurfaceFormat format)
{
scoped_refptr<GLSurface> surface;
switch (GetGLImplementation()) {
@@ -124,21 +141,10 @@ CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format
}
case kGLImplementationEGLANGLE:
case kGLImplementationEGLGLES2: {
- surface = new GLSurfaceEGLQt(size);
- if (surface->Initialize(format))
- return surface;
-
- // Surfaceless context will be used ONLY if pseudo surfaceless context
- // is not available since some implementations of surfaceless context
- // have problems. (e.g. QTBUG-57290)
- if (GLSurfaceEGLQt::g_egl_surfaceless_context_supported) {
- surface = new GLSurfacelessQtEGL(size);
- if (surface->Initialize(format))
- return surface;
- }
- LOG(ERROR) << "eglCreatePbufferSurface failed and surfaceless context not available";
- LOG(WARNING) << "Failed to create offscreen GL surface";
- break;
+ GLDisplayEGL *display_egl = display->GetAs<gl::GLDisplayEGL>();
+ if (display_egl->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0)
+ return InitializeGLSurfaceWithFormat(new SurfacelessEGL(display_egl, size), format);
+ return InitializeGLSurfaceWithFormat(new PbufferGLSurfaceEGL(display_egl, size), format);
}
default:
break;
@@ -149,9 +155,8 @@ CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format
}
scoped_refptr<GLSurface>
-CreateViewGLSurface(gfx::AcceleratedWidget window)
+CreateViewGLSurface(GLDisplay *display, gfx::AcceleratedWidget window)
{
- QT_NOT_USED
return nullptr;
}
@@ -159,63 +164,4 @@ CreateViewGLSurface(gfx::AcceleratedWidget window)
#endif // BUILDFLAG(IS_WIN)
} // namespace gl
-#if BUILDFLAG(IS_WIN)
-namespace gpu {
-class GpuCommandBufferStub;
-class GpuChannelManager;
-scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface(base::WeakPtr<ImageTransportSurfaceDelegate>,
- SurfaceHandle, gl::GLSurfaceFormat)
-{
- QT_NOT_USED
- return scoped_refptr<gl::GLSurface>();
-}
-} // namespace gpu
-
-namespace gl {
-
-bool DirectCompositionSurfaceWin::IsDirectCompositionSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::IsDecodeSwapChainSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::IsHDRSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::IsSwapChainTearingSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::AreOverlaysSupported()
-{
- return false;
-}
-
-UINT DirectCompositionSurfaceWin::GetOverlaySupportFlags(DXGI_FORMAT format)
-{
- Q_UNUSED(format);
- return 0;
-}
-
-void DirectCompositionSurfaceWin::DisableDecodeSwapChain()
-{
-}
-
-void DirectCompositionSurfaceWin::DisableSoftwareOverlays()
-{
-}
-
-void DirectCompositionSurfaceWin::ShutdownOneOff()
-{
-}
-
-} // namespace gl
-#endif // BUILDFLAG(IS_WIN)
#endif // !defined(Q_OS_MACOS)
diff --git a/src/core/ozone/gl_surface_qt.h b/src/core/ozone/gl_surface_qt.h
index f9d18a0ae..0ef8fbbca 100644
--- a/src/core/ozone/gl_surface_qt.h
+++ b/src/core/ozone/gl_surface_qt.h
@@ -21,7 +21,7 @@ public:
GLDisplay *GetGLDisplay() override;
void *GetConfig() override;
bool IsOffscreen() override;
- gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
+ gfx::SwapResult SwapBuffers(PresentationCallback callback, FrameData data) override;
gfx::Size GetSize() override;
GLSurfaceFormat GetFormat() override;
diff --git a/src/core/ozone/gl_surface_wgl_qt.cpp b/src/core/ozone/gl_surface_wgl_qt.cpp
index 57493c14a..0788a04c1 100644
--- a/src/core/ozone/gl_surface_wgl_qt.cpp
+++ b/src/core/ozone/gl_surface_wgl_qt.cpp
@@ -4,6 +4,7 @@
#include "gl_surface_wgl_qt.h"
#if BUILDFLAG(IS_WIN)
+#include "ui/gl/gl_display_manager.h"
#include "ui/gl/gl_surface_wgl.h"
namespace gl {
@@ -19,9 +20,12 @@ GLSurfaceWGLQt::~GLSurfaceWGLQt()
Destroy();
}
-bool GLSurfaceWGLQt::InitializeOneOff()
+gl::GLDisplay *GLSurfaceWGLQt::InitializeOneOff(uint64_t system_device_id)
{
- return GLSurfaceWGL::InitializeOneOff();
+ if (GLSurfaceWGL::InitializeOneOff())
+ return GLDisplayManagerWGL::GetInstance()->GetDisplay(GpuPreference::kDefault);
+
+ return nullptr;
}
bool GLSurfaceWGLQt::Initialize(GLSurfaceFormat format)
diff --git a/src/core/ozone/gl_surface_wgl_qt.h b/src/core/ozone/gl_surface_wgl_qt.h
index e1a1253bb..5b671ebd9 100644
--- a/src/core/ozone/gl_surface_wgl_qt.h
+++ b/src/core/ozone/gl_surface_wgl_qt.h
@@ -16,7 +16,7 @@ class GLSurfaceWGLQt: public GLSurfaceQt {
public:
explicit GLSurfaceWGLQt(const gfx::Size& size);
- static bool InitializeOneOff();
+ static gl::GLDisplay *InitializeOneOff(uint64_t system_device_id);
bool Initialize(GLSurfaceFormat format) override;
void Destroy() override;
diff --git a/src/core/ozone/ozone_extra.gni b/src/core/ozone/ozone_extra.gni
index a832f741a..191bb3787 100644
--- a/src/core/ozone/ozone_extra.gni
+++ b/src/core/ozone/ozone_extra.gni
@@ -17,3 +17,17 @@ ozone_external_platform_deps = []
# so that they get included into ozone_unittests.
# ozone_external_platform_test_deps = [ "platform/foo1:foo1_unitests", ... ]
ozone_external_platform_test_deps = []
+
+# If a platform has integration tests, the corresponding source_set can be
+# listed here so that they get included into ozone_integration_tests.
+ozone_external_platform_integration_test_deps = []
+
+# If a platform has test support files for ui, the corresponding source_set can
+# be listed here so that they get included into ui_test_support.
+# ozone_external_platform_ui_test_support_deps = [ "platform/foo1:ui_test_support", ... ]
+ozone_external_platform_ui_test_support_deps = []
+
+# If a platform has a test support for interactive_ui_tests, the corresponding
+# source_set can be listed here so that they can included into
+# interactive_ui_tests.
+ozone_external_interactive_ui_tests_deps = []
diff --git a/src/core/ozone/ozone_platform_qt.cpp b/src/core/ozone/ozone_platform_qt.cpp
index 8ab3aa1a7..5b7e9b4d7 100644
--- a/src/core/ozone/ozone_platform_qt.cpp
+++ b/src/core/ozone/ozone_platform_qt.cpp
@@ -4,6 +4,7 @@
#include "ozone_platform_qt.h"
#if defined(USE_OZONE)
+#include "base/no_destructor.h"
#include "ui/base/buildflags.h"
#include "ui/base/ime/input_method.h"
#include "ui/display/types/native_display_delegate.h"
@@ -24,11 +25,13 @@
#include "platform_window_qt.h"
#if BUILDFLAG(USE_XKBCOMMON)
+#include "base/logging.h"
#include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h"
#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
#include <X11/XKBlib.h>
#include <X11/extensions/XKBrules.h>
+#include <filesystem>
extern void *GetQtXDisplay();
#endif // BUILDFLAG(USE_XKBCOMMON)
@@ -50,8 +53,10 @@ public:
ui::InputController* GetInputController() override;
std::unique_ptr<ui::SystemInputInjector> CreateSystemInputInjector() override;
ui::OverlayManagerOzone* GetOverlayManager() override;
- std::unique_ptr<InputMethod> CreateInputMethod(internal::InputMethodDelegate *delegate, gfx::AcceleratedWidget widget) override;
+ std::unique_ptr<InputMethod> CreateInputMethod(ImeKeyEventDispatcher *ime_key_event_dispatcher, gfx::AcceleratedWidget widget) override;
std::unique_ptr<ui::PlatformScreen> CreateScreen() override { return nullptr; }
+ const PlatformProperties &GetPlatformProperties() override;
+
private:
bool InitializeUI(const ui::OzonePlatform::InitParams &) override;
void InitializeGPU(const ui::OzonePlatform::InitParams &) override;
@@ -76,6 +81,19 @@ OzonePlatformQt::OzonePlatformQt() {}
OzonePlatformQt::~OzonePlatformQt() {}
+const ui::OzonePlatform::PlatformProperties &OzonePlatformQt::GetPlatformProperties()
+{
+ static base::NoDestructor<ui::OzonePlatform::PlatformProperties> properties;
+ static bool initialized = false;
+ if (!initialized) {
+ properties->fetch_buffer_formats_for_gmb_on_gpu = true;
+
+ initialized = true;
+ }
+
+ return *properties;
+}
+
ui::SurfaceFactoryOzone* OzonePlatformQt::GetSurfaceFactoryOzone()
{
return surface_factory_ozone_.get();
@@ -165,8 +183,10 @@ static std::string getCurrentKeyboardLayout()
bool OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &)
{
#if BUILDFLAG(USE_XKBCOMMON)
+ std::string xkb_path("/usr/share/X11/xkb");
std::string layout = getCurrentKeyboardLayout();
- if (layout.empty()) {
+ if (layout.empty() || !std::filesystem::exists(xkb_path) || std::filesystem::is_empty(xkb_path)) {
+ LOG(WARNING) << "Failed to load keymap file, falling back to StubKeyboardLayoutEngine";
m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>();
} else {
m_keyboardLayoutEngine = std::make_unique<XkbKeyboardLayoutEngine>(m_xkbEvdevCodeConverter);
@@ -190,7 +210,7 @@ void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &)
surface_factory_ozone_.reset(new QtWebEngineCore::SurfaceFactoryQt());
}
-std::unique_ptr<InputMethod> OzonePlatformQt::CreateInputMethod(internal::InputMethodDelegate *, gfx::AcceleratedWidget)
+std::unique_ptr<InputMethod> OzonePlatformQt::CreateInputMethod(ImeKeyEventDispatcher *, gfx::AcceleratedWidget)
{
NOTREACHED();
return nullptr;
diff --git a/src/core/ozone/platform_window_qt.cpp b/src/core/ozone/platform_window_qt.cpp
index 01b0ae139..fe8a715ce 100644
--- a/src/core/ozone/platform_window_qt.cpp
+++ b/src/core/ozone/platform_window_qt.cpp
@@ -24,7 +24,7 @@ PlatformWindowQt::~PlatformWindowQt()
ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}
-gfx::Rect PlatformWindowQt::GetBounds() const
+gfx::Rect PlatformWindowQt::GetBoundsInPixels() const
{
return bounds_;
}
@@ -34,12 +34,14 @@ void PlatformWindowQt::Close()
delegate_->OnClosed();
}
-void PlatformWindowQt::SetBounds(const gfx::Rect& bounds)
+void PlatformWindowQt::SetBoundsInPixels(const gfx::Rect& bounds)
{
if (bounds == bounds_)
return;
+ const bool origin_changed = (bounds_.origin() != bounds.origin());
+
bounds_ = bounds;
- delegate_->OnBoundsChanged(bounds);
+ delegate_->OnBoundsChanged({origin_changed});
}
bool PlatformWindowQt::CanDispatchEvent(const ui::PlatformEvent& /*ne*/)
@@ -47,6 +49,16 @@ bool PlatformWindowQt::CanDispatchEvent(const ui::PlatformEvent& /*ne*/)
return true;
}
+gfx::Rect PlatformWindowQt::GetBoundsInDIP() const
+{
+ return delegate_->ConvertRectToDIP(bounds_);
+}
+
+void PlatformWindowQt::SetBoundsInDIP(const gfx::Rect &bounds_in_dip)
+{
+ SetBoundsInPixels(delegate_->ConvertRectToPixels(bounds_in_dip));
+}
+
uint32_t PlatformWindowQt::DispatchEvent(const ui::PlatformEvent& native_event)
{
DispatchEventFromNativeUiEvent(
diff --git a/src/core/ozone/platform_window_qt.h b/src/core/ozone/platform_window_qt.h
index fee4728cf..0d1743f68 100644
--- a/src/core/ozone/platform_window_qt.h
+++ b/src/core/ozone/platform_window_qt.h
@@ -21,8 +21,10 @@ public:
PlatformWindowQt(PlatformWindowDelegate* delegate, const gfx::Rect& bounds);
~PlatformWindowQt() override;
// PlatformWindow:
- gfx::Rect GetBounds() const override;
- void SetBounds(const gfx::Rect& bounds) override;
+ gfx::Rect GetBoundsInPixels() const override;
+ void SetBoundsInPixels(const gfx::Rect& bounds) override;
+ gfx::Rect GetBoundsInDIP() const override;
+ void SetBoundsInDIP(const gfx::Rect& bounds) override;
void Show(bool inactive = false) override { }
void Hide() override { }
void Close() override;
@@ -39,8 +41,8 @@ public:
void SetCursor(scoped_refptr<PlatformCursor>) override { }
void MoveCursorTo(const gfx::Point&) override { }
void ConfineCursorToBounds(const gfx::Rect&) override { }
- void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override { }
- gfx::Rect GetRestoredBoundsInPixels() const override { return gfx::Rect(); }
+ void SetRestoredBoundsInDIP(const gfx::Rect& bounds) override { }
+ gfx::Rect GetRestoredBoundsInDIP() const override { return gfx::Rect(); }
void Activate() override { }
void Deactivate() override { }
void SetUseNativeFrame(bool use_native_frame) override { }
diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp
index 33164d076..13c1a7b11 100644
--- a/src/core/ozone/surface_factory_qt.cpp
+++ b/src/core/ozone/surface_factory_qt.cpp
@@ -10,6 +10,12 @@
#include "ozone/gl_ozone_glx_qt.h"
#endif
+#include "qtwebenginecoreglobal_p.h"
+
+#if QT_CONFIG(webengine_vulkan)
+#include "compositor/vulkan_implementation_qt.h"
+#endif
+
namespace QtWebEngineCore {
SurfaceFactoryQt::SurfaceFactoryQt()
@@ -27,7 +33,6 @@ SurfaceFactoryQt::SurfaceFactoryQt()
gl::GLImplementationParts(gl::kGLImplementationDisabled) };
m_ozone.reset(new ui::GLOzoneEGLQt());
} else {
- qWarning("No suitable graphics backend found\n");
m_impl = { gl::GLImplementationParts(gl::kGLImplementationDisabled) };
}
}
@@ -41,6 +46,18 @@ ui::GLOzone *SurfaceFactoryQt::GetGLOzone(const gl::GLImplementationParts &imple
{
return m_ozone.get();
}
+#if BUILDFLAG(ENABLE_VULKAN)
+std::unique_ptr<gpu::VulkanImplementation>
+SurfaceFactoryQt::CreateVulkanImplementation(bool /*allow_protected_memory*/,
+ bool /*enforce_protected_memory*/)
+{
+#if QT_CONFIG(webengine_vulkan)
+ return std::make_unique<gpu::VulkanImplementationQt>();
+#else
+ return nullptr;
+#endif
+}
+#endif
} // namespace QtWebEngineCore
#endif // defined(USE_OZONE)
diff --git a/src/core/ozone/surface_factory_qt.h b/src/core/ozone/surface_factory_qt.h
index 767b69b85..bfcfa014b 100644
--- a/src/core/ozone/surface_factory_qt.h
+++ b/src/core/ozone/surface_factory_qt.h
@@ -16,6 +16,10 @@ public:
SurfaceFactoryQt();
std::vector<gl::GLImplementationParts> GetAllowedGLImplementations() override;
ui::GLOzone *GetGLOzone(const gl::GLImplementationParts &implementation) override;
+#if BUILDFLAG(ENABLE_VULKAN)
+ std::unique_ptr<gpu::VulkanImplementation>
+ CreateVulkanImplementation(bool allow_protected_memory, bool enforce_protected_memory) override;
+#endif
private:
std::vector<gl::GLImplementationParts> m_impl;
std::unique_ptr<ui::GLOzone> m_ozone;
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index a1727bda3..28e1c981d 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -6,9 +6,9 @@
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/permission_controller.h"
-#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
+#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "type_conversion.h"
#include "web_contents_delegate_qt.h"
@@ -16,44 +16,44 @@
namespace QtWebEngineCore {
-static ProfileAdapter::PermissionType toQt(content::PermissionType type)
+static ProfileAdapter::PermissionType toQt(blink::PermissionType type)
{
switch (type) {
- case content::PermissionType::GEOLOCATION:
+ case blink::PermissionType::GEOLOCATION:
return ProfileAdapter::GeolocationPermission;
- case content::PermissionType::AUDIO_CAPTURE:
+ case blink::PermissionType::AUDIO_CAPTURE:
return ProfileAdapter::AudioCapturePermission;
- case content::PermissionType::VIDEO_CAPTURE:
+ case blink::PermissionType::VIDEO_CAPTURE:
return ProfileAdapter::VideoCapturePermission;
- case content::PermissionType::CLIPBOARD_READ_WRITE:
+ case blink::PermissionType::CLIPBOARD_READ_WRITE:
return ProfileAdapter::ClipboardRead;
- case content::PermissionType::CLIPBOARD_SANITIZED_WRITE:
+ case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
return ProfileAdapter::ClipboardWrite;
- case content::PermissionType::NOTIFICATIONS:
+ case blink::PermissionType::NOTIFICATIONS:
return ProfileAdapter::NotificationPermission;
- case content::PermissionType::ACCESSIBILITY_EVENTS:
- case content::PermissionType::CAMERA_PAN_TILT_ZOOM:
- case content::PermissionType::WINDOW_PLACEMENT:
+ case blink::PermissionType::ACCESSIBILITY_EVENTS:
+ case blink::PermissionType::CAMERA_PAN_TILT_ZOOM:
+ case blink::PermissionType::WINDOW_PLACEMENT:
return ProfileAdapter::UnsupportedPermission;
- case content::PermissionType::MIDI_SYSEX:
- case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
- case content::PermissionType::MIDI:
- case content::PermissionType::DURABLE_STORAGE:
- case content::PermissionType::BACKGROUND_SYNC:
- case content::PermissionType::SENSORS:
- case content::PermissionType::PAYMENT_HANDLER:
- case content::PermissionType::BACKGROUND_FETCH:
- case content::PermissionType::IDLE_DETECTION:
- case content::PermissionType::PERIODIC_BACKGROUND_SYNC:
- case content::PermissionType::WAKE_LOCK_SCREEN:
- case content::PermissionType::WAKE_LOCK_SYSTEM:
- case content::PermissionType::NFC:
- case content::PermissionType::AR:
- case content::PermissionType::VR:
- case content::PermissionType::STORAGE_ACCESS_GRANT:
- case content::PermissionType::LOCAL_FONTS:
- case content::PermissionType::DISPLAY_CAPTURE:
- case content::PermissionType::NUM:
+ case blink::PermissionType::MIDI_SYSEX:
+ case blink::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
+ case blink::PermissionType::MIDI:
+ case blink::PermissionType::DURABLE_STORAGE:
+ case blink::PermissionType::BACKGROUND_SYNC:
+ case blink::PermissionType::SENSORS:
+ case blink::PermissionType::PAYMENT_HANDLER:
+ case blink::PermissionType::BACKGROUND_FETCH:
+ case blink::PermissionType::IDLE_DETECTION:
+ case blink::PermissionType::PERIODIC_BACKGROUND_SYNC:
+ case blink::PermissionType::WAKE_LOCK_SCREEN:
+ case blink::PermissionType::WAKE_LOCK_SYSTEM:
+ case blink::PermissionType::NFC:
+ case blink::PermissionType::AR:
+ case blink::PermissionType::VR:
+ case blink::PermissionType::STORAGE_ACCESS_GRANT:
+ case blink::PermissionType::LOCAL_FONTS:
+ case blink::PermissionType::DISPLAY_CAPTURE:
+ case blink::PermissionType::NUM:
LOG(INFO) << "Unexpected unsupported permission type: " << static_cast<int>(type);
break;
}
@@ -84,6 +84,22 @@ static blink::mojom::PermissionStatus toBlink(ProfileAdapter::PermissionState re
}
}
+static blink::mojom::PermissionStatus getStatusFromSettings(blink::PermissionType type, WebEngineSettings *settings)
+{
+ switch (type) {
+ case blink::PermissionType::CLIPBOARD_READ_WRITE:
+ if (!settings->testAttribute(QWebEngineSettings::JavascriptCanPaste))
+ return blink::mojom::PermissionStatus::DENIED;
+ Q_FALLTHROUGH();
+ case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
+ if (!settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard))
+ return blink::mojom::PermissionStatus::DENIED;
+ return blink::mojom::PermissionStatus::GRANTED;
+ default:
+ return blink::mojom::PermissionStatus::ASK;
+ }
+}
+
PermissionManagerQt::PermissionManagerQt()
: m_requestIdCount(0)
{
@@ -130,7 +146,7 @@ void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter
bool answerable = true;
std::vector<blink::mojom::PermissionStatus> result;
result.reserve(it->types.size());
- for (content::PermissionType permission : it->types) {
+ for (blink::PermissionType permission : it->types) {
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == ProfileAdapter::UnsupportedPermission) {
result.push_back(blink::mojom::PermissionStatus::DENIED);
@@ -163,7 +179,7 @@ bool PermissionManagerQt::checkPermission(const QUrl &origin, ProfileAdapter::Pe
return m_permissions.contains(key) && m_permissions[key];
}
-void PermissionManagerQt::RequestPermission(content::PermissionType permission,
+void PermissionManagerQt::RequestPermission(blink::PermissionType permission,
content::RenderFrameHost *frameHost,
const GURL& requesting_origin,
bool /*user_gesture*/,
@@ -179,13 +195,8 @@ void PermissionManagerQt::RequestPermission(content::PermissionType permission,
Q_ASSERT(contentsDelegate);
ProfileAdapter::PermissionType permissionType = toQt(permission);
- if (permissionType == ProfileAdapter::ClipboardRead) {
- WebEngineSettings *settings = contentsDelegate->webEngineSettings();
- if (settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard)
- && settings->testAttribute(QWebEngineSettings::JavascriptCanPaste))
- std::move(callback).Run(blink::mojom::PermissionStatus::GRANTED);
- else
- std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
+ if (permissionType == ProfileAdapter::ClipboardRead || permissionType == ProfileAdapter::ClipboardWrite) {
+ std::move(callback).Run(getStatusFromSettings(permission, contentsDelegate->webEngineSettings()));
return;
} else if (!canRequestPermissionFor(permissionType)) {
std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
@@ -198,7 +209,7 @@ void PermissionManagerQt::RequestPermission(content::PermissionType permission,
contentsDelegate->requestFeaturePermission(permissionType, requestOrigin);
}
-void PermissionManagerQt::RequestPermissions(const std::vector<content::PermissionType> &permissions,
+void PermissionManagerQt::RequestPermissions(const std::vector<blink::PermissionType> &permissions,
content::RenderFrameHost *frameHost,
const GURL &requesting_origin,
bool /*user_gesture*/,
@@ -216,18 +227,13 @@ void PermissionManagerQt::RequestPermissions(const std::vector<content::Permissi
bool answerable = true;
std::vector<blink::mojom::PermissionStatus> result;
result.reserve(permissions.size());
- for (content::PermissionType permission : permissions) {
+ for (blink::PermissionType permission : permissions) {
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == ProfileAdapter::UnsupportedPermission)
result.push_back(blink::mojom::PermissionStatus::DENIED);
- else if (permissionType == ProfileAdapter::ClipboardRead) {
- WebEngineSettings *settings = contentsDelegate->webEngineSettings();
- if (settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard)
- && settings->testAttribute(QWebEngineSettings::JavascriptCanPaste))
- result.push_back(blink::mojom::PermissionStatus::GRANTED);
- else
- result.push_back(blink::mojom::PermissionStatus::DENIED);
- } else {
+ else if (permissionType == ProfileAdapter::ClipboardRead || permissionType == ProfileAdapter::ClipboardWrite)
+ result.push_back(getStatusFromSettings(permission, contentsDelegate->webEngineSettings()));
+ else {
answerable = false;
break;
}
@@ -240,15 +246,23 @@ void PermissionManagerQt::RequestPermissions(const std::vector<content::Permissi
int request_id = ++m_requestIdCount;
auto requestOrigin = toQt(requesting_origin);
m_multiRequests.push_back({ request_id, permissions, requestOrigin, std::move(callback) });
- for (content::PermissionType permission : permissions) {
+ for (blink::PermissionType permission : permissions) {
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (canRequestPermissionFor(permissionType))
contentsDelegate->requestFeaturePermission(permissionType, requestOrigin);
}
}
+void PermissionManagerQt::RequestPermissionsFromCurrentDocument(const std::vector<blink::PermissionType> &permissions,
+ content::RenderFrameHost *frameHost,
+ bool user_gesture,
+ base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
+{
+ RequestPermissions(permissions, frameHost, frameHost->GetLastCommittedOrigin().GetURL(), user_gesture, std::move(callback));
+}
+
blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& /*embedding_origin*/)
{
@@ -264,51 +278,44 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
return blink::mojom::PermissionStatus::DENIED;
}
-blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForFrame(
- content::PermissionType permission,
- content::RenderFrameHost *render_frame_host,
- const GURL &requesting_origin)
+blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForCurrentDocument(
+ blink::PermissionType permission,
+ content::RenderFrameHost *render_frame_host)
{
- if (permission == content::PermissionType::CLIPBOARD_READ_WRITE ||
- permission == content::PermissionType::CLIPBOARD_SANITIZED_WRITE) {
+ if (permission == blink::PermissionType::CLIPBOARD_READ_WRITE ||
+ permission == blink::PermissionType::CLIPBOARD_SANITIZED_WRITE) {
WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(
content::WebContents::FromRenderFrameHost(render_frame_host)->GetDelegate());
- if (!delegate->webEngineSettings()->testAttribute(
- QWebEngineSettings::JavascriptCanAccessClipboard))
- return blink::mojom::PermissionStatus::DENIED;
- if (permission == content::PermissionType::CLIPBOARD_READ_WRITE
- && !delegate->webEngineSettings()->testAttribute(
- QWebEngineSettings::JavascriptCanPaste))
- return blink::mojom::PermissionStatus::DENIED;
- return blink::mojom::PermissionStatus::GRANTED;
+ Q_ASSERT(delegate);
+ return getStatusFromSettings(permission, delegate->webEngineSettings());
}
return GetPermissionStatus(
permission,
- requesting_origin,
- render_frame_host->GetLastCommittedOrigin().GetURL());
-}
-
-blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForCurrentDocument(
- content::PermissionType permission,
- content::RenderFrameHost *render_frame_host)
-{
- return GetPermissionStatusForFrame(
- permission,
- render_frame_host,
+ render_frame_host->GetLastCommittedOrigin().GetURL(),
render_frame_host->GetLastCommittedOrigin().GetURL());
}
blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForWorker(
- content::PermissionType permission,
+ blink::PermissionType permission,
content::RenderProcessHost *render_process_host,
const GURL &url)
{
return GetPermissionStatus(permission, url, url);
}
+content::PermissionResult PermissionManagerQt::GetPermissionResultForOriginWithoutContext(
+ blink::PermissionType permission,
+ const url::Origin &origin)
+{
+ blink::mojom::PermissionStatus status =
+ GetPermissionStatus(permission, origin.GetURL(), origin.GetURL());
+
+ return content::PermissionResult(status, content::PermissionStatusSource::UNSPECIFIED);
+}
+
void PermissionManagerQt::ResetPermission(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& /*embedding_origin*/)
{
@@ -321,7 +328,7 @@ void PermissionManagerQt::ResetPermission(
}
content::PermissionControllerDelegate::SubscriptionId PermissionManagerQt::SubscribePermissionStatusChange(
- content::PermissionType permission,
+ blink::PermissionType permission,
content::RenderProcessHost * /*render_process_host*/,
content::RenderFrameHost * /* render_frame_host */,
const GURL& requesting_origin,
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index 566e0839b..8778c538d 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -13,8 +13,8 @@
namespace QtWebEngineCore {
-class PermissionManagerQt : public content::PermissionControllerDelegate {
-
+class PermissionManagerQt : public content::PermissionControllerDelegate
+{
public:
PermissionManagerQt();
~PermissionManagerQt();
@@ -24,41 +24,45 @@ public:
// content::PermissionManager implementation:
void RequestPermission(
- content::PermissionType permission,
+ blink::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) override;
blink::mojom::PermissionStatus GetPermissionStatus(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
- blink::mojom::PermissionStatus GetPermissionStatusForFrame(
- content::PermissionType permission,
- content::RenderFrameHost *render_frame_host,
- const GURL& requesting_origin) override;
+ blink::mojom::PermissionStatus GetPermissionStatusForCurrentDocument(blink::PermissionType, content::RenderFrameHost *) override;
- blink::mojom::PermissionStatus GetPermissionStatusForCurrentDocument(content::PermissionType, content::RenderFrameHost *) override;
+ blink::mojom::PermissionStatus GetPermissionStatusForWorker(blink::PermissionType, content::RenderProcessHost *, const GURL &) override;
- blink::mojom::PermissionStatus GetPermissionStatusForWorker(content::PermissionType, content::RenderProcessHost *, const GURL &) override;
+ content::PermissionResult GetPermissionResultForOriginWithoutContext(blink::PermissionType, const url::Origin &) override;
void ResetPermission(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
void RequestPermissions(
- const std::vector<content::PermissionType>& permission,
+ const std::vector<blink::PermissionType>& permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
base::OnceCallback<void(
const std::vector<blink::mojom::PermissionStatus>&)> callback) override;
+ void RequestPermissionsFromCurrentDocument(
+ const std::vector<blink::PermissionType>& permissions,
+ content::RenderFrameHost* render_frame_host,
+ bool user_gesture,
+ base::OnceCallback<void(
+ const std::vector<blink::mojom::PermissionStatus>&)> callback) override;
+
content::PermissionControllerDelegate::SubscriptionId SubscribePermissionStatusChange(
- content::PermissionType permission,
+ blink::PermissionType permission,
content::RenderProcessHost* render_process_host,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
@@ -76,7 +80,7 @@ private:
};
struct MultiRequest {
int id;
- std::vector<content::PermissionType> types;
+ std::vector<blink::PermissionType> types;
QUrl origin;
base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback;
};
diff --git a/src/core/platform_notification_service_qt.cpp b/src/core/platform_notification_service_qt.cpp
index 277de55f0..182a5ad84 100644
--- a/src/core/platform_notification_service_qt.cpp
+++ b/src/core/platform_notification_service_qt.cpp
@@ -6,7 +6,6 @@
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/permission_type.h"
#include "content/public/browser/notification_event_dispatcher.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
diff --git a/src/core/pointer_device_qt.cpp b/src/core/pointer_device_qt.cpp
new file mode 100644
index 000000000..a3d7f3d37
--- /dev/null
+++ b/src/core/pointer_device_qt.cpp
@@ -0,0 +1,102 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chromium/ui/base/pointer/pointer_device_linux.cc
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/pointer/pointer_device.h"
+
+#include <algorithm>
+#include <QPointingDevice>
+
+namespace ui {
+
+namespace {
+
+bool IsTouchScreen(const QInputDevice *device)
+{
+ return device->type() & QPointingDevice::DeviceType::TouchScreen;
+}
+
+bool IsMouseOrTouchpad(const QInputDevice *device)
+{
+ return device->type()
+ & (QPointingDevice::DeviceType::TouchPad | QPointingDevice::DeviceType::Mouse);
+}
+
+bool IsTouchDevicePresent()
+{
+ QList<const QInputDevice *> devices = QInputDevice::devices();
+ return std::any_of(devices.constBegin(), devices.constEnd(), IsTouchScreen);
+}
+
+bool IsMouseOrTouchpadPresent()
+{
+ QList<const QInputDevice *> devices = QInputDevice::devices();
+ return std::any_of(devices.constBegin(), devices.constEnd(), IsMouseOrTouchpad);
+}
+
+} // namespace
+
+int GetAvailablePointerTypes()
+{
+ int available_pointer_types = POINTER_TYPE_NONE;
+ if (IsMouseOrTouchpadPresent())
+ available_pointer_types |= POINTER_TYPE_FINE;
+
+ if (IsTouchDevicePresent())
+ available_pointer_types |= POINTER_TYPE_COARSE;
+
+ return available_pointer_types;
+}
+
+int GetAvailableHoverTypes()
+{
+ if (IsMouseOrTouchpadPresent())
+ return HOVER_TYPE_HOVER;
+
+ return HOVER_TYPE_NONE;
+}
+
+TouchScreensAvailability GetTouchScreensAvailability()
+{
+ if (!IsTouchDevicePresent())
+ return TouchScreensAvailability::NONE;
+
+ return TouchScreensAvailability::ENABLED;
+}
+
+int MaxTouchPoints()
+{
+ int max_touch = 0;
+ for (const auto *device : QInputDevice::devices()) {
+ if (IsTouchScreen(device)) {
+ int points = static_cast<const QPointingDevice *>(device)->maximumPoints();
+ max_touch = points > max_touch ? points : max_touch;
+ }
+ }
+
+ return max_touch;
+}
+
+PointerType GetPrimaryPointerType(int available_pointer_types)
+{
+ if (available_pointer_types & POINTER_TYPE_FINE)
+ return POINTER_TYPE_FINE;
+ if (available_pointer_types & POINTER_TYPE_COARSE)
+ return POINTER_TYPE_COARSE;
+ Q_ASSERT(available_pointer_types == POINTER_TYPE_NONE);
+ return POINTER_TYPE_NONE;
+}
+
+HoverType GetPrimaryHoverType(int available_hover_types)
+{
+ if (available_hover_types & HOVER_TYPE_HOVER)
+ return HOVER_TYPE_HOVER;
+ Q_ASSERT(available_hover_types == HOVER_TYPE_NONE);
+ return HOVER_TYPE_NONE;
+}
+
+} // namespace ui
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 27212f9b2..b6cfc2714 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -18,12 +18,17 @@
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/pref_registry_simple.h"
+#include "components/signin/internal/identity_manager/account_tracker_service.h"
+#include "components/signin/public/base/signin_pref_names.h"
#include "components/user_prefs/user_prefs.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "chrome/common/pref_names.h"
#include "extensions/buildflags/buildflags.h"
#include "content/public/browser/browser_context.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "chrome/browser/devtools/devtools_settings.h"
+
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "components/spellcheck/browser/pref_names.h"
@@ -37,6 +42,10 @@
#include "extensions/common/constants.h"
#endif
+#if defined(Q_OS_WIN)
+#include "components/os_crypt/os_crypt.h"
+#endif
+
namespace {
static const char kPrefMediaDeviceIDSalt[] = "qtwebengine.media_device_salt_id";
}
@@ -76,6 +85,21 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
registry->RegisterBooleanPref(prefs::kShowInternalAccessibilityTree, false);
registry->RegisterBooleanPref(prefs::kAccessibilityImageLabelsEnabled, false);
registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
+ registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap);
+ registry->RegisterListPref(prefs::kAccountInfo);
+ registry->RegisterStringPref(prefs::kGoogleServicesLastAccountId,
+ std::string());
+ registry->RegisterStringPref(prefs::kGoogleServicesLastUsername,
+ std::string());
+ registry->RegisterStringPref(prefs::kGoogleServicesAccountId, std::string());
+ registry->RegisterBooleanPref(prefs::kGoogleServicesConsentedToSync, false);
+ registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
+ registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
+ registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
+ registry->RegisterBooleanPref(prefs::kSignedInWithCredentialProvider, false);
+#if defined(Q_OS_WIN)
+ OSCrypt::RegisterLocalPrefs(registry.get());
+#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
registry->RegisterDictionaryPref(extensions::pref_names::kExtensions);
@@ -101,8 +125,20 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
registry->RegisterBooleanPref(autofill::prefs::kAutofillCreditCardEnabled, false);
registry->RegisterBooleanPref(autofill::prefs::kAutofillCreditCardFidoAuthEnabled, false);
registry->RegisterBooleanPref(autofill::prefs::kAutofillWalletImportEnabled, false);
- registry->RegisterBooleanPref(autofill::prefs::kAutofillJapanCityFieldMigratedDeprecated,
- false);
+
+ // devtools
+ registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
+ registry->RegisterDictionaryPref(prefs::kDevToolsEditedFiles);
+ registry->RegisterDictionaryPref(prefs::kDevToolsPreferences);
+ registry->RegisterBooleanPref(prefs::kDevToolsSyncPreferences, false);
+ // even if kDevToolsSyncPreferences is disabled, the js frontend tries to access
+ // these two. E.g.: 'clearPreferences', that is overridden by devtools_compatibility.js
+ registry->RegisterDictionaryPref(prefs::kDevToolsSyncedPreferencesSyncDisabled);
+ registry->RegisterDictionaryPref(prefs::kDevToolsSyncedPreferencesSyncEnabled);
+
+ registry->RegisterStringPref(prefs::kGoogleServicesSigninScopedDeviceId, std::string());
+ registry->RegisterStringPref(prefs::kGaiaCookieLastListAccountsData, std::string());
+ registry->RegisterStringPref(prefs::kGCMProductCategoryForSubtypes, std::string());
{
base::ScopedAllowBlocking allowBlock;
@@ -161,7 +197,7 @@ QStringList PrefServiceAdapter::spellCheckLanguages() const
{
QStringList spellcheck_dictionaries;
const auto &list = m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries);
- for (const auto &dictionary : list->GetList()) {
+ for (const auto &dictionary : list) {
spellcheck_dictionaries.append(QString::fromStdString(dictionary.GetString()));
}
diff --git a/src/core/printing/pdf_web_contents_helper_client_qt.cpp b/src/core/printing/pdf_web_contents_helper_client_qt.cpp
index 7c2a46ebf..4deb398c6 100644
--- a/src/core/printing/pdf_web_contents_helper_client_qt.cpp
+++ b/src/core/printing/pdf_web_contents_helper_client_qt.cpp
@@ -24,15 +24,14 @@ content::RenderFrameHost *FindPdfChildFrame(content::RenderFrameHost *rfh)
content::RenderFrameHost *pdf_rfh = nullptr;
rfh->ForEachRenderFrameHost(
- base::BindRepeating(
- [](content::RenderFrameHost *&pdf_rfh, content::RenderFrameHost *rfh) {
+ [&pdf_rfh](content::RenderFrameHost *rfh) {
if (!rfh->GetProcess()->IsPdf())
return;
DCHECK(IsPdfExtensionOrigin(rfh->GetParent()->GetLastCommittedOrigin()));
DCHECK(!pdf_rfh);
pdf_rfh = rfh;
- }, std::ref(pdf_rfh)));
+ });
return pdf_rfh;
}
@@ -43,14 +42,18 @@ PDFWebContentsHelperClientQt::~PDFWebContentsHelperClientQt() = default;
content::RenderFrameHost *PDFWebContentsHelperClientQt::FindPdfFrame(content::WebContents *contents)
{
- content::RenderFrameHost *main_frame = contents->GetMainFrame();
+ content::RenderFrameHost *main_frame = contents->GetPrimaryMainFrame();
content::RenderFrameHost *pdf_frame = FindPdfChildFrame(main_frame);
return pdf_frame ? pdf_frame : main_frame;
}
-void PDFWebContentsHelperClientQt::SetPluginCanSave(content::WebContents *contents, bool can_save)
+void PDFWebContentsHelperClientQt::SetPluginCanSave(content::RenderFrameHost *render_frame_host, bool can_save)
{
- auto *guest_view = extensions::MimeHandlerViewGuest::FromWebContents(contents);
+ auto *guest_view = extensions::MimeHandlerViewGuest::FromRenderFrameHost(render_frame_host);
if (guest_view)
guest_view->SetPluginCanSave(can_save);
}
+
+void PDFWebContentsHelperClientQt::UpdateContentRestrictions(content::RenderFrameHost *, int)
+{
+}
diff --git a/src/core/printing/pdf_web_contents_helper_client_qt.h b/src/core/printing/pdf_web_contents_helper_client_qt.h
index ccc552986..10df8a746 100644
--- a/src/core/printing/pdf_web_contents_helper_client_qt.h
+++ b/src/core/printing/pdf_web_contents_helper_client_qt.h
@@ -18,10 +18,10 @@ public:
private:
// pdf::PDFWebContentsHelperClient:
content::RenderFrameHost* FindPdfFrame(content::WebContents *contents) override;
- void UpdateContentRestrictions(content::WebContents *contents, int content_restrictions) override {}
void OnPDFHasUnsupportedFeature(content::WebContents *contents) override {}
void OnSaveURL(content::WebContents *contents) override {}
- void SetPluginCanSave(content::WebContents *contents, bool can_save) override;
+ void SetPluginCanSave(content::RenderFrameHost *render_frame_host, bool can_save) override;
+ void UpdateContentRestrictions(content::RenderFrameHost *, int) override;
};
#endif // PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp
index 3af6ecf44..f071b59ad 100644
--- a/src/core/printing/print_view_manager_base_qt.cpp
+++ b/src/core/printing/print_view_manager_base_qt.cpp
@@ -14,7 +14,7 @@
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
#include "base/task/current_thread.h"
-#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
@@ -47,21 +47,18 @@ void GetDefaultPrintSettingsReply(printing::mojom::PrintManagerHost::GetDefaultP
std::move(callback).Run(std::move(params));
}
-void GetDefaultPrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
+void OnDidGetDefaultPrintSettings(scoped_refptr<printing::PrintQueriesQueue> queue,
std::unique_ptr<printing::PrinterQuery> printer_query,
printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
printing::mojom::PrintParamsPtr params = printing::mojom::PrintParams::New();
if (printer_query && printer_query->last_status() == printing::mojom::ResultCode::kSuccess) {
RenderParamsFromPrintSettings(printer_query->settings(), params.get());
params->document_cookie = printer_query->cookie();
}
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&GetDefaultPrintSettingsReply,
- std::move(callback), std::move(params)));
+ GetDefaultPrintSettingsReply(std::move(callback), std::move(params));
// If printing was enabled.
if (printer_query) {
@@ -74,26 +71,6 @@ void GetDefaultPrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue>
}
}
-void GetDefaultPrintSettingsOnIO(printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback,
- scoped_refptr<printing::PrintQueriesQueue> queue,
- bool is_modifiable,
- content::GlobalRenderFrameHostId rfh_id)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(0);
- if (!printer_query)
- printer_query = queue->CreatePrinterQuery(rfh_id);
-
- // Loads default settings. This is asynchronous, only the mojo message sender
- // will hang until the settings are retrieved.
- auto *printer_query_ptr = printer_query.get();
- printer_query_ptr->GetDefaultSettings(
- base::BindOnce(&GetDefaultPrintSettingsReplyOnIO, queue,
- std::move(printer_query), std::move(callback)),
- is_modifiable);
-}
-
printing::mojom::PrintPagesParamsPtr CreateEmptyPrintPagesParamsPtr()
{
auto params = printing::mojom::PrintPagesParams::New();
@@ -112,25 +89,23 @@ void UpdatePrintSettingsReply(printing::mojom::PrintManagerHost::UpdatePrintSett
std::move(callback).Run(std::move(params), canceled);
}
-void UpdatePrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
+void OnDidUpdatePrintSettings(scoped_refptr<printing::PrintQueriesQueue> queue,
std::unique_ptr<printing::PrinterQuery> printer_query,
printing::mojom::PrintManagerHost::UpdatePrintSettingsCallback callback,
int process_id, int routing_id)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(printer_query);
auto params = printing::mojom::PrintPagesParams::New();
params->params = printing::mojom::PrintParams::New();
if (printer_query->last_status() == printing::mojom::ResultCode::kSuccess) {
RenderParamsFromPrintSettings(printer_query->settings(), params->params.get());
params->params->document_cookie = printer_query->cookie();
- params->pages = printing::PageRange::GetPages(printer_query->settings().ranges());
+ params->pages = printer_query->settings().ranges();
}
- bool canceled = printer_query->last_status() == printing::mojom::ResultCode::kAccessDenied;
+ bool canceled = printer_query->last_status() == printing::mojom::ResultCode::kCanceled;
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&UpdatePrintSettingsReply, std::move(callback), std::move(params), canceled));
+ UpdatePrintSettingsReply(std::move(callback), std::move(params), canceled);
if (printer_query->cookie() && printer_query->settings().dpi()) {
queue->QueuePrinterQuery(std::move(printer_query));
@@ -139,40 +114,21 @@ void UpdatePrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> que
}
}
-void UpdatePrintSettingsOnIO(int32_t cookie,
- printing::mojom::PrintManagerHost::UpdatePrintSettingsCallback callback,
- scoped_refptr<printing::PrintQueriesQueue> queue,
- base::Value::Dict job_settings,
- int process_id, int routing_id)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(cookie);
- if (!printer_query)
- printer_query = queue->CreatePrinterQuery(content::GlobalRenderFrameHostId());
-
- auto *printer_query_ptr = printer_query.get();
- printer_query_ptr->SetSettings(
- std::move(job_settings),
- base::BindOnce(&UpdatePrintSettingsReplyOnIO,
- queue, std::move(printer_query), std::move(callback),
- process_id, routing_id));
-}
-void ScriptedPrintReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
+void OnDidScriptedPrint(scoped_refptr<printing::PrintQueriesQueue> queue,
std::unique_ptr<printing::PrinterQuery> printer_query,
printing::mojom::PrintManagerHost::ScriptedPrintCallback callback)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
printing::mojom::PrintPagesParamsPtr params = CreateEmptyPrintPagesParamsPtr();
if (printer_query->last_status() == printing::mojom::ResultCode::kSuccess && printer_query->settings().dpi()) {
RenderParamsFromPrintSettings(printer_query->settings(), params->params.get());
params->params->document_cookie = printer_query->cookie();
- params->pages = printing::PageRange::GetPages(printer_query->settings().ranges());
+ params->pages = printer_query->settings().ranges();
}
bool has_valid_cookie = params->params->document_cookie;
bool has_dpi = !params->params->dpi.IsEmpty();
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(params)));
+ std::move(callback).Run(std::move(params));
if (has_dpi && has_valid_cookie) {
queue->QueuePrinterQuery(std::move(printer_query));
@@ -181,25 +137,6 @@ void ScriptedPrintReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
}
}
-void ScriptedPrintOnIO(printing::mojom::ScriptedPrintParamsPtr params,
- printing::mojom::PrintManagerHost::ScriptedPrintCallback callback,
- scoped_refptr<printing::PrintQueriesQueue> queue,
- bool is_modifiable,
- content::GlobalRenderFrameHostId rfh_id)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(params->cookie);
- if (!printer_query)
- printer_query = queue->CreatePrinterQuery(rfh_id);
-
- auto *printer_query_ptr = printer_query.get();
- printer_query_ptr->GetSettingsFromUser(
- params->expected_pages_count, params->has_selection, params->margin_type,
- params->is_scripted, is_modifiable,
- base::BindOnce(&ScriptedPrintReplyOnIO, queue, std::move(printer_query), std::move(callback)));
-}
-
} // namespace
PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents)
@@ -251,9 +188,9 @@ void PrintViewManagerBaseQt::UpdatePrintingEnabled()
#if QT_CONFIG(webengine_printing_and_pdf)
enabled = true;
#endif
- web_contents()->ForEachFrame(
- base::BindRepeating(&PrintViewManagerBaseQt::SendPrintingEnabled,
- base::Unretained(this), enabled));
+ web_contents()->ForEachRenderFrameHost([this, enabled](content::RenderFrameHost *rfh) {
+ SendPrintingEnabled(enabled, rfh);
+ });
}
void PrintViewManagerBaseQt::NavigationStopped()
@@ -334,21 +271,30 @@ void PrintViewManagerBaseQt::GetDefaultPrintSettings(GetDefaultPrintSettingsCall
print_manager_host_receivers_.GetCurrentTargetFrame();
content::RenderProcessHost *render_process_host =
render_frame_host->GetProcess();
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&GetDefaultPrintSettingsOnIO, std::move(callback), m_printerQueriesQueue,
- !render_process_host->IsPdf(),
- render_frame_host->GetGlobalId()));
+
+ auto callback_wrapper =
+ base::BindOnce(&GetDefaultPrintSettingsReply, std::move(callback));
+ std::unique_ptr<printing::PrinterQuery> printer_query = m_printerQueriesQueue->PopPrinterQuery(0);
+ if (!printer_query)
+ printer_query = m_printerQueriesQueue->CreatePrinterQuery(render_frame_host->GetGlobalId());
+
+ // Loads default settings. This is asynchronous, only the mojo message sender
+ // will hang until the settings are retrieved.
+ auto *printer_query_ptr = printer_query.get();
+ printer_query_ptr->GetDefaultSettings(
+ base::BindOnce(&OnDidGetDefaultPrintSettings, m_printerQueriesQueue,
+ std::move(printer_query), std::move(callback_wrapper)),
+ !render_process_host->IsPdf());
}
-void PrintViewManagerBaseQt::PrintingFailed(int32_t cookie)
+void PrintViewManagerBaseQt::PrintingFailed(int32_t cookie, printing::mojom::PrintFailureReason reason)
{
// Note: Not redundant with cookie checks in the same method in other parts of
// the class hierarchy.
if (!IsValidCookie(cookie))
return;
- PrintManager::PrintingFailed(cookie);
+ PrintManager::PrintingFailed(cookie, reason);
ReleasePrinterQuery();
}
@@ -365,10 +311,17 @@ void PrintViewManagerBaseQt::ScriptedPrint(printing::mojom::ScriptedPrintParamsP
auto callback_wrapper = base::BindOnce(
&PrintViewManagerBaseQt::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
std::move(callback), render_process_host->GetID());
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&ScriptedPrintOnIO, std::move(params), std::move(callback_wrapper),
- m_printerQueriesQueue, !render_process_host->IsPdf(), render_frame_host->GetGlobalId()));
+
+ std::unique_ptr<printing::PrinterQuery> printer_query =
+ m_printerQueriesQueue->PopPrinterQuery(params->cookie);
+ if (!printer_query)
+ printer_query = m_printerQueriesQueue->CreatePrinterQuery(render_frame_host->GetGlobalId());
+
+ auto *printer_query_ptr = printer_query.get();
+ printer_query_ptr->GetSettingsFromUser(
+ params->expected_pages_count, params->has_selection, params->margin_type,
+ params->is_scripted, !render_process_host->IsPdf(),
+ base::BindOnce(&OnDidScriptedPrint, m_printerQueriesQueue, std::move(printer_query), std::move(callback_wrapper)));
}
void PrintViewManagerBaseQt::ShowInvalidPrinterSettingsError()
@@ -408,42 +361,22 @@ void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render
}
}
-void PrintViewManagerBaseQt::Observe(int type,
- const content::NotificationSource& /*source*/,
- const content::NotificationDetails& details)
+void PrintViewManagerBaseQt::OnDocDone(int /*job_id*/, printing::PrintedDocument * /*document*/)
{
- DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type);
- OnNotifyPrintJobEvent(*content::Details<printing::JobEventDetails>(details).ptr());
}
-void PrintViewManagerBaseQt::OnNotifyPrintJobEvent(const printing::JobEventDetails& event_details)
+void PrintViewManagerBaseQt::OnJobDone()
{
- switch (event_details.type()) {
- case printing::JobEventDetails::FAILED: {
- TerminatePrintJob(true);
- break;
- }
-// case printing::JobEventDetails::ALL_PAGES_REQUESTED: {
-// ShouldQuitFromInnerMessageLoop();
-// break;
-// }
- case printing::JobEventDetails::NEW_DOC:
- case printing::JobEventDetails::DOC_DONE: {
- // Don't care about the actual printing process.
- break;
- }
- case printing::JobEventDetails::JOB_DONE: {
- // Printing is done, we don't need it anymore.
- // print_job_->is_job_pending() may still be true, depending on the order
- // of object registration.
- m_didPrintingSucceed = true;
- ReleasePrintJob();
- break;
- }
- default:
- NOTREACHED();
- break;
- }
+ // Printing is done, we don't need it anymore.
+ // print_job_->is_job_pending() may still be true, depending on the order
+ // of object registration.
+ m_didPrintingSucceed = true;
+ ReleasePrintJob();
+}
+
+void PrintViewManagerBaseQt::OnFailed()
+{
+ TerminatePrintJob(true);
}
// Requests the RenderView to render all the missing pages for the print job.
@@ -462,8 +395,8 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow()
// We can't print if there is no renderer.
if (!web_contents() ||
- !web_contents()->GetMainFrame() ||
- !web_contents()->GetMainFrame()->IsRenderFrameLive()) {
+ !web_contents()->GetPrimaryMainFrame() ||
+ !web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive()) {
return false;
}
@@ -502,11 +435,14 @@ bool PrintViewManagerBaseQt::CreateNewPrintJob(std::unique_ptr<printing::Printer
DCHECK(query);
// Disconnect the current |m_printJob|.
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
DisconnectFromCurrentPrintJob();
+ if (!weak_this)
+ return false;
// We can't print if there is no renderer.
- if (!web_contents()->GetMainFrame() ||
- !web_contents()->GetMainFrame()->IsRenderFrameLive()) {
+ if (!web_contents()->GetPrimaryMainFrame() ||
+ !web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive()) {
return false;
}
@@ -516,8 +452,7 @@ bool PrintViewManagerBaseQt::CreateNewPrintJob(std::unique_ptr<printing::Printer
m_printJob = base::MakeRefCounted<printing::PrintJob>(nullptr /*g_browser_process->print_job_manager()*/);
m_printJob->Initialize(std::move(query), RenderSourceName(), number_pages_);
- m_registrar.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
- content::Source<printing::PrintJob>(m_printJob.get()));
+ m_printJob->AddObserver(*this);
m_didPrintingSucceed = false;
return true;
}
@@ -573,8 +508,8 @@ void PrintViewManagerBaseQt::ReleasePrintJob()
if (rfh)
GetPrintRenderFrame(rfh)->PrintingDone(m_didPrintingSucceed);
- m_registrar.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
- content::Source<printing::PrintJob>(m_printJob.get()));
+ m_printJob->RemoveObserver(*this);
+
// Don't close the worker thread.
m_printJob = nullptr;
}
@@ -660,8 +595,7 @@ void PrintViewManagerBaseQt::ReleasePrinterQuery()
printerQuery = m_printerQueriesQueue->PopPrinterQuery(cookie);
if (!printerQuery)
return;
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&printing::PrinterQuery::StopWorker, std::move(printerQuery)));
+ printerQuery->StopWorker();
}
// Originally from print_preview_message_handler.cc:
@@ -669,12 +603,11 @@ void PrintViewManagerBaseQt::StopWorker(int documentCookie)
{
if (documentCookie <= 0)
return;
- std::unique_ptr<printing::PrinterQuery> printer_query =
+ std::unique_ptr<printing::PrinterQuery> printerQuery =
m_printerQueriesQueue->PopPrinterQuery(documentCookie);
- if (printer_query.get()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&printing::PrinterQuery::StopWorker, std::move(printer_query)));
- }
+ if (!printerQuery)
+ return;
+ printerQuery->StopWorker();
}
void PrintViewManagerBaseQt::SendPrintingEnabled(bool enabled, content::RenderFrameHost* rfh)
@@ -695,13 +628,16 @@ void PrintViewManagerBaseQt::UpdatePrintSettings(int32_t cookie, base::Value::Di
content::RenderFrameHost *render_frame_host =
print_manager_host_receivers_.GetCurrentTargetFrame();
+ std::unique_ptr<printing::PrinterQuery> printer_query = m_printerQueriesQueue->PopPrinterQuery(cookie);
+ if (!printer_query)
+ printer_query = m_printerQueriesQueue->CreatePrinterQuery(content::GlobalRenderFrameHostId());
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&UpdatePrintSettingsOnIO, cookie, std::move(callback),
- m_printerQueriesQueue, std::move(job_settings),
- render_frame_host->GetProcess()->GetID(),
- render_frame_host->GetRoutingID()));
+ auto *printer_query_ptr = printer_query.get();
+ printer_query_ptr->SetSettings(
+ std::move(job_settings),
+ base::BindOnce(&OnDidUpdatePrintSettings,
+ m_printerQueriesQueue, std::move(printer_query), std::move(callback),
+ render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()));
}
} // namespace QtWebEngineCore
diff --git a/src/core/printing/print_view_manager_base_qt.h b/src/core/printing/print_view_manager_base_qt.h
index b83a9d286..8201a4225 100644
--- a/src/core/printing/print_view_manager_base_qt.h
+++ b/src/core/printing/print_view_manager_base_qt.h
@@ -9,6 +9,7 @@
#define PRINT_VIEW_MANAGER_BASE_QT_H
#include "base/memory/ref_counted_memory.h"
+#include "chrome/browser/printing/print_job.h"
#include "components/prefs/pref_member.h"
#include "components/printing/browser/print_manager.h"
#include "components/printing/common/print.mojom-forward.h"
@@ -24,15 +25,13 @@ class RenderFrameHost;
}
namespace printing {
-class JobEventDetails;
-class PrintJob;
class PrintQueriesQueue;
class PrinterQuery;
}
namespace QtWebEngineCore {
-class PrintViewManagerBaseQt : public content::NotificationObserver
- , public printing::PrintManager
+class PrintViewManagerBaseQt : public printing::PrintManager
+ , public printing::PrintJob::Observer
{
public:
~PrintViewManagerBaseQt() override;
@@ -52,7 +51,8 @@ public:
void ScriptedPrint(printing::mojom::ScriptedPrintParamsPtr,
printing::mojom::PrintManagerHost::ScriptedPrintCallback) override;
void ShowInvalidPrinterSettingsError() override;
- void PrintingFailed(int32_t cookie) override;
+ void PrintingFailed(int32_t cookie,
+ printing::mojom::PrintFailureReason reason) override;
protected:
explicit PrintViewManagerBaseQt(content::WebContents*);
@@ -75,20 +75,17 @@ protected:
// disconnect from it.
void DisconnectFromCurrentPrintJob();
+ // PrintJob::Observer overrides:
+ void OnDocDone(int job_id, printing::PrintedDocument *document) override;
+ void OnJobDone() override;
+ void OnFailed() override;
+
void StopWorker(int documentCookie);
private:
- // content::NotificationObserver implementation.
- void Observe(int,
- const content::NotificationSource&,
- const content::NotificationDetails&) override;
-
// content::WebContentsObserver implementation.
void DidStartLoading() override;
- // Processes a NOTIFY_PRINT_JOB_EVENT notification.
- void OnNotifyPrintJobEvent(const printing::JobEventDetails &event_details);
-
// Requests the RenderView to render all the missing pages for the print job.
// No-op if no print job is pending. Returns true if at least one page has
// been requested to the renderer.
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index 6eb3d7419..7d8a796f7 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -19,7 +19,6 @@
#include "base/values.h"
#include "base/memory/ref_counted_memory.h"
-#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.h"
@@ -74,47 +73,47 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
base::File file(path,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
bool success = file.IsValid() && metafile.SaveTo(&file);
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(saveCallback), success));
}
-static base::DictionaryValue *createPrintSettings()
+static base::Value::Dict createPrintSettings()
{
- base::DictionaryValue *printSettings = new base::DictionaryValue();
+ base::Value::Dict printSettings;
// TO DO: Check if we can use the request ID from Qt here somehow.
static int internalRequestId = 0;
- printSettings->SetBoolean(printing::kIsFirstRequest, internalRequestId++ == 0);
- printSettings->SetInteger(printing::kPreviewRequestID, internalRequestId);
+ printSettings.Set(printing::kIsFirstRequest, internalRequestId++ == 0);
+ printSettings.Set(printing::kPreviewRequestID, internalRequestId);
// The following are standard settings that Chromium expects to be set.
- printSettings->SetInteger(printing::kSettingPrinterType, static_cast<int>(printing::mojom::PrinterType::kPdf));
+ printSettings.Set(printing::kSettingPrinterType, static_cast<int>(printing::mojom::PrinterType::kPdf));
- printSettings->SetInteger(printing::kSettingDpiHorizontal, printing::kPointsPerInch);
- printSettings->SetInteger(printing::kSettingDpiVertical, printing::kPointsPerInch);
+ printSettings.Set(printing::kSettingDpiHorizontal, printing::kPointsPerInch);
+ printSettings.Set(printing::kSettingDpiVertical, printing::kPointsPerInch);
- printSettings->SetInteger(printing::kSettingDuplexMode, static_cast<int>(printing::mojom::DuplexMode::kSimplex));
- printSettings->SetInteger(printing::kSettingCopies, 1);
- printSettings->SetInteger(printing::kSettingPagesPerSheet, 1);
- printSettings->SetBoolean(printing::kSettingCollate, false);
+ printSettings.Set(printing::kSettingDuplexMode, static_cast<int>(printing::mojom::DuplexMode::kSimplex));
+ printSettings.Set(printing::kSettingCopies, 1);
+ printSettings.Set(printing::kSettingPagesPerSheet, 1);
+ printSettings.Set(printing::kSettingCollate, false);
// printSettings->SetBoolean(printing::kSettingGenerateDraftData, false);
- printSettings->SetBoolean(printing::kSettingPreviewModifiable, false);
+ printSettings.Set(printing::kSettingPreviewModifiable, false);
- printSettings->SetKey(printing::kSettingShouldPrintSelectionOnly, base::Value(false));
- printSettings->SetKey(printing::kSettingShouldPrintBackgrounds, base::Value(true));
- printSettings->SetKey(printing::kSettingHeaderFooterEnabled, base::Value(false));
- printSettings->SetKey(printing::kSettingRasterizePdf, base::Value(false));
- printSettings->SetInteger(printing::kSettingScaleFactor, 100);
- printSettings->SetString(printing::kSettingDeviceName, "");
- printSettings->SetInteger(printing::kPreviewUIID, 12345678);
+ printSettings.Set(printing::kSettingShouldPrintSelectionOnly, base::Value(false));
+ printSettings.Set(printing::kSettingShouldPrintBackgrounds, base::Value(true));
+ printSettings.Set(printing::kSettingHeaderFooterEnabled, base::Value(false));
+ printSettings.Set(printing::kSettingRasterizePdf, base::Value(false));
+ printSettings.Set(printing::kSettingScaleFactor, 100);
+ printSettings.Set(printing::kSettingDeviceName, "");
+ printSettings.Set(printing::kPreviewUIID, 12345678);
return printSettings;
}
-static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout,
+static base::Value::Dict createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout,
bool useCustomMargins)
{
- base::DictionaryValue *printSettings = createPrintSettings();
+ base::Value::Dict printSettings = createPrintSettings();
QRectF pageSizeInMillimeter;
if (useCustomMargins) {
@@ -122,43 +121,43 @@ static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayo
pageSizeInMillimeter = pageLayout.pageSize().rect(QPageSize::Millimeter);
QMargins pageMarginsInPoints = pageLayout.marginsPoints();
- std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue);
- marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top());
- marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
- marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left());
- marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
+ base::Value::Dict marginsDict;
+ marginsDict.Set(printing::kSettingMarginTop, pageMarginsInPoints.top());
+ marginsDict.Set(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
+ marginsDict.Set(printing::kSettingMarginLeft, pageMarginsInPoints.left());
+ marginsDict.Set(printing::kSettingMarginRight, pageMarginsInPoints.right());
- printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict));
- printSettings->SetInteger(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kCustomMargins);
+ printSettings.Set(printing::kSettingMarginsCustom, std::move(marginsDict));
+ printSettings.Set(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kCustomMargins);
// pageSizeInMillimeter is in portrait orientation. Transpose it if necessary.
- printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
+ printSettings.Set(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
} else {
// QPrinter will handle margins
pageSizeInMillimeter = pageLayout.paintRect(QPageLayout::Millimeter);
- printSettings->SetInteger(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kNoMargins);
+ printSettings.Set(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kNoMargins);
// pageSizeInMillimeter already contains the orientation.
- printSettings->SetBoolean(printing::kSettingLandscape, false);
+ printSettings.Set(printing::kSettingLandscape, false);
}
//Set page size attributes, chromium expects these in micrometers
- std::unique_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue);
- sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMillimeter.width() * kMicronsToMillimeter);
- sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMillimeter.height() * kMicronsToMillimeter);
- printSettings->Set(printing::kSettingMediaSize, std::move(sizeDict));
+ base::Value::Dict sizeDict;
+ sizeDict.Set(printing::kSettingMediaSizeWidthMicrons, int(pageSizeInMillimeter.width() * kMicronsToMillimeter));
+ sizeDict.Set(printing::kSettingMediaSizeHeightMicrons, int(pageSizeInMillimeter.height() * kMicronsToMillimeter));
+ printSettings.Set(printing::kSettingMediaSize, std::move(sizeDict));
return printSettings;
}
-static base::ListValue *createPageRangeSettings(const QList<QPageRanges::Range> &ranges)
+static base::Value::List createPageRangeSettings(const QList<QPageRanges::Range> &ranges)
{
- base::ListValue *pageRangeArray = new base::ListValue;
+ base::Value::List pageRangeArray;
for (int i = 0; i < ranges.count(); i++) {
- std::unique_ptr<base::DictionaryValue> pageRange(new base::DictionaryValue);
- pageRange->SetInteger(printing::kSettingPageRangeFrom, ranges.at(i).from);
- pageRange->SetInteger(printing::kSettingPageRangeTo, ranges.at(i).to);
- pageRangeArray->Append(std::move(pageRange));
+ base::Value::Dict pageRange;
+ pageRange.Set(printing::kSettingPageRangeFrom, ranges.at(i).from);
+ pageRange.Set(printing::kSettingPageRangeTo, ranges.at(i).to);
+ pageRangeArray.Append(std::move(pageRange));
}
return pageRangeArray;
}
@@ -180,8 +179,8 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
if (callback.is_null())
return;
- if (m_printSettings || !filePath.length()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ if (!m_printSettings.empty() || !filePath.length()) {
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), false));
return;
}
@@ -189,7 +188,7 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
m_pdfOutputPath = toFilePath(filePath);
m_pdfSaveCallback = std::move(callback);
if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor)) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(m_pdfSaveCallback), false));
resetPdfState();
}
@@ -205,15 +204,15 @@ void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout,
return;
// If there already is a pending print in progress, don't try starting another one.
- if (m_printSettings) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ if (!m_printSettings.empty()) {
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), QSharedPointer<QByteArray>()));
return;
}
m_pdfPrintCallback = std::move(callback);
if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor, useCustomMargins)) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(m_pdfPrintCallback), QSharedPointer<QByteArray>()));
resetPdfState();
@@ -228,19 +227,18 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
if (!pageLayout.isValid())
return false;
- m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, useCustomMargins));
- m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds,
+ m_printSettings = createPrintSettingsFromQPageLayout(pageLayout, useCustomMargins);
+ m_printSettings.Set(printing::kSettingShouldPrintBackgrounds,
web_contents()->GetOrCreateWebPreferences().should_print_backgrounds);
- m_printSettings->SetInteger(printing::kSettingColor,
+ m_printSettings.Set(printing::kSettingColor,
int(printInColor ? printing::mojom::ColorModel::kColor : printing::mojom::ColorModel::kGrayscale));
if (!pageRanges.isEmpty())
- m_printSettings->Set(printing::kSettingPageRange,
- std::unique_ptr<base::ListValue>(createPageRangeSettings(pageRanges.toRangeList())));
+ m_printSettings.Set(printing::kSettingPageRange, createPageRangeSettings(pageRanges.toRangeList()));
if (web_contents()->IsCrashed())
return false;
- content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
+ content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame();
GetPrintRenderFrame(rfh)->InitiatePrintPreview(mojo::PendingAssociatedRemote<printing::mojom::PrintRenderer>(), false);
DCHECK(!m_printPreviewRfh);
@@ -274,12 +272,12 @@ void PrintViewManagerQt::resetPdfState()
m_pdfOutputPath.clear();
m_pdfPrintCallback.Reset();
m_pdfSaveCallback.Reset();
- m_printSettings.reset();
+ m_printSettings.clear();
}
void PrintViewManagerQt::PrintPreviewDone()
{
- if (IsPrintRenderFrameConnected(m_printPreviewRfh))
+ if (m_printPreviewRfh->IsRenderFrameLive() && IsPrintRenderFrameConnected(m_printPreviewRfh))
GetPrintRenderFrame(m_printPreviewRfh)->OnPrintPreviewDialogClosed();
m_printPreviewRfh = nullptr;
}
@@ -289,7 +287,7 @@ void PrintViewManagerQt::PrintPreviewDone()
void PrintViewManagerQt::NavigationStopped()
{
if (!m_pdfPrintCallback.is_null()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(m_pdfPrintCallback), QSharedPointer<QByteArray>()));
}
resetPdfState();
@@ -300,7 +298,7 @@ void PrintViewManagerQt::PrimaryMainFrameRenderProcessGone(base::TerminationStat
{
PrintViewManagerBaseQt::PrimaryMainFrameRenderProcessGone(status);
if (!m_pdfPrintCallback.is_null()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(m_pdfPrintCallback), QSharedPointer<QByteArray>()));
}
resetPdfState();
@@ -340,9 +338,13 @@ void PrintViewManagerQt::ShowScriptedPrintPreview(bool /*source_is_modifiable*/)
void PrintViewManagerQt::RequestPrintPreview(printing::mojom::RequestPrintPreviewParamsPtr /*params*/)
{
+ if (m_printSettings.empty()) {
+ PrintPreviewDone();
+ return;
+ }
mojo::AssociatedRemote<printing::mojom::PrintRenderFrame> printRenderFrame;
m_printPreviewRfh->GetRemoteAssociatedInterfaces()->GetInterface(&printRenderFrame);
- printRenderFrame->PrintPreview(m_printSettings->Clone());
+ printRenderFrame->PrintPreview(m_printSettings.Clone());
PrintPreviewDone();
}
@@ -375,7 +377,7 @@ void PrintViewManagerQt::MetafileReadyForPrinting(printing::mojom::DidPreviewDoc
if (!pdf_print_callback.is_null()) {
QSharedPointer<QByteArray> data_array = GetStdVectorFromHandle(params->content->metafile_data_region);
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(std::move(pdf_print_callback), data_array));
} else {
scoped_refptr<base::RefCountedBytes> data_bytes = GetBytesFromHandle(params->content->metafile_data_region);
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index 7d0894a0d..956849ef9 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -87,7 +87,7 @@ private:
base::FilePath m_pdfOutputPath;
PrintToPDFCallback m_pdfPrintCallback;
PrintToPDFFileCallback m_pdfSaveCallback;
- std::unique_ptr<base::DictionaryValue> m_printSettings;
+ base::Value::Dict m_printSettings;
friend class content::WebContentsUserData<PrintViewManagerQt>;
};
diff --git a/src/core/printing/printer_worker.cpp b/src/core/printing/printer_worker.cpp
index 9eb82c590..da7165623 100644
--- a/src/core/printing/printer_worker.cpp
+++ b/src/core/printing/printer_worker.cpp
@@ -65,8 +65,8 @@ void PrinterWorker::print()
bool isLandscape = documentSize.width() > documentSize.height();
m_device->setPageOrientation(isLandscape ? QPageLayout::Landscape
: QPageLayout::Portrait);
- QRectF pageRect = m_device->pageLayout().pageSize().rectPixels(m_deviceResolution);
- documentSize = documentSize.scaled(pageRect.size(), Qt::KeepAspectRatio);
+ QRectF paintRect = m_device->pageLayout().paintRectPixels(m_deviceResolution);
+ documentSize = documentSize.scaled(paintRect.size(), Qt::KeepAspectRatio);
// setPageOrientation has to be called before qpainter.begin() or before
// qprinter.newPage() so correct metrics is used, therefore call begin now for only
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index e557e69a7..e9e9aaeda 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -63,6 +63,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
+ , m_pushServiceEnabled(false)
, m_httpCacheMaxSize(0)
{
WebEngineContext::current()->addProfileAdapter(this);
@@ -76,6 +77,8 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
extensions::ExtensionSystem::Get(m_profile.data())->InitForRegularProfile(true);
#endif
m_cancelableTaskTracker.reset(new base::CancelableTaskTracker());
+
+ m_profile->DoFinalInit();
}
ProfileAdapter::~ProfileAdapter()
@@ -626,6 +629,16 @@ bool ProfileAdapter::isSpellCheckEnabled() const
#endif
}
+bool ProfileAdapter::pushServiceEnabled() const
+{
+ return m_pushServiceEnabled;
+}
+
+void ProfileAdapter::setPushServiceEnabled(bool enabled)
+{
+ m_pushServiceEnabled = enabled;
+}
+
void ProfileAdapter::addWebContentsAdapterClient(WebContentsAdapterClient *client)
{
m_webContentsAdapterClients.append(client);
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 46993f5bd..ab4622a4b 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -101,6 +101,9 @@ public:
void setSpellCheckEnabled(bool enabled);
bool isSpellCheckEnabled() const;
+ bool pushServiceEnabled() const;
+ void setPushServiceEnabled(bool enabled);
+
void addWebContentsAdapterClient(WebContentsAdapterClient *client);
void removeWebContentsAdapterClient(WebContentsAdapterClient *client);
void releaseAllWebContentsAdapterClients();
@@ -221,6 +224,7 @@ private:
QList<ProfileAdapterClient*> m_clients;
QList<WebContentsAdapterClient *> m_webContentsAdapterClients;
+ bool m_pushServiceEnabled;
int m_httpCacheMaxSize;
QrcUrlSchemeHandler m_qrcHandler;
std::unique_ptr<base::CancelableTaskTracker> m_cancelableTaskTracker;
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index cd381afc5..c11d35c95 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -3,7 +3,6 @@
#include "profile_io_data_qt.h"
-#include "base/task/post_task.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 9820ca787..410340fb8 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -5,6 +5,7 @@
#include "profile_adapter.h"
#include "browsing_data_remover_delegate_qt.h"
+#include "client_hints.h"
#include "download_manager_delegate_qt.h"
#include "file_system_access/file_system_access_permission_context_factory_qt.h"
#include "net/ssl_host_state_delegate_qt.h"
@@ -35,6 +36,9 @@
#include "components/user_prefs/user_prefs.h"
#include "components/profile_metrics/browser_profile_type.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
+#include "chrome/browser/push_messaging/push_messaging_service_factory.h"
+#include "chrome/browser/push_messaging/push_messaging_service_impl.h"
#include "chrome/common/pref_names.h"
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spellcheck_service.h"
@@ -50,6 +54,10 @@
#include "extensions/extension_system_qt.h"
#endif
+#if defined(Q_OS_WIN)
+#include "components/os_crypt/os_crypt.h"
+#endif
+
namespace QtWebEngineCore {
ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
@@ -59,6 +67,10 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
, m_extensionSystem(nullptr)
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
{
+ profile_metrics::SetBrowserProfileType(this, IsOffTheRecord()
+ ? profile_metrics::BrowserProfileType::kIncognito
+ : profile_metrics::BrowserProfileType::kRegular);
+
setupPrefService();
// Mark the context as live. This prevents the use-after-free DCHECK in
@@ -78,12 +90,20 @@ ProfileQt::~ProfileQt()
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
m_prefServiceAdapter.commit();
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(this);
+ // Remembering push subscriptions and not persisting notification permissions would
+ // confuse most of web applications.
+ PushMessagingAppIdentifier::DeleteAllFromPrefs(this);
ShutdownStoragePartitions();
m_profileIOData->shutdownOnUIThread();
//Should be deleted by IO Thread
m_profileIOData.release();
}
+void ProfileQt::DoFinalInit()
+{
+ PushMessagingServiceImpl::InitializeForProfile(this);
+}
+
PrefService* ProfileQt::GetPrefs()
{
return m_prefServiceAdapter.prefService();
@@ -141,7 +161,10 @@ storage::SpecialStoragePolicy *ProfileQt::GetSpecialStoragePolicy()
content::PushMessagingService *ProfileQt::GetPushMessagingService()
{
- return nullptr;
+ if (m_profileAdapter->pushServiceEnabled())
+ return PushMessagingServiceFactory::GetForProfile(this);
+ else
+ return nullptr;
}
content::SSLHostStateDelegate* ProfileQt::GetSSLHostStateDelegate()
@@ -182,7 +205,7 @@ content::PermissionControllerDelegate *ProfileQt::GetPermissionControllerDelegat
content::ClientHintsControllerDelegate *ProfileQt::GetClientHintsControllerDelegate()
{
- return nullptr;
+ return ClientHintsFactory::GetForBrowserContext(this);
}
content::StorageNotificationService *ProfileQt::GetStorageNotificationService()
@@ -190,6 +213,11 @@ content::StorageNotificationService *ProfileQt::GetStorageNotificationService()
return nullptr;
}
+content::ReduceAcceptLanguageControllerDelegate *ProfileQt::GetReduceAcceptLanguageControllerDelegate()
+{
+ return nullptr;
+}
+
#if QT_CONFIG(webengine_spellchecker)
void ProfileQt::FailedToLoadDictionary(const std::string &language)
{
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index 2f8ff3255..9fb8cb444 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -56,13 +56,14 @@ public:
content::PlatformNotificationService *GetPlatformNotificationService() override;
std::string GetMediaDeviceIDSalt() override;
content::FileSystemAccessPermissionContext *GetFileSystemAccessPermissionContext() override;
+ content::ReduceAcceptLanguageControllerDelegate *GetReduceAcceptLanguageControllerDelegate() override;
// Profile implementation:
PrefService *GetPrefs() override;
const PrefService *GetPrefs() const override;
bool IsNewProfile() const override;
- void Initialize();
+ void DoFinalInit();
ProfileAdapter *profileAdapter() { return m_profileAdapter; }
#if QT_CONFIG(webengine_spellchecker)
diff --git a/src/core/quota_permission_context_qt.cpp b/src/core/quota_permission_context_qt.cpp
deleted file mode 100644
index 5ace64b62..000000000
--- a/src/core/quota_permission_context_qt.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "quota_permission_context_qt.h"
-
-#include "base/task/post_task.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_frame_host.h"
-#include "quota_request_controller_impl.h"
-#include "qwebenginequotarequest.h"
-#include "web_contents_delegate_qt.h"
-#include "web_contents_view_qt.h"
-
-using content::QuotaPermissionContext;
-using content::RenderFrameHost;
-using content::StorageQuotaParams;
-using content::WebContents;
-
-namespace QtWebEngineCore {
-
-void QuotaPermissionContextQt::RequestQuotaPermission(const StorageQuotaParams &params, int render_process_id, PermissionCallback callback)
-{
- if (params.storage_type != blink::mojom::StorageType::kPersistent) {
- // For now we only support requesting quota with this interface
- // for Persistent storage type.
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_DISALLOW);
- return;
- }
-
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- base::PostTask(
- FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&QuotaPermissionContextQt::RequestQuotaPermission, this,
- params, render_process_id, std::move(callback)));
- return;
- }
-
- RenderFrameHost *renderFrameHost = RenderFrameHost::FromID(render_process_id, params.render_frame_id);
- if (!renderFrameHost) {
- LOG(WARNING) << "Attempt to request quota from frameless renderer: "
- << render_process_id << "," << params.render_frame_id;
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
- return;
- }
-
- WebContents *webContents = WebContents::FromRenderFrameHost(renderFrameHost);
- if (!webContents) {
- LOG(ERROR) << "Attempt to request quota from frame missing webcontents";
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
- return;
- }
-
- WebContentsAdapterClient *client = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(webContents)->GetView())->client();
- if (!client) {
- LOG(ERROR) << "Attempt to request quota from content missing webcontents client";
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
- return;
- }
-
- QWebEngineQuotaRequest request(
- QSharedPointer<QuotaRequestControllerImpl>::create(this, params, std::move(callback)));
- client->runQuotaRequest(std::move(request));
-}
-
-void QuotaPermissionContextQt::dispatchCallbackOnIOThread(PermissionCallback callback,
- QuotaPermissionContext::QuotaPermissionResponse response)
-{
- if (callback.is_null())
- return;
-
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
- base::PostTask(
- FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&QuotaPermissionContextQt::dispatchCallbackOnIOThread,
- this, std::move(callback), response));
- return;
- }
-
- std::move(callback).Run(response);
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/quota_permission_context_qt.h b/src/core/quota_permission_context_qt.h
deleted file mode 100644
index 665f046cd..000000000
--- a/src/core/quota_permission_context_qt.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef QUOTA_PERMISSION_CONTEXT_QT_H
-#define QUOTA_PERMISSION_CONTEXT_QT_H
-
-#include "content/public/browser/quota_permission_context.h"
-
-namespace QtWebEngineCore {
-
-class QuotaPermissionContextQt : public content::QuotaPermissionContext {
-public:
- void RequestQuotaPermission(const content::StorageQuotaParams &params,
- int render_process_id,
- PermissionCallback callback) override;
-
- void dispatchCallbackOnIOThread(PermissionCallback callback,
- QuotaPermissionContext::QuotaPermissionResponse response);
-};
-
-} // namespace QtWebEngineCore
-
-#endif // QUOTA_PERMISSION_CONTEXT_QT_H
diff --git a/src/core/quota_request_controller.h b/src/core/quota_request_controller.h
deleted file mode 100644
index d39a209d3..000000000
--- a/src/core/quota_request_controller.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef QUOTA_REQUEST_CONTROLLER_H
-#define QUOTA_REQUEST_CONTROLLER_H
-
-#include "request_controller.h"
-
-namespace QtWebEngineCore {
-
-class QuotaRequestController : public RequestController {
-public:
- QuotaRequestController(QUrl origin, qint64 requestedSize)
- : RequestController(std::move(origin))
- , m_requestedSize(requestedSize)
- {}
-
- qint64 requestedSize() const { return m_requestedSize; }
-
-private:
- qint64 m_requestedSize;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // QUOTA_REQUEST_CONTROLLER_H
diff --git a/src/core/quota_request_controller_impl.cpp b/src/core/quota_request_controller_impl.cpp
deleted file mode 100644
index 32d7a6d63..000000000
--- a/src/core/quota_request_controller_impl.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "quota_request_controller_impl.h"
-
-#include "type_conversion.h"
-
-namespace QtWebEngineCore {
-
-QuotaRequestControllerImpl::QuotaRequestControllerImpl(QuotaPermissionContextQt *context,
- const content::StorageQuotaParams &params,
- content::QuotaPermissionContext::PermissionCallback callback)
- : QuotaRequestController(
- toQt(params.origin_url),
- params.requested_size)
- , m_context(context)
- , m_callback(std::move(callback))
-{}
-
-QuotaRequestControllerImpl::~QuotaRequestControllerImpl()
-{
- if (m_callback)
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
-}
-
-void QuotaRequestControllerImpl::accepted()
-{
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
-}
-
-void QuotaRequestControllerImpl::rejected()
-{
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/quota_request_controller_impl.h b/src/core/quota_request_controller_impl.h
deleted file mode 100644
index a9a002380..000000000
--- a/src/core/quota_request_controller_impl.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef QUOTA_REQUEST_CONTROLLER_IMPL_H
-#define QUOTA_REQUEST_CONTROLLER_IMPL_H
-
-#include "quota_permission_context_qt.h"
-#include "quota_request_controller.h"
-
-namespace QtWebEngineCore {
-
-class QuotaRequestControllerImpl final : public QuotaRequestController {
-public:
- QuotaRequestControllerImpl(
- QuotaPermissionContextQt *context,
- const content::StorageQuotaParams &params,
- content::QuotaPermissionContext::PermissionCallback callback);
-
- ~QuotaRequestControllerImpl();
-
-protected:
- void accepted() override;
- void rejected() override;
-
-private:
- scoped_refptr<QuotaPermissionContextQt> m_context;
- content::QuotaPermissionContext::PermissionCallback m_callback;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // QUOTA_REQUEST_CONTROLLER_IMPL_H
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index dfbbe72e7..3d4e5bbc2 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -3,7 +3,6 @@
#include "render_widget_host_view_qt.h"
-#include "browser_accessibility_manager_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "render_widget_host_view_qt_delegate.h"
#include "render_widget_host_view_qt_delegate_client.h"
@@ -19,6 +18,7 @@
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/image_transport_factory.h"
+#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/cursor_manager.h"
@@ -30,6 +30,7 @@
#include "content/browser/renderer_host/ui_events_helper.h"
#include "content/common/content_switches_internal.h"
#include "content/common/cursors/webcursor.h"
+#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/resource/resource_bundle.h"
@@ -46,12 +47,12 @@
#endif
#if defined(USE_AURA)
-#include "ui/aura/cursor/cursors_aura.h"
+#include "ui/wm/core/cursors_aura.h"
#include "ui/base/cursor/cursor_size.h"
#endif
#if defined(Q_OS_MACOS)
-#include "content/app/resources/grit/content_resources.h"
+#include "ui/resources/grit/ui_resources.h"
#endif
#include <QGuiApplication>
@@ -142,33 +143,10 @@ public:
}
};
-class GuestInputEventObserverQt : public content::RenderWidgetHost::InputEventObserver
-{
-public:
- GuestInputEventObserverQt(RenderWidgetHostViewQt *rwhv)
- : m_rwhv(rwhv)
- {
- }
- ~GuestInputEventObserverQt() {}
-
- void OnInputEvent(const blink::WebInputEvent&) override {}
- void OnInputEventAck(blink::mojom::InputEventResultSource,
- blink::mojom::InputEventResultState state,
- const blink::WebInputEvent &event) override
- {
- if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel)
- m_rwhv->WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state);
- }
-
-private:
- RenderWidgetHostViewQt *m_rwhv;
-};
-
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget)
: content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget)
, m_taskRunner(base::ThreadTaskRunnerHandle::Get())
, m_gestureProvider(QtGestureProviderConfig(), this)
- , m_guestInputEventObserver(new GuestInputEventObserverQt(this))
, m_frameSinkId(host()->GetFrameSinkId())
, m_delegateClient(new RenderWidgetHostViewQtDelegateClient(this))
{
@@ -217,6 +195,9 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
+ if (host()->delegate())
+ m_touchSelectionControllerClient->resetControls();
+
m_touchSelectionController.reset();
m_touchSelectionControllerClient.reset();
@@ -245,9 +226,34 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC
m_adapterClient = nullptr; });
}
-void RenderWidgetHostViewQt::addGuest(content::RenderWidgetHost *rwh)
+void RenderWidgetHostViewQt::OnInputEventAck(blink::mojom::InputEventResultSource,
+ blink::mojom::InputEventResultState state,
+ const blink::WebInputEvent &event)
{
- rwh->AddInputEventObserver(m_guestInputEventObserver.get());
+ if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel)
+ WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state);
+}
+
+// static
+// Called when new child/guest renderframes created.
+void RenderWidgetHostViewQt::registerInputEventObserver(content::WebContents *webContents,
+ content::RenderFrameHost *rfh)
+{
+ if (static_cast<content::RenderFrameHostImpl *>(rfh)->is_local_root_subframe()) {
+ content::WebContents *parent = webContents->GetOutermostWebContents();
+ QtWebEngineCore::RenderWidgetHostViewQt *mainRwhv =
+ static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(
+ parent->GetRenderWidgetHostView());
+ // Child (originAgentCluster) or guest (pdf) frame that is embedded into the main frame
+ content::RenderWidgetHost *childFrame = rfh->GetRenderWidgetHost();
+ childFrame->AddInputEventObserver(mainRwhv);
+
+ if (webContents->IsInnerWebContentsForGuest()) {
+ // The frame which holds the actual PDF content inside the guest
+ content::RenderWidgetHost *guestFrame = webContents->GetRenderViewHost()->GetWidget();
+ guestFrame->AddInputEventObserver(mainRwhv);
+ }
+ }
}
void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView)
@@ -286,11 +292,6 @@ gfx::NativeView RenderWidgetHostViewQt::GetNativeView()
return gfx::NativeView();
}
-gfx::NativeViewAccessible RenderWidgetHostViewQt::GetNativeViewAccessible()
-{
- return 0;
-}
-
content::WebContentsAccessibility *RenderWidgetHostViewQt::GetWebContentsAccessibility()
{
if (!m_webContentsAccessibility)
@@ -419,7 +420,7 @@ bool RenderWidgetHostViewQt::updateCursorFromResource(ui::mojom::CursorType type
#if defined(USE_AURA)
gfx::Point hotspot;
- if (!aura::GetCursorDataFor(ui::CursorSize::kNormal, type, hotspotDpr, &resourceId, &hotspot))
+ if (!wm::GetCursorDataFor(ui::CursorSize::kNormal, type, hotspotDpr, &resourceId, &hotspot))
return false;
hotX = hotspot.x();
hotY = hotspot.y();
@@ -903,7 +904,9 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even
}
}
-void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event, blink::mojom::InputEventResultState ack_result)
+void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event,
+ blink::mojom::InputEventResultState ack_result,
+ blink::mojom::ScrollResultDataPtr scroll_result_data)
{
// Forward unhandled scroll events back as wheel events
if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollUpdate)
@@ -1003,12 +1006,17 @@ void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation(base::T
m_touchSelectionControllerClient->UpdateClientSelectionBounds(m_selectionStart, m_selectionEnd);
}
- gfx::PointF scrollOffset = metadata.root_scroll_offset.value_or(gfx::PointF());
- gfx::SizeF contentsSize = metadata.root_layer_size;
+ gfx::PointF scrollOffset = gfx::PointF();
+ if (metadata.root_scroll_offset.has_value())
+ scrollOffset = gfx::ScalePoint(metadata.root_scroll_offset.value(),
+ 1 / metadata.device_scale_factor);
std::swap(m_lastScrollOffset, scrollOffset);
- std::swap(m_lastContentsSize, contentsSize);
if (m_adapterClient && scrollOffset != m_lastScrollOffset)
m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset));
+
+ gfx::SizeF contentsSize =
+ gfx::ScaleSize(metadata.root_layer_size, 1 / metadata.device_scale_factor);
+ std::swap(m_lastContentsSize, contentsSize);
if (m_adapterClient && contentsSize != m_lastContentsSize)
m_adapterClient->updateContentsSize(toQt(m_lastContentsSize));
}
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index bdc0efc24..25fd20115 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -12,18 +12,16 @@
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/host/host_frame_sink_client.h"
-#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/web_contents_accessibility.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
-QT_FORWARD_DECLARE_CLASS(QAccessibleInterface)
-
namespace content {
class RenderFrameHost;
class RenderWidgetHostImpl;
+class WebContents;
}
namespace ui {
@@ -33,7 +31,7 @@ class TouchSelectionController;
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateClient;
-class GuestInputEventObserverQt;
+class InputEventObserverQt;
class TouchSelectionControllerClientQt;
class WebContentsAccessibilityQt;
class WebContentsAdapterClient;
@@ -44,6 +42,7 @@ class RenderWidgetHostViewQt
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
, public content::TextInputManager::Observer
, public content::RenderFrameMetadataProvider::Observer
+ , public content::RenderWidgetHost::InputEventObserver
{
public:
RenderWidgetHostViewQt(content::RenderWidgetHost* widget);
@@ -54,14 +53,14 @@ public:
WebContentsAdapterClient *adapterClient() { return m_adapterClient; }
void setAdapterClient(WebContentsAdapterClient *adapterClient);
RenderWidgetHostViewQtDelegateClient *delegateClient() const { return m_delegateClient.get(); }
- void addGuest(content::RenderWidgetHost *);
+ // Overridden from RenderWidgetHostView:
void InitAsChild(gfx::NativeView) override;
void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&, const gfx::Rect&) override;
void SetSize(const gfx::Size& size) override;
void SetBounds(const gfx::Rect&) override;
gfx::NativeView GetNativeView() override;
- gfx::NativeViewAccessible GetNativeViewAccessible() override;
+ gfx::NativeViewAccessible GetNativeViewAccessible() override { return nullptr; }
void Focus() override;
bool HasFocus() override;
bool IsMouseLocked() override;
@@ -94,7 +93,8 @@ public:
void WheelEventAck(const blink::WebMouseWheelEvent &event,
blink::mojom::InputEventResultState ack_result) override;
void GestureEventAck(const blink::WebGestureEvent &event,
- blink::mojom::InputEventResultState ack_result) override;
+ blink::mojom::InputEventResultState ack_result,
+ blink::mojom::ScrollResultDataPtr scroll_result_data) override;
content::MouseWheelPhaseHandler *GetMouseWheelPhaseHandler() override;
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(const cc::RenderFrameMetadata &metadata) override;
void OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata);
@@ -118,6 +118,7 @@ public:
ui::Compositor *GetCompositor() override;
absl::optional<content::DisplayFeature> GetDisplayFeature() override;
void SetDisplayFeatureForTesting(const content::DisplayFeature*) override;
+ content::WebContentsAccessibility *GetWebContentsAccessibility() override;
#if BUILDFLAG(IS_MAC)
void ShowSharePicker(
const std::string &title,
@@ -143,15 +144,20 @@ public:
void OnSelectionBoundsChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
void OnTextSelectionChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
- // Overridden from content::BrowserAccessibilityDelegate
- content::WebContentsAccessibility *GetWebContentsAccessibility() override;
-
// Overridden from content::RenderFrameMetadataProvider::Observer
void OnRenderFrameMetadataChangedAfterActivation(base::TimeTicks activation_time) override;
void OnRenderFrameMetadataChangedBeforeActivation(const cc::RenderFrameMetadata &) override {}
void OnRenderFrameSubmission() override {}
void OnLocalSurfaceIdChanged(const cc::RenderFrameMetadata &) override {}
+ // Overridden from content::RenderWidgetHost::InputEventObserver
+ void OnInputEvent(const blink::WebInputEvent &) override { }
+ void OnInputEventAck(blink::mojom::InputEventResultSource,
+ blink::mojom::InputEventResultState state,
+ const blink::WebInputEvent &event) override;
+
+ static void registerInputEventObserver(content::WebContents *, content::RenderFrameHost *);
+
// Called from RenderWidgetHostViewQtDelegateClient.
Compositor::Id compositorId();
void notifyShown();
@@ -188,7 +194,6 @@ private:
std::unique_ptr<content::CursorManager> m_cursorManager;
ui::FilteredGestureProvider m_gestureProvider;
- std::unique_ptr<GuestInputEventObserverQt> m_guestInputEventObserver;
viz::FrameSinkId m_frameSinkId;
std::unique_ptr<RenderWidgetHostViewQtDelegateClient> m_delegateClient;
diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index 7078b82f8..1b30e9953 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -410,6 +410,7 @@ void RenderWidgetHostViewQtDelegateClient::handlePointerEvent(T *event)
webEvent.movement_x = event->globalPosition().x() - m_previousMousePosition.x();
webEvent.movement_y = event->globalPosition().y() - m_previousMousePosition.y();
+ webEvent.is_raw_movement_event = true;
if (m_rwhv->IsMouseLocked())
QCursor::setPos(m_previousMousePosition);
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 63eea37e2..e6145f7a6 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -5,10 +5,14 @@
#include "render_widget_host_view_qt_delegate_client.h"
-#include <QGuiApplication>
-#include <QMouseEvent>
-#include <QSGImageNode>
-#include <QWindow>
+#include <QtGui/qevent.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qwindow.h>
+#include <QtQuick/qsgimagenode.h>
+
+#if QT_CONFIG(accessibility)
+#include <QtGui/qaccessible.h>
+#endif
namespace QtWebEngineCore {
@@ -29,6 +33,7 @@ RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWid
RenderWidgetHostViewQtDelegateItem::~RenderWidgetHostViewQtDelegateItem()
{
+ releaseVulkanResources();
if (m_widgetDelegate) {
m_widgetDelegate->Unbind();
m_widgetDelegate->Destroy();
@@ -315,8 +320,16 @@ void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const Ite
if (value.window) {
m_windowConnections.append(connect(value.window, &QQuickWindow::beforeRendering,
this, &RenderWidgetHostViewQtDelegateItem::onBeforeRendering, Qt::DirectConnection));
+ m_windowConnections.append(connect(value.window, &QQuickWindow::afterFrameEnd,
+ this, &RenderWidgetHostViewQtDelegateItem::onAfterRendering, Qt::DirectConnection));
m_windowConnections.append(connect(value.window, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
m_windowConnections.append(connect(value.window, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
+#if QT_CONFIG(webengine_vulkan)
+ m_windowConnections.append(
+ connect(value.window, &QQuickWindow::sceneGraphAboutToStop, this,
+ &RenderWidgetHostViewQtDelegateItem::releaseVulkanResources,
+ Qt::DirectConnection));
+#endif
if (!m_isPopup)
m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
}
@@ -336,15 +349,22 @@ QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, U
{
auto comp = compositor();
if (!comp)
- return nullptr;
+ return oldNode;
QQuickWindow *win = QQuickItem::window();
+ QSGImageNode *node = nullptr;
// Delete old node before swapFrame to decrement refcount of
// QImage in software mode.
- delete oldNode;
- QSGImageNode *node = win->createImageNode();
- node->setOwnsTexture(true);
+ if (comp->type() == Compositor::Type::Software)
+ delete oldNode;
+ else
+ node = static_cast<QSGImageNode*>(oldNode);
+
+ if (!node) {
+ node = win->createImageNode();
+ node->setOwnsTexture(true);
+ }
comp->swapFrame();
@@ -352,20 +372,22 @@ QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, U
QSizeF texSizeInDips = QSizeF(texSize) / comp->devicePixelRatio();
node->setRect(QRectF(QPointF(0, 0), texSizeInDips));
- if (comp->type() == Compositor::Type::Software) {
- QImage image = comp->image();
- node->setTexture(win->createTextureFromImage(image));
-#if QT_CONFIG(opengl)
- } else if (comp->type() == Compositor::Type::OpenGL) {
- QQuickWindow::CreateTextureOptions texOpts;
- if (comp->hasAlphaChannel())
- texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
- int texId = comp->textureId();
- node->setTexture(QNativeInterface::QSGOpenGLTexture::fromNative(texId, win, texSize, texOpts));
- node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
-#endif
+ QQuickWindow::CreateTextureOptions texOpts;
+ if (comp->requiresAlphaChannel() || m_clearColor.alpha() < 255)
+ texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
+ else
+ texOpts.setFlag(QQuickWindow::TextureIsOpaque);
+ QSGTexture *texture = comp->texture(win, texOpts);
+ if (texture) {
+ node->setTexture(texture);
+ if (comp->textureIsFlipped())
+ node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
} else {
- Q_UNREACHABLE();
+ if (!oldNode || comp->type() == Compositor::Type::Software) {
+ qDebug("Compositor returned null texture");
+ delete node;
+ return nullptr;
+ }
}
return node;
@@ -374,11 +396,19 @@ QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, U
void RenderWidgetHostViewQtDelegateItem::onBeforeRendering()
{
auto comp = compositor();
- if (!comp || comp->type() != Compositor::Type::OpenGL)
+ if (!comp || comp->type() == Compositor::Type::Software)
return;
comp->waitForTexture();
}
+void RenderWidgetHostViewQtDelegateItem::onAfterRendering()
+{
+ auto comp = compositor();
+ if (!comp || comp->type() != Compositor::Type::NativeBuffer)
+ return;
+ comp->releaseTexture();
+}
+
void RenderWidgetHostViewQtDelegateItem::onWindowPosChanged()
{
m_client->visualPropertiesChanged();
@@ -390,6 +420,17 @@ void RenderWidgetHostViewQtDelegateItem::onHide()
m_client->forwardEvent(&event);
}
+void RenderWidgetHostViewQtDelegateItem::releaseVulkanResources()
+{
+#if QT_CONFIG(webengine_vulkan)
+ auto comp = compositor();
+ if (!comp || comp->type() != Compositor::Type::Vulkan)
+ return;
+
+ comp->releaseVulkanResources(QQuickItem::window());
+#endif
+}
+
void RenderWidgetHostViewQtDelegateItem::adapterClientChanged(WebContentsAdapterClient *client)
{
m_adapterClient = client;
diff --git a/src/core/render_widget_host_view_qt_delegate_item.h b/src/core/render_widget_host_view_qt_delegate_item.h
index e057d37d9..6af81fea3 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.h
+++ b/src/core/render_widget_host_view_qt_delegate_item.h
@@ -100,7 +100,9 @@ protected:
private Q_SLOTS:
void onBeforeRendering();
+ void onAfterRendering();
void onWindowPosChanged();
+ void releaseVulkanResources();
void onHide();
private:
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 5544b08df..80bbabf63 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -3,94 +3,89 @@
#include "renderer/content_renderer_client_qt.h"
-#include "extensions/buildflags/buildflags.h"
-#include "printing/buildflags/buildflags.h"
#include "renderer/content_settings_observer_qt.h"
-#include "base/i18n/rtl.h"
-#include "base/strings/string_split.h"
-#if QT_CONFIG(webengine_spellchecker)
-#include "components/spellcheck/renderer/spellcheck.h"
-#include "components/spellcheck/renderer/spellcheck_provider.h"
-#endif
+#include "renderer/render_configuration.h"
+#include "renderer/render_frame_observer_qt.h"
+#include "renderer/user_resource_controller.h"
+#include "renderer/web_engine_page_render_frame.h"
+#include "web_engine_library_info.h"
+
#include "components/autofill/content/renderer/autofill_agent.h"
#include "components/autofill/content/renderer/autofill_assistant_agent.h"
#include "components/autofill/content/renderer/password_autofill_agent.h"
#include "components/autofill/content/renderer/password_generation_agent.h"
-#include "components/cdm/renderer/external_clear_key_key_system_properties.h"
-#include "components/cdm/renderer/widevine_key_system_properties.h"
+#include "components/cdm/renderer/external_clear_key_key_system_info.h"
+#include "components/cdm/renderer/widevine_key_system_info.h"
#include "components/error_page/common/error.h"
#include "components/error_page/common/localized_error.h"
+#include "components/grit/components_resources.h"
#include "components/network_hints/renderer/web_prescient_networking_impl.h"
-#if QT_CONFIG(webengine_printing_and_pdf)
-#include "components/printing/renderer/print_render_frame_helper.h"
-#endif
#include "components/visitedlink/renderer/visitedlink_reader.h"
#include "components/web_cache/renderer/web_cache_impl.h"
#include "content/public/renderer/render_frame.h"
-#include "content/public/child/child_thread.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
-#include "media/base/key_system_properties.h"
+#include "extensions/buildflags/buildflags.h"
+#include "media/base/key_system_info.h"
+#include "media/cdm/cdm_capability.h"
#include "media/media_buildflags.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "net/base/net_errors.h"
#include "ppapi/buildflags/buildflags.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
+#include "printing/buildflags/buildflags.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/platform/web_url_error.h"
-#include "third_party/blink/public/platform/web_url_request.h"
-#include "third_party/blink/public/web/web_security_policy.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
+#if QT_CONFIG(webengine_spellchecker)
+#include "components/spellcheck/renderer/spellcheck.h"
+#include "components/spellcheck/renderer/spellcheck_provider.h"
+#endif
+
#if QT_CONFIG(webengine_printing_and_pdf)
+#include "renderer/print_web_view_helper_delegate_qt.h"
+
#include "components/pdf/renderer/internal_plugin_renderer_helpers.h"
#include "components/pdf/renderer/pdf_internal_plugin_delegate.h"
-#include "renderer/print_web_view_helper_delegate_qt.h"
+#include "components/printing/renderer/print_render_frame_helper.h"
#endif
-#include "renderer/render_frame_observer_qt.h"
-#include "renderer/web_engine_page_render_frame.h"
-#include "renderer/render_configuration.h"
-#include "renderer/user_resource_controller.h"
#if QT_CONFIG(webengine_webchannel)
#include "renderer/web_channel_ipc_transport.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "common/extensions/extensions_client_qt.h"
-#include "extensions/common/constants.h"
#include "extensions/extensions_renderer_client_qt.h"
+
+#include "extensions/common/constants.h"
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
-#endif //ENABLE_EXTENSIONS
+#include "services/service_manager/public/cpp/binder_registry.h"
+#include "third_party/blink/public/web/web_security_policy.h"
+#endif // ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
#include "content/renderer/render_frame_impl.h"
#include "plugins/loadable_plugin_placeholder_qt.h"
#endif // ENABLE_PLUGINS
-#include "services/service_manager/public/cpp/binder_registry.h"
-#include "services/service_manager/public/cpp/connector.h"
-
-#include "components/grit/components_resources.h"
-
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "base/feature_list.h"
#include "content/public/renderer/key_system_support.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
#include "third_party/widevine/cdm/buildflags.h"
+#if BUILDFLAG(ENABLE_WIDEVINE)
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#endif
+#endif
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
#include "chrome/renderer/media/webrtc_logging_agent_impl.h"
#endif
-#include "web_engine_library_info.h"
-
namespace QtWebEngineCore {
ContentRendererClientQt::ContentRendererClientQt()
@@ -135,14 +130,17 @@ void ContentRendererClientQt::RenderThreadStarted()
void ContentRendererClientQt::ExposeInterfacesToBrowser(mojo::BinderMap* binders)
{
- binders->Add(m_visitedLinkReader->GetBindCallback(), base::SequencedTaskRunnerHandle::Get());
+ binders->Add<visitedlink::mojom::VisitedLinkNotificationSink>(
+ m_visitedLinkReader->GetBindCallback(), base::SequencedTaskRunnerHandle::Get());
- binders->Add(base::BindRepeating(&web_cache::WebCacheImpl::BindReceiver,
- base::Unretained(m_webCacheImpl.get())),
- base::SequencedTaskRunnerHandle::Get());
+ binders->Add<web_cache::mojom::WebCache>(
+ base::BindRepeating(&web_cache::WebCacheImpl::BindReceiver,
+ base::Unretained(m_webCacheImpl.get())),
+ base::SequencedTaskRunnerHandle::Get());
#if QT_CONFIG(webengine_spellchecker)
- binders->Add(base::BindRepeating(
+ binders->Add<spellcheck::mojom::SpellChecker>(
+ base::BindRepeating(
[](ContentRendererClientQt *client,
mojo::PendingReceiver<spellcheck::mojom::SpellChecker> receiver) {
if (!client->m_spellCheck)
@@ -153,7 +151,8 @@ void ContentRendererClientQt::ExposeInterfacesToBrowser(mojo::BinderMap* binders
#endif
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
- binders->Add(base::BindRepeating(
+ binders->Add<chrome::mojom::WebRtcLoggingAgent>(
+ base::BindRepeating(
[](ContentRendererClientQt *client,
mojo::PendingReceiver<chrome::mojom::WebRtcLoggingAgent> receiver) {
client->GetWebRtcLoggingAgent()->AddReceiver(std::move(receiver));
@@ -187,9 +186,10 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
blink::AssociatedInterfaceRegistry *associated_interfaces = render_frame_observer->associatedInterfaces();
#if BUILDFLAG(ENABLE_EXTENSIONS)
- associated_interfaces->AddInterface(base::BindRepeating(
- &extensions::MimeHandlerViewContainerManager::BindReceiver,
- render_frame->GetRoutingID()));
+ associated_interfaces->AddInterface<extensions::mojom::MimeHandlerViewContainerManager>(
+ base::BindRepeating(
+ &extensions::MimeHandlerViewContainerManager::BindReceiver,
+ render_frame->GetRoutingID()));
auto registry = std::make_unique<service_manager::BinderRegistry>();
ExtensionsRendererClientQt::GetInstance()->RenderFrameCreated(render_frame, render_frame_observer->registry());
@@ -207,6 +207,16 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
autofill_assistant_agent, associated_interfaces);
}
+void ContentRendererClientQt::WebViewCreated(blink::WebView *web_view,
+ bool was_created_by_renderer,
+ const url::Origin *outermost_origin)
+{
+ Q_UNUSED(was_created_by_renderer);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ExtensionsRendererClientQt::GetInstance()->WebViewCreated(web_view, outermost_origin);
+#endif
+}
+
void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame *render_frame)
{
#if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -293,7 +303,7 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
if (template_html.empty())
NOTREACHED() << "unable to load template. ID: " << resourceId;
else // "t" is the id of the templates root node.
- *errorHtml = webui::GetTemplatesHtml(template_html, &errorPageState.strings, "t");
+ *errorHtml = webui::GetTemplatesHtml(template_html, errorPageState.strings, "t");
}
}
@@ -405,7 +415,7 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
#if BUILDFLAG(ENABLE_EXTENSIONS)
if (!ExtensionsRendererClientQt::GetInstance()->OverrideCreatePlugin(render_frame, params))
return false;
-#endif //ENABLE_EXTENSIONS
+#endif // ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
content::WebPluginInfo info;
@@ -432,7 +442,7 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
return true;
}
*plugin = render_frame->CreatePlugin(info, params);
-#endif // BUILDFLAG(ENABLE_PLUGINS)
+#endif // BUILDFLAG(ENABLE_PLUGINS)
return true;
}
@@ -467,7 +477,7 @@ static const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"
// External Clear Key (used for testing).
static void AddExternalClearKey(const media::mojom::KeySystemCapabilityPtr &capability,
- media::KeySystemPropertiesVector *key_systems)
+ media::KeySystemInfoVector *key_systems)
{
Q_UNUSED(capability);
if (!base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting)) {
@@ -480,7 +490,7 @@ static void AddExternalClearKey(const media::mojom::KeySystemCapabilityPtr &capa
}
#if BUILDFLAG(ENABLE_WIDEVINE)
-media::SupportedCodecs GetVP9Codecs(const std::vector<media::VideoCodecProfile> &profiles)
+media::SupportedCodecs GetVP9Codecs(const base::flat_set<media::VideoCodecProfile> &profiles)
{
if (profiles.empty()) {
// If no profiles are specified, then all are supported.
@@ -507,7 +517,7 @@ media::SupportedCodecs GetVP9Codecs(const std::vector<media::VideoCodecProfile>
}
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
-SupportedCodecs GetHevcCodecs(const std::vector<media::VideoCodecProfile> &profiles)
+media::SupportedCodecs GetHevcCodecs(const base::flat_set<media::VideoCodecProfile> &profiles)
{
// If no profiles are specified, then all are supported.
if (profiles.empty()) {
@@ -568,7 +578,7 @@ static media::SupportedCodecs GetSupportedCodecs(const media::CdmCapability& cap
supported_codecs |= media::EME_CODEC_VP8;
break;
case media::VideoCodec::kVP9:
- supported_codecs |= GetVP9Codecs(codec.second);
+ supported_codecs |= GetVP9Codecs(codec.second.supported_profiles);
break;
case media::VideoCodec::kAV1:
supported_codecs |= media::EME_CODEC_AV1;
@@ -580,7 +590,7 @@ static media::SupportedCodecs GetSupportedCodecs(const media::CdmCapability& cap
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
case media::VideoCodec::kHEVC:
- supported_codecs |= GetHevcCodecs(codec.second);
+ supported_codecs |= GetHevcCodecs(codec.second.supported_profiles);
break;
#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
default:
@@ -593,13 +603,15 @@ static media::SupportedCodecs GetSupportedCodecs(const media::CdmCapability& cap
}
static void AddWidevine(const media::mojom::KeySystemCapabilityPtr &capability,
- media::KeySystemPropertiesVector *key_systems)
+ media::KeySystemInfoVector *key_systems)
{
// Codecs and encryption schemes.
media::SupportedCodecs codecs = media::EME_CODEC_NONE;
media::SupportedCodecs hw_secure_codecs = media::EME_CODEC_NONE;
base::flat_set<media::EncryptionScheme> encryption_schemes;
base::flat_set<media::EncryptionScheme> hw_secure_encryption_schemes;
+ base::flat_set<media::CdmSessionType> session_types;
+ base::flat_set<media::CdmSessionType> hw_secure_session_types;
if (capability->sw_secure_capability) {
codecs = GetSupportedCodecs(capability->sw_secure_capability.value(), /*is_secure=*/false);
encryption_schemes = capability->sw_secure_capability->encryption_schemes;
@@ -619,7 +631,7 @@ static void AddWidevine(const media::mojom::KeySystemCapabilityPtr &capability,
}
// Robustness.
- using Robustness = cdm::WidevineKeySystemProperties::Robustness;
+ using Robustness = cdm::WidevineKeySystemInfo::Robustness;
auto max_audio_robustness = Robustness::SW_SECURE_CRYPTO;
auto max_video_robustness = Robustness::SW_SECURE_DECODE;
@@ -628,16 +640,16 @@ static void AddWidevine(const media::mojom::KeySystemCapabilityPtr &capability,
max_video_robustness = Robustness::HW_SECURE_ALL;
}
- auto persistent_license_support = media::EmeSessionTypeSupport::NOT_SUPPORTED;
-
// Others.
auto persistent_state_support = media::EmeFeatureSupport::REQUESTABLE;
auto distinctive_identifier_support = media::EmeFeatureSupport::NOT_SUPPORTED;
- key_systems->emplace_back(new cdm::WidevineKeySystemProperties(
- codecs, encryption_schemes, hw_secure_codecs,
- hw_secure_encryption_schemes, max_audio_robustness, max_video_robustness,
- persistent_license_support, persistent_state_support,
+ key_systems->emplace_back(new cdm::WidevineKeySystemInfo(
+ codecs, std::move(encryption_schemes), std::move(session_types),
+ hw_secure_codecs, std::move(hw_secure_encryption_schemes),
+ std::move(hw_secure_session_types),
+ max_audio_robustness, max_video_robustness,
+ persistent_state_support,
distinctive_identifier_support));
}
#endif // BUILDFLAG(ENABLE_WIDEVINE)
@@ -646,21 +658,23 @@ static void AddWidevine(const media::mojom::KeySystemCapabilityPtr &capability,
void OnKeySystemSupportUpdated(media::GetSupportedKeySystemsCB cb,
content::KeySystemCapabilityPtrMap key_system_capabilities)
{
- media::KeySystemPropertiesVector key_systems;
+ media::KeySystemInfoVector key_systems;
for (const auto &entry : key_system_capabilities) {
const auto &key_system = entry.first;
const auto &capability = entry.second;
+#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if BUILDFLAG(ENABLE_WIDEVINE)
if (key_system == kWidevineKeySystem) {
AddWidevine(capability, &key_systems);
continue;
}
-#endif // BUILDFLAG(ENABLE_WIDEVINE)
+#endif // BUILDFLAG(ENABLE_WIDEVINE)
if (key_system == kExternalClearKeyKeySystem) {
AddExternalClearKey(capability, &key_systems);
continue;
}
+#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
DLOG(ERROR) << "Unrecognized key system: " << key_system;
}
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index 6c4cdf0ee..b2231f00a 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -5,7 +5,6 @@
#include "qtwebenginecoreglobal_p.h"
#include "content/public/renderer/content_renderer_client.h"
-#include "components/spellcheck/spellcheck_buildflags.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/local_interface_provider.h"
@@ -52,6 +51,9 @@ public:
void RenderThreadStarted() override;
void ExposeInterfacesToBrowser(mojo::BinderMap* binders) override;
void RenderFrameCreated(content::RenderFrame *render_frame) override;
+ void WebViewCreated(blink::WebView *web_view,
+ bool was_created_by_renderer,
+ const url::Origin *outermost_origin) override;
void PrepareErrorPage(content::RenderFrame *render_frame,
const blink::WebURLError &error,
@@ -93,7 +95,7 @@ public:
private:
-#if BUILDFLAG(ENABLE_SPELLCHECK)
+#if QT_CONFIG(webengine_spellchecker)
void InitSpellCheck();
#endif
// service_manager::LocalInterfaceProvider:
diff --git a/src/core/renderer/content_settings_observer_qt.cpp b/src/core/renderer/content_settings_observer_qt.cpp
index 3a45f28e6..3e3c159f5 100644
--- a/src/core/renderer/content_settings_observer_qt.cpp
+++ b/src/core/renderer/content_settings_observer_qt.cpp
@@ -10,15 +10,12 @@
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/platform/web_security_origin.h"
-#include "third_party/blink/public/web/web_plugin_document.h"
+#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "url/origin.h"
#include "common/qt_messages.h"
-using blink::WebSecurityOrigin;
-using blink::WebString;
-
namespace {
bool IsUniqueFrame(blink::WebFrame *frame)
diff --git a/src/core/renderer/content_settings_observer_qt.h b/src/core/renderer/content_settings_observer_qt.h
index 89dcbad08..415d0b6b7 100644
--- a/src/core/renderer/content_settings_observer_qt.h
+++ b/src/core/renderer/content_settings_observer_qt.h
@@ -14,10 +14,6 @@
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "url/gurl.h"
-namespace blink {
-class WebSecurityOrigin;
-}
-
namespace QtWebEngineCore {
// Handles blocking content per content settings for each RenderFrame.
@@ -57,4 +53,4 @@ private:
} // namespace QtWebEngineCore
-#endif // RENDERER_CONTENT_SETTINGS_OBSERVER_QT_H
+#endif // CONTENT_SETTINGS_OBSERVER_QT_H
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
index b29892b68..b36ed9e8b 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
@@ -16,6 +16,7 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/stl_util.h"
+#include "base/types/optional_util.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
@@ -26,6 +27,7 @@
#include "extensions/common/switches.h"
#include "extensions/renderer/dispatcher.h"
#include "extensions/renderer/extension_frame_helper.h"
+#include "extensions/renderer/extension_web_view_helper.h"
#include "extensions/renderer/extensions_render_frame_observer.h"
#include "extensions/renderer/renderer_extension_registry.h"
#include "extensions/renderer/script_context.h"
@@ -114,6 +116,11 @@ void ExtensionsRendererClientQt::RenderThreadStarted()
thread->AddObserver(extension_dispatcher_.get());
}
+void ExtensionsRendererClientQt::WebViewCreated(blink::WebView *web_view, const url::Origin *outermost_origin)
+{
+ new extensions::ExtensionWebViewHelper(web_view, outermost_origin);
+}
+
void ExtensionsRendererClientQt::RenderFrameCreated(content::RenderFrame *render_frame,
service_manager::BinderRegistry *registry)
{
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.h b/src/core/renderer/extensions/extensions_renderer_client_qt.h
index f9cac443c..163819cbc 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.h
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.h
@@ -16,6 +16,7 @@ namespace blink {
class WebLocalFrame;
struct WebPluginParams;
class WebURL;
+class WebView;
}
namespace content {
@@ -55,6 +56,8 @@ public:
// Match ContentRendererClientQt's method names...
void RenderThreadStarted();
+ void WebViewCreated(blink::WebView *web_view,
+ const url::Origin *outermost_origin);
void RenderFrameCreated(content::RenderFrame *, service_manager::BinderRegistry *);
bool OverrideCreatePlugin(content::RenderFrame *render_frame,
const blink::WebPluginParams &params);
diff --git a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
index 70fd791fd..06fd4f71f 100644
--- a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
+++ b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
@@ -40,11 +40,11 @@ LoadablePluginPlaceholderQt* LoadablePluginPlaceholderQt::CreateLoadableMissingP
{
std::string template_html(ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_BLOCKED_PLUGIN_HTML));
- base::DictionaryValue values;
- values.SetString("name", "");
- values.SetString("message", l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
+ base::Value::Dict values;
+ values.Set("name", "");
+ values.Set("message", l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
- const std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
+ const std::string html_data = webui::GetI18nTemplateHtml(template_html, std::move(values));
// Will destroy itself when its WebViewPlugin is going away.
return new LoadablePluginPlaceholderQt(render_frame, params, html_data, params.mime_type.Utf16());
diff --git a/src/core/renderer/print_web_view_helper_delegate_qt.cpp b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
index 9891c654d..f77b6fbbc 100644
--- a/src/core/renderer/print_web_view_helper_delegate_qt.cpp
+++ b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
@@ -5,23 +5,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.Chromium file.
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_view.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/constants.h"
-#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "url/origin.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/common/webui_url_constants.h"
#include "extensions/common/constants.h"
+#include "third_party/blink/public/web/web_document.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#include "print_web_view_helper_delegate_qt.h"
#include "web_engine_library_info.h"
namespace QtWebEngineCore {
+
PrintWebViewHelperDelegateQt::~PrintWebViewHelperDelegateQt() {}
bool IsPdfExtensionOrigin(const url::Origin& origin)
@@ -66,7 +66,7 @@ bool PrintWebViewHelperDelegateQt::OverridePrint(blink::WebLocalFrame *frame)
return false;
}
-}
+} // namespace QtWebEngineCore
namespace printing {
// std::string PrintingContextDelegate::GetAppLocale()
diff --git a/src/core/renderer/print_web_view_helper_delegate_qt.h b/src/core/renderer/print_web_view_helper_delegate_qt.h
index 0cca02022..5c7dd2431 100644
--- a/src/core/renderer/print_web_view_helper_delegate_qt.h
+++ b/src/core/renderer/print_web_view_helper_delegate_qt.h
@@ -10,8 +10,8 @@
#include "components/printing/renderer/print_render_frame_helper.h"
-namespace content {
-class RenderView;
+namespace blink {
+class WebLocalFrame;
}
namespace QtWebEngineCore {
@@ -26,7 +26,8 @@ public:
bool IsPrintPreviewEnabled() override;
bool OverridePrint(blink::WebLocalFrame *frame) override;
-}; // class PrintWebViewHelperDelegateQt
-}
+};
+
+} // namespace QtWebEngineCore
#endif // PRINT_WEB_VIEW_HELPER_DELEGATE_QT_H
diff --git a/src/core/renderer/render_configuration.cpp b/src/core/renderer/render_configuration.cpp
index 3bf8186dc..7b35cdd48 100644
--- a/src/core/renderer/render_configuration.cpp
+++ b/src/core/renderer/render_configuration.cpp
@@ -7,7 +7,6 @@
// found in the LICENSE file.
#include "renderer/render_configuration.h"
-#include "user_resource_controller.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
namespace QtWebEngineCore {
@@ -17,7 +16,7 @@ bool RenderConfiguration::m_isIncognitoProcess = false;
void RenderConfiguration::RegisterMojoInterfaces(
blink::AssociatedInterfaceRegistry *associated_interfaces)
{
- associated_interfaces->AddInterface(
+ associated_interfaces->AddInterface<qtwebengine::mojom::RendererConfiguration>(
base::BindRepeating(&RenderConfiguration::OnRendererConfigurationAssociatedRequest,
base::Unretained(this)));
}
diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp
index b8163f6eb..e6489eefb 100644
--- a/src/core/renderer/render_frame_observer_qt.cpp
+++ b/src/core/renderer/render_frame_observer_qt.cpp
@@ -10,6 +10,7 @@
#include "components/web_cache/renderer/web_cache_impl.h"
#include "content/public/renderer/render_frame.h"
+#include "third_party/blink/public/web/web_document_loader.h"
#if QT_CONFIG(webengine_pepper_plugins)
#include "base/memory/ptr_util.h"
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp
index 1588f26ec..ce942e0c8 100644
--- a/src/core/renderer/user_resource_controller.cpp
+++ b/src/core/renderer/user_resource_controller.cpp
@@ -4,19 +4,13 @@
#include "user_resource_controller.h"
#include "base/memory/weak_ptr.h"
-#include "base/pending_task.h"
#include "base/strings/pattern.h"
#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_frame_observer.h"
#include "extensions/common/url_pattern.h"
-#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_script_source.h"
-#include "third_party/blink/public/web/web_view.h"
-#include "v8/include/v8.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "qtwebengine/userscript/user_script_data.h"
@@ -188,7 +182,7 @@ UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(
, m_binding(this)
, m_userResourceController(controller)
{
- render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+ render_frame->GetAssociatedInterfaceRegistry()->AddInterface<qtwebengine::mojom::UserResourceControllerRenderFrame>(
base::BindRepeating(&UserResourceController::RenderFrameObserverHelper::BindReceiver,
base::Unretained(this)));
}
@@ -295,10 +289,11 @@ void UserResourceController::renderFrameDestroyed(content::RenderFrame *renderFr
FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(renderFrame);
if (it == m_frameUserScriptMap.end()) // ASSERT maybe?
return;
- for (uint64_t id : std::as_const(it.value())) {
- m_scripts.remove(id);
+ if (renderFrame->IsMainFrame()) {
+ for (uint64_t id : std::as_const(it.value()))
+ m_scripts.remove(id);
}
- m_frameUserScriptMap.remove(renderFrame);
+ m_frameUserScriptMap.erase(it);
}
void UserResourceController::addScriptForFrame(const QtWebEngineCore::UserScriptData &script,
@@ -306,11 +301,12 @@ void UserResourceController::addScriptForFrame(const QtWebEngineCore::UserScript
{
FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame);
if (it == m_frameUserScriptMap.end())
- it = m_frameUserScriptMap.insert(frame, UserScriptSet());
+ it = m_frameUserScriptMap.insert(frame, UserScriptList());
if (!(*it).contains(script.scriptId))
(*it).append(script.scriptId);
- m_scripts.insert(script.scriptId, script);
+ if (!frame || frame->IsMainFrame())
+ m_scripts.insert(script.scriptId, script);
}
void UserResourceController::removeScriptForFrame(const QtWebEngineCore::UserScriptData &script,
@@ -321,7 +317,8 @@ void UserResourceController::removeScriptForFrame(const QtWebEngineCore::UserScr
return;
(*it).removeOne(script.scriptId);
- m_scripts.remove(script.scriptId);
+ if (!frame || frame->IsMainFrame())
+ m_scripts.remove(script.scriptId);
}
void UserResourceController::clearScriptsForFrame(content::RenderFrame *frame)
@@ -329,8 +326,10 @@ void UserResourceController::clearScriptsForFrame(content::RenderFrame *frame)
FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame);
if (it == m_frameUserScriptMap.end())
return;
- for (uint64_t id : std::as_const(it.value()))
- m_scripts.remove(id);
+ if (!frame || frame->IsMainFrame()) {
+ for (uint64_t id : std::as_const(it.value()))
+ m_scripts.remove(id);
+ }
m_frameUserScriptMap.remove(frame);
}
@@ -353,7 +352,7 @@ void UserResourceController::ClearScripts()
void UserResourceController::RegisterMojoInterfaces(
blink::AssociatedInterfaceRegistry *associated_interfaces)
{
- associated_interfaces->AddInterface(
+ associated_interfaces->AddInterface<qtwebengine::mojom::UserResourceController>(
base::BindRepeating(&UserResourceController::BindReceiver, base::Unretained(this)));
}
diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h
index ba2ca000d..a5dab73f1 100644
--- a/src/core/renderer/user_resource_controller.h
+++ b/src/core/renderer/user_resource_controller.h
@@ -10,7 +10,7 @@
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include <QtCore/QHash>
-#include <QtCore/QSet>
+#include <QtCore/QList>
namespace blink {
class WebLocalFrame;
@@ -18,7 +18,6 @@ class WebLocalFrame;
namespace content {
class RenderFrame;
-class RenderView;
}
namespace QtWebEngineCore {
@@ -47,7 +46,6 @@ private:
void UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override;
class RenderFrameObserverHelper;
- class RenderViewObserverHelper;
void AddScript(const QtWebEngineCore::UserScriptData &data) override;
void RemoveScript(const QtWebEngineCore::UserScriptData &data) override;
@@ -55,12 +53,13 @@ private:
void runScripts(QtWebEngineCore::UserScriptData::InjectionPoint, blink::WebLocalFrame *);
- typedef QList<uint64_t> UserScriptSet;
- typedef QHash<const content::RenderFrame *, UserScriptSet> FrameUserScriptMap;
+ typedef QList<uint64_t> UserScriptList;
+ typedef QHash<const content::RenderFrame *, UserScriptList> FrameUserScriptMap;
FrameUserScriptMap m_frameUserScriptMap;
QHash<uint64_t, QtWebEngineCore::UserScriptData> m_scripts;
mojo::AssociatedReceiver<qtwebengine::mojom::UserResourceController> m_binding;
friend class RenderFrameObserverHelper;
};
-} // namespace
+
+} // namespace QtWebEngineCore
#endif // USER_RESOURCE_CONTROLLER_H
diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
index 584c509a1..04a4ce705 100644
--- a/src/core/renderer/web_channel_ipc_transport.cpp
+++ b/src/core/renderer/web_channel_ipc_transport.cpp
@@ -16,11 +16,8 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "v8/include/v8.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "qtwebengine/browser/qtwebchannel.mojom.h"
-#include <QJsonDocument>
-
namespace QtWebEngineCore {
class WebChannelTransport : public gin::Wrappable<WebChannelTransport>
@@ -142,7 +139,7 @@ WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame
, m_worldInitialized(false)
, m_binding(this)
{
- renderFrame->GetAssociatedInterfaceRegistry()->AddInterface(
+ renderFrame->GetAssociatedInterfaceRegistry()->AddInterface<qtwebchannel::mojom::WebChannelTransportRender>(
base::BindRepeating(&WebChannelIPCTransport::BindReceiver, base::Unretained(this)));
}
diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h
index ded5ef26c..95aa39850 100644
--- a/src/core/renderer/web_channel_ipc_transport.h
+++ b/src/core/renderer/web_channel_ipc_transport.h
@@ -5,8 +5,8 @@
#define WEB_CHANNEL_IPC_TRANSPORT_H
#include "content/public/renderer/render_frame_observer.h"
-#include "services/service_manager/public/cpp/binder_registry.h"
-#include "mojo/public/cpp/bindings/associated_receiver_set.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "qtwebengine/browser/qtwebchannel.mojom.h"
diff --git a/src/core/renderer/web_engine_page_render_frame.cpp b/src/core/renderer/web_engine_page_render_frame.cpp
index 87c2cee7f..1e7ac62fc 100644
--- a/src/core/renderer/web_engine_page_render_frame.cpp
+++ b/src/core/renderer/web_engine_page_render_frame.cpp
@@ -3,14 +3,10 @@
#include "renderer/web_engine_page_render_frame.h"
#include "content/public/renderer/render_frame.h"
-#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
-#include "third_party/blink/public/web/web_document.h"
-#include "third_party/blink/public/web/web_element.h"
-#include "third_party/blink/public/web/web_frame.h"
+#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_frame_content_dumper.h"
-#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
@@ -19,7 +15,7 @@ namespace QtWebEngineCore {
WebEnginePageRenderFrame::WebEnginePageRenderFrame(content::RenderFrame *render_frame)
: content::RenderFrameObserver(render_frame), m_binding(this), m_ready(false)
{
- render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+ render_frame->GetAssociatedInterfaceRegistry()->AddInterface<qtwebenginepage::mojom::WebEnginePageRenderFrame>(
base::BindRepeating(&WebEnginePageRenderFrame::BindReceiver, base::Unretained(this)));
}
diff --git a/src/core/renderer/web_engine_page_render_frame.h b/src/core/renderer/web_engine_page_render_frame.h
index 2d47d46f3..7d0e25267 100644
--- a/src/core/renderer/web_engine_page_render_frame.h
+++ b/src/core/renderer/web_engine_page_render_frame.h
@@ -36,6 +36,6 @@ private:
mojo::AssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame> m_binding;
bool m_ready;
};
-} // namespace
+} // namespace QtWebEngineCore
#endif // WEB_ENGINE_PAGE_RENDER_FRAME_H
diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp
index 98a640695..f2a00fc72 100644
--- a/src/core/renderer_host/user_resource_controller_host.cpp
+++ b/src/core/renderer_host/user_resource_controller_host.cpp
@@ -117,7 +117,7 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont
m_perContentsScripts.insert(contents, currentScripts);
}
}
- GetUserResourceControllerRenderFrame(contents->GetMainFrame())
+ GetUserResourceControllerRenderFrame(contents->GetPrimaryMainFrame())
->AddScript(script.data());
}
}
@@ -140,7 +140,7 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC
QList<UserScript>::iterator it = std::find(list.begin(), list.end(), script);
if (it == list.end())
return false;
- GetUserResourceControllerRenderFrame(contents->GetMainFrame())
+ GetUserResourceControllerRenderFrame(contents->GetPrimaryMainFrame())
->RemoveScript((*it).data());
list.erase(it);
}
@@ -159,7 +159,7 @@ void UserResourceControllerHost::clearAllScripts(WebContentsAdapter *adapter)
m_perContentsScripts.remove(contents);
mojo::AssociatedRemote<qtwebengine::mojom::UserResourceControllerRenderFrame>
userResourceController;
- GetUserResourceControllerRenderFrame(contents->GetMainFrame())
+ GetUserResourceControllerRenderFrame(contents->GetPrimaryMainFrame())
->ClearScripts();
}
}
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
index d234fb141..0824ed56d 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
@@ -30,10 +30,9 @@ WebChannelIPCTransportHost::WebChannelIPCTransportHost(content::WebContents *con
, m_worldId(worldId)
, m_receiver(contents, this)
{
- contents->ForEachFrame(base::BindRepeating([](WebChannelIPCTransportHost *that, uint32_t worldId, content::RenderFrameHost *frame) {
- that->setWorldId(frame, worldId);
- },
- base::Unretained(this), worldId));
+ contents->ForEachRenderFrameHost([this, worldId](content::RenderFrameHost *frame) {
+ setWorldId(frame, worldId);
+ });
}
WebChannelIPCTransportHost::~WebChannelIPCTransportHost()
@@ -50,7 +49,7 @@ void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message)
{
QJsonDocument doc(message);
QByteArray json = doc.toJson(QJsonDocument::Compact);
- content::RenderFrameHost *frame = web_contents()->GetMainFrame();
+ content::RenderFrameHost *frame = web_contents()->GetPrimaryMainFrame();
qCDebug(log).nospace() << "sending webchannel message to " << frame << ": " << doc;
GetWebChannelIPCTransportRemote(frame)->DispatchWebChannelMessage(
std::vector<uint8_t>(json.begin(), json.end()), m_worldId);
@@ -60,10 +59,9 @@ void WebChannelIPCTransportHost::setWorldId(uint32_t worldId)
{
if (m_worldId == worldId)
return;
- web_contents()->ForEachFrame(base::BindRepeating([](WebChannelIPCTransportHost *that, uint32_t worldId, content::RenderFrameHost *frame) {
- that->setWorldId(frame, worldId);
- },
- base::Unretained(this), worldId));
+ web_contents()->ForEachRenderFrameHost([this, worldId](content::RenderFrameHost *frame) {
+ setWorldId(frame, worldId);
+ });
m_worldId = worldId;
}
@@ -77,16 +75,16 @@ void WebChannelIPCTransportHost::setWorldId(content::RenderFrameHost *frame, uin
void WebChannelIPCTransportHost::resetWorldId()
{
- web_contents()->ForEachFrame(base::BindRepeating([](WebChannelIPCTransportHost *that, content::RenderFrameHost *frame) {
+ web_contents()->ForEachRenderFrameHost([this] (content::RenderFrameHost *frame) {
if (!frame->IsRenderFrameLive())
return;
- that->GetWebChannelIPCTransportRemote(frame)->ResetWorldId();
- }, this));
+ GetWebChannelIPCTransportRemote(frame)->ResetWorldId();
+ });
}
void WebChannelIPCTransportHost::DispatchWebChannelMessage(const std::vector<uint8_t> &json)
{
- content::RenderFrameHost *frame = web_contents()->GetMainFrame();
+ content::RenderFrameHost *frame = web_contents()->GetPrimaryMainFrame();
if (m_receiver.GetCurrentTargetFrame() != frame) {
return;
diff --git a/src/core/renderer_host/web_engine_page_host.cpp b/src/core/renderer_host/web_engine_page_host.cpp
index 1b9b9863a..ea9b363ea 100644
--- a/src/core/renderer_host/web_engine_page_host.cpp
+++ b/src/core/renderer_host/web_engine_page_host.cpp
@@ -21,7 +21,7 @@ WebEnginePageHost::WebEnginePageHost(content::WebContents *webContents,
void WebEnginePageHost::FetchDocumentMarkup(uint64_t requestId)
{
- auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetPrimaryMainFrame());
remote->FetchDocumentMarkup(
requestId,
base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentMarkup, base::Unretained(this)));
@@ -29,7 +29,7 @@ void WebEnginePageHost::FetchDocumentMarkup(uint64_t requestId)
void WebEnginePageHost::FetchDocumentInnerText(uint64_t requestId)
{
- auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetPrimaryMainFrame());
remote->FetchDocumentInnerText(requestId,
base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentInnerText,
base::Unretained(this)));
@@ -53,7 +53,7 @@ void WebEnginePageHost::RenderFrameDeleted(content::RenderFrameHost *render_fram
void WebEnginePageHost::SetBackgroundColor(uint32_t color)
{
- auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetPrimaryMainFrame());
remote->SetBackgroundColor(color);
}
diff --git a/src/core/sandbox_win.cpp b/src/core/sandbox_win.cpp
index 81fecc62c..bc70bced7 100644
--- a/src/core/sandbox_win.cpp
+++ b/src/core/sandbox_win.cpp
@@ -11,7 +11,7 @@
#endif
namespace QtWebEngineSandbox {
-// A duplicate of the function by same name in startup_helper_win.cc
+// A duplicate of the function by same name in sandbox_helper_win.cc
static void InitializeSandboxInfo(sandbox::SandboxInterfaceInfo *info)
{
info->broker_services = sandbox::SandboxFactory::GetBrokerServices();
@@ -19,7 +19,7 @@ static void InitializeSandboxInfo(sandbox::SandboxInterfaceInfo *info)
info->target_services = sandbox::SandboxFactory::GetTargetServices();
} else {
// Ensure the proper mitigations are enforced for the browser process.
- sandbox::ApplyProcessMitigationsToCurrentProcess(
+ info->broker_services->RatchetDownSecurityMitigations(
sandbox::MITIGATION_DEP | sandbox::MITIGATION_DEP_NO_ATL_THUNK |
sandbox::MITIGATION_HARDEN_TOKEN_IL_POLICY);
// Note: these mitigations are "post-startup". Some mitigations that need
diff --git a/src/core/select_file_dialog_factory_qt.cpp b/src/core/select_file_dialog_factory_qt.cpp
index 1bf20918d..9da27a4cf 100644
--- a/src/core/select_file_dialog_factory_qt.cpp
+++ b/src/core/select_file_dialog_factory_qt.cpp
@@ -65,7 +65,8 @@ public:
void SelectFileImpl(Type type, const std::u16string &title, const base::FilePath &default_path,
const FileTypeInfo *file_types, int file_type_index,
const base::FilePath::StringType &default_extension,
- gfx::NativeWindow owning_window, void *params) override;
+ gfx::NativeWindow owning_window, void *params, const GURL *) override;
+
bool HasMultipleFileTypeChoicesImpl() override;
private:
@@ -105,13 +106,14 @@ void SelectFileDialogQt::SelectFileImpl(Type type, const std::u16string &title,
const base::FilePath &default_path,
const FileTypeInfo *file_types, int file_type_index,
const base::FilePath::StringType &default_extension,
- gfx::NativeWindow owning_window, void *params)
+ gfx::NativeWindow owning_window, void *params, const GURL *caller)
{
Q_UNUSED(title);
Q_UNUSED(file_type_index);
Q_UNUSED(default_extension);
Q_UNUSED(owning_window);
Q_UNUSED(params);
+ Q_UNUSED(caller);
QStringList acceptedSuffixes;
if (file_types) {
diff --git a/src/core/tools/CMakeLists.txt b/src/core/tools/CMakeLists.txt
index 5f14c6ebd..9029b60a1 100644
--- a/src/core/tools/CMakeLists.txt
+++ b/src/core/tools/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
##
# WEBENGINECORE DICT CONVERT TOOL
diff --git a/src/core/user_script.cpp b/src/core/user_script.cpp
index 47c4fd528..c33fb9081 100644
--- a/src/core/user_script.cpp
+++ b/src/core/user_script.cpp
@@ -20,7 +20,7 @@ bool GetDeclarationValue(const base::StringPiece& line,
std::string temp(line.data() + index + prefix.length(),
line.length() - index - prefix.length());
- if (temp.empty() || !base::IsUnicodeWhitespace(temp[0]))
+ if (temp.empty() || !base::IsWhitespace(temp[0]))
return false;
base::TrimWhitespaceASCII(temp, base::TRIM_ALL, value);
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index f6901a071..37f3b13ac 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -8,6 +8,7 @@
#include "web_contents_adapter.h"
#include "autofill_client_qt.h"
+#include "content_browser_client_qt.h"
#include "devtools_frontend_qt.h"
#include "download_manager_delegate_qt.h"
#include "favicon_driver_qt.h"
@@ -27,13 +28,13 @@
#include "base/command_line.h"
#include "base/metrics/user_metrics.h"
#include "base/task/current_thread.h"
-#include "base/task/post_task.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/values.h"
#include "chrome/browser/tab_contents/form_interaction_tab_helper.h"
#include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/content/browser/content_autofill_driver_factory.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "components/favicon/core/favicon_service.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/text_input_manager.h"
@@ -49,6 +50,7 @@
#include "content/public/browser/favicon_status.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/drop_data.h"
+#include "content/public/common/url_constants.h"
#include "extensions/buildflags/buildflags.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/common/page_state/page_state.h"
@@ -60,6 +62,23 @@
#include "ui/gfx/font_render_params.h"
#include "qtwebengine/browser/qtwebenginepage.mojom.h"
+#include <QtCore/QVariant>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QMimeData>
+#include <QtCore/QTemporaryDir>
+#include <QtGui/QDrag>
+#include <QtGui/QDragEnterEvent>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QPageLayout>
+#include <QtGui/QPixmap>
+#include <QtGui/QStyleHints>
+
+#if QT_CONFIG(accessibility)
+#include "browser_accessibility_qt.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include <QtGui/qaccessible.h>
+#endif
+
#if QT_CONFIG(webengine_printing_and_pdf)
#include "components/pdf/browser/pdf_web_contents_helper.h"
#include "printing/pdf_web_contents_helper_client_qt.h"
@@ -75,22 +94,6 @@
#include "extensions/extension_web_contents_observer_qt.h"
#endif
-#include <QtCore/QVariant>
-#include <QtCore/QElapsedTimer>
-#include <QtCore/QMimeData>
-#include <QtCore/QTemporaryDir>
-#include <QtGui/QDrag>
-#include <QtGui/QDragEnterEvent>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QPageLayout>
-#include <QtGui/QPixmap>
-#include <QtGui/QStyleHints>
-
-// Can't include headers as qaccessible.h conflicts with Chromium headers.
-namespace content {
-extern QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *acc);
-}
-
namespace QtWebEngineCore {
#define CHECK_INITIALIZED(return_value) \
@@ -151,14 +154,10 @@ static QVariant fromJSValue(const base::Value *result)
}
case base::Value::Type::DICTIONARY:
{
- const base::DictionaryValue *out;
- if (result->GetAsDictionary(&out)) {
+ if (const auto dict = result->GetIfDict()) {
QVariantMap map;
- base::DictionaryValue::Iterator it(*out);
- while (!it.IsAtEnd()) {
- map.insert(toQt(it.key()), fromJSValue(&it.value()));
- it.Advance();
- }
+ for (const auto pair : *dict)
+ map.insert(toQt(pair.first), fromJSValue(&pair.second));
ret.setValue(map);
}
break;
@@ -394,7 +393,7 @@ QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavig
// Set up the file access rights for the selected navigation entry.
// TODO(joth): This is duplicated from chrome/.../session_restore.cc and
// should be shared e.g. in NavigationController. http://crbug.com/68222
- const int id = newWebContents->GetMainFrame()->GetProcess()->GetID();
+ const int id = newWebContents->GetPrimaryMainFrame()->GetProcess()->GetID();
const blink::PageState& pageState = controller.GetActiveEntry()->GetPageState();
const std::vector<base::FilePath>& filePaths = pageState.GetReferencedFiles();
for (std::vector<base::FilePath>::const_iterator file = filePaths.begin(); file != filePaths.end(); ++file)
@@ -487,7 +486,7 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
AutofillClientQt::CreateForWebContents(webContents());
autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
webContents(), AutofillClientQt::FromWebContents(webContents()),
- /* app_locale = */ "", autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
+ base::BindRepeating(&autofill::BrowserDriverInitHook, AutofillClientQt::FromWebContents(webContents()), ""));
#if QT_CONFIG(webengine_printing_and_pdf) && QT_CONFIG(webengine_extensions)
pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
@@ -503,7 +502,7 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
// Create a RenderView with the initial empty document
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
- if (!m_webContents->GetMainFrame()->IsRenderFrameLive())
+ if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive())
static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager(
rvh, absl::nullopt, nullptr);
@@ -522,6 +521,7 @@ void WebContentsAdapter::initializeRenderPrefs()
rendererPrefs->caret_blink_interval =
base::Milliseconds(0.5 * static_cast<double>(qtCursorFlashTime));
rendererPrefs->user_agent_override = blink::UserAgentOverride::UserAgentOnly(m_profileAdapter->httpUserAgent().toStdString());
+ rendererPrefs->user_agent_override.ua_metadata_override = ContentBrowserClientQt::getUserAgentMetadata();
rendererPrefs->accept_languages = m_profileAdapter->httpAcceptLanguageWithoutQualities().toStdString();
#if QT_CONFIG(webengine_webrtc)
base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess();
@@ -586,7 +586,7 @@ void WebContentsAdapter::reload()
bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
setLifecycleState(LifecycleState::Active);
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings());
settings->doApply();
if (!wasDiscarded) // undiscard() already triggers a reload
@@ -601,7 +601,7 @@ void WebContentsAdapter::reloadAndBypassCache()
bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
setLifecycleState(LifecycleState::Active);
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings());
settings->doApply();
if (!wasDiscarded) // undiscard() already triggers a reload
@@ -633,7 +633,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
setLifecycleState(LifecycleState::Active);
}
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply();
@@ -707,7 +707,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
if (resizeNeeded) {
// Schedule navigation on the event loop.
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&NavigateTask, sharedFromThis().toWeakRef(), std::move(params)));
} else {
Navigate(this, params);
@@ -721,7 +721,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
else
setLifecycleState(LifecycleState::Active);
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply();
@@ -872,7 +872,7 @@ void WebContentsAdapter::navigateBack()
{
CHECK_INITIALIZED();
base::RecordAction(base::UserMetricsAction("Back"));
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
if (!m_webContents->GetController().CanGoBack())
return;
m_webContents->GetController().GoBack();
@@ -883,7 +883,7 @@ void WebContentsAdapter::navigateForward()
{
CHECK_INITIALIZED();
base::RecordAction(base::UserMetricsAction("Forward"));
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
if (!m_webContents->GetController().CanGoForward())
return;
m_webContents->GetController().GoForward();
@@ -893,7 +893,7 @@ void WebContentsAdapter::navigateForward()
void WebContentsAdapter::navigateToIndex(int offset)
{
CHECK_INITIALIZED();
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
m_webContents->GetController().GoToIndex(offset);
focusIfNecessary();
}
@@ -901,7 +901,7 @@ void WebContentsAdapter::navigateToIndex(int offset)
void WebContentsAdapter::navigateToOffset(int offset)
{
CHECK_INITIALIZED();
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetMainFrame());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
m_webContents->GetController().GoToOffset(offset);
focusIfNecessary();
}
@@ -979,7 +979,7 @@ void WebContentsAdapter::setZoomFactor(qreal factor)
content::HostZoomMap *zoomMap = content::HostZoomMap::GetForWebContents(m_webContents.get());
if (zoomMap) {
- int render_process_id = m_webContents->GetMainFrame()->GetProcess()->GetID();
+ int render_process_id = m_webContents->GetPrimaryMainFrame()->GetProcess()->GetID();
int render_view_id = m_webContents->GetRenderViewHost()->GetRoutingID();
zoomMap->SetTemporaryZoomLevel(render_process_id, render_view_id, zoomLevel);
}
@@ -1017,13 +1017,13 @@ QWebEngineUrlRequestInterceptor* WebContentsAdapter::requestInterceptor() const
QAccessibleInterface *WebContentsAdapter::browserAccessible()
{
CHECK_INITIALIZED(nullptr);
- content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(m_webContents->GetMainFrame());
+ content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(m_webContents->GetPrimaryMainFrame());
if (!rfh)
return nullptr;
content::BrowserAccessibilityManager *manager = rfh->GetOrCreateBrowserAccessibilityManager();
if (!manager) // FIXME!
return nullptr;
- content::BrowserAccessibility *acc = manager->GetRoot();
+ content::BrowserAccessibility *acc = manager->GetFromAXNode(manager->GetRoot());
return content::toQAccessibleInterface(acc);
}
@@ -1032,8 +1032,12 @@ QAccessibleInterface *WebContentsAdapter::browserAccessible()
void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldId)
{
CHECK_INITIALIZED();
- content::RenderFrameHost *rfh = m_webContents->GetMainFrame();
+ content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame();
Q_ASSERT(rfh);
+ if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) {
+ qWarning() << "Local frame is gone, not running script";
+ return;
+ }
if (worldId == 0)
rfh->ExecuteJavaScript(toString16(javaScript), base::NullCallback());
else
@@ -1043,8 +1047,12 @@ void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldI
quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId)
{
CHECK_INITIALIZED(0);
- content::RenderFrameHost *rfh = m_webContents->GetMainFrame();
+ content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame();
Q_ASSERT(rfh);
+ if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) {
+ qWarning() << "Local frame is gone, not running script";
+ return 0;
+ }
content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, m_nextRequestId);
if (worldId == 0)
rfh->ExecuteJavaScript(toString16(javaScript), std::move(callback));
@@ -1155,7 +1163,7 @@ qint64 WebContentsAdapter::renderProcessPid() const
{
CHECK_INITIALIZED(0);
- content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess();
+ content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess();
const base::Process &process = renderProcessHost->GetProcess();
if (!process.IsValid())
return 0;
@@ -1165,7 +1173,7 @@ qint64 WebContentsAdapter::renderProcessPid() const
void WebContentsAdapter::copyImageAt(const QPoint &location)
{
CHECK_INITIALIZED();
- m_webContents->GetMainFrame()->CopyImageAt(location.x(), location.y());
+ m_webContents->GetPrimaryMainFrame()->CopyImageAt(location.x(), location.y());
}
static blink::mojom::MediaPlayerActionType toBlinkMediaPlayerActionType(WebContentsAdapter::MediaPlayerAction action)
@@ -1192,7 +1200,7 @@ void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, Medi
if (action == MediaPlayerNoAction)
return;
blink::mojom::MediaPlayerAction blinkAction(toBlinkMediaPlayerActionType(action), enable);
- m_webContents->GetMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction);
+ m_webContents->GetPrimaryMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction);
}
void WebContentsAdapter::inspectElementAt(const QPoint &location)
@@ -1815,7 +1823,7 @@ void WebContentsAdapter::viewSource()
{
CHECK_INITIALIZED();
base::RecordAction(base::UserMetricsAction("ViewSource"));
- m_webContents->GetMainFrame()->ViewSource();
+ m_webContents->GetPrimaryMainFrame()->ViewSource();
}
bool WebContentsAdapter::canViewSource()
@@ -2002,7 +2010,7 @@ void WebContentsAdapter::discard()
nullContents->SetWasDiscarded(true);
// Kill render process if this is the only page it's got.
- content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess();
+ content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess();
renderProcessHost->FastShutdownIfPossible(/* page_count */ 1u,
/* skip_unload_handlers */ false);
@@ -2039,7 +2047,7 @@ void WebContentsAdapter::undiscard()
// Create a RenderView with the initial empty document
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
- if (!m_webContents->GetMainFrame()->IsRenderFrameLive())
+ if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive())
static_cast<content::WebContentsImpl *>(m_webContents.get())
->CreateRenderViewForRenderManager(rvh, absl::nullopt, nullptr);
m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh);
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 8d6ae5636..afbd2b5f2 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -30,7 +30,6 @@ QT_FORWARD_DECLARE_CLASS(QVariant)
QT_FORWARD_DECLARE_CLASS(QWebEngineFileSystemAccessRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineFindTextResult)
QT_FORWARD_DECLARE_CLASS(QWebEngineLoadingInfo)
-QT_FORWARD_DECLARE_CLASS(QWebEngineQuotaRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineRegisterProtocolHandlerRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInfo)
QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInterceptor)
@@ -187,7 +186,6 @@ public:
virtual void runFeaturePermissionRequest(ProfileAdapter::PermissionType, const QUrl &securityOrigin) = 0;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
- virtual void runQuotaRequest(QWebEngineQuotaRequest) = 0;
virtual void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) = 0;
virtual void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) = 0;
virtual QWebEngineSettings *webEngineSettings() const = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index f3b57484d..b58b56500 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -48,6 +48,7 @@
#include "content/public/common/url_constants.h"
#include "net/base/data_url.h"
#include "net/base/url_util.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#include <QDesktopServices>
#include <QTimer>
@@ -204,11 +205,11 @@ QUrl WebContentsDelegateQt::url(content::WebContents *source) const
m_pendingUrlUpdate = false;
return newUrl;
}
-void WebContentsDelegateQt::AddNewContents(content::WebContents* source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
- WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked)
+void WebContentsDelegateQt::AddNewContents(content::WebContents *source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
+ WindowOpenDisposition disposition, const blink::mojom::WindowFeatures &window_features, bool user_gesture, bool *was_blocked)
{
Q_UNUSED(source)
- QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, initial_pos, toQt(target_url), user_gesture);
+ QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, window_features.bounds, toQt(target_url), user_gesture);
// Chromium can forget to pass user-agent override settings to new windows (see QTBUG-61774 and QTBUG-76249),
// so set it here. Note the actual value doesn't really matter here. Only the second value does, but we try
// to give the correct user-agent anyway.
@@ -254,6 +255,10 @@ void WebContentsDelegateQt::RenderFrameCreated(content::RenderFrameHost *render_
{
content::FrameTreeNode *node = static_cast<content::RenderFrameHostImpl *>(render_frame_host)->frame_tree_node();
m_frameFocusedObserver.addNode(node);
+
+ // If it's a child frame (render_widget_host_view_child_frame) install an InputEventObserver on
+ // it. Note that it is only needed for WheelEventAck.
+ RenderWidgetHostViewQt::registerInputEventObserver(web_contents(), render_frame_host);
}
void WebContentsDelegateQt::PrimaryMainFrameRenderProcessGone(base::TerminationStatus status)
@@ -472,7 +477,7 @@ void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_h
{
setLoadingState(LoadingState::Loaded);
- if (render_frame_host != web_contents()->GetMainFrame())
+ if (render_frame_host != web_contents()->GetPrimaryMainFrame())
return;
if (validated_url.spec() == content::kUnreachableWebDataURL) {
@@ -623,7 +628,7 @@ void WebContentsDelegateQt::UpdateTargetURL(content::WebContents* source, const
void WebContentsDelegateQt::OnVisibilityChanged(content::Visibility visibility)
{
if (visibility != content::Visibility::HIDDEN)
- web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetMainFrame()->GetProcess()->GetID());
+ web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID());
}
void WebContentsDelegateQt::ActivateContents(content::WebContents* contents)
@@ -869,6 +874,7 @@ int &WebContentsDelegateQt::streamCount(blink::mojom::MediaStreamType type)
case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE:
case blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE:
case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB:
+ case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET:
return m_desktopStreamCount;
case blink::mojom::MediaStreamType::NO_SERVICE:
@@ -880,22 +886,36 @@ int &WebContentsDelegateQt::streamCount(blink::mojom::MediaStreamType type)
return m_videoStreamCount;
}
-void WebContentsDelegateQt::addDevices(const blink::MediaStreamDevices &devices)
+void WebContentsDelegateQt::addDevices(const blink::mojom::StreamDevices &devices)
{
- for (const auto &device : devices)
- ++streamCount(device.type);
+ if (devices.audio_device.has_value())
+ addDevice(devices.audio_device.value());
+ if (devices.video_device.has_value())
+ addDevice(devices.video_device.value());
webContentsAdapter()->updateRecommendedState();
}
-void WebContentsDelegateQt::removeDevices(const blink::MediaStreamDevices &devices)
+void WebContentsDelegateQt::removeDevices(const blink::mojom::StreamDevices &devices)
{
- for (const auto &device : devices)
- ++streamCount(device.type);
+ if (devices.audio_device.has_value())
+ removeDevice(devices.audio_device.value());
+ if (devices.video_device.has_value())
+ removeDevice(devices.video_device.value());
webContentsAdapter()->updateRecommendedState();
}
+void WebContentsDelegateQt::addDevice(const blink::MediaStreamDevice &device)
+{
+ ++streamCount(device.type);
+}
+
+void WebContentsDelegateQt::removeDevice(const blink::MediaStreamDevice &device)
+{
+ --streamCount(device.type);
+}
+
FrameFocusedObserver::FrameFocusedObserver(WebContentsAdapterClient *adapterClient)
: m_viewClient(adapterClient)
{}
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 37ab7ef5d..eda4e1e57 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -81,7 +81,7 @@ public:
content::WebContents *OpenURLFromTab(content::WebContents *source, const content::OpenURLParams &params) override;
void NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) override;
void AddNewContents(content::WebContents *source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
- WindowOpenDisposition disposition, const gfx::Rect &initial_pos, bool user_gesture, bool *was_blocked) override;
+ WindowOpenDisposition disposition, const blink::mojom::WindowFeatures &window_features, bool user_gesture, bool *was_blocked) override;
void CloseContents(content::WebContents *source) override;
void LoadProgressChanged(double progress) override;
bool HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override;
@@ -150,8 +150,10 @@ public:
using LoadingState = WebContentsAdapterClient::LoadingState;
LoadingState loadingState() const { return m_loadingState; }
- void addDevices(const blink::MediaStreamDevices &devices);
- void removeDevices(const blink::MediaStreamDevices &devices);
+ void addDevices(const blink::mojom::StreamDevices &devices);
+ void removeDevices(const blink::mojom::StreamDevices &devices);
+ void addDevice(const blink::MediaStreamDevice &device);
+ void removeDevice(const blink::MediaStreamDevice &device);
bool isCapturingAudio() const { return m_audioStreamCount > 0; }
bool isCapturingVideo() const { return m_videoStreamCount > 0; }
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 286fc198c..023f9e99f 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -230,8 +230,9 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
blink::DragOperationsMask allowed_ops,
const gfx::ImageSkia &image,
const gfx::Vector2d &image_offset,
+ const gfx::Rect &drag_obj_rect,
const blink::mojom::DragEventSourceInfo &event_info,
- content::RenderWidgetHostImpl* source_rwh)
+ content::RenderWidgetHostImpl *source_rwh)
{
#if QT_CONFIG(draganddrop)
Q_UNUSED(event_info);
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 2e236f2b2..15528b41d 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -72,6 +72,7 @@ public:
void FocusThroughTabTraversal(bool reverse) override;
void OnCapturerCountChanged() override { QT_NOT_YET_IMPLEMENTED }
+ void FullscreenStateChanged(bool) override { }
#if BUILDFLAG(IS_MAC)
bool CloseTabAfterEventTrackingIfNeeded() override { QT_NOT_YET_IMPLEMENTED return false; }
@@ -80,6 +81,7 @@ public:
// content::RenderViewHostDelegateView overrides:
void StartDragging(const content::DropData& drop_data, blink::DragOperationsMask allowed_ops,
const gfx::ImageSkia& image, const gfx::Vector2d& image_offset,
+ const gfx::Rect& drag_obj_rect,
const blink::mojom::DragEventSourceInfo &event_info,
content::RenderWidgetHostImpl *source_rwh) override;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 147c53b8e..d0da744d7 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -13,7 +13,6 @@
#include "base/power_monitor/power_monitor_device_source.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
-#include "base/task/post_task.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/thread_restrictions.h"
@@ -22,6 +21,7 @@
#include "chrome/browser/media/webrtc/webrtc_log_uploader.h"
#endif
#include "chrome/common/chrome_switches.h"
+#include "content/common/process_visibility_tracker.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/compositor/viz_process_transport_factory.h"
@@ -31,6 +31,7 @@
#endif
#include "components/discardable_memory/service/discardable_shared_memory_manager.h"
#include "components/download/public/common/download_task_runner.h"
+#include "components/power_scheduler/power_mode_arbiter.h"
#include "components/viz/common/features.h"
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/app/mojo_ipc_support.h"
@@ -54,7 +55,7 @@
#include "content/public/common/main_function_params.h"
#include "content/public/common/network_service_util.h"
#include "gpu/command_buffer/service/gpu_switches.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
+#include "gpu/config/gpu_finch_features.h"
#include "media/audio/audio_manager.h"
#include "media/base/media_switches.h"
#include "mojo/core/embedder/embedder.h"
@@ -117,13 +118,21 @@ Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
QT_END_NAMESPACE
#endif
+#define STRINGIFY_LITERAL(x) #x
+#define STRINGIFY_EXPANDED(x) STRINGIFY_LITERAL(x)
+
namespace QtWebEngineCore {
+Q_LOGGING_CATEGORY(webEngineContextLog, "qt.webenginecontext")
+
#if QT_CONFIG(opengl)
static bool usingSupportedSGBackend()
{
- if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL)
+ if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Vulkan
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Metal
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Direct3D11)
return false;
const QStringList args = QGuiApplication::arguments();
@@ -183,6 +192,14 @@ static const char *getGLType(bool enableGLSoftwareRendering, bool disableGpu)
if (disableGpu || (!tryGL && !enableGLSoftwareRendering))
return glType;
+#if defined(Q_OS_MACOS)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Metal)
+ return gl::kGLImplementationANGLEName;
+#elif defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11)
+ return gl::kGLImplementationANGLEName;
+#endif
+
if (!qt_gl_global_share_context() || !qt_gl_global_share_context()->isValid()) {
qWarning("WebEngineContext is used before QtWebEngineQuick::initialize() or OpenGL context "
"creation failed.");
@@ -220,8 +237,17 @@ static const char *getGLType(bool enableGLSoftwareRendering, bool disableGpu)
return glType;
}
#else
-static const char *getGLType(bool enableGLSoftwareRendering, bool disableGpu)
+static const char *getGLType(bool /*enableGLSoftwareRendering*/, bool disableGpu)
{
+ if (disableGpu)
+ return gl::kGLImplementationDisabledName;
+#if defined(Q_OS_MACOS)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Metal)
+ return gl::kGLImplementationANGLEName;
+#elif defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11)
+ return gl::kGLImplementationANGLEName;
+#endif
return gl::kGLImplementationDisabledName;
}
#endif // QT_CONFIG(opengl)
@@ -234,36 +260,42 @@ void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
static void logContext(const char *glType, base::CommandLine *cmd)
{
- QLoggingCategory webEngineContextLog("qt.webenginecontext");
- if (webEngineContextLog.isInfoEnabled()) {
-#if QT_CONFIG(opengl)
- const QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
- const auto profile = QMetaEnum::fromType<QSurfaceFormat::OpenGLContextProfile>().valueToKey(
- sharedFormat.profile());
- const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
- sharedFormat.renderableType());
+ if (Q_UNLIKELY(webEngineContextLog().isDebugEnabled())) {
const base::CommandLine::SwitchMap switch_map = cmd->GetSwitches();
QStringList params;
for (const auto &pair : switch_map)
params << " * " << toQt(pair.first)
<< toQt(pair.second) << "\n";
- qCInfo(webEngineContextLog,
- "\n\nGL Type: %s\n"
- "Surface Type: %s\n"
- "Surface Profile: %s\n"
- "Surface Version: %d.%d\n"
- "QSG RHI Backend: %s\n"
- "Using Supported QSG Backend: %s\n"
- "Using Software Dynamic GL: %s\n"
- "Using Multithreaded OpenGL: %s\n\n"
- "Init Parameters:\n %s",
- glType, type, profile, sharedFormat.majorVersion(), sharedFormat.minorVersion(),
- qUtf8Printable(QSGRhiSupport::instance()->rhiBackendName()),
- usingSupportedSGBackend() ? "yes" : "no", usingSoftwareDynamicGL() ? "yes" : "no",
- !WebEngineContext::isGpuServiceOnUIThread() ? "yes" : "no",
- qPrintable(params.join(" ")));
+#if QT_CONFIG(opengl)
+ const QSurfaceFormat sharedFormat = qt_gl_global_share_context() ? qt_gl_global_share_context()->format() : QSurfaceFormat::defaultFormat();
+ const auto profile = QMetaEnum::fromType<QSurfaceFormat::OpenGLContextProfile>().valueToKey(
+ sharedFormat.profile());
+ const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
+ sharedFormat.renderableType());
+ qCDebug(webEngineContextLog,
+ "\n\nChromium GL Backend: %s\n"
+ "Surface Type: %s\n"
+ "Surface Profile: %s\n"
+ "Surface Version: %d.%d\n"
+ "QSG RHI Backend: %s\n"
+ "Using Supported QSG Backend: %s\n"
+ "Using Software Dynamic GL: %s\n"
+ "Using Shared GL: %s\n"
+ "Using Multithreaded OpenGL: %s\n\n"
+ "Init Parameters:\n %s",
+ glType, type, profile, sharedFormat.majorVersion(), sharedFormat.minorVersion(),
+ qUtf8Printable(QSGRhiSupport::instance()->rhiBackendName()),
+ usingSupportedSGBackend() ? "yes" : "no", usingSoftwareDynamicGL() ? "yes" : "no",
+ qt_gl_global_share_context() ? "yes" : "no",
+ !WebEngineContext::isGpuServiceOnUIThread() ? "yes" : "no",
+ qPrintable(params.join(" ")));
#else
- qCInfo(webEngineContextLog) << "WebEngine compiled with no opengl enabled.";
+ qCDebug(webEngineContextLog,
+ "\n\nChromium GL Backend: %s\n"
+ "QSG RHI Backend: %s\n\n"
+ "Init Parameters:\n %s",
+ glType, qUtf8Printable(QSGRhiSupport::instance()->rhiBackendName()),
+ qPrintable(params.join(" ")));
#endif //QT_CONFIG(opengl)
}
}
@@ -468,7 +500,6 @@ WebEngineContext::~WebEngineContext()
Q_ASSERT(!m_devtoolsServer);
Q_ASSERT(!m_browserRunner);
Q_ASSERT(m_profileAdapters.isEmpty());
- delete s_syncPointManager.fetchAndStoreRelaxed(nullptr);
}
WebEngineContext *WebEngineContext::current()
@@ -669,6 +700,11 @@ WebEngineContext::WebEngineContext()
// Avoid crashing when websites tries using this feature (since 83)
disableFeatures.push_back(features::kInstalledApp.name);
+ // Not implemented but it overrides the devtools eyedropper
+ // Should be sync with kEyeDropper base::Feature
+ parsedCommandLine->AppendSwitchASCII(switches::kDisableBlinkFeatures, "EyeDropperAPI");
+ disableFeatures.push_back(features::kEyeDropper.name);
+
// Explicitly tell Chromium about default-on features we do not support
disableFeatures.push_back(features::kBackgroundFetch.name);
disableFeatures.push_back(features::kWebOTP.name);
@@ -683,6 +719,14 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
+#if QT_CONFIG(webengine_vulkan)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ enableFeatures.push_back(features::kVulkan.name);
+ parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,
+ switches::kVulkanImplementationNameNative);
+ }
+#endif
+
initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures);
GLContextHelper::initialize();
@@ -703,19 +747,21 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kIgnoreGpuBlocklist);
}
#if QT_CONFIG(opengl)
- const QSurfaceFormat sharedFormat = QOpenGLContext::globalShareContext()->format();
- if (sharedFormat.profile() == QSurfaceFormat::CompatibilityProfile)
- parsedCommandLine->AppendSwitch(switches::kCreateDefaultGLContext);
+ if (glType != gl::kGLImplementationANGLEName) {
+ const QSurfaceFormat sharedFormat = QOpenGLContext::globalShareContext()->format();
+ if (sharedFormat.profile() == QSurfaceFormat::CompatibilityProfile)
+ parsedCommandLine->AppendSwitch(switches::kCreateDefaultGLContext);
#if defined(Q_OS_WIN)
- // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
- // an OpenGL Core Profile context. If the switch is not set, it would always try to create a
- // Core Profile context, even if Qt uses a legacy profile, which causes
- // "Could not share GL contexts" warnings, because it's not possible to share between Core and
- // legacy profiles. See GLContextWGL::Initialize().
- if (sharedFormat.renderableType() == QSurfaceFormat::OpenGL
- && sharedFormat.profile() != QSurfaceFormat::CoreProfile)
- parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
+ // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
+ // an OpenGL Core Profile context. If the switch is not set, it would always try to create a
+ // Core Profile context, even if Qt uses a legacy profile, which causes
+ // "Could not share GL contexts" warnings, because it's not possible to share between Core and
+ // legacy profiles. See GLContextWGL::Initialize().
+ if (sharedFormat.renderableType() == QSurfaceFormat::OpenGL
+ && sharedFormat.profile() != QSurfaceFormat::CoreProfile)
+ parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
#endif
+ }
#endif //QT_CONFIG(opengl)
} else if (!disableGpu) {
parsedCommandLine->AppendSwitch(switches::kDisableGpu);
@@ -745,12 +791,14 @@ WebEngineContext::WebEngineContext()
m_mainDelegate->PreBrowserMain();
base::MessagePump::OverrideMessagePumpForUIFactory(messagePumpFactory);
content::BrowserTaskExecutor::Create();
- m_mainDelegate->PostEarlyInitialization(false);
+ m_mainDelegate->PostEarlyInitialization({});
content::StartBrowserThreadPool();
content::BrowserTaskExecutor::PostFeatureListSetup();
tracing::InitTracingPostThreadPoolStartAndFeatureList(false);
- m_discardableSharedMemoryManager = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
base::PowerMonitor::Initialize(std::make_unique<base::PowerMonitorDeviceSource>());
+ content::ProcessVisibilityTracker::GetInstance();
+ m_discardableSharedMemoryManager = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
+ power_scheduler::PowerModeArbiter::GetInstance()->OnThreadPoolAvailable();
m_mojoIpcSupport = std::make_unique<content::MojoIpcSupport>(content::BrowserTaskExecutor::CreateIOThread());
download::SetIOTaskRunner(m_mojoIpcSupport->io_thread()->task_runner());
@@ -816,60 +864,52 @@ WebRtcLogUploader *WebEngineContext::webRtcLogUploader()
#endif
-static QMutex s_spmMutex;
-QAtomicPointer<gpu::SyncPointManager> WebEngineContext::s_syncPointManager;
-
-gpu::SyncPointManager *WebEngineContext::syncPointManager()
-{
- if (gpu::SyncPointManager *spm = s_syncPointManager.loadAcquire())
- return spm;
- QMutexLocker lock(&s_spmMutex);
- if (!s_syncPointManager)
- s_syncPointManager.storeRelaxed(new gpu::SyncPointManager());
- return s_syncPointManager.loadRelaxed();
-}
-
base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
bool &enableGLSoftwareRendering)
{
- if (base::CommandLine::CreateEmpty()) {
- base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
- QStringList appArgs = QCoreApplication::arguments();
- if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
- appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
- appArgs.append(parseEnvCommandLine(qEnvironmentVariable(kChromiumFlagsEnv)));
+ if (!base::CommandLine::CreateEmpty())
+ qFatal("base::CommandLine has been initialized unexpectedly.");
+
+ QStringList appArgs = QCoreApplication::arguments();
+ if (appArgs.empty()) {
+ qFatal("Argument list is empty, the program name is not passed to QCoreApplication. "
+ "base::CommandLine cannot be properly initialized.");
+ }
+
+ base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
+ appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
+ appArgs.append(parseEnvCommandLine(qEnvironmentVariable(kChromiumFlagsEnv)));
+ } else {
+ int index = appArgs.indexOf(QLatin1String("--webEngineArgs"));
+ if (index > -1) {
+ appArgs.erase(appArgs.begin() + 1, appArgs.begin() + index + 1);
} else {
- int index = appArgs.indexOf(QLatin1String("--webEngineArgs"));
- if (index > -1) {
- appArgs.erase(appArgs.begin() + 1, appArgs.begin() + index + 1);
- } else {
- appArgs = appArgs.mid(0, 1);
- }
+ appArgs = appArgs.mid(0, 1);
}
+ }
#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
- useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
+ useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
#else
- useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
+ useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
#endif
- enableGLSoftwareRendering =
+ enableGLSoftwareRendering =
appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
- appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
- appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+ appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
+ appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
- base::CommandLine::StringVector argv;
- argv.resize(appArgs.size());
+ base::CommandLine::StringVector argv;
+ argv.resize(appArgs.size());
#if defined(Q_OS_WIN)
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = appArgs[i].toStdWString();
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdWString();
#else
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = appArgs[i].toStdString();
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdString();
#endif
- parsedCommandLine->InitFromArgv(argv);
- return parsedCommandLine;
- } else {
- return base::CommandLine::ForCurrentProcess();
- }
+ parsedCommandLine->InitFromArgv(argv);
+
+ return parsedCommandLine;
}
bool WebEngineContext::closingDown()
@@ -882,16 +922,22 @@ bool WebEngineContext::closingDown()
QT_BEGIN_NAMESPACE
const char *qWebEngineVersion() noexcept
{
- return QTWEBENGINECORE_VERSION_STR;
+ return STRINGIFY_EXPANDED(QTWEBENGINECORE_VERSION_STR);
+}
+
+const char *qWebEngineProcessName() noexcept
+{
+ return STRINGIFY_EXPANDED(QTWEBENGINEPROCESS_NAME);
}
const char *qWebEngineChromiumVersion() noexcept
{
- return CHROMIUM_VERSION;
+ return STRINGIFY_EXPANDED(CHROMIUM_VERSION);
}
+
const char *qWebEngineChromiumSecurityPatchVersion() noexcept
{
- return "111.0.5563.110"; // FIXME: Remember to update
+ return "114.0.5735.133"; // FIXME: Remember to update
}
QT_END_NAMESPACE
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index f7dbd1e53..5a2fd4c3e 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -21,7 +21,6 @@ class CommandLine;
namespace content {
class BrowserMainRunner;
class ContentMainRunner;
-class GpuProcess;
class GpuThreadController;
class InProcessChildThreadParams;
class MojoIpcSupport;
@@ -33,7 +32,6 @@ class DiscardableSharedMemoryManager;
namespace gpu {
struct GpuPreferences;
-class SyncPointManager;
}
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -86,8 +84,6 @@ public:
static base::CommandLine *initCommandLine(bool &useEmbeddedSwitches,
bool &enableGLSoftwareRendering);
- static gpu::SyncPointManager *syncPointManager();
-
static bool isGpuServiceOnUIThread();
private:
@@ -122,7 +118,6 @@ private:
static scoped_refptr<QtWebEngineCore::WebEngineContext> m_handle;
static bool m_destroyed;
static bool m_closingDown;
- static QAtomicPointer<gpu::SyncPointManager> s_syncPointManager;
};
} // namespace
diff --git a/src/core/web_engine_context_threads.cpp b/src/core/web_engine_context_threads.cpp
index 2d0f8a90c..f62e2074e 100644
--- a/src/core/web_engine_context_threads.cpp
+++ b/src/core/web_engine_context_threads.cpp
@@ -4,14 +4,14 @@
#include "web_engine_context.h"
#include "base/bind.h"
-#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/gpu/gpu_main_thread_factory.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/utility_process_host.h"
+#include "content/child/child_process.h"
#include "content/gpu/gpu_child_thread.h"
-#include "content/gpu/gpu_process.h"
#include "content/gpu/in_process_gpu_thread.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
@@ -29,14 +29,14 @@ struct GpuThreadControllerQt : content::GpuThreadController
{
GpuThreadControllerQt(const content::InProcessChildThreadParams &params, const gpu::GpuPreferences &gpuPreferences)
{
- base::PostTask(
- FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&GpuThreadControllerQt::createGpuProcess, params, gpuPreferences));
}
~GpuThreadControllerQt() override
{
- base::PostTask(
- FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&GpuThreadControllerQt::destroyGpuProcess));
}
@@ -48,11 +48,11 @@ struct GpuThreadControllerQt : content::GpuThreadController
if (s_gpuProcessDestroyed)
return;
- s_gpuProcess = std::make_unique<content::GpuProcess>(base::ThreadPriority::NORMAL);
+ s_gpuProcess = std::make_unique<content::ChildProcess>(base::ThreadType::kDefault);
auto gpuInit = std::make_unique<gpu::GpuInit>();
gpuInit->InitializeInProcess(base::CommandLine::ForCurrentProcess(), gpuPreferences);
auto childThread = new content::GpuChildThread(params, std::move(gpuInit));
- childThread->Init(base::Time::Now());
+ childThread->Init(base::TimeTicks::Now());
s_gpuProcess->set_main_thread(childThread);
}
@@ -68,11 +68,11 @@ struct GpuThreadControllerQt : content::GpuThreadController
s_gpuProcessDestroyed = true;
}
- static std::unique_ptr<content::GpuProcess> s_gpuProcess;
+ static std::unique_ptr<content::ChildProcess> s_gpuProcess;
static bool s_gpuProcessDestroyed;
};
-std::unique_ptr<content::GpuProcess> GpuThreadControllerQt::s_gpuProcess;
+std::unique_ptr<content::ChildProcess> GpuThreadControllerQt::s_gpuProcess;
bool GpuThreadControllerQt::s_gpuProcessDestroyed = false;
static std::unique_ptr<content::GpuThreadController> createGpuThreadController(
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 588af5cc6..277317f6f 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -57,7 +57,7 @@ static QString getBundlePath(CFBundleRef frameworkBundle)
// The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before.
// We use it for the other OS X versions as well to make sure it works and because
// the directory structure should be the same.
- if (qApp->applicationName() == QLatin1String(QTWEBENGINEPROCESS_NAME)) {
+ if (qApp->applicationName() == QLatin1String(qWebEngineProcessName())) {
path = QDir::cleanPath(qApp->applicationDirPath() % QLatin1String("/../../../.."));
} else if (frameworkBundle) {
CFURLRef bundleUrl = CFBundleCopyBundleURL(frameworkBundle);
@@ -75,7 +75,7 @@ static QString getResourcesPath(CFBundleRef frameworkBundle)
// The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before.
// We use it for the other OS X versions as well to make sure it works and because
// the directory structure should be the same.
- if (qApp->applicationName() == QLatin1String(QTWEBENGINEPROCESS_NAME)) {
+ if (qApp->applicationName() == QLatin1String(qWebEngineProcessName())) {
path = getBundlePath(frameworkBundle) % QLatin1String("/Resources");
} else if (frameworkBundle) {
CFURLRef resourcesRelativeUrl = CFBundleCopyResourcesDirectoryURL(frameworkBundle);
@@ -121,9 +121,9 @@ QString subProcessPath()
static QString processPath;
if (processPath.isEmpty()) {
#if defined(Q_OS_WIN)
- const QString processBinary = QLatin1String(QTWEBENGINEPROCESS_NAME) % QLatin1String(".exe");
+ const QString processBinary = QLatin1String(qWebEngineProcessName()) % QLatin1String(".exe");
#else
- const QString processBinary = QLatin1String(QTWEBENGINEPROCESS_NAME);
+ const QString processBinary = QLatin1String(qWebEngineProcessName());
#endif
QStringList candidatePaths;
@@ -133,8 +133,9 @@ QString subProcessPath()
candidatePaths << fromEnv;
} else {
#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
- candidatePaths << getBundlePath(frameworkBundle())
- % QStringLiteral("/Helpers/" QTWEBENGINEPROCESS_NAME ".app/Contents/MacOS/" QTWEBENGINEPROCESS_NAME);
+ candidatePaths << getBundlePath(frameworkBundle()) % QStringLiteral("/Helpers/")
+ % qWebEngineProcessName() % QStringLiteral(".app/Contents/MacOS/")
+ % qWebEngineProcessName();
#else
candidatePaths << QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath)
% QLatin1Char('/') % processBinary;
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 3e829457e..906f9fb72 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -422,7 +422,6 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
prefs->text_track_font_family = style->font_family;
prefs->text_track_font_variant = style->font_variant;
prefs->text_track_window_color = style->window_color;
- prefs->text_track_window_padding = style->window_padding;
prefs->text_track_window_radius = style->window_radius;
}
}
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 007492843..508a4b557 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -1444,6 +1444,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev)
webKitEvent.SetPositionInWidget(ev->position().x(), ev->position().y());
webKitEvent.movement_x = ev->position().x() - ev->oldPos().x();
webKitEvent.movement_y = ev->position().y() - ev->oldPos().y();
+ webKitEvent.is_raw_movement_event = true;
webKitEvent.pointer_type = WebPointerProperties::PointerType::kMouse;
return webKitEvent;
diff --git a/src/gn/CMakeLists.txt b/src/gn/CMakeLists.txt
index 5e20b26f7..3897e123d 100644
--- a/src/gn/CMakeLists.txt
+++ b/src/gn/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt
index 6c110c98e..59e003025 100644
--- a/src/host/CMakeLists.txt
+++ b/src/host/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
if(NOT DEFINED WEBENGINE_ROOT_SOURCE_DIR)
@@ -18,6 +21,10 @@ project(QtWebEngineConfigure
find_package(Qt6 6.2 CONFIG REQUIRED COMPONENTS BuildInternals Core)
+if(COMMAND qt_internal_project_setup)
+ qt_internal_project_setup()
+endif()
+
set(buildDir ${CMAKE_CURRENT_BINARY_DIR})
configure_gn_toolchain(host ${TEST_architecture_arch} ${TEST_architecture_arch}
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
diff --git a/src/ninja/CMakeLists.txt b/src/ninja/CMakeLists.txt
index 6f43b89fc..0258b3da9 100644
--- a/src/ninja/CMakeLists.txt
+++ b/src/ninja/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
index ed2da1032..e79bbd85e 100644
--- a/src/pdf/CMakeLists.txt
+++ b/src/pdf/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
find_package(Ninja 1.7.2 REQUIRED)
find_package(Nodejs 12 REQUIRED)
@@ -40,6 +43,10 @@ qt_internal_add_module(Pdf
add_subdirectory(plugins/imageformats/pdf)
+get_install_config(config)
+get_architectures(archs)
+list(GET archs 0 arch)
+
##
# PDF DOCS
##
@@ -48,6 +55,16 @@ qt_internal_add_docs(Pdf
doc/qtpdf.qdocconf
)
+add_code_attributions_target(
+ TARGET generate_pdf_attributions
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pdf_attributions.qdoc
+ GN_TARGET :QtPdf
+ FILE_TEMPLATE doc/about_credits.tmpl
+ ENTRY_TEMPLATE doc/about_credits_entry.tmpl
+ BUILDDIR ${buildDir}/${config}/${arch}
+)
+add_dependencies(generate_pdf_attributions run_pdf_GnDone)
+add_dependencies(docs generate_pdf_attributions)
##
# TOOLCHAIN SETUP
@@ -111,15 +128,21 @@ foreach(arch ${archs})
strip_absolute_paths_from_debug_symbols=false
)
- if(LINUX)
+ if(LINUX OR ANDROID)
list(APPEND gnArgArg
is_cfi=false
ozone_auto_platforms=false
- use_gnome_keyring=false)
+ use_gnome_keyring=false
+ enable_vr=false
+ )
extend_gn_list(gnArgArg
ARGS use_system_icu
CONDITION QT_FEATURE_webengine_system_icu
)
+ extend_gn_list(gnArgArg
+ ARGS use_system_libopenjpeg2
+ CONDITION QT_FEATURE_webengine_system_libopenjpeg2
+ )
endif()
if(MACOS)
list(APPEND gnArgArg angle_enable_vulkan=false)
@@ -166,6 +189,14 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_pdf_xfa_tiff
)
extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_zlib
+ CONDITION QT_FEATURE_webengine_system_zlib
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_libpng use_system_libpng
+ CONDITION QT_FEATURE_webengine_system_libpng
+ )
+ extend_gn_list(gnArgArg
ARGS pdfium_use_qt_libpng
CONDITION QT_FEATURE_webengine_qt_libpng
)
@@ -186,7 +217,7 @@ foreach(arch ${archs})
CMAKE_TARGET Pdf
NINJA_TARGETS QtPdf
GN_TARGET ${buildGn}
- GN_ARGS "${gnArgArg}"
+ GN_ARGS ${gnArgArg}
BUILDDIR ${buildDir}/${config}/${arch}
MODULE pdf
)
diff --git a/src/pdf/configure.cmake b/src/pdf/configure.cmake
index 8d1a07183..ac4e4e25f 100644
--- a/src/pdf/configure.cmake
+++ b/src/pdf/configure.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_feature("pdf-v8" PRIVATE
LABEL "Support V8"
PURPOSE "Enables javascript support."
diff --git a/src/pdf/configure/BUILD.root.gn.in b/src/pdf/configure/BUILD.root.gn.in
index 5420e8581..3918c1e9f 100644
--- a/src/pdf/configure/BUILD.root.gn.in
+++ b/src/pdf/configure/BUILD.root.gn.in
@@ -51,7 +51,7 @@ config("cpp17_config") {
static_library("QtPdf") {
complete_static_lib = true
- rsp_types = [ "objects", "archives", "libs" ]
+ rsp_types = [ "objects", "archives", "libs", "lflags" ]
configs += [
":cpp17_config",
":QtPdf_config"
@@ -59,4 +59,10 @@ static_library("QtPdf") {
deps = [
"//third_party/pdfium"
]
+ if (is_win) {
+ libs = [
+ "dloadhelper.lib",
+ "winmm.lib",
+ ]
+ }
}
diff --git a/src/pdf/doc/about_credits.tmpl b/src/pdf/doc/about_credits.tmpl
new file mode 100644
index 000000000..57fae9e78
--- /dev/null
+++ b/src/pdf/doc/about_credits.tmpl
@@ -0,0 +1 @@
+{{entries}}
diff --git a/src/pdf/doc/about_credits_entry.tmpl b/src/pdf/doc/about_credits_entry.tmpl
new file mode 100644
index 000000000..294198709
--- /dev/null
+++ b/src/pdf/doc/about_credits_entry.tmpl
@@ -0,0 +1,13 @@
+/*!
+\page qtpdf-3rdparty-{{name-sanitized}}.html
+\attribution
+\ingroup qtpdf-licensing
+\brief {{license-type}}
+\title {{name}}
+
+\l{{{url}}}{Project Homepage}
+
+\badcode
+{{license}}
+\endcode
+*/
diff --git a/src/pdf/doc/images/pdfviewer.png b/src/pdf/doc/images/pdfviewer.png
new file mode 100644
index 000000000..ac8a31ac0
--- /dev/null
+++ b/src/pdf/doc/images/pdfviewer.png
Binary files differ
diff --git a/src/pdf/doc/src/qtpdf-index.qdoc b/src/pdf/doc/src/qtpdf-index.qdoc
index 07c151f47..fb44eb5fa 100644
--- a/src/pdf/doc/src/qtpdf-index.qdoc
+++ b/src/pdf/doc/src/qtpdf-index.qdoc
@@ -64,4 +64,12 @@
\li \l{Qt PDF C++ Classes}
\li \l{Qt Quick PDF QML Types}
\endlist
+
+ \section1 Licenses and Attributions
+
+ Qt PDF is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under the
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt PDF Licensing} for further details about this module.
*/
diff --git a/src/pdf/doc/src/qtpdf-licensing.qdoc b/src/pdf/doc/src/qtpdf-licensing.qdoc
new file mode 100644
index 000000000..190ee8331
--- /dev/null
+++ b/src/pdf/doc/src/qtpdf-licensing.qdoc
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \group qtpdf-licensing
+ \title Qt PDF Licensing
+
+ Qt PDF is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under the
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
+ The module includes a snapshot of PDFium. As such, users need to respect
+ the licenses of PDFium and third-party code included in it.
+
+ Third party licenses included in the sources are:
+*/
diff --git a/src/pdf/plugins/imageformats/pdf/CMakeLists.txt b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
index 517d152c7..73a0b3144 100644
--- a/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
+++ b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_plugin(QPdfPlugin
OUTPUT_NAME qpdf
PLUGIN_TYPE imageformats
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index a3e412c5c..268389f4a 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -824,22 +824,6 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
result.fill(Qt::transparent);
FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(result.width(), result.height(), FPDFBitmap_BGRA, result.bits(), result.bytesPerLine());
- int rotation = 0;
- switch (renderOptions.rotation()) {
- case QPdfDocumentRenderOptions::Rotation::None:
- rotation = 0;
- break;
- case QPdfDocumentRenderOptions::Rotation::Clockwise90:
- rotation = 1;
- break;
- case QPdfDocumentRenderOptions::Rotation::Clockwise180:
- rotation = 2;
- break;
- case QPdfDocumentRenderOptions::Rotation::Clockwise270:
- rotation = 3;
- break;
- }
-
const QPdfDocumentRenderOptions::RenderFlags renderFlags = renderOptions.renderFlags();
int flags = 0;
if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::Annotations)
@@ -885,6 +869,7 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
qCDebug(qLcDoc) << "page" << page << "region" << renderOptions.scaledClipRect()
<< "size" << imageSize << "took" << timer.elapsed() << "ms";
} else {
+ const auto rotation = QPdfDocumentPrivate::toFPDFRotation(renderOptions.rotation());
FPDF_RenderPageBitmap(bitmap, pdfPage, 0, 0, result.width(), result.height(), rotation, flags);
qCDebug(qLcDoc) << "page" << page << "size" << imageSize << "took" << timer.elapsed() << "ms";
}
diff --git a/src/pdf/qpdfdocument_p.h b/src/pdf/qpdfdocument_p.h
index 973dc1d4a..d52aabe4b 100644
--- a/src/pdf/qpdfdocument_p.h
+++ b/src/pdf/qpdfdocument_p.h
@@ -81,6 +81,31 @@ public:
QPointF getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex);
QRectF getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex);
+ // FPDF takes the rotation parameter as an int.
+ // This enum is mapping the int values defined in fpdfview.h:956.
+ // (not using enum class to ensure int convertability)
+ enum QFPDFRotation {
+ Normal = 0,
+ ClockWise90 = 1,
+ ClockWise180 = 2,
+ CounterClockWise90 = 3
+ };
+
+ static constexpr QFPDFRotation toFPDFRotation(QPdfDocumentRenderOptions::Rotation rotation)
+ {
+ switch (rotation) {
+ case QPdfDocumentRenderOptions::Rotation::None:
+ return QFPDFRotation::Normal;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise90:
+ return QFPDFRotation::ClockWise90;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise180:
+ return QFPDFRotation::ClockWise180;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise270:
+ return QFPDFRotation::CounterClockWise90;
+ }
+ Q_UNREACHABLE();
+ }
+
struct TextPosition {
QPointF position;
qreal height = 0;
diff --git a/src/pdf/qpdflink.cpp b/src/pdf/qpdflink.cpp
index d1f5bdfdc..0c2867086 100644
--- a/src/pdf/qpdflink.cpp
+++ b/src/pdf/qpdflink.cpp
@@ -152,12 +152,11 @@ QList<QRectF> QPdfLink::rectangles() const
*/
QString QPdfLink::toString() const
{
- static const QString format = QPdfLinkModel::tr("page %1 location %2,%3 zoom %4");
- return d->page > 0 ? format.arg(QString::number(d->page),
- QString::number(d->location.x()),
- QString::number(d->location.y()),
- QString::number(d->zoom))
- : d->url.toString();
+ if (d->page <= 0)
+ return d->url.toString();
+ return QPdfLinkModel::tr("Page %1 location %2, %3 zoom %4")
+ .arg(d->page).arg(d->location.x(), 0, 'f', 1).arg(d->location.y(), 0, 'f', 1)
+ .arg(d->zoom, 0, 'f', 0);
}
/*!
diff --git a/src/pdf/qpdflinkmodel.cpp b/src/pdf/qpdflinkmodel.cpp
index a8e98926a..c98a8723e 100644
--- a/src/pdf/qpdflinkmodel.cpp
+++ b/src/pdf/qpdflinkmodel.cpp
@@ -180,6 +180,12 @@ void QPdfLinkModelPrivate::update()
qCWarning(qLcLink) << "skipping link with invalid bounding box";
continue; // while enumerating links
}
+ // In case horizontal/vertical coordinates are flipped, swap them.
+ if (rect.right < rect.left)
+ std::swap(rect.right, rect.left);
+ if (rect.bottom > rect.top)
+ std::swap(rect.bottom, rect.top);
+
QPdfLink linkData;
linkData.d->rects << QRectF(rect.left, pageHeight - rect.top,
rect.right - rect.left, rect.top - rect.bottom);
diff --git a/src/pdf/qpdfsearchmodel.cpp b/src/pdf/qpdfsearchmodel.cpp
index a8946ccfe..3109430f0 100644
--- a/src/pdf/qpdfsearchmodel.cpp
+++ b/src/pdf/qpdfsearchmodel.cpp
@@ -20,7 +20,6 @@ Q_LOGGING_CATEGORY(qLcS, "qt.pdf.search")
static const int UpdateTimerInterval = 100;
static const int ContextChars = 64;
-static const double CharacterHitTolerance = 6.0;
/*!
\class QPdfSearchModel
@@ -195,11 +194,23 @@ void QPdfSearchModel::setDocument(QPdfDocument *document)
if (d->document == document)
return;
+ disconnect(d->documentConnection);
+ d->documentConnection = connect(document, &QPdfDocument::pageCountChanged, this,
+ &QPdfSearchModel::onDocumentPageCountChanged);
+
d->document = document;
d->clearResults();
emit documentChanged();
}
+void QPdfSearchModel::onDocumentPageCountChanged(int count)
+{
+ Q_UNUSED(count);
+
+ Q_D(QPdfSearchModel);
+ d->clearResults();
+}
+
void QPdfSearchModel::timerEvent(QTimerEvent *event)
{
Q_D(QPdfSearchModel);
@@ -257,6 +268,7 @@ bool QPdfSearchModelPrivate::doSearch(int page)
}
FPDF_SCHHANDLE sh = FPDFText_FindStart(textPage, searchString.utf16(), 0, 0);
QList<QPdfLink> newSearchResults;
+ constexpr double CharacterHitTolerance = 6.0;
while (FPDFText_FindNext(sh)) {
int idx = FPDFText_GetSchResultIndex(sh);
int count = FPDFText_GetSchCount(sh);
diff --git a/src/pdf/qpdfsearchmodel.h b/src/pdf/qpdfsearchmodel.h
index c1e4e64ec..b1094b67b 100644
--- a/src/pdf/qpdfsearchmodel.h
+++ b/src/pdf/qpdfsearchmodel.h
@@ -55,6 +55,7 @@ Q_SIGNALS:
protected:
void updatePage(int page);
void timerEvent(QTimerEvent *event) override;
+ void onDocumentPageCountChanged(int count);
private:
QHash<int, QByteArray> m_roleNames;
diff --git a/src/pdf/qpdfsearchmodel_p.h b/src/pdf/qpdfsearchmodel_p.h
index 4922c81e9..5ffa08f5d 100644
--- a/src/pdf/qpdfsearchmodel_p.h
+++ b/src/pdf/qpdfsearchmodel_p.h
@@ -45,6 +45,8 @@ public:
int rowCountSoFar = 0;
int updateTimerId = -1;
int nextPageToUpdate = 0;
+
+ QMetaObject::Connection documentConnection;
};
QT_END_NAMESPACE
diff --git a/src/pdfquick/CMakeLists.txt b/src/pdfquick/CMakeLists.txt
index 112321015..560817446 100644
--- a/src/pdfquick/CMakeLists.txt
+++ b/src/pdfquick/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Qml Quick)
set(qml_files
diff --git a/src/pdfquick/qquickpdfdocument.cpp b/src/pdfquick/qquickpdfdocument.cpp
index 5564a7474..492c320d6 100644
--- a/src/pdfquick/qquickpdfdocument.cpp
+++ b/src/pdfquick/qquickpdfdocument.cpp
@@ -74,10 +74,8 @@ void QQuickPdfDocument::setSource(QUrl source)
emit sourceChanged();
const QQmlContext *context = qmlContext(this);
m_resolvedSource = context ? context->resolvedUrl(source) : source;
- if (source.scheme() == QLatin1String("qrc"))
- m_doc->load(QLatin1Char(':') + m_resolvedSource.path());
- else
- m_doc->load(m_resolvedSource.toLocalFile());
+ if (m_resolvedSource.isValid())
+ m_doc->load(QQmlFile::urlToLocalFileOrQrc(m_resolvedSource));
}
/*!
diff --git a/src/pdfwidgets/CMakeLists.txt b/src/pdfwidgets/CMakeLists.txt
index 2d2616556..d374315e3 100644
--- a/src/pdfwidgets/CMakeLists.txt
+++ b/src/pdfwidgets/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Widgets)
qt_internal_add_module(PdfWidgets
diff --git a/src/process/CMakeLists.txt b/src/process/CMakeLists.txt
index 7054cac79..63783af69 100644
--- a/src/process/CMakeLists.txt
+++ b/src/process/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(NOT DEFINED WEBENGINE_ROOT_SOURCE_DIR)
get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." REALPATH)
endif()
@@ -66,6 +69,7 @@ if(isFramework)
set_target_properties(${qtWebEngineProcessName} PROPERTIES
MACOSX_BUNDLE TRUE
INSTALL_RPATH "@loader_path/../../../../../../../"
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info_mac.plist.in"
)
target_sources(${qtWebEngineProcessName} PRIVATE QtWebEngineProcess.entitlements)
diff --git a/src/process/Info_mac.plist.in b/src/process/Info_mac.plist.in
new file mode 100644
index 000000000..22c8c026d
--- /dev/null
+++ b/src/process/Info_mac.plist.in
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleAllowMixedLocalizations</key>
+ <true/>
+
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>LSUIElement</key>
+ <true/>
+</dict>
+</plist>
diff --git a/src/process/QtWebEngineProcess.entitlements b/src/process/QtWebEngineProcess.entitlements
index f2fbabddb..59a4b6c15 100644
--- a/src/process/QtWebEngineProcess.entitlements
+++ b/src/process/QtWebEngineProcess.entitlements
@@ -8,5 +8,7 @@
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
+ <key>com.apple.security.cs.disable-executable-page-protection</key>
+ <true/>
</dict>
</plist>
diff --git a/src/webenginequick/CMakeLists.txt b/src/webenginequick/CMakeLists.txt
index ebe1ddf54..0081edb7f 100644
--- a/src/webenginequick/CMakeLists.txt
+++ b/src/webenginequick/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(ui)
qt_internal_add_qml_module(WebEngineQuick
@@ -34,7 +37,6 @@ qt_internal_add_qml_module(WebEngineQuick
api/qquickwebengineforeigntypes_p.h
api/qtwebenginequickglobal.cpp api/qtwebenginequickglobal.h
api/qtwebenginequickglobal_p.h
- qquickwebengine_accessible.cpp qquickwebengine_accessible.h
render_widget_host_view_qt_delegate_quickwindow.cpp render_widget_host_view_qt_delegate_quickwindow.h
ui_delegates_manager.cpp ui_delegates_manager.h
DEFINES
@@ -55,6 +57,11 @@ qt_internal_add_qml_module(WebEngineQuick
Qt::WebEngineCore
)
+qt_internal_extend_target(WebEngineQuick CONDITION QT_FEATURE_accessibility
+ SOURCES
+ qquickwebengine_accessible.cpp qquickwebengine_accessible.h
+)
+
qt_internal_extend_target(qtwebenginequickplugin
SOURCES
plugin.cpp
diff --git a/src/webenginequick/api/qquickwebengineaction.cpp b/src/webenginequick/api/qquickwebengineaction.cpp
index 70205f883..006715c70 100644
--- a/src/webenginequick/api/qquickwebengineaction.cpp
+++ b/src/webenginequick/api/qquickwebengineaction.cpp
@@ -20,7 +20,7 @@ QT_BEGIN_NAMESPACE
method. It provides information about the action, such as
whether it is \l enabled.
- The following code uses the \l WebEngineView::action() method to check if the
+ The following code uses the \l WebEngineView::action() method to check if
the copy action is enabled:
\code
@@ -30,6 +30,14 @@ QT_BEGIN_NAMESPACE
else
console.log("Copy is disabled.");
\endcode
+
+ A \l ToolButton can be connected to a WebEngineAction as follows:
+
+ \snippet qtwebengine_webengineaction.qml 0
+
+ A context menu could be implemented like this:
+
+ \snippet qtwebengine_webengineaction.qml 1
*/
QQuickWebEngineActionPrivate::QQuickWebEngineActionPrivate(const QVariant &data, const QString &text, const QString &iconName, bool enabled)
diff --git a/src/webenginequick/api/qquickwebenginedialogrequests.cpp b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
index 3c9f8a9a7..d49f17397 100644
--- a/src/webenginequick/api/qquickwebenginedialogrequests.cpp
+++ b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
@@ -685,6 +685,35 @@ void QQuickWebEngineFileDialogRequest::dialogReject()
\since QtWebEngine 1.10
\brief A request for showing a tooltip to the user.
+
+ A TooltipRequest is a request object that is passed as a
+ parameter of the WebEngineView::tooltipRequested signal. Use the
+ \c onTooltipRequested signal handler to handle requests for
+ custom tooltip menus at specific positions.
+
+ The \l accepted property of the request indicates whether the request
+ is handled by the user code or the default tooltip should
+ be displayed.
+
+ The following code uses a custom tooltip to handle the request:
+
+ \code
+ WebEngineView {
+ // ...
+ onTooltipRequested: function(request) {
+ if (request.type == TooltipRequest.Show) {
+ tooltip.visible = true;
+ tooltip.x = request.x;
+ tooltip.y = request.y;
+ tooltip.text = request.text;
+ } else {
+ tooltip.visible = false;
+ }
+ request.accepted = true;
+ }
+ // ...
+ }
+ \endcode
*/
QQuickWebEngineTooltipRequest::QQuickWebEngineTooltipRequest(
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 3c7989cf0..8292da894 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -823,6 +823,41 @@ QString QQuickWebEngineProfile::downloadPath() const
}
/*!
+ \qmlproperty bool WebEngineProfile::isPushServiceEnabled
+ \since QtWebEngine 6.5
+
+ Whether the push messaging service is enabled.
+ \note By default the push messaging service is disabled.
+ \note \QWE uses the \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)} as a browser push service.
+ Therefore, all push messages will go through the Google push service and its respective servers.
+*/
+
+/*!
+ \property QQuickWebEngineProfile::isPushServiceEnabled
+ \since QtWebEngine 6.5
+
+ Whether the push messaging service is enabled.
+ \note By default the push messaging service is disabled.
+ \note \QWE uses the \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)} as a browser push service.
+ Therefore, all push messages will go through the Google push service and its respective servers.
+*/
+
+bool QQuickWebEngineProfile::isPushServiceEnabled() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->profileAdapter()->pushServiceEnabled();
+}
+
+void QQuickWebEngineProfile::setPushServiceEnabled(bool enabled)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (isPushServiceEnabled() == enabled)
+ return;
+ d->profileAdapter()->setPushServiceEnabled(enabled);
+ emit pushServiceEnabledChanged();
+}
+
+/*!
Returns the cookie store for this profile.
*/
diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h
index 77e367d02..29d6ee0b2 100644
--- a/src/webenginequick/api/qquickwebengineprofile.h
+++ b/src/webenginequick/api/qquickwebengineprofile.h
@@ -37,6 +37,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject {
Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION(1,3))
Q_PROPERTY(QQuickWebEngineScriptCollection *userScripts READ userScripts)
Q_PROPERTY(QString downloadPath READ downloadPath WRITE setDownloadPath NOTIFY downloadPathChanged FINAL REVISION(1,5))
+ Q_PROPERTY(bool isPushServiceEnabled READ isPushServiceEnabled WRITE setPushServiceEnabled NOTIFY pushServiceEnabledChanged FINAL REVISION(6,5))
QML_NAMED_ELEMENT(WebEngineProfile)
QML_ADDED_IN_VERSION(1, 1)
QML_EXTRA_VERSION(2, 0)
@@ -108,6 +109,9 @@ public:
QString downloadPath() const;
void setDownloadPath(const QString &path);
+ bool isPushServiceEnabled() const;
+ void setPushServiceEnabled(bool enable);
+
QWebEngineClientCertificateStore *clientCertificateStore();
static QQuickWebEngineProfile *defaultProfile();
@@ -125,6 +129,7 @@ Q_SIGNALS:
Q_REVISION(1,3) void spellCheckLanguagesChanged();
Q_REVISION(1,3) void spellCheckEnabledChanged();
Q_REVISION(1,5) void downloadPathChanged();
+ Q_REVISION(6,5) void pushServiceEnabledChanged();
void downloadRequested(QQuickWebEngineDownloadRequest *download);
void downloadFinished(QQuickWebEngineDownloadRequest *download);
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index deb68c6d3..5e248327d 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -24,7 +24,6 @@
#include "file_picker_controller.h"
#include "find_text_helper.h"
#include "javascript_dialog_controller.h"
-#include "qquickwebengine_accessible.h"
#include "render_widget_host_view_qt_delegate_item.h"
#include "render_widget_host_view_qt_delegate_quickwindow.h"
#include "touch_selection_menu_controller.h"
@@ -37,7 +36,6 @@
#include <QtWebEngineCore/qwebenginefullscreenrequest.h>
#include <QtWebEngineCore/qwebengineloadinginfo.h>
#include <QtWebEngineCore/qwebenginenavigationrequest.h>
-#include <QtWebEngineCore/qwebenginequotarequest.h>
#include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
#include <QtWebEngineCore/qwebenginescriptcollection.h>
#include <QtWebEngineCore/private/qwebenginecontextmenurequest_p.h>
@@ -59,6 +57,12 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlproperty.h>
+#if QT_CONFIG(accessibility)
+#include "qquickwebengine_accessible.h"
+
+#include <QtGui/qaccessible.h>
+#endif
+
#if QT_CONFIG(webengine_printing_and_pdf)
#include <QtCore/qmargins.h>
#include <QtGui/qpagelayout.h>
@@ -174,7 +178,6 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_fullscreenMode(false)
, isLoading(false)
, m_activeFocusOnPress(true)
- , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio())
, m_webChannel(nullptr)
, m_webChannelWorld(0)
, m_defaultAudioMuted(false)
@@ -651,12 +654,6 @@ void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &secur
adapter->grantMouseLockPermission(securityOrigin, false);
}
-void QQuickWebEngineViewPrivate::runQuotaRequest(QWebEngineQuotaRequest request)
-{
- Q_Q(QQuickWebEngineView);
- Q_EMIT q->quotaRequested(request);
-}
-
void QQuickWebEngineViewPrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
{
Q_Q(QQuickWebEngineView);
@@ -1349,7 +1346,11 @@ void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId,
d->ensureContentsAdapter();
if (!callback.isUndefined()) {
quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, worldId);
- d->m_callbacks.insert(requestId, callback);
+ if (requestId) {
+ d->m_callbacks.insert(requestId, callback);
+ } else {
+ callback.call();
+ }
} else
d->adapter->runJavaScript(script, worldId);
}
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index 00c6f3018..906e7c3fd 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -16,6 +16,7 @@
//
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtWebEngineCore/qwebenginequotarequest.h>
#include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h>
#include <QtGui/qcolor.h>
#include <QtQml/qqmlregistration.h>
@@ -46,7 +47,6 @@ class QWebEngineHistory;
class QWebEngineLoadingInfo;
class QWebEngineNavigationRequest;
class QWebEngineNewWindowRequest;
-class QWebEngineQuotaRequest;
class QWebEngineRegisterProtocolHandlerRequest;
class QQuickWebEngineScriptCollection;
class QQuickWebEngineTouchSelectionMenuRequest;
@@ -516,7 +516,10 @@ Q_SIGNALS:
Q_REVISION(1,4) void colorDialogRequested(QQuickWebEngineColorDialogRequest *request);
Q_REVISION(1,4) void fileDialogRequested(QQuickWebEngineFileDialogRequest *request);
Q_REVISION(1,5) void pdfPrintingFinished(const QString &filePath, bool success);
- Q_REVISION(1,7) void quotaRequested(const QWebEngineQuotaRequest &request);
+#if QT_DEPRECATED_SINCE(6, 5)
+ QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.")
+ Q_REVISION(1, 7) void quotaRequested(const QWebEngineQuotaRequest &request);
+#endif
Q_REVISION(1,7) void geometryChangeRequested(const QRect &geometry, const QRect &frameGeometry);
Q_REVISION(1,7) void inspectedViewChanged();
Q_REVISION(1,7) void devToolsViewChanged();
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index 2d28a89af..aa67fd291 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -27,7 +27,6 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qstring.h>
-#include <QtGui/qaccessibleobject.h>
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateItem;
@@ -103,7 +102,6 @@ public:
void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override;
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
- void runQuotaRequest(QWebEngineQuotaRequest) override;
void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) override;
QObject *accessibilityParentObject() override;
@@ -158,8 +156,6 @@ public:
bool m_fullscreenMode;
bool isLoading;
bool m_activeFocusOnPress;
- bool m_navigationActionTriggered;
- qreal devicePixelRatio;
QMap<quint64, QJSValue> m_callbacks;
QQmlWebChannel *m_webChannel;
QPointer<QQuickWebEngineView> inspectedView;
diff --git a/src/webenginequick/api/qtwebenginequickglobal.cpp b/src/webenginequick/api/qtwebenginequickglobal.cpp
index 607777e55..f8f520a05 100644
--- a/src/webenginequick/api/qtwebenginequickglobal.cpp
+++ b/src/webenginequick/api/qtwebenginequickglobal.cpp
@@ -43,9 +43,13 @@ void initialize()
QtWebEngineCore::initialize();
return;
}
+
// call initialize the same way as widgets do
qAddPreRoutine(QtWebEngineCore::initialize);
- QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
+ auto api = QQuickWindow::graphicsApi();
+ if (api != QSGRendererInterface::OpenGL && api != QSGRendererInterface::Vulkan
+ && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11)
+ QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
}
} // namespace QtWebEngineQuick
diff --git a/src/webenginequick/configure.cmake b/src/webenginequick/configure.cmake
index 649154301..b256e5a1d 100644
--- a/src/webenginequick/configure.cmake
+++ b/src/webenginequick/configure.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_feature("webenginequick-ui-delegates" PRIVATE
SECTION "WebEngine"
LABEL "UI Delegates"
diff --git a/src/webenginequick/doc/snippets/minimal/main.cpp b/src/webenginequick/doc/snippets/minimal/main.cpp
new file mode 100644
index 000000000..e17493a36
--- /dev/null
+++ b/src/webenginequick/doc/snippets/minimal/main.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [Minimal Example]
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+ QtWebEngineQuick::initialize();
+ QGuiApplication app(argc, argv);
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ return app.exec();
+}
+//! [Minimal Example]
diff --git a/src/webenginequick/doc/snippets/minimal/main.qml b/src/webenginequick/doc/snippets/minimal/main.qml
new file mode 100644
index 000000000..87a8757df
--- /dev/null
+++ b/src/webenginequick/doc/snippets/minimal/main.qml
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [Minimal Example]
+import QtQuick
+import QtQuick.Window
+import QtWebEngine
+
+Window {
+ width: 1024
+ height: 750
+ visible: true
+ WebEngineView {
+ anchors.fill: parent
+ url: "https://www.qt.io"
+ }
+}
+//! [Minimal Example]
diff --git a/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml b/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml
new file mode 100644
index 000000000..2fd5f490b
--- /dev/null
+++ b/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml
@@ -0,0 +1,123 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Window
+import QtWebEngine
+import QtQuick.Controls
+import QtQuick.Layouts
+
+ApplicationWindow {
+ id: window
+ visible: true
+ width: 800
+ height: 600
+ title: qsTr("WebEngineAction Example")
+
+ header: ToolBar {
+ RowLayout {
+ anchors.fill: parent
+//! [0]
+ ToolButton {
+ property int itemAction: WebEngineView.Back
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+//! [0]
+ ToolButton {
+ property int itemAction: WebEngineView.Forward
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ ToolButton {
+ property int itemAction: webEngineView.loading ? WebEngineView.Stop : WebEngineView.Reload
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ TextField {
+ Layout.fillWidth: true
+
+ text: webEngineView.url
+ selectByMouse: true
+ onEditingFinished: webEngineView.url = utils.fromUserInput(text)
+ }
+
+ ToolButton {
+ id: settingsButton
+ text: "Settings"
+ icon.name: "settings-configure"
+ display: AbstractButton.TextUnderIcon
+ onClicked: settingsMenu.open()
+ checked: settingsMenu.visible
+
+ Menu {
+ id: settingsMenu
+ y: settingsButton.height
+
+ MenuItem {
+ id: customContextMenuOption
+ checkable: true
+ checked: true
+
+ text: "Custom context menu"
+ }
+ }
+ }
+ }
+ }
+
+ WebEngineView {
+ id: webEngineView
+ url: "https://qt.io"
+ anchors.fill: parent
+
+ Component.onCompleted: {
+ profile.downloadRequested.connect(function(download){
+ download.accept();
+ })
+ }
+
+//! [1]
+ property Menu contextMenu: Menu {
+ Repeater {
+ model: [
+ WebEngineView.Back,
+ WebEngineView.Forward,
+ WebEngineView.Reload,
+ WebEngineView.SavePage,
+ WebEngineView.Copy,
+ WebEngineView.Paste,
+ WebEngineView.Cut,
+ WebEngineView.ChangeTextDirectionLTR,
+ WebEngineView.ChangeTextDirectionRTL,
+ ]
+ MenuItem {
+ text: webEngineView.action(modelData).text
+ enabled: webEngineView.action(modelData).enabled
+ onClicked: webEngineView.action(modelData).trigger()
+ icon.name: webEngineView.action(modelData).iconName
+ display: MenuItem.TextBesideIcon
+ }
+ }
+ }
+
+ onContextMenuRequested: function(request) {
+ if (customContextMenuOption.checked) {
+ request.accepted = true;
+ contextMenu.popup();
+ }
+ }
+//! [1]
+ }
+}
diff --git a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
index 19348508c..ecf3a4a6e 100644
--- a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
+++ b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
@@ -17,4 +17,13 @@
in the Qt6 package and \c target_link_libraries() to link against the module:
\snippet qtwebengine_build_snippet.qdoc 2
+
+ The minimal amount of code needed to load and display an HTML page using the QML engine
+ requires a proper initialization:
+
+ \snippet minimal/main.cpp Minimal Example
+
+ Where the content of main.qml is simply:
+
+ \snippet minimal/main.qml Minimal Example
*/
diff --git a/src/webenginequick/doc/src/quota_request.qdoc b/src/webenginequick/doc/src/quota_request.qdoc
index 579d78008..01f4ec286 100644
--- a/src/webenginequick/doc/src/quota_request.qdoc
+++ b/src/webenginequick/doc/src/quota_request.qdoc
@@ -6,8 +6,12 @@
\instantiates QWebEngineQuotaRequest
\inqmlmodule QtWebEngine
\since QtWebEngine 1.7
+ \deprecated [6.5] Requesting host quota is no longer supported by Chromium.
- \brief A utility type for the WebEngineView::quotaRequested() signal.
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
+
+ For further details, see https://crbug.com/1233525
\sa WebEngineView::quotaRequested()
*/
@@ -15,36 +19,18 @@
/*!
\qmlproperty url QuotaRequest::origin
\readonly
-
- The URL of the web page that issued the quota request.
*/
/*!
\qmlproperty qint64 QuotaRequest::requestedSize
\readonly
-
- Contains the size of the requested disk space in bytes.
*/
/*!
\qmlmethod void QuotaRequest::accept()
-
- Accepts the quota request.
-
- \qml
- WebEngineView {
- onQuotaRequested: function(request) {
- if (request.requestedSize <= 5 * 1024 * 1024)
- request.accept();
- else
- request.reject();
- }
- }
- \endqml
*/
/*!
\qmlmethod void QuotaRequest::reject()
- Rejects the quota request.
*/
diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index 6534518e7..6390c0c02 100644
--- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc
+++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
@@ -24,7 +24,7 @@
\l QtWebEngineQuick::initialize in the application main source file, as illustrated by the
following code snippet:
- \quotefromfile webenginequick/minimal/main.cpp
+ \quotefromfile minimal/main.cpp
\skipto main
\printuntil }
@@ -39,7 +39,7 @@
The following sample QML application loads a web page using the \c url property:
- \quotefromfile webenginequick/minimal/main.qml
+ \quotefromfile minimal/main.qml
\skipto import
\printuntil /^\}/
@@ -1230,10 +1230,13 @@
/*!
\qmlsignal WebEngineView::quotaRequested(QuotaRequest request)
\since QtWebEngine 1.7
+ \deprecated [6.5] This signal is no longer emitted.
- This signal is emitted when the web page issues a \a request for a larger persistent storage
- than the application's current allocation in File System API. The default quota
- is 0 bytes.
+ Requesting host quota is no longer supported by Chromium.
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
+
+ For further details, see https://crbug.com/1233525
\sa QuotaRequest
*/
@@ -1498,6 +1501,27 @@
// ...
}
\endcode
+
+ The touch handles can be also switched dynamically:
+
+ \code
+ Component {
+ id: circleTouchHandle
+ Rectangle {
+ color: "blue"
+ radius: 50
+ }
+ }
+ function showDefaultHandle(isDefault) {
+ if (isDefault)
+ webEngineView.touchHandleDelegate = circleTouchHandle
+ else
+ webEngineView.touchHandleDelegate = null
+ }
+ \endcode
+
+ \note If no delegate is provided, Chromium's default touch handles will appear.
+
*/
\sa {WebEngine Qt Quick Custom Touch Handle Example}
diff --git a/src/webenginequick/qquickwebengine_accessible.cpp b/src/webenginequick/qquickwebengine_accessible.cpp
index 80e2adbbd..2941f01b5 100644
--- a/src/webenginequick/qquickwebengine_accessible.cpp
+++ b/src/webenginequick/qquickwebengine_accessible.cpp
@@ -10,8 +10,6 @@
#include "api/qquickwebengineview_p_p.h"
#include "web_contents_adapter.h"
-
-#if QT_CONFIG(accessibility)
QT_BEGIN_NAMESPACE
QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o)
: QAccessibleObject(o)
@@ -147,4 +145,3 @@ QQuickWebEngineViewAccessible *RenderWidgetHostViewQtDelegateQuickAccessible::vi
return static_cast<QQuickWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
}
} // namespace QtWebEngineCore
-#endif // QT_CONFIG(accessibility)
diff --git a/src/webenginequick/qquickwebengine_accessible.h b/src/webenginequick/qquickwebengine_accessible.h
index b1a4a34f5..479de9789 100644
--- a/src/webenginequick/qquickwebengine_accessible.h
+++ b/src/webenginequick/qquickwebengine_accessible.h
@@ -7,8 +7,6 @@
#include <QtCore/qpointer.h>
#include <QtGui/qaccessibleobject.h>
-#if QT_CONFIG(accessibility)
-
QT_BEGIN_NAMESPACE
class QQuickWebEngineView;
@@ -55,6 +53,4 @@ private:
};
} // namespace QtWebEngineCore
-#endif // QT_CONFIG(accessibility)
-
#endif // QQUICKWEBENGINE_ACCESSIBLE_H
diff --git a/src/webenginequick/ui/CMakeLists.txt b/src/webenginequick/ui/CMakeLists.txt
index f2f281ef5..96dedf016 100644
--- a/src/webenginequick/ui/CMakeLists.txt
+++ b/src/webenginequick/ui/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
set(qml_files
"AlertDialog.qml"
"AuthenticationDialog.qml"
diff --git a/src/webenginequick/ui_delegates_manager.cpp b/src/webenginequick/ui_delegates_manager.cpp
index a075a4c9b..b4036c5ee 100644
--- a/src/webenginequick/ui_delegates_manager.cpp
+++ b/src/webenginequick/ui_delegates_manager.cpp
@@ -33,15 +33,9 @@
namespace QtWebEngineCore {
#define NO_SEPARATOR
-#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
-#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
- case UIDelegatesManager::TYPE:\
- return QString::fromLatin1(#TYPE ##".qml");
-#else
#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
case UIDelegatesManager::TYPE:\
return QStringLiteral(#TYPE".qml");
-#endif
static QString fileNameForComponent(UIDelegatesManager::ComponentType type)
{
diff --git a/src/webenginewidgets/CMakeLists.txt b/src/webenginewidgets/CMakeLists.txt
index 97bde6b56..f9365adc9 100644
--- a/src/webenginewidgets/CMakeLists.txt
+++ b/src/webenginewidgets/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(TARGET Qt::Designer)
add_subdirectory(plugins/qwebengineview)
else()
@@ -8,13 +11,15 @@ qt_internal_add_module(WebEngineWidgets
api/qtwebenginewidgetsglobal.h
api/qwebenginenotificationpresenter.cpp api/qwebenginenotificationpresenter_p.h
api/qwebengineview.cpp api/qwebengineview.h api/qwebengineview_p.h
- qwebengine_accessible.cpp qwebengine_accessible.h
ui/autofillpopupwidget.cpp ui/autofillpopupwidget_p.h
+ ui/touchhandlewidget.cpp ui/touchhandlewidget_p.h
+ ui/touchselectionmenuwidget.cpp ui/touchselectionmenuwidget_p.h
DEFINES
QT_BUILD_WEBENGINEWIDGETS_LIB
INCLUDE_DIRECTORIES
../core
api
+ ui
LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
@@ -29,6 +34,11 @@ qt_internal_add_module(WebEngineWidgets
Qt::WebEngineCore
)
+qt_internal_extend_target(WebEngineWidgets CONDITION QT_FEATURE_accessibility
+ SOURCES
+ qwebengine_accessible.cpp qwebengine_accessible.h
+)
+
qt_internal_extend_target(WebEngineWidgets CONDITION QT_FEATURE_webengine_printing_and_pdf
PUBLIC_LIBRARIES
Qt::PrintSupport
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index b9aef4a38..35fb98138 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -6,8 +6,9 @@
#include "qwebengineview_p.h"
#include "render_widget_host_view_qt_delegate_client.h"
#include "render_widget_host_view_qt_delegate_item.h"
-#include "qwebengine_accessible.h"
#include "ui/autofillpopupwidget_p.h"
+#include "touchhandlewidget_p.h"
+#include "touchselectionmenuwidget_p.h"
#include <QtWebEngineCore/private/qwebenginepage_p.h>
#include <QtWebEngineCore/qwebenginecontextmenurequest.h>
@@ -17,6 +18,7 @@
#include "autofill_popup_controller.h"
#include "color_chooser_controller.h"
+#include "touch_selection_menu_controller.h"
#include "web_contents_adapter.h"
#include <QContextMenuEvent>
@@ -28,6 +30,10 @@
#include <QGuiApplication>
#include <QQuickWidget>
+#if QT_CONFIG(accessibility)
+#include "qwebengine_accessible.h"
+#endif
+
#if QT_CONFIG(action)
#include <QAction>
#endif
@@ -57,6 +63,7 @@
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/printer_worker.h"
+#include <QPrintEngine>
#include <QPrinter>
#include <QThread>
#endif
@@ -807,7 +814,11 @@ void QWebEngineViewPrivate::didPrintPage(QPrinter *&currentPrinter, QSharedPoint
printerWorker->m_documentCopies = currentPrinter->copyCount();
printerWorker->m_collateCopies = currentPrinter->collateCopies();
- QObject::connect(printerWorker, &QtWebEngineCore::PrinterWorker::resultReady, q, [q, &currentPrinter](bool success) {
+ int oldCopyCount = currentPrinter->copyCount();
+ currentPrinter->printEngine()->setProperty(QPrintEngine::PPK_CopyCount, 1);
+
+ QObject::connect(printerWorker, &QtWebEngineCore::PrinterWorker::resultReady, q, [q, &currentPrinter, oldCopyCount](bool success) {
+ currentPrinter->printEngine()->setProperty(QPrintEngine::PPK_CopyCount, oldCopyCount);
currentPrinter = nullptr;
Q_EMIT q->printFinished(success);
});
@@ -1397,6 +1408,9 @@ void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &re
\note Printing runs on the browser process, which is by default not sandboxed.
+ \note The data generation step of printing can be interrupted for a short period of time using
+ the \l QWebEnginePage::Stop web action.
+
\note This function rasterizes the result when rendering onto \a printer. Please consider raising
the default resolution of \a printer to at least 300 DPI or using printToPdf() to produce
PDF file output more effectively.
@@ -1591,6 +1605,49 @@ bool QContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem)
}
#endif // QT_CONFIG(action)
+QtWebEngineCore::TouchHandleDrawableDelegate *
+QWebEngineViewPrivate::createTouchHandleDelegate(const QMap<int, QImage> &images)
+{
+ Q_Q(QWebEngineView);
+ return new QtWebEngineWidgetUI::TouchHandleWidget(q, images);
+}
+
+void QWebEngineViewPrivate::hideTouchSelectionMenu()
+{
+ if (m_touchSelectionMenu)
+ m_touchSelectionMenu->close();
+}
+
+void QWebEngineViewPrivate::showTouchSelectionMenu(
+ QtWebEngineCore::TouchSelectionMenuController *controller, const QRect &selectionBounds)
+{
+ Q_ASSERT(m_touchSelectionMenu == nullptr);
+ Q_Q(QWebEngineView);
+
+ // Do not show outside of view
+ QSize parentSize = q->nativeParentWidget() ? q->nativeParentWidget()->size() : q->size();
+ if (selectionBounds.x() < 0 || selectionBounds.x() > parentSize.width()
+ || selectionBounds.y() < 0 || selectionBounds.y() > parentSize.height())
+ return;
+
+ m_touchSelectionMenu = new QtWebEngineWidgetUI::TouchSelectionMenuWidget(q, controller);
+
+ const int kSpacingBetweenButtons = 2;
+ const int kMenuButtonMinWidth = 80;
+ const int kMenuButtonMinHeight = 40;
+
+ int buttonCount = controller->buttonCount();
+ int width = (kSpacingBetweenButtons * (buttonCount + 1)) + (kMenuButtonMinWidth * buttonCount);
+ int height = kMenuButtonMinHeight + kSpacingBetweenButtons;
+ int x = (selectionBounds.x() + selectionBounds.x() + selectionBounds.width() - width) / 2;
+ int y = selectionBounds.y() - height - 2;
+
+ QPoint pos = q->mapToGlobal(QPoint(x, y));
+
+ m_touchSelectionMenu->setGeometry(pos.x(), pos.y(), width, height);
+ m_touchSelectionMenu->show();
+}
+
QT_END_NAMESPACE
#include "moc_qwebengineview.cpp"
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index 379fcae75..dc1393885 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -19,7 +19,6 @@ class AutofillPopupWidget;
QT_BEGIN_NAMESPACE
class QContextMenuEvent;
-class QMenu;
class QPrinter;
class QUrl;
class QWebEngineContextMenuRequest;
@@ -28,6 +27,7 @@ class QWebEngineHttpRequest;
class QWebEngineSettings;
class QWebEngineViewAccessible;
class QWebEngineViewPrivate;
+class QMenu;
class QWEBENGINEWIDGETS_EXPORT QWebEngineView : public QWidget
{
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index 7855f9ef3..7c0f3fe60 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -25,10 +25,13 @@ class QWebEngineContextMenuRequest;
class WebEngineQuickWidget;
class RenderWidgetHostViewQtDelegate;
class RenderWidgetHostViewQtDelegateClient;
+class TouchSelectionMenuController;
}
namespace QtWebEngineWidgetUI {
class AutofillPopupWidget;
+class TouchHandleDrawableDelegate;
+class TouchSelectionMenuWidget;
}
QT_BEGIN_NAMESPACE
@@ -71,7 +74,12 @@ public:
void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
const QRect &bounds, bool autoselectFirstSuggestion) override;
void hideAutofillPopup() override;
+ QtWebEngineCore::TouchHandleDrawableDelegate *
+ createTouchHandleDelegate(const QMap<int, QImage> &images) override;
+ void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *,
+ const QRect &) override;
+ void hideTouchSelectionMenu() override;
QWebEngineViewPrivate();
virtual ~QWebEngineViewPrivate();
static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view);
@@ -90,6 +98,7 @@ public:
mutable bool m_ownsPage;
QWebEngineContextMenuRequest *m_contextRequest;
QScopedPointer<QtWebEngineWidgetUI::AutofillPopupWidget> m_autofillPopupWidget;
+ QPointer<QtWebEngineWidgetUI::TouchSelectionMenuWidget> m_touchSelectionMenu;
};
class QContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt
diff --git a/src/webenginewidgets/doc/snippets/push-notifications/commands b/src/webenginewidgets/doc/snippets/push-notifications/commands
new file mode 100644
index 000000000..aee9761c1
--- /dev/null
+++ b/src/webenginewidgets/doc/snippets/push-notifications/commands
@@ -0,0 +1,19 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [0]
+npm init -y
+npm install web-push express
+//! [0]
+
+//! [1]
+"start": "node server.js"
+//! [1]
+
+//! [2]
+./node_odules/.bin/web-push generate-vapid-keys
+//! [2]
+
+//! [3]
+npm start
+//! [3]
diff --git a/src/webenginewidgets/doc/snippets/simple/main.cpp b/src/webenginewidgets/doc/snippets/simple/main.cpp
index f887aabaa..08613906b 100644
--- a/src/webenginewidgets/doc/snippets/simple/main.cpp
+++ b/src/webenginewidgets/doc/snippets/simple/main.cpp
@@ -1,18 +1,19 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//! [Minimal Example]
#include <QApplication>
-#include <QUrl>
#include <QWebEngineView>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- QWidget *parent = nullptr;
//! [Using QWebEngineView]
- QWebEngineView *view = new QWebEngineView(parent);
- view->load(QUrl("http://qt-project.org/"));
- view->show();
+ QWebEngineView view;
+ view.load(QUrl("https://qt-project.org/"));
+ view.resize(1024, 750);
+ view.show();
//! [Using QWebEngineView]
return app.exec();
}
+//! [Minimal Example]
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
index df06909df..ef5a1c4b5 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
@@ -24,4 +24,9 @@
\snippet qtwebenginewidgets_build_snippet.qdoc 2
\endif
+
+ The minimum amount of code needed to load and display an HTML page requires just
+ implementing the \c QWebEngineView class.
+
+ \snippet simple/main.cpp Minimal Example
*/
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 14e6c3ed8..84f71cf10 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -61,7 +61,7 @@
new windows, such as pop-up windows, you can subclass QWebEngineView and
reimplement the createWindow() function.
- \sa {WebEngine Widgets Simple Browser Example}, {WebEngine Content Manipulation Example}, {WebEngine Markdown Editor Example}
+ \sa {WebEngine Widgets Simple Browser Example}, {WebEngine Content Manipulation Example}, {WebEngine Recipe Browser Example}
*/
diff --git a/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt b/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt
index 3e6f324da..0e7644bf7 100644
--- a/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt
+++ b/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_plugin(QWebEngineViewPlugin
OUTPUT_NAME qwebengineview
PLUGIN_TYPE designer
diff --git a/src/webenginewidgets/qwebengine_accessible.cpp b/src/webenginewidgets/qwebengine_accessible.cpp
index 53a812604..6880a5a3a 100644
--- a/src/webenginewidgets/qwebengine_accessible.cpp
+++ b/src/webenginewidgets/qwebengine_accessible.cpp
@@ -8,8 +8,6 @@
#include "web_contents_adapter.h"
-#if QT_CONFIG(accessibility)
-
QT_BEGIN_NAMESPACE
QWebEngineViewAccessible::QWebEngineViewAccessible(QWebEngineView *o) : QAccessibleWidget(o)
@@ -102,5 +100,3 @@ QWebEngineViewAccessible *RenderWidgetHostViewQtDelegateWidgetAccessible::viewAc
}
} // namespace QtWebEngineCore
-
-#endif // QT_CONFIG(accessibility)
diff --git a/src/webenginewidgets/qwebengine_accessible.h b/src/webenginewidgets/qwebengine_accessible.h
index ac87bb343..f47996cf7 100644
--- a/src/webenginewidgets/qwebengine_accessible.h
+++ b/src/webenginewidgets/qwebengine_accessible.h
@@ -4,10 +4,8 @@
#ifndef QWEBENGINE_ACCESSIBLE_H
#define QWEBENGINE_ACCESSIBLE_H
-#include <QAccessibleWidget>
-#include <QPointer>
-
-#if QT_CONFIG(accessibility)
+#include <QtCore/QPointer>
+#include <QtWidgets/QAccessibleWidget>
QT_BEGIN_NAMESPACE
class QWebEngineView;
@@ -47,6 +45,5 @@ private:
QPointer<QWebEngineView> m_view;
};
} // namespace QtWebEngineCore
-#endif // QT_CONFIG(accessibility)
#endif // QWEBENGINE_ACCESSIBLE_H
diff --git a/src/webenginewidgets/ui/touchhandlewidget.cpp b/src/webenginewidgets/ui/touchhandlewidget.cpp
new file mode 100644
index 000000000..88af0ff36
--- /dev/null
+++ b/src/webenginewidgets/ui/touchhandlewidget.cpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "touchhandlewidget_p.h"
+#include "qwebengineview.h"
+
+#include <QBoxLayout>
+#include <QGraphicsOpacityEffect>
+#include <QLabel>
+#include <QWidget>
+
+namespace QtWebEngineWidgetUI {
+TouchHandleWidget::TouchHandleWidget(QWebEngineView *view, const QMap<int, QImage> &images)
+ : m_widget(new QWidget(view))
+ , m_label(new QLabel(m_widget))
+ , m_opacityEffect(new QGraphicsOpacityEffect(m_widget))
+ , m_images(images)
+{
+ m_widget->setAttribute(Qt::WA_AcceptTouchEvents, true);
+ m_widget->setAttribute(Qt::WA_TransparentForMouseEvents, true);
+}
+
+TouchHandleWidget::~TouchHandleWidget()
+{
+}
+
+void TouchHandleWidget::setImage(int orientation)
+{
+ const QImage &img = m_images[orientation];
+ m_label->setPixmap(QPixmap::fromImage(img));
+ m_label->setFrameStyle(QFrame::NoFrame);
+ m_label->resize(img.size());
+ m_label->setVisible(true);
+
+ QVBoxLayout layout;
+ layout.setSpacing(0);
+ layout.setContentsMargins(QMargins());
+ layout.addWidget(m_label);
+ layout.setParent(m_widget);
+ m_widget->setLayout(&layout);
+ m_widget->resize(img.size());
+}
+
+void TouchHandleWidget::setBounds(const QRect &bounds)
+{
+ m_widget->setGeometry(bounds);
+}
+
+void TouchHandleWidget::setVisible(bool visible)
+{
+ m_widget->setVisible(visible);
+}
+
+void TouchHandleWidget::setOpacity(float opacity)
+{
+ m_opacityEffect->setOpacity(opacity);
+ m_widget->setGraphicsEffect(m_opacityEffect);
+}
+} // namespace QtWebEngineWidgetUI
diff --git a/src/webenginewidgets/ui/touchhandlewidget_p.h b/src/webenginewidgets/ui/touchhandlewidget_p.h
new file mode 100644
index 000000000..9f181c935
--- /dev/null
+++ b/src/webenginewidgets/ui/touchhandlewidget_p.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef TOUCHHANDLEWIDGET_P_H
+#define TOUCHHANDLEWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "touch_handle_drawable_client.h"
+
+#include <QImage>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+class QGraphicsOpacityEffect;
+class QLabel;
+class QWebEngineView;
+class QWidget;
+QT_END_NAMESPACE
+
+namespace QtWebEngineWidgetUI {
+class TouchHandleWidget : public QtWebEngineCore::TouchHandleDrawableDelegate
+{
+public:
+ TouchHandleWidget(QWebEngineView *view, const QMap<int, QImage> &images);
+ ~TouchHandleWidget();
+
+ void setImage(int orientation) override;
+ void setBounds(const QRect &bounds) override;
+ void setVisible(bool visible) override;
+ void setOpacity(float opacity) override;
+
+private:
+ QWidget *m_widget;
+ QLabel *m_label;
+ QGraphicsOpacityEffect *m_opacityEffect;
+ QMap<int, QImage> m_images;
+};
+} // namespace QtWebEngineWidgetUI
+
+#endif // TOUCHHANDLEWIDGET_P_H
diff --git a/src/webenginewidgets/ui/touchselectionmenuwidget.cpp b/src/webenginewidgets/ui/touchselectionmenuwidget.cpp
new file mode 100644
index 000000000..ff69fe84b
--- /dev/null
+++ b/src/webenginewidgets/ui/touchselectionmenuwidget.cpp
@@ -0,0 +1,117 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "touchselectionmenuwidget_p.h"
+#include "qwebengineview.h"
+
+#include "touch_selection_menu_controller.h"
+
+#include <QBoxLayout>
+#include <QEvent>
+
+namespace QtWebEngineWidgetUI {
+namespace {
+// The Widgets module is built with rtti in developer-build while Core is not.
+// The MOC will throw "undefined reference to typeinfo..." errors if we connect slots
+// from QtWebEngineCore via function pointers, because it expects rtti on them.
+// To workaround this we use lambdas.
+void connectButton(TouchSelectionMenuWidget::TouchButton *button, std::function<void()> callback)
+{
+ QObject::connect(button, &QPushButton::clicked, std::move(callback));
+}
+} // namespace
+
+TouchSelectionMenuWidget::TouchButton::TouchButton(QString name, QWidget *parent)
+ : QPushButton(name, parent)
+{
+ setAttribute(Qt::WA_AcceptTouchEvents, true);
+}
+
+TouchSelectionMenuWidget::TouchButton::~TouchButton()
+{
+}
+
+bool TouchSelectionMenuWidget::TouchButton::event(QEvent *ev)
+{
+ switch (ev->type()) {
+ case QEvent::TouchBegin:
+ ev->accept();
+ return true;
+ case QEvent::TouchEnd:
+ Q_EMIT clicked();
+ ev->accept();
+ return true;
+ default:
+ break;
+ }
+
+ return QPushButton::event(ev);
+}
+
+TouchSelectionMenuWidget::TouchSelectionMenuWidget(
+ QWebEngineView *view, QtWebEngineCore::TouchSelectionMenuController *controller)
+ : QWidget(view,
+ Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
+ | Qt::WindowDoesNotAcceptFocus)
+{
+ setAttribute(Qt::WA_AcceptTouchEvents, true);
+ setAttribute(Qt::WA_TransparentForMouseEvents, true);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ bool cutEnabled =
+ controller->isCommandEnabled(QtWebEngineCore::TouchSelectionMenuController::Cut);
+ bool copyEnabled =
+ controller->isCommandEnabled(QtWebEngineCore::TouchSelectionMenuController::Copy);
+ bool pasteEnabled =
+ controller->isCommandEnabled(QtWebEngineCore::TouchSelectionMenuController::Paste);
+
+ QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ QHBoxLayout *layout = new QHBoxLayout();
+
+ if (cutEnabled) {
+ TouchButton *button = new TouchButton(tr("Cut"), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->cut(); });
+ }
+
+ if (copyEnabled) {
+ TouchButton *button = new TouchButton(tr("Copy"), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->copy(); });
+ }
+
+ if (pasteEnabled) {
+ TouchButton *button = new TouchButton(tr("Paste"), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->paste(); });
+ }
+
+ TouchButton *button = new TouchButton(tr("..."), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->runContextMenu(); });
+
+ layout->setSpacing(2);
+ layout->setSizeConstraint(QLayout::SetMinimumSize);
+ layout->setContentsMargins(0, 0, 0, 0);
+ setLayout(layout);
+
+ nativeParentWidget()->installEventFilter(this);
+}
+
+TouchSelectionMenuWidget::~TouchSelectionMenuWidget()
+{
+}
+
+bool TouchSelectionMenuWidget::eventFilter(QObject *obj, QEvent *ev)
+{
+ // Close the menu if the window is moved
+ if (ev->type() == QEvent::Move)
+ close();
+
+ return QWidget::eventFilter(obj, ev);
+}
+} // QtWebEngineWidgetUI
diff --git a/src/webenginewidgets/ui/touchselectionmenuwidget_p.h b/src/webenginewidgets/ui/touchselectionmenuwidget_p.h
new file mode 100644
index 000000000..1f822023b
--- /dev/null
+++ b/src/webenginewidgets/ui/touchselectionmenuwidget_p.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef TOUCHSELECTIONMENUWIDGET_P_H
+#define TOUCHSELECTIONMENUWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QPushButton>
+#include <QWidget>
+
+namespace QtWebEngineCore {
+class TouchSelectionMenuController;
+}
+
+QT_BEGIN_NAMESPACE
+class QWebEngineView;
+QT_END_NAMESPACE
+
+namespace QtWebEngineWidgetUI {
+class TouchSelectionMenuWidget : public QWidget
+{
+public:
+ class TouchButton : public QPushButton
+ {
+ public:
+ TouchButton(QString name, QWidget *parent);
+ ~TouchButton();
+
+ protected:
+ bool event(QEvent *ev) override;
+ };
+
+ TouchSelectionMenuWidget(QWebEngineView *view,
+ QtWebEngineCore::TouchSelectionMenuController *controller);
+ ~TouchSelectionMenuWidget();
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *ev) override;
+};
+} // namespace QtWebEngineWidgetUI
+
+#endif // TOUCHSELECTIONMENUWIDGET_P_H
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
index 0a651e9ad..6fff2b35c 100644
--- a/tests/auto/CMakeLists.txt
+++ b/tests/auto/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+# SPDX-License-Identifier: BSD-3-Clause
if(TARGET Qt::WebEngineCore)
add_subdirectory(httpserver)
add_subdirectory(util)
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index c5d7c3f9a..83ebf5a23 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
diff --git a/tests/auto/core/CMakeLists.txt b/tests/auto/core/CMakeLists.txt
index 619c0358b..4e8d5f128 100644
--- a/tests/auto/core/CMakeLists.txt
+++ b/tests/auto/core/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(qwebenginecookiestore)
add_subdirectory(qwebenginesettings)
add_subdirectory(qwebengineurlrequestinterceptor)
diff --git a/tests/auto/core/certificateerror/CMakeLists.txt b/tests/auto/core/certificateerror/CMakeLists.txt
index 57801e195..6223ca25c 100644
--- a/tests/auto/core/certificateerror/CMakeLists.txt
+++ b/tests/auto/core/certificateerror/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/core/devtools/CMakeLists.txt b/tests/auto/core/devtools/CMakeLists.txt
index fd8d850f0..efde75240 100644
--- a/tests/auto/core/devtools/CMakeLists.txt
+++ b/tests/auto/core/devtools/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_devtools
SOURCES
tst_devtools.cpp
diff --git a/tests/auto/core/origins/CMakeLists.txt b/tests/auto/core/origins/CMakeLists.txt
index e25e616c5..10a185f0a 100644
--- a/tests/auto/core/origins/CMakeLists.txt
+++ b/tests/auto/core/origins/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/core/origins/tst_origins.cpp b/tests/auto/core/origins/tst_origins.cpp
index c3efb4bc7..1d716c418 100644
--- a/tests/auto/core/origins/tst_origins.cpp
+++ b/tests/auto/core/origins/tst_origins.cpp
@@ -460,8 +460,8 @@ void tst_Origins::jsUrlRelative()
// URLs even without an initial slash.
QCOMPARE(eval(QSL("new URL('bar', 'qrc:foo').href")), QVariant(QSL("qrc:bar")));
QCOMPARE(eval(QSL("new URL('baz', 'qrc:foo/bar').href")), QVariant(QSL("qrc:foo/baz")));
- QCOMPARE(eval(QSL("new URL('bar', 'qrc://foo').href")), QVariant());
- QCOMPARE(eval(QSL("new URL('bar', 'qrc:///foo').href")), QVariant());
+ QCOMPARE(eval(QSL("new URL('bar', 'qrc://foo').href")), QVariant(QSL("qrc://bar")));
+ QCOMPARE(eval(QSL("new URL('bar', 'qrc:///foo').href")), QVariant(QSL("qrc:///bar")));
// With a slash it works the same as http except 'foo' is part of the path and not the host.
QCOMPARE(eval(QSL("new URL('bar', 'qrc:/foo').href")), QVariant(QSL("qrc:/bar")));
diff --git a/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt b/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt
index ee5473348..8cee7f630 100644
--- a/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt
+++ b/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/core/qwebenginecookiestore/CMakeLists.txt b/tests/auto/core/qwebenginecookiestore/CMakeLists.txt
index 33ba5ff1a..cc14940f1 100644
--- a/tests/auto/core/qwebenginecookiestore/CMakeLists.txt
+++ b/tests/auto/core/qwebenginecookiestore/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/core/qwebenginesettings/CMakeLists.txt b/tests/auto/core/qwebenginesettings/CMakeLists.txt
index 7f8b49d1b..44e8f5252 100644
--- a/tests/auto/core/qwebenginesettings/CMakeLists.txt
+++ b/tests/auto/core/qwebenginesettings/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebenginesettings
diff --git a/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp b/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
index 4220f496b..e0bb604e2 100644
--- a/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
+++ b/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
@@ -143,7 +143,7 @@ void tst_QWebEngineSettings::javascriptClipboard()
// - return value of queryCommandEnabled and
// - return value of execCommand
// - comparing the clipboard / input field
- QGuiApplication::clipboard()->clear();
+ QGuiApplication::clipboard()->setText(QString());
QCOMPARE(evaluateJavaScriptSync(&page, "document.queryCommandEnabled('copy')").toBool(),
copyResult);
QCOMPARE(evaluateJavaScriptSync(&page, "document.execCommand('copy')").toBool(), copyResult);
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt b/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt
index e03caa6d7..33cc7c150 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
include(../../httpserver/httpserver.cmake)
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index f79a80641..73185837a 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -8,6 +8,7 @@
#include <QtWebEngineCore/qwebenginesettings.h>
#include <QtWebEngineCore/qwebengineprofile.h>
#include <QtWebEngineCore/qwebenginepage.h>
+#include <QtWebEngineCore/qwebenginehttprequest.h>
#include <httpserver.h>
#include <httpreqrep.h>
@@ -39,6 +40,7 @@ private Q_SLOTS:
void requestInterceptorByResourceType_data();
void requestInterceptorByResourceType();
void firstPartyUrlHttp();
+ void headers();
void customHeaders();
void initiator();
void jsServiceWorker();
@@ -78,12 +80,14 @@ struct RequestInfo {
, firstPartyUrl(info.firstPartyUrl())
, initiator(info.initiator())
, resourceType(info.resourceType())
+ , headers(info.httpHeaders())
{}
QUrl requestUrl;
QUrl firstPartyUrl;
QUrl initiator;
int resourceType;
+ QHash<QByteArray, QByteArray> headers;
};
static const QUrl kRedirectUrl = QUrl("qrc:///resources/content.html");
@@ -230,7 +234,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl("qrc:///resources/index.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
QVariant success = loadSpy.takeFirst().takeFirst();
QVERIFY(success.toBool());
loadSpy.clear();
@@ -238,7 +242,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
page.runJavaScript("post();", [&ok](const QVariant result){ ok = result; });
QTRY_VERIFY(ok.toBool());
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
success = loadSpy.takeFirst().takeFirst();
// We block non-GET requests, so this should not succeed.
QVERIFY(!success.toBool());
@@ -246,22 +250,22 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
interceptor.shouldRedirect = true;
page.load(QUrl("qrc:///resources/__placeholder__"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
success = loadSpy.takeFirst().takeFirst();
// The redirection for __placeholder__ should succeed.
QVERIFY(success.toBool());
loadSpy.clear();
- QCOMPARE(interceptor.requestInfos.count(), 4);
+ QCOMPARE(interceptor.requestInfos.size(), 4);
// Make sure that registering an observer does not modify the request.
TestRequestInterceptor observer(/* intercept */ false);
profile.setUrlRequestInterceptor(&observer);
page.load(QUrl("qrc:///resources/__placeholder__"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
success = loadSpy.takeFirst().takeFirst();
// Since we do not intercept, loading an invalid path should not succeed.
QVERIFY(!success.toBool());
- QCOMPARE(observer.requestInfos.count(), 1);
+ QCOMPARE(observer.requestInfos.size(), 1);
}
class LocalhostContentProvider : public QWebEngineUrlRequestInterceptor
@@ -294,15 +298,15 @@ void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));
page.setHtml("<p>Hi", QUrl::fromEncoded("http://[::1]/index.html"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
- QCOMPARE(contentProvider.requestedUrls.count(), 0);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
+ QCOMPARE(contentProvider.requestedUrls.size(), 0);
evaluateJavaScriptSync(&page, "var r = new XMLHttpRequest();"
"r.open('GET', 'http://[::1]/test.xml', false);"
"r.send(null);"
);
- QCOMPARE(contentProvider.requestedUrls.count(), 1);
+ QCOMPARE(contentProvider.requestedUrls.size(), 1);
QCOMPARE(contentProvider.requestedUrls.at(0), QUrl::fromEncoded("http://[::1]/test.xml"));
}
@@ -330,8 +334,8 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
- QVERIFY(interceptor.requestInfos.count() >= 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
+ QVERIFY(interceptor.requestInfos.size() >= 1);
QCOMPARE(interceptor.requestInfos.at(0).requestUrl, QUrl("qrc:///resources/content.html"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
@@ -339,15 +343,15 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
interceptor.shouldRedirect = false;
page.setUrl(QUrl("qrc:/non-existent.html"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
- QVERIFY(interceptor.requestInfos.count() >= 3);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
+ QVERIFY(interceptor.requestInfos.size() >= 3);
QCOMPARE(interceptor.requestInfos.at(2).requestUrl, QUrl("qrc:/non-existent.html"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
page.setUrl(QUrl("http://abcdef.abcdef"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 3, 20000);
- QVERIFY(interceptor.requestInfos.count() >= 4);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 3, 20000);
+ QVERIFY(interceptor.requestInfos.size() >= 4);
QCOMPARE(interceptor.requestInfos.at(3).requestUrl, QUrl("http://abcdef.abcdef/"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
@@ -375,23 +379,23 @@ void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl()
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
// Now a case without redirect.
page.setUrl(QUrl("qrc:///resources/content.html"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
}
void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
@@ -405,12 +409,12 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
page.setUrl(QUrl("qrc:///resources/firstparty.html"));
QVERIFY(spy.wait());
- QVERIFY(interceptor.requestInfos.count() >= 2);
+ QVERIFY(interceptor.requestInfos.size() >= 2);
QCOMPARE(interceptor.requestInfos.at(0).requestUrl, QUrl("qrc:///resources/firstparty.html"));
QCOMPARE(interceptor.requestInfos.at(1).requestUrl, QUrl("qrc:///resources/content.html"));
QCOMPARE(interceptor.requestInfos.at(0).firstPartyUrl, QUrl("qrc:///resources/firstparty.html"));
QCOMPARE(interceptor.requestInfos.at(1).firstPartyUrl, QUrl("qrc:///resources/firstparty.html"));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes_data()
@@ -443,21 +447,21 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes()
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(requestUrl);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
- QVERIFY(interceptor.requestInfos.count() >= 1);
+ QVERIFY(interceptor.requestInfos.size() >= 1);
RequestInfo info = interceptor.requestInfos.at(0);
QCOMPARE(info.requestUrl, requestUrl);
QCOMPARE(info.firstPartyUrl, requestUrl);
QCOMPARE(info.resourceType, QWebEngineUrlRequestInfo::ResourceTypeMainFrame);
- QVERIFY(interceptor.requestInfos.count() >= 2);
+ QVERIFY(interceptor.requestInfos.size() >= 2);
info = interceptor.requestInfos.at(1);
QCOMPARE(info.requestUrl, QUrl(adjustedUrl + "iframe2.html"));
QCOMPARE(info.firstPartyUrl, requestUrl);
QCOMPARE(info.resourceType, QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
- QVERIFY(interceptor.requestInfos.count() >= 3);
+ QVERIFY(interceptor.requestInfos.size() >= 3);
info = interceptor.requestInfos.at(2);
QCOMPARE(info.requestUrl, QUrl(adjustedUrl + "iframe3.html"));
QCOMPARE(info.firstPartyUrl, requestUrl);
@@ -533,11 +537,11 @@ void tst_QWebEngineUrlRequestInterceptor::requestInterceptorByResourceType()
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(firstPartyUrl);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
- QTRY_COMPARE(interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)).count(), 1);
+ QTRY_COMPARE(interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)).size(), 1);
QList<RequestInfo> infos = interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType));
- QVERIFY(infos.count() >= 1);
+ QVERIFY(infos.size() >= 1);
QCOMPARE(infos.at(0).requestUrl, requestUrl);
QCOMPARE(infos.at(0).firstPartyUrl, firstPartyUrl);
QCOMPARE(infos.at(0).resourceType, resourceType);
@@ -601,6 +605,40 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
QCOMPARE(info.firstPartyUrl, firstPartyUrl);
}
+void tst_QWebEngineUrlRequestInterceptor::headers()
+{
+ HttpServer httpServer;
+ httpServer.setResourceDirs({ QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() + "/resources" });
+ QVERIFY(httpServer.start());
+ QWebEngineProfile profile;
+ TestRequestInterceptor interceptor(false);
+ profile.setUrlRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ QWebEngineHttpRequest request(httpServer.url("/content.html"));
+ request.setHeader("X-HEADERNAME", "HEADERVALUE");
+ page.load(request);
+ QVERIFY(spy.wait());
+ QVERIFY(interceptor.requestInfos.last().headers.contains("X-HEADERNAME"));
+ QCOMPARE(interceptor.requestInfos.last().headers.value("X-HEADERNAME"),
+ QByteArray("HEADERVALUE"));
+
+ bool jsFinished = false;
+
+ page.runJavaScript(R"(
+var request = new XMLHttpRequest();
+request.open('GET', 'resource.html', /* async = */ false);
+request.setRequestHeader('X-FOO', 'BAR');
+request.send();
+)",
+ [&](const QVariant &) { jsFinished = true; });
+ QTRY_VERIFY(jsFinished);
+ QVERIFY(interceptor.requestInfos.last().headers.contains("X-FOO"));
+ QCOMPARE(interceptor.requestInfos.last().headers.value("X-FOO"), QByteArray("BAR"));
+}
+
void tst_QWebEngineUrlRequestInterceptor::customHeaders()
{
// Create HTTP Server to parse the request.
@@ -735,7 +773,7 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
// We expect only one message here, because logging of services workers is not exposed in our API.
// Note this is very fragile setup , you need fresh profile otherwise install event might not get triggered
// and this in turn can lead to incorrect intercepted requests, therefore we should keep this off the record.
- QTRY_COMPARE_WITH_TIMEOUT(page->messages.count(), 5, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(page->messages.size(), 5, 20000);
QCOMPARE(page->levels.at(0), QWebEnginePage::InfoMessageLevel);
QCOMPARE(page->messages.at(0),QLatin1String("Service worker installing"));
@@ -809,7 +847,7 @@ void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor()
});
page.setUrl(server.url("/favicon.html"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
QTRY_VERIFY(fetchFinished);
QString s; QDebug d(&s);
@@ -853,7 +891,7 @@ void tst_QWebEngineUrlRequestInterceptor::replaceOnIntercept()
};
page.setUrl(server.url("/favicon.html"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QTRY_COMPARE(profileInterceptor.requestInfos.size(), 2);
// if interceptor for page was replaced on intercept call in profile then, since request first
diff --git a/tests/auto/httpserver/CMakeLists.txt b/tests/auto/httpserver/CMakeLists.txt
index 7d4ddd030..0a1f881b9 100644
--- a/tests/auto/httpserver/CMakeLists.txt
+++ b/tests/auto/httpserver/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(minimal LANGUAGES CXX)
diff --git a/tests/auto/httpserver/httpserver.cmake b/tests/auto/httpserver/httpserver.cmake
index 84b350c0e..f98434e1a 100644
--- a/tests/auto/httpserver/httpserver.cmake
+++ b/tests/auto/httpserver/httpserver.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT TARGET Test::HttpServer)
add_library(httpserver STATIC
diff --git a/tests/auto/pdf/CMakeLists.txt b/tests/auto/pdf/CMakeLists.txt
index e2ba73c6e..8bda0c3c3 100644
--- a/tests/auto/pdf/CMakeLists.txt
+++ b/tests/auto/pdf/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(qpdfbookmarkmodel)
#add_subdirectory(qpdfpagenavigator)
add_subdirectory(qpdfpagerenderer)
diff --git a/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt b/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt
index f0300ce7b..729bc9138 100644
--- a/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt
@@ -1,9 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfbookmarkmodel
SOURCES
tst_qpdfbookmarkmodel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::Pdf
+ TESTDATA
+ pdf-sample.bookmarks.pdf
+ pdf-sample.bookmarks_pages.pdf
)
diff --git a/tests/auto/pdf/qpdfdocument/CMakeLists.txt b/tests/auto/pdf/qpdfdocument/CMakeLists.txt
index 4551fdb6c..aadc192b3 100644
--- a/tests/auto/pdf/qpdfdocument/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfdocument/CMakeLists.txt
@@ -1,9 +1,16 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfdocument
SOURCES
tst_qpdfdocument.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::PrintSupport
Qt::Pdf
+ TESTDATA
+ pdf-sample.protected.pdf
+ pdf-sample.metadata.pdf
+ test.pdf
)
diff --git a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
index 96a0e265e..6bb007e7f 100644
--- a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
+++ b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
@@ -7,7 +7,9 @@
#include <QPainter>
#include <QPdfDocument>
#include <QPrinter>
+#include <QDateTime>
#include <QTemporaryFile>
+#include <QTimeZone>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
@@ -376,8 +378,10 @@ void tst_QPdfDocument::metaData()
QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Keywords).toString(), QString::fromLatin1("meta data keywords"));
QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Producer).toString(), QString::fromLatin1("LibreOffice 5.1"));
QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Creator).toString(), QString::fromLatin1("Writer"));
- QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::CreationDate).toDateTime(), QDateTime(QDate(2016, 8, 7), QTime(7, 3, 6), Qt::UTC));
- QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::ModificationDate).toDateTime(), QDateTime(QDate(2016, 8, 8), QTime(8, 3, 6), Qt::UTC));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::CreationDate).toDateTime(),
+ QDateTime(QDate(2016, 8, 7), QTime(7, 3, 6), QTimeZone::UTC));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::ModificationDate).toDateTime(),
+ QDateTime(QDate(2016, 8, 8), QTime(8, 3, 6), QTimeZone::UTC));
}
void tst_QPdfDocument::pageLabels()
diff --git a/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt b/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt
index f4084cce1..53a68fe59 100644
--- a/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt
@@ -1,9 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfpagerenderer
SOURCES
tst_qpdfpagerenderer.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::Pdf
+ TESTDATA
+ pdf-sample.pagerenderer.pdf
)
diff --git a/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt b/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt
index 2c3e744d0..3a0486be5 100644
--- a/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt
@@ -1,8 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfsearchmodel
SOURCES
tst_qpdfsearchmodel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::Pdf
+ TESTDATA
+ test.pdf
)
diff --git a/tests/auto/pdfquick/multipageview/BLACKLIST b/tests/auto/pdfquick/multipageview/BLACKLIST
new file mode 100644
index 000000000..9012902f6
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/BLACKLIST
@@ -0,0 +1,7 @@
+# QTBUG-111306
+[navigation:click links and go back, twice]
+android
+
+# QTBUG-111306
+[navigation:click two links in series and then go back]
+android
diff --git a/tests/auto/pdfquick/multipageview/CMakeLists.txt b/tests/auto/pdfquick/multipageview/CMakeLists.txt
index 99bf8a675..50f7d7d8f 100644
--- a/tests/auto/pdfquick/multipageview/CMakeLists.txt
+++ b/tests/auto/pdfquick/multipageview/CMakeLists.txt
@@ -8,7 +8,7 @@ qt_internal_add_test(tst_multipageview
SOURCES
tst_multipageview.cpp
../shared/util.cpp ../shared/util.h
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Quick
Qt::PdfQuickPrivate
@@ -20,11 +20,11 @@ qt_internal_add_test(tst_multipageview
qt_internal_extend_target(tst_multipageview CONDITION ANDROID OR IOS
DEFINES
- QT_QMLTEST_DATADIR=\\\":/data\\\"
+ QT_QMLTEST_DATADIR=":/data"
)
qt_internal_extend_target(tst_multipageview CONDITION NOT ANDROID AND NOT IOS
DEFINES
- QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\"
+ QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data"
)
diff --git a/tests/auto/pdfquick/multipageview/tst_multipageview.cpp b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
index 764a69959..9cd8e3e2d 100644
--- a/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
+++ b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
@@ -75,7 +75,7 @@ void tst_MultiPageView::internalLink()
QVERIFY(showView(window, testFileUrl("multiPageView.qml")));
QQuickItem *pdfView = window.rootObject();
QVERIFY(pdfView);
- pdfView->setProperty("source", "bookmarksAndLinks.pdf");
+ pdfView->setProperty("source", testFileUrl("bookmarksAndLinks.pdf"));
QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
QQuickItem *table = static_cast<QQuickItem *>(findFirstChild(pdfView, "QQuickTableView"));
@@ -259,7 +259,7 @@ void tst_MultiPageView::password()
// actual QPdfDocument::pageCountChanged(int), for comparison with the illusory QQuickPdfDocument::pageCountChanged
QVERIFY(extPageCountChangedSpy.isValid());
- QVERIFY(pdfView->setProperty("source", u"pdf-sample.protected.pdf"_s));
+ QVERIFY(pdfView->setProperty("source", testFileUrl(u"pdf-sample.protected.pdf"_s)));
QTRY_COMPARE(passwordRequiredSpy.size(), 1);
qCDebug(lcTests) << "error while awaiting password" << doc->error()
@@ -291,7 +291,7 @@ void tst_MultiPageView::selectionAndClipboard()
QQuickPdfDocument *doc = pdfView->property("document").value<QQuickPdfDocument*>();
QVERIFY(doc);
QVERIFY(doc->setProperty("password", u"Qt"_s));
- QVERIFY(pdfView->setProperty("source", u"pdf-sample.protected.pdf"_s));
+ QVERIFY(pdfView->setProperty("source", testFileUrl((u"pdf-sample.protected.pdf"_s))));
QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
QVERIFY(QMetaObject::invokeMethod(pdfView, "selectAll"));
@@ -319,7 +319,7 @@ void tst_MultiPageView::search()
QQuickPdfDocument *doc = pdfView->property("document").value<QQuickPdfDocument*>();
QVERIFY(doc);
QVERIFY(doc->setProperty("password", u"Qt"_s));
- QVERIFY(pdfView->setProperty("source", u"pdf-sample.protected.pdf"_s));
+ QVERIFY(pdfView->setProperty("source", testFileUrl(u"pdf-sample.protected.pdf"_s)));
QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
QPdfSearchModel *searchModel = pdfView->property("searchModel").value<QPdfSearchModel*>();
QVERIFY(searchModel);
diff --git a/tests/auto/quick/CMakeLists.txt b/tests/auto/quick/CMakeLists.txt
index 48a83e7de..d2cf7c3b3 100644
--- a/tests/auto/quick/CMakeLists.txt
+++ b/tests/auto/quick/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(dialogs)
add_subdirectory(publicapi)
add_subdirectory(qquickwebenginedefaultsurfaceformat)
diff --git a/tests/auto/quick/dialogs/CMakeLists.txt b/tests/auto/quick/dialogs/CMakeLists.txt
index b7f088f0d..4d8dc853b 100644
--- a/tests/auto/quick/dialogs/CMakeLists.txt
+++ b/tests/auto/quick/dialogs/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/quick/inspectorserver/BLACKLIST b/tests/auto/quick/inspectorserver/BLACKLIST
index 318dae7a5..076dd5f10 100644
--- a/tests/auto/quick/inspectorserver/BLACKLIST
+++ b/tests/auto/quick/inspectorserver/BLACKLIST
@@ -1,2 +1,2 @@
[openRemoteDebuggingSession]
-*
+macos
diff --git a/tests/auto/quick/inspectorserver/CMakeLists.txt b/tests/auto/quick/inspectorserver/CMakeLists.txt
index e2c3bb2ab..d890581b8 100644
--- a/tests/auto/quick/inspectorserver/CMakeLists.txt
+++ b/tests/auto/quick/inspectorserver/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_inspectorserver
SOURCES
tst_inspectorserver.cpp
diff --git a/tests/auto/quick/publicapi/CMakeLists.txt b/tests/auto/quick/publicapi/CMakeLists.txt
index 4fa18e0b3..e345a076a 100644
--- a/tests/auto/quick/publicapi/CMakeLists.txt
+++ b/tests/auto/quick/publicapi/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_publicapi
SOURCES
tst_publicapi.cpp
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 371969b2a..0cd031940 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -363,6 +363,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.persistentCookiesPolicyChanged() --> void"
<< "QQuickWebEngineProfile.persistentStoragePath --> QString"
<< "QQuickWebEngineProfile.persistentStoragePathChanged() --> void"
+ << "QQuickWebEngineProfile.isPushServiceEnabled --> bool"
+ << "QQuickWebEngineProfile.pushServiceEnabledChanged() --> void"
<< "QQuickWebEngineProfile.spellCheckEnabled --> bool"
<< "QQuickWebEngineProfile.spellCheckEnabledChanged() --> void"
<< "QQuickWebEngineProfile.spellCheckLanguages --> QStringList"
diff --git a/tests/auto/quick/qmltests/CMakeLists.txt b/tests/auto/quick/qmltests/CMakeLists.txt
index c7ebe8b11..542e44706 100644
--- a/tests/auto/quick/qmltests/CMakeLists.txt
+++ b/tests/auto/quick/qmltests/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
index 774708af0..284390619 100644
--- a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
+++ b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
@@ -85,6 +85,9 @@ TestWebEngineView {
function test_iconDatabase(row)
{
+ if (Screen.devicePixelRatio !== 1.0)
+ skip("This test is not supported on High DPI screens.");
+
webEngineView.profile = row.profile;
compare(iconChangedSpy.count, 0);
@@ -129,6 +132,9 @@ TestWebEngineView {
function test_iconDatabaseMultiView()
{
+ if (Screen.devicePixelRatio !== 1.0)
+ skip("This test is not supported on High DPI screens.");
+
var pixel;
var faviconImage = Qt.createQmlObject("
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index a47862565..6d4bdbb41 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -98,7 +98,7 @@ TestWebEngineView {
if (viewType === "dialog") {
tryVerify(dialog.webEngineView.loadSucceeded)
- compare(dialog.webEngineView.url, "");
+ compare(dialog.webEngineView.url, Qt.url("about:blank"));
dialog.destroy();
}
// https://chromium-review.googlesource.com/c/chromium/src/+/1300395
diff --git a/tests/auto/quick/qmltests/data/tst_scrollPosition.qml b/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
index e9c72ab7d..cc7d15e4c 100644
--- a/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
+++ b/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
-import QtQuick.Window
import QtTest
import QtWebEngine
@@ -36,7 +35,7 @@ TestWebEngineView {
tryCompare(scrollPositionSpy, "count", 1);
compare(webEngineView.scrollPosition.x, 0);
- compare(webEngineView.scrollPosition.y, 600 * Screen.devicePixelRatio);
+ compare(webEngineView.scrollPosition.y, 600);
}
function test_scrollPositionAfterReload() {
@@ -49,13 +48,13 @@ TestWebEngineView {
// Wait for proper scroll position change otherwise we cannot expect
// the new y position after reload.
tryCompare(webEngineView.scrollPosition, "x", 0);
- tryCompare(webEngineView.scrollPosition, "y", 600 * Screen.devicePixelRatio);
+ tryCompare(webEngineView.scrollPosition, "y", 600);
webEngineView.reload();
verify(webEngineView.waitForLoadSucceeded());
tryCompare(webEngineView.scrollPosition, "x", 0);
- tryCompare(webEngineView.scrollPosition, "y", 600 * Screen.devicePixelRatio);
+ tryCompare(webEngineView.scrollPosition, "y", 600);
}
}
}
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt
index 07b184b89..9856ed513 100644
--- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qquickwebenginedefaultsurfaceformat
diff --git a/tests/auto/quick/qquickwebengineview/CMakeLists.txt b/tests/auto/quick/qquickwebengineview/CMakeLists.txt
index b0488048f..307ea36c9 100644
--- a/tests/auto/quick/qquickwebengineview/CMakeLists.txt
+++ b/tests/auto/quick/qquickwebengineview/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qquickwebengineview
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index fe9f42053..5ae032061 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -69,8 +69,10 @@ private Q_SLOTS:
void javascriptClipboard_data();
void javascriptClipboard();
void setProfile();
- void focusChild();
+#if QT_CONFIG(accessibility)
void focusChild_data();
+ void focusChild();
+#endif
void htmlSelectPopup();
private:
@@ -1117,7 +1119,7 @@ void tst_QQuickWebEngineView::javascriptClipboard()
// - return value of queryCommandEnabled and
// - return value of execCommand
// - comparing the clipboard / input field
- QGuiApplication::clipboard()->clear();
+ QGuiApplication::clipboard()->setText(QString());
QCOMPARE(evaluateJavaScriptSync(view, "document.queryCommandEnabled('copy')").toBool(),
copyResult);
QCOMPARE(evaluateJavaScriptSync(view, "document.execCommand('copy')").toBool(), copyResult);
@@ -1180,6 +1182,7 @@ void tst_QQuickWebEngineView::setProfile() {
QTRY_COMPARE(webEngineView()->url() ,urlFromTestPath("html/basic_page2.html"));
}
+#if QT_CONFIG(accessibility)
void tst_QQuickWebEngineView::focusChild_data()
{
QTest::addColumn<QString>("interfaceName");
@@ -1242,6 +1245,7 @@ void tst_QQuickWebEngineView::focusChild()
// <html> -> <body> -> <input>
QCOMPARE(traverseToWebDocumentAccessibleInterface(iface)->child(0)->child(0), iface->focusChild());
}
+#endif // QT_CONFIG(accessibility)
void tst_QQuickWebEngineView::htmlSelectPopup()
{
@@ -1270,8 +1274,12 @@ void tst_QQuickWebEngineView::htmlSelectPopup()
QCOMPARE(evaluateJavaScriptSync(&view, "document.getElementById('select').value").toString(), QStringLiteral("O2"));
}
+#if QT_CONFIG(accessibility)
static QByteArrayList params = QByteArrayList()
<< "--force-renderer-accessibility";
+#else
+static QByteArrayList params;
+#endif
W_QTEST_MAIN(tst_QQuickWebEngineView, params)
#include "tst_qquickwebengineview.moc"
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt b/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt
index 6bc0bc866..f22408d15 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt
+++ b/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qquickwebengineviewgraphics
SOURCES
diff --git a/tests/auto/quick/qtbug-70248/CMakeLists.txt b/tests/auto/quick/qtbug-70248/CMakeLists.txt
index b1df50211..b177c5309 100644
--- a/tests/auto/quick/qtbug-70248/CMakeLists.txt
+++ b/tests/auto/quick/qtbug-70248/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qtbug-70248
SOURCES
tst_qtbug-70248.cpp
diff --git a/tests/auto/quick/uidelegates/CMakeLists.txt b/tests/auto/quick/uidelegates/CMakeLists.txt
index d8699ccfc..bdf041e04 100644
--- a/tests/auto/quick/uidelegates/CMakeLists.txt
+++ b/tests/auto/quick/uidelegates/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/util/CMakeLists.txt b/tests/auto/util/CMakeLists.txt
index fa2f84cec..0af0e5032 100644
--- a/tests/auto/util/CMakeLists.txt
+++ b/tests/auto/util/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(minimal LANGUAGES CXX)
diff --git a/tests/auto/util/util.cmake b/tests/auto/util/util.cmake
index 84d7f593f..e5142d0b2 100644
--- a/tests/auto/util/util.cmake
+++ b/tests/auto/util/util.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT TARGET Test::Util)
add_library(qtestutil INTERFACE)
target_include_directories(qtestutil INTERFACE ${CMAKE_CURRENT_LIST_DIR})
diff --git a/tests/auto/widgets/CMakeLists.txt b/tests/auto/widgets/CMakeLists.txt
index bedb00f53..34d165c94 100644
--- a/tests/auto/widgets/CMakeLists.txt
+++ b/tests/auto/widgets/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(defaultsurfaceformat)
add_subdirectory(qwebenginepage)
add_subdirectory(qwebengineprofile)
diff --git a/tests/auto/widgets/accessibility/CMakeLists.txt b/tests/auto/widgets/accessibility/CMakeLists.txt
index bd04bddd0..4c0bb17ee 100644
--- a/tests/auto/widgets/accessibility/CMakeLists.txt
+++ b/tests/auto/widgets/accessibility/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_webengine_accessibility
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index a420d041c..68566c082 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -475,7 +475,7 @@ void tst_Accessibility::roles_data()
QTest::newRow("ax::mojom::Role::kNote") << QString("<div role='note'>a</div>") << 0 << QAccessible::Note;
//QTest::newRow("ax::mojom::Role::kPane"); // No mapping to ARIA role
QTest::newRow("ax::mojom::Role::kParagraph") << QString("<p>a</p>") << 0 << QAccessible::Paragraph;
- QTest::newRow("ax::mojom::Role::kPopUpButton") << QString("<select><option>a</option></select>") << 1 << QAccessible::ComboBox;
+ QTest::newRow("ax::mojom::Role::kPopUpButton") << QString("<select><option>a</option></select>") << 1 << QAccessible::PopupMenu;
QTest::newRow("ax::mojom::Role::kPre") << QString("<pre>a</pre>") << 0 << QAccessible::Section;
//QTest::newRow("ax::mojom::Role::kPresentational") << QString("<div role='presentation'>a</div>") << 0 << QAccessible::NoRole; // FIXME: Aria role 'presentation' should work
QTest::newRow("ax::mojom::Role::kProgressIndicator") << QString("<div role='progressbar' aria-valuenow='77' aria-valuemin='22' aria-valuemax='99'></div>") << 0 << QAccessible::ProgressBar;
diff --git a/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt b/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt
index 6dd05f58f..d95c1355b 100644
--- a/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt
+++ b/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_defaultsurfaceformat
diff --git a/tests/auto/widgets/favicon/CMakeLists.txt b/tests/auto/widgets/favicon/CMakeLists.txt
index 3a2f6f255..0deae6a37 100644
--- a/tests/auto/widgets/favicon/CMakeLists.txt
+++ b/tests/auto/widgets/favicon/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_favicon
diff --git a/tests/auto/widgets/loadsignals/CMakeLists.txt b/tests/auto/widgets/loadsignals/CMakeLists.txt
index 5de957148..bbd0387d9 100644
--- a/tests/auto/widgets/loadsignals/CMakeLists.txt
+++ b/tests/auto/widgets/loadsignals/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/widgets/offscreen/CMakeLists.txt b/tests/auto/widgets/offscreen/CMakeLists.txt
index d51459a3e..756e53c43 100644
--- a/tests/auto/widgets/offscreen/CMakeLists.txt
+++ b/tests/auto/widgets/offscreen/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_offscreen
SOURCES
tst_offscreen.cpp
diff --git a/tests/auto/widgets/printing/CMakeLists.txt b/tests/auto/widgets/printing/CMakeLists.txt
index 9e14fd752..baa3cf747 100644
--- a/tests/auto/widgets/printing/CMakeLists.txt
+++ b/tests/auto/widgets/printing/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
find_package(PkgConfig)
@@ -8,10 +11,9 @@ endif()
qt_internal_add_test(tst_printing
SOURCES
tst_printing.cpp
- PUBLIC_LIBRARIES
- Qt::WebEngineWidgets
LIBRARIES
Qt::CorePrivate
+ Qt::WebEngineWidgets
Qt::WebEngineCorePrivate
Test::Util
)
diff --git a/tests/auto/widgets/printing/tst_printing.cpp b/tests/auto/widgets/printing/tst_printing.cpp
index 1c1e0615e..1f9b5059c 100644
--- a/tests/auto/widgets/printing/tst_printing.cpp
+++ b/tests/auto/widgets/printing/tst_printing.cpp
@@ -23,6 +23,7 @@ private slots:
#if QT_CONFIG(webengine_system_poppler)
void printToPdfPoppler();
#endif
+ void interruptPrinting();
};
void tst_Printing::printToPdfBasic()
@@ -117,6 +118,19 @@ void tst_Printing::printToPdfPoppler()
}
#endif
+void tst_Printing::interruptPrinting()
+{
+ QWebEngineView view;
+ QSignalSpy spy(&view, &QWebEngineView::loadFinished);
+ view.load(QUrl("qrc:///resources/basic_printing_page.html"));
+ QTRY_VERIFY(spy.size() == 1);
+
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
+ QVERIFY(tempDir.isValid());
+ view.page()->printToPdf(tempDir.path() + "/file.pdf");
+ // Navigation stop interrupts print job, preferably do this without crash/assert
+ view.page()->triggerAction(QWebEnginePage::Stop);
+}
QTEST_MAIN(tst_Printing)
#include "tst_printing.moc"
diff --git a/tests/auto/widgets/proxy/CMakeLists.txt b/tests/auto/widgets/proxy/CMakeLists.txt
index 03af3c35f..95dc903ed 100644
--- a/tests/auto/widgets/proxy/CMakeLists.txt
+++ b/tests/auto/widgets/proxy/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
qt_internal_add_test(tst_webengine_proxy
diff --git a/tests/auto/widgets/proxypac/CMakeLists.txt b/tests/auto/widgets/proxypac/CMakeLists.txt
index d3ddfd0c5..f27160cb6 100644
--- a/tests/auto/widgets/proxypac/CMakeLists.txt
+++ b/tests/auto/widgets/proxypac/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
qt_internal_add_test(tst_proxypac_file
diff --git a/tests/auto/widgets/proxypac/tst_proxypac.cpp b/tests/auto/widgets/proxypac/tst_proxypac.cpp
index afdccdea8..43ccbf028 100644
--- a/tests/auto/widgets/proxypac/tst_proxypac.cpp
+++ b/tests/auto/widgets/proxypac/tst_proxypac.cpp
@@ -50,7 +50,7 @@ void tst_ProxyPac::proxypac()
QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
page.load(QUrl("https://contribute.qt-project.org"));
- QTRY_VERIFY_WITH_TIMEOUT(!spyFinished.isEmpty(), 100000);
+ QTRY_VERIFY_WITH_TIMEOUT(!spyFinished.isEmpty(), 200000);
}
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt b/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
index 3a8244c0f..5b76909b1 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/widgets/qwebenginehistory/CMakeLists.txt b/tests/auto/widgets/qwebenginehistory/CMakeLists.txt
index b91281a45..e277a7326 100644
--- a/tests/auto/widgets/qwebenginehistory/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginehistory/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebenginehistory
diff --git a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
index 9589e83e1..6ddc031d5 100644
--- a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
+++ b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
@@ -487,9 +487,9 @@ void tst_QWebEngineHistory::clear()
QWebEnginePage page2(this);
QWebEngineHistory* hist2 = page2.history();
- QVERIFY(hist2->count() == 0);
+ QCOMPARE(hist2->count(), 1);
hist2->clear();
- QVERIFY(hist2->count() == 0); // Do not change anything.
+ QCOMPARE(hist2->count(), 1); // Do not change anything.
}
void tst_QWebEngineHistory::historyItemFromDeletedPage()
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 7eb97b3bb..66c5de42c 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -13,3 +13,6 @@ macos
[comboBoxPopupPositionAfterChildMove]
macos
+
+[backgroundColor]
+macos
diff --git a/tests/auto/widgets/qwebenginepage/CMakeLists.txt b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
index 599e22990..a15bb6e06 100644
--- a/tests/auto/widgets/qwebenginepage/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
@@ -5,7 +8,9 @@ qt_internal_add_test(tst_qwebenginepage
SOURCES
tst_qwebenginepage.cpp
LIBRARIES
+ Qt::CorePrivate
Qt::NetworkPrivate
+ Qt::WebEngineCorePrivate
Qt::WebEngineWidgets
Test::HttpServer
Test::Util
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index bfa97ea79..ba88fd99e 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -20,7 +20,9 @@
*/
#include <widgetutil.h>
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtWebEngineCore/qtwebenginecore-config.h>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include <QByteArray>
#include <QClipboard>
#include <QDir>
@@ -34,6 +36,7 @@
#include <QPaintEngine>
#include <QPushButton>
#include <QScreen>
+#include <QWheelEvent>
#if defined(QT_STATEMACHINE_LIB)
# include <QStateMachine>
#endif
@@ -47,7 +50,6 @@
#include <qnetworkcookiejar.h>
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
-#include <QtNetwork/private/qtnetwork-config_p.h>
#include <qwebenginedownloadrequest.h>
#include <qwebenginefilesystemaccessrequest.h>
#include <qwebenginefindtextresult.h>
@@ -164,7 +166,8 @@ private Q_SLOTS:
void runJavaScriptDisabled();
void runJavaScriptFromSlot();
void fullScreenRequested();
- void quotaRequested();
+ void requestQuota_data();
+ void requestQuota();
// Tests from tst_QWebEngineFrame
@@ -262,6 +265,10 @@ private Q_SLOTS:
void fileSystemAccessDialog();
void localToRemoteNavigation();
+ void clientHints();
+ void childFrameInput();
+ void openLinkInNewPageWithWebWindowType_data();
+ void openLinkInNewPageWithWebWindowType();
private:
static QPoint elementCenter(QWebEnginePage *page, const QString &id);
@@ -289,6 +296,13 @@ private:
QTest::touchEvent(window, s_touchDevice.get()).release(1, p);
}
};
+
+ void makeScroll(QWidget *target, QPointF pos, QPoint globalPos, QPoint angleDelta)
+ {
+ QWheelEvent ev(pos, globalPos, QPoint(0, 0), angleDelta, Qt::NoButton, Qt::NoModifier,
+ Qt::NoScrollPhase, false);
+ QGuiApplication::sendEvent(target, &ev);
+ }
};
tst_QWebEnginePage::tst_QWebEnginePage()
@@ -2013,8 +2027,18 @@ void tst_QWebEnginePage::fullScreenRequested()
QTRY_VERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
}
-void tst_QWebEnginePage::quotaRequested()
+void tst_QWebEnginePage::requestQuota_data()
+{
+ QTest::addColumn<QString>("storage");
+ QTest::addRow("webkitPersistentStorage") << "navigator.webkitPersistentStorage";
+ QTest::addRow("webkitTemporaryStorage") << "navigator.webkitTemporaryStorage";
+
+}
+
+void tst_QWebEnginePage::requestQuota()
{
+ QFETCH(QString, storage);
+
ConsolePage page;
QWebEngineView view;
view.setPage(&page);
@@ -2022,35 +2046,23 @@ void tst_QWebEnginePage::quotaRequested()
page.load(QUrl("qrc:///resources/content.html"));
QVERIFY(loadFinishedSpy.wait());
- connect(&page, &QWebEnginePage::quotaRequested,
- [] (QWebEngineQuotaRequest request)
- {
- if (request.requestedSize() <= 5000)
- request.accept();
- else
- request.reject();
- });
-
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.requestQuota(1024, function(grantedSize) {" \
- "console.log(grantedSize);" \
- "});");
+ evaluateJavaScriptSync(&page, QString(
+ "var storage = %1;"
+ "storage.requestQuota(1024, function(grantedSize) {"
+ " console.log(grantedSize);"
+ "});").arg(storage));
QTRY_COMPARE(page.messages.size(), 1);
QTRY_COMPARE(page.messages[0], QString("1024"));
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.requestQuota(6000, function(grantedSize) {" \
- "console.log(grantedSize);" \
- "});");
- QTRY_COMPARE(page.messages.size(), 2);
- QTRY_COMPARE(page.messages[1], QString("1024"));
-
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.queryUsageAndQuota(function(usedBytes, grantedBytes) {" \
- "console.log(usedBytes + ', ' + grantedBytes);" \
- "});");
+ evaluateJavaScriptSync(&page, QString(
+ "var storage = %1;"
+ "storage.queryUsageAndQuota(function(usedBytes, grantedBytes) {"
+ " console.log(usedBytes);"
+ " console.log(grantedBytes);"
+ "});").arg(storage));
QTRY_COMPARE(page.messages.size(), 3);
- QTRY_COMPARE(page.messages[2], QString("0, 1024"));
+ QTRY_COMPARE(page.messages[1], QString("0"));
+ QTRY_VERIFY(page.messages[2].toLongLong() >= 1024);
}
void tst_QWebEnginePage::symmetricUrl()
@@ -2060,14 +2072,14 @@ void tst_QWebEnginePage::symmetricUrl()
QVERIFY(view.url().isEmpty());
- QCOMPARE(view.history()->count(), 0);
+ QCOMPARE(view.history()->count(), 1);
QUrl dataUrl("data:text/html,<h1>Test");
view.setUrl(dataUrl);
view.show();
QCOMPARE(view.url(), dataUrl);
- QCOMPARE(view.history()->count(), 0);
+ QCOMPARE(view.history()->count(), 1);
// loading is _not_ immediate, so the text isn't set just yet.
QVERIFY(toPlainTextSync(view.page()).isEmpty());
@@ -2380,7 +2392,7 @@ void tst_QWebEnginePage::setHtmlWithBaseURL()
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
// no history item has to be added.
- QCOMPARE(m_view->page()->history()->count(), 0);
+ QCOMPARE(m_view->page()->history()->count(), 1);
}
class MyPage : public QWebEnginePage
@@ -2481,7 +2493,8 @@ void tst_QWebEnginePage::baseUrl()
void tst_QWebEnginePage::scrollPosition()
{
// enlarged image in a small viewport, to provoke the scrollbars to appear
- QString html("<html><body><img src='qrc:/image.png' height=500 width=500/></body></html>");
+ QString html(
+ "<html><body><img src='qrc:/resources/image.png' height=500 width=500/></body></html>");
QWebEngineView view;
view.setFixedSize(200,200);
@@ -2495,8 +2508,8 @@ void tst_QWebEnginePage::scrollPosition()
// try to set the scroll offset programmatically
view.page()->runJavaScript("window.scrollTo(23, 29);");
- QTRY_COMPARE(view.page()->scrollPosition().x(), 23 * view.windowHandle()->devicePixelRatio());
- QCOMPARE(view.page()->scrollPosition().y(), 29 * view.windowHandle()->devicePixelRatio());
+ QTRY_COMPARE(view.page()->scrollPosition().x(), 23);
+ QCOMPARE(view.page()->scrollPosition().y(), 29);
int x = evaluateJavaScriptSync(view.page(), "window.scrollX").toInt();
int y = evaluateJavaScriptSync(view.page(), "window.scrollY").toInt();
@@ -2810,7 +2823,7 @@ void tst_QWebEnginePage::setUrlHistory()
int expectedLoadFinishedCount = 0;
QSignalSpy spy(m_page, SIGNAL(loadFinished(bool)));
- QCOMPARE(m_page->history()->count(), 0);
+ QCOMPARE(m_page->history()->count(), 1);
m_page->setUrl(QUrl());
expectedLoadFinishedCount++;
@@ -2884,7 +2897,7 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
int expectedUrlChangeCount = 0;
- QCOMPARE(m_page->history()->count(), 0);
+ QCOMPARE(m_page->history()->count(), 1);
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
@@ -3709,7 +3722,7 @@ void tst_QWebEnginePage::openLinkInNewPage()
QCOMPARE(page1.history()->count(), 1);
else
QCOMPARE(page1.history()->count(), 2);
- QCOMPARE(page2.history()->count(), 0);
+ QCOMPARE(page2.history()->count(), 1);
break;
case Effect::LoadInOther:
QTRY_COMPARE(page2.spy.size(), 1);
@@ -4822,10 +4835,6 @@ public:
Q_UNUSED(oldFiles);
chosenFileSelectionMode = mode;
chosenAcceptedMimeTypes = acceptedMimeTypes;
-
- if (chosenFileSelectionMode == QWebEnginePage::FileSelectUploadFolder)
- return QStringList() << m_tempDir.path();
-
return QStringList() << (m_tempDir.path() + "/file.txt");
}
@@ -5122,6 +5131,204 @@ void tst_QWebEnginePage::localToRemoteNavigation()
QVERIFY(!remote.loaded);
}
+void tst_QWebEnginePage::clientHints()
+{
+ HttpServer server;
+ connect(&server, &HttpServer::newRequest, [&] (HttpReqRep *r) {
+ r->setResponseBody(r->requestHeader("Sec-Ch-Ua-Platform"));
+ r->sendResponse();
+ });
+ QVERIFY(server.start());
+
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setUrl(server.url());
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QVERIFY(loadSpy.takeFirst().value(0).toBool());
+
+ QString platform = toPlainTextSync(&page);
+#ifdef Q_OS_LINUX
+ QCOMPARE(platform.toLower(), "\"linux\"");
+#elif defined (Q_OS_MACOS)
+ QCOMPARE(platform.toLower(), "\"macos\"");
+#elif defined (Q_OS_WIN)
+ QCOMPARE(platform.toLower(), "\"windows\"");
+#endif
+
+}
+
+void tst_QWebEnginePage::childFrameInput()
+{
+ HttpServer server;
+ server.setHostDomain("localhost");
+
+ // The cross-origin policy blocks scripting this frame with QWebEnginePage::runJavaScript.
+ // Use console messages to validate events.
+ QString innerHtml(
+ "<html><head><style>body{height:1200px;width:1200px;}</style></head><body>test<script>"
+ " let lastX, lastY = 0;"
+ " document.onscroll = (e) => {"
+ " if (window.scrollY > lastY) console.log(\"Down\");"
+ " if (window.scrollY < lastY) console.log(\"Up\");"
+ " if (window.scrollX > lastX) console.log(\"Right\");"
+ " if (window.scrollX < lastX) console.log(\"Left\");"
+ " lastX = window.scrollX;"
+ " lastY = window.scrollY;"
+ " };"
+ " window.onload = () => {console.log('loaded');};"
+ "</script></body></html>");
+
+ QVERIFY(server.start());
+ connect(&server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestPath() == "/main.html") {
+ // the Origin-Agent-Cluster header enables dedicated processes for origins
+ rr->setResponseHeader("Origin-Agent-Cluster", "?1");
+ // the same-site-cross-origin page forces to create the frame in a different process
+ server.setHostDomain("sub.localhost");
+ rr->setResponseBody(("<html><body>"
+ "<iframe id=\"iframe\" width=90% height=90% src=\""
+ + server.url().toString().toUtf8()
+ + "inner.html\"></iframe>"
+ "</body></html>"));
+ }
+ if (rr->requestPath() == "/inner.html")
+ rr->setResponseBody(innerHtml.toUtf8());
+ rr->sendResponse();
+ });
+
+ QWebEngineView view;
+ ConsolePage page;
+ view.setPage(&page);
+ view.resize(640, 480);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ page.load(server.url("/main.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QTRY_VERIFY(evaluateJavaScriptSync(&page, "window.originAgentCluster").toBool());
+
+ // make sure the frame is loaded
+ QTRY_COMPARE(page.messages.size(), 1);
+ QTRY_COMPARE(page.messages[0], QString("loaded"));
+
+ // focus
+ evaluateJavaScriptSync(&page, "document.getElementById('iframe').contentWindow.focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "document.activeElement.id").toString(),
+ QStringLiteral("iframe"));
+
+ QPoint globalPos = view.windowHandle()->position();
+ QPoint p = elementCenter(&page, QString("iframe"));
+
+ // Even if the document is loaded, it is not necessarily drawn.
+ // Hit-testing (in Viz) for pointer events will be flacky in this scenario.
+ // Send keyClick events first so the target frame will be cached for wheel events.
+ QTest::keyClick(view.focusProxy(), Qt::Key_Down);
+ QTRY_COMPARE(page.messages.size(), 2);
+ QTRY_COMPARE(page.messages[1], QString("Down"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Up);
+ QTRY_COMPARE(page.messages.size(), 3);
+ QTRY_COMPARE(page.messages[2], QString("Up"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Right);
+ QTRY_COMPARE(page.messages.size(), 4);
+ QTRY_COMPARE(page.messages[3], QString("Right"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Left);
+ QTRY_COMPARE(page.messages.size(), 5);
+ QTRY_COMPARE(page.messages[4], QString("Left"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(0, -120));
+ QTRY_COMPARE(page.messages.size(), 6);
+ QTRY_COMPARE(page.messages[5], QString("Down"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(0, 120));
+ QTRY_COMPARE(page.messages.size(), 7);
+ QTRY_COMPARE(page.messages[6], QString("Up"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(-120, 0));
+ QTRY_COMPARE(page.messages.size(), 8);
+ QTRY_COMPARE(page.messages[7], QString("Right"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(120, 0));
+ QTRY_COMPARE(page.messages.size(), 9);
+ QTRY_COMPARE(page.messages[8], QString("Left"));
+}
+
+void tst_QWebEnginePage::openLinkInNewPageWithWebWindowType_data()
+{
+ QTest::addColumn<QWebEnginePage::WebWindowType>("webWindowType");
+ QTest::addColumn<QString>("elementId");
+ QTest::addColumn<Qt::MouseButton>("button");
+ QTest::addColumn<Qt::KeyboardModifier>("keyboardModififer");
+ QTest::newRow("webBrowserWindow")
+ << QWebEnginePage::WebBrowserWindow << "link" << Qt::LeftButton << Qt::ShiftModifier;
+ QTest::newRow("webBrowserTab")
+ << QWebEnginePage::WebBrowserTab << "link" << Qt::LeftButton << Qt::NoModifier;
+ QTest::newRow("webDialog") << QWebEnginePage::WebDialog << "openWindow" << Qt::LeftButton
+ << Qt::NoModifier;
+ QTest::newRow("webBrowserBackgroundTab") << QWebEnginePage::WebBrowserBackgroundTab << "link"
+ << Qt::MiddleButton << Qt::NoModifier;
+}
+
+class WebWindowTypeTestPage : public QWebEnginePage
+{
+ Q_OBJECT
+
+public:
+ WebWindowType windowType;
+
+signals:
+ void windowCreated();
+
+private:
+ QWebEnginePage *createWindow(WebWindowType type) override
+ {
+ windowType = type;
+ emit windowCreated();
+ return nullptr;
+ }
+};
+
+void tst_QWebEnginePage::openLinkInNewPageWithWebWindowType()
+{
+ QFETCH(QWebEnginePage::WebWindowType, webWindowType);
+ QFETCH(QString, elementId);
+ QFETCH(Qt::MouseButton, button);
+ QFETCH(Qt::KeyboardModifier, keyboardModififer);
+
+ WebWindowTypeTestPage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy windowCreatedSpy(&page, &WebWindowTypeTestPage::windowCreated);
+ QWebEngineView view(&page);
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
+ QString html = "<html><body>"
+ "<a id='link' href='hello' target='_blank'>link</a>"
+ "<br><br>"
+ "<button id='openWindow' onclick='myFunction()'>Try it</button>"
+ "<script>"
+ "function myFunction() {"
+ " const myWindow = window.open('', '', 'width=300,height=300');"
+ "}"
+ "</script>"
+ "</body></html>";
+
+ page.setHtml(html);
+ QVERIFY(loadFinishedSpy.wait());
+
+ QTest::mouseClick(view.focusProxy(), button, keyboardModififer,
+ elementCenter(&page, elementId));
+ QVERIFY(windowCreatedSpy.wait());
+ QCOMPARE(page.windowType, webWindowType);
+}
+
static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)
diff --git a/tests/auto/widgets/qwebengineprofile/CMakeLists.txt b/tests/auto/widgets/qwebengineprofile/CMakeLists.txt
index 744f44405..d7393eaef 100644
--- a/tests/auto/widgets/qwebengineprofile/CMakeLists.txt
+++ b/tests/auto/widgets/qwebengineprofile/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/widgets/qwebenginescript/CMakeLists.txt b/tests/auto/widgets/qwebenginescript/CMakeLists.txt
index 6e768cf90..d0d499b84 100644
--- a/tests/auto/widgets/qwebenginescript/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginescript/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebenginescript
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index ed12fdba0..9ba13589f 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -76,6 +76,7 @@ private Q_SLOTS:
void scriptsInNestedIframes();
void matchQrcUrl();
void injectionOrder();
+ void reloadWithSubframes();
};
void tst_QWebEngineScript::domEditing()
@@ -694,6 +695,38 @@ void tst_QWebEngineScript::injectionOrder()
QTRY_COMPARE(page.log, expected);
}
+void tst_QWebEngineScript::reloadWithSubframes()
+{
+ class Page : public QWebEnginePage
+ {
+ public:
+ Page() : QWebEnginePage() {}
+ QVector<QString> log;
+
+ protected:
+ void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel, const QString &message, int,
+ const QString &) override
+ {
+ log.append(message);
+ }
+ } page;
+
+ QWebEngineScript s;
+ s.setInjectionPoint(QWebEngineScript::DocumentCreation);
+ s.setSourceCode(QStringLiteral("console.log('Hello');"));
+ page.scripts().insert(s);
+
+ page.setHtml(QStringLiteral("<body>"
+ " <h1>Test scripts working on reload </h1>"
+ " <iframe src='about://blank'>"
+ " </iframe>"
+ "</body>"));
+ QTRY_COMPARE(page.log.size(), 1);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(page.log.size(), 2);
+}
+
QTEST_MAIN(tst_QWebEngineScript)
#include "tst_qwebenginescript.moc"
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index 5d9cc038a..356f9c9b0 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -9,3 +9,5 @@ windows
[horizontalScrollbarTest]
b2qt # different scrollbar
+macos
+rhel # flaky
diff --git a/tests/auto/widgets/qwebengineview/CMakeLists.txt b/tests/auto/widgets/qwebengineview/CMakeLists.txt
index b06ee7201..9583184d0 100644
--- a/tests/auto/widgets/qwebengineview/CMakeLists.txt
+++ b/tests/auto/widgets/qwebengineview/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebengineview
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index a45799e70..15e226139 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -3231,7 +3231,7 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::newRow("process-internals") << QUrl("chrome://process-internals") << true;
QTest::newRow("quota-internals") << QUrl("chrome://quota-internals") << true;
QTest::newRow("safe-browsing") << QUrl("chrome://safe-browsing") << false;
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
QTest::newRow("sandbox") << QUrl("chrome://sandbox") << true;
#else
QTest::newRow("sandbox") << QUrl("chrome://sandbox") << false;
diff --git a/tests/auto/widgets/schemes/CMakeLists.txt b/tests/auto/widgets/schemes/CMakeLists.txt
index 446ae5751..5299b3148 100644
--- a/tests/auto/widgets/schemes/CMakeLists.txt
+++ b/tests/auto/widgets/schemes/CMakeLists.txt
@@ -1,7 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(../../util/util.cmake)
+
qt_internal_add_test(tst_schemes
SOURCES
tst_schemes.cpp
LIBRARIES
Qt::WebEngineWidgets
+ Test::Util
)
diff --git a/tests/auto/widgets/schemes/tst_schemes.cpp b/tests/auto/widgets/schemes/tst_schemes.cpp
index 09aaecac4..188c112e4 100644
--- a/tests/auto/widgets/schemes/tst_schemes.cpp
+++ b/tests/auto/widgets/schemes/tst_schemes.cpp
@@ -3,20 +3,48 @@
#include <QtTest/QtTest>
-#include <qwebengineview.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
#include <qwebenginesettings.h>
+#include <qwebengineurlrequestjob.h>
+#include <qwebengineurlscheme.h>
+#include <qwebengineurlschemehandler.h>
+#include <qwebengineview.h>
+#include <widgetutil.h>
class tst_Schemes : public QObject
{
Q_OBJECT
private Q_SLOTS:
+ void initTestCase();
void unknownUrlSchemePolicy_data();
void unknownUrlSchemePolicy();
+ void customSchemeFragmentNavigation_data();
+ void customSchemeFragmentNavigation();
};
+void tst_Schemes::initTestCase()
+{
+ QWebEngineUrlScheme pathScheme("path");
+ pathScheme.setSyntax(QWebEngineUrlScheme::Syntax::Path);
+ QWebEngineUrlScheme::registerScheme(pathScheme);
+
+ QWebEngineUrlScheme hostScheme("host");
+ hostScheme.setSyntax(QWebEngineUrlScheme::Syntax::Host);
+ QWebEngineUrlScheme::registerScheme(hostScheme);
+
+ QWebEngineUrlScheme hostAndPortScheme("hostandport");
+ hostAndPortScheme.setSyntax(QWebEngineUrlScheme::Syntax::HostAndPort);
+ hostAndPortScheme.setDefaultPort(3000);
+ QWebEngineUrlScheme::registerScheme(hostAndPortScheme);
+
+ QWebEngineUrlScheme hostPortUserInfoScheme("hostportuserinfo");
+ hostPortUserInfoScheme.setSyntax(QWebEngineUrlScheme::Syntax::HostPortAndUserInformation);
+ hostPortUserInfoScheme.setDefaultPort(3000);
+ QWebEngineUrlScheme::registerScheme(hostPortUserInfoScheme);
+}
+
class AcceptNavigationRequestHandler : public QWebEnginePage
{
public:
@@ -93,5 +121,161 @@ void tst_Schemes::unknownUrlSchemePolicy()
QCOMPARE(page.acceptNavigationRequestCalls, shouldAccept ? 1 : 0);
}
+class CustomScheme : public QWebEngineUrlSchemeHandler
+{
+public:
+ CustomScheme(const QString &linkUrl) : m_linkUrl(linkUrl) { }
+
+ void requestStarted(QWebEngineUrlRequestJob *requestJob) override
+ {
+ QString html = QString("<html><body>"
+ "<p style='height: 2000px;'>"
+ "<a href='%1' id='link'>Click link</a>"
+ "</p><p id='anchor'>Anchor</p>"
+ "</body></html>")
+ .arg(m_linkUrl);
+ QBuffer *buffer = new QBuffer(requestJob);
+ buffer->setData(html.toUtf8());
+ requestJob->reply("text/html", buffer);
+ }
+
+ QString m_linkUrl;
+};
+
+void tst_Schemes::customSchemeFragmentNavigation_data()
+{
+ QTest::addColumn<QUrl>("baseUrl");
+ QTest::addColumn<QString>("linkUrl");
+ QTest::addColumn<QUrl>("expectedUrl");
+
+ // Path syntax
+ // - Preserves each part of the URL after navigation
+ QTest::newRow("Path syntax, path only, relative url")
+ << QUrl("path://path") << "#anchor" << QUrl("path://path#anchor");
+ QTest::newRow("Path syntax, path only, absolute url")
+ << QUrl("path://path") << "path://path#anchor" << QUrl("path://path#anchor");
+ QTest::newRow("Path syntax, host/path, relative url")
+ << QUrl("path://host/path") << "#anchor" << QUrl("path://host/path#anchor");
+ QTest::newRow("Path syntax, host/path, absolute url")
+ << QUrl("path://host/path") << "path://host/path#anchor"
+ << QUrl("path://host/path#anchor");
+ QTest::newRow("Path syntax, host:port, relative url")
+ << QUrl("path://host:3000") << "#anchor" << QUrl("path://host:3000#anchor");
+ QTest::newRow("Path syntax, host:port, absolute url")
+ << QUrl("path://host:3000") << "path://host:3000#anchor"
+ << QUrl("path://host:3000#anchor");
+ QTest::newRow("Path syntax, userinfo@host:port, relative url")
+ << QUrl("path://user:password@host:3000") << "#anchor"
+ << QUrl("path://user:password@host:3000#anchor");
+ QTest::newRow("Path syntax, userinfo@host:port, absolute url")
+ << QUrl("path://user:password@host:3000") << "path://user:password@host:3000#anchor"
+ << QUrl("path://user:password@host:3000#anchor");
+
+ // Host syntax
+ // - We lose the port and the user info from the authority after navigation
+ QTest::newRow("Host syntax, host only, relative url")
+ << QUrl("host://host") << "#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, host only, absolute url")
+ << QUrl("host://host") << "host://host#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, host/path, relative url")
+ << QUrl("host://host/path") << "#anchor" << QUrl("host://host/path#anchor");
+ QTest::newRow("Host syntax, host/path, absolute url")
+ << QUrl("host://host/path") << "host://host/path#anchor"
+ << QUrl("host://host/path#anchor");
+ QTest::newRow("Host syntax, host:port, relative url")
+ << QUrl("host://host:3000") << "#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, host:port, absolute url")
+ << QUrl("host://host:3000") << "host://host:3000#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, userinfo@host:port, relative url")
+ << QUrl("host://user:password@host:3000") << "#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, userinfo@host:port, absolute url")
+ << QUrl("host://user:password@host:3000") << "host://user:password@host:3000#anchor"
+ << QUrl("host://host/#anchor");
+
+ // HostAndPort syntax
+ // - We lose the port and the user info from the authority after navigation
+ QTest::newRow("HostAndPort syntax, host only, relative url")
+ << QUrl("hostandport://host") << "#anchor" << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, host only, absolute url")
+ << QUrl("hostandport://host") << "hostandport://host#anchor"
+ << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, host/path, relative url")
+ << QUrl("hostandport://host/path") << "#anchor"
+ << QUrl("hostandport://host/path#anchor");
+ QTest::newRow("HostAndPort syntax, host/path, absolute url")
+ << QUrl("hostandport://host/path") << "hostandport://host/path#anchor"
+ << QUrl("hostandport://host/path#anchor");
+ QTest::newRow("HostAndPort syntax, host:port, relative url")
+ << QUrl("hostandport://host:3000") << "#anchor" << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, host:port, absolute url")
+ << QUrl("hostandport://host:3000") << "hostandport://host:3000#anchor"
+ << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, userinfo@host:port, relative url")
+ << QUrl("hostandport://user:password@host:3000") << "#anchor"
+ << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, userinfo@host:port, absolute url")
+ << QUrl("hostandport://user:password@host:3000")
+ << "hostandport://user:password@host:3000#anchor" << QUrl("hostandport://host/#anchor");
+
+ // HostPortAndUserInformation syntax
+ // - We lose the port and it preserves the user info in the authority after navigation
+ QTest::newRow("HostPortAndUserInformation syntax, host only, relative url")
+ << QUrl("hostportuserinfo://host") << "#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host only, absolute url")
+ << QUrl("hostportuserinfo://host") << "hostportuserinfo://host#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host/path, relative url")
+ << QUrl("hostportuserinfo://host/path") << "#anchor"
+ << QUrl("hostportuserinfo://host/path#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host/path, absolute url")
+ << QUrl("hostportuserinfo://host/path") << "hostportuserinfo://host/path#anchor"
+ << QUrl("hostportuserinfo://host/path#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host:port, relative url")
+ << QUrl("hostportuserinfo://host:3000") << "#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host:port, absolute url")
+ << QUrl("hostportuserinfo://host:3000") << "hostportuserinfo://host:3000#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, userinfo@host:port, relative url")
+ << QUrl("hostportuserinfo://user:password@host:3000") << "#anchor"
+ << QUrl("hostportuserinfo://user:password@host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, userinfo@host:port, absolute url")
+ << QUrl("hostportuserinfo://user:password@host:3000")
+ << "hostportuserinfo://user:password@host:3000#anchor"
+ << QUrl("hostportuserinfo://user:password@host/#anchor");
+}
+
+void tst_Schemes::customSchemeFragmentNavigation()
+{
+ QFETCH(QUrl, baseUrl);
+ QFETCH(QUrl, expectedUrl);
+ QFETCH(QString, linkUrl);
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QWebEngineView view;
+ view.setPage(&page);
+ view.resize(800, 600);
+ view.show();
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy urlChangedSpy(&page, SIGNAL(urlChanged(QUrl)));
+
+ CustomScheme *schemeHandler = new CustomScheme(linkUrl);
+ page.profile()->installUrlSchemeHandler(baseUrl.scheme().toUtf8(), schemeHandler);
+
+ view.load(baseUrl);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.scrollY").toInt() == 0);
+
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QVERIFY(urlChangedSpy.wait());
+ QCOMPARE(page.url(), expectedUrl);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.scrollY").toInt() > 0);
+
+ // Same document navigation doesn't emit loadFinished
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+}
+
QTEST_MAIN(tst_Schemes)
#include "tst_schemes.moc"
diff --git a/tests/auto/widgets/shutdown/CMakeLists.txt b/tests/auto/widgets/shutdown/CMakeLists.txt
index 12ca27c3d..e2ce9eeb9 100644
--- a/tests/auto/widgets/shutdown/CMakeLists.txt
+++ b/tests/auto/widgets/shutdown/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_shutdown
SOURCES
tst_shutdown.cpp
diff --git a/tests/auto/widgets/spellchecking/CMakeLists.txt b/tests/auto/widgets/spellchecking/CMakeLists.txt
index 2c1926476..8c538377d 100644
--- a/tests/auto/widgets/spellchecking/CMakeLists.txt
+++ b/tests/auto/widgets/spellchecking/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_spellchecking
diff --git a/tests/auto/widgets/touchinput/CMakeLists.txt b/tests/auto/widgets/touchinput/CMakeLists.txt
index 82e3fca4a..bd76666d6 100644
--- a/tests/auto/widgets/touchinput/CMakeLists.txt
+++ b/tests/auto/widgets/touchinput/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_touchinput
diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt
index c6d3e6e50..4bb14e72d 100644
--- a/tests/manual/CMakeLists.txt
+++ b/tests/manual/CMakeLists.txt
@@ -1,2 +1,3 @@
+add_subdirectory(examples)
add_subdirectory(quick)
add_subdirectory(widgets)
diff --git a/tests/manual/examples/CMakeLists.txt b/tests/manual/examples/CMakeLists.txt
new file mode 100644
index 000000000..6c9b56c43
--- /dev/null
+++ b/tests/manual/examples/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(widgets)
+add_subdirectory(quick)
diff --git a/tests/manual/examples/quick/CMakeLists.txt b/tests/manual/examples/quick/CMakeLists.txt
new file mode 100644
index 000000000..c461f2dbb
--- /dev/null
+++ b/tests/manual/examples/quick/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_subdirectory(minimal)
+add_subdirectory(customdialogs)
+add_subdirectory(customtouchhandle)
+add_subdirectory(webengineaction)
diff --git a/examples/webenginequick/customdialogs/CMakeLists.txt b/tests/manual/examples/quick/customdialogs/CMakeLists.txt
index b1899fd66..f0cdd54fa 100644
--- a/examples/webenginequick/customdialogs/CMakeLists.txt
+++ b/tests/manual/examples/quick/customdialogs/CMakeLists.txt
@@ -1,20 +1,14 @@
-cmake_minimum_required(VERSION 3.16)
-project(customdialogs LANGUAGES CXX)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(customdialogs LANGUAGES CXX)
+ find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
endif()
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/customdialogs")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
-
-qt_add_executable(customdialogs
- main.cpp
- server.cpp server.h
+qt_internal_add_manual_test(customdialogs
+ SOURCES main.cpp server.cpp server.h
)
set_target_properties(customdialogs PROPERTIES
@@ -60,14 +54,3 @@ qt_add_resources(customdialogs "customdialogs"
${customdialogs_resource_files}
)
-if(TARGET Qt::Widgets)
- target_link_libraries(customdialogs PUBLIC
- Qt::Widgets
- )
-endif()
-
-install(TARGETS customdialogs
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/customdialogs/MessageRectangle.qml b/tests/manual/examples/quick/customdialogs/MessageRectangle.qml
index 09a202cf3..09a202cf3 100644
--- a/examples/webenginequick/customdialogs/MessageRectangle.qml
+++ b/tests/manual/examples/quick/customdialogs/MessageRectangle.qml
diff --git a/examples/webenginequick/customdialogs/SwitchButton.qml b/tests/manual/examples/quick/customdialogs/SwitchButton.qml
index 69fc1427e..69fc1427e 100644
--- a/examples/webenginequick/customdialogs/SwitchButton.qml
+++ b/tests/manual/examples/quick/customdialogs/SwitchButton.qml
diff --git a/examples/webenginequick/customdialogs/WebView.qml b/tests/manual/examples/quick/customdialogs/WebView.qml
index 5c99ee7e7..5c99ee7e7 100644
--- a/examples/webenginequick/customdialogs/WebView.qml
+++ b/tests/manual/examples/quick/customdialogs/WebView.qml
diff --git a/examples/webenginequick/customdialogs/customdialogs.pro b/tests/manual/examples/quick/customdialogs/customdialogs.pro
index 1b9a6778e..1b9a6778e 100644
--- a/examples/webenginequick/customdialogs/customdialogs.pro
+++ b/tests/manual/examples/quick/customdialogs/customdialogs.pro
diff --git a/examples/webenginequick/customdialogs/customdialogs.qrc b/tests/manual/examples/quick/customdialogs/customdialogs.qrc
index bb2677198..bb2677198 100644
--- a/examples/webenginequick/customdialogs/customdialogs.qrc
+++ b/tests/manual/examples/quick/customdialogs/customdialogs.qrc
diff --git a/examples/webenginequick/customdialogs/forms/Authentication.qml b/tests/manual/examples/quick/customdialogs/forms/Authentication.qml
index 151a7c4aa..151a7c4aa 100644
--- a/examples/webenginequick/customdialogs/forms/Authentication.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/Authentication.qml
diff --git a/examples/webenginequick/customdialogs/forms/AuthenticationForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/AuthenticationForm.ui.qml
index f14986b20..f14986b20 100644
--- a/examples/webenginequick/customdialogs/forms/AuthenticationForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/AuthenticationForm.ui.qml
diff --git a/examples/webenginequick/customdialogs/forms/ColorCell.qml b/tests/manual/examples/quick/customdialogs/forms/ColorCell.qml
index 57151780c..57151780c 100644
--- a/examples/webenginequick/customdialogs/forms/ColorCell.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/ColorCell.qml
diff --git a/examples/webenginequick/customdialogs/forms/ColorPicker.qml b/tests/manual/examples/quick/customdialogs/forms/ColorPicker.qml
index 63269ddff..63269ddff 100644
--- a/examples/webenginequick/customdialogs/forms/ColorPicker.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/ColorPicker.qml
diff --git a/examples/webenginequick/customdialogs/forms/ColorPickerForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/ColorPickerForm.ui.qml
index 060aeef7d..060aeef7d 100644
--- a/examples/webenginequick/customdialogs/forms/ColorPickerForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/ColorPickerForm.ui.qml
diff --git a/examples/webenginequick/customdialogs/forms/CustomButton.qml b/tests/manual/examples/quick/customdialogs/forms/CustomButton.qml
index 00a06d558..00a06d558 100644
--- a/examples/webenginequick/customdialogs/forms/CustomButton.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/CustomButton.qml
diff --git a/examples/webenginequick/customdialogs/forms/FilePicker.qml b/tests/manual/examples/quick/customdialogs/forms/FilePicker.qml
index 45ffefb3a..45ffefb3a 100644
--- a/examples/webenginequick/customdialogs/forms/FilePicker.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/FilePicker.qml
diff --git a/examples/webenginequick/customdialogs/forms/FilePickerForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/FilePickerForm.ui.qml
index 1e99b1a91..1e99b1a91 100644
--- a/examples/webenginequick/customdialogs/forms/FilePickerForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/FilePickerForm.ui.qml
diff --git a/examples/webenginequick/customdialogs/forms/FileRow.qml b/tests/manual/examples/quick/customdialogs/forms/FileRow.qml
index 1a0cfc0a0..1a0cfc0a0 100644
--- a/examples/webenginequick/customdialogs/forms/FileRow.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/FileRow.qml
diff --git a/examples/webenginequick/customdialogs/forms/JavaScript.qml b/tests/manual/examples/quick/customdialogs/forms/JavaScript.qml
index 132c95697..132c95697 100644
--- a/examples/webenginequick/customdialogs/forms/JavaScript.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/JavaScript.qml
diff --git a/examples/webenginequick/customdialogs/forms/JavaScriptForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/JavaScriptForm.ui.qml
index b535e7ef9..b535e7ef9 100644
--- a/examples/webenginequick/customdialogs/forms/JavaScriptForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/JavaScriptForm.ui.qml
diff --git a/examples/webenginequick/customdialogs/forms/Menu.qml b/tests/manual/examples/quick/customdialogs/forms/Menu.qml
index b90802a0c..b90802a0c 100644
--- a/examples/webenginequick/customdialogs/forms/Menu.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/Menu.qml
diff --git a/examples/webenginequick/customdialogs/forms/MenuForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/MenuForm.ui.qml
index b4c06bb7d..b4c06bb7d 100644
--- a/examples/webenginequick/customdialogs/forms/MenuForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/MenuForm.ui.qml
diff --git a/examples/webenginequick/customdialogs/forms/TouchSelectionMenu.qml b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenu.qml
index 1b0c19789..1b0c19789 100644
--- a/examples/webenginequick/customdialogs/forms/TouchSelectionMenu.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenu.qml
diff --git a/examples/webenginequick/customdialogs/forms/TouchSelectionMenuForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenuForm.ui.qml
index bed39566f..bed39566f 100644
--- a/examples/webenginequick/customdialogs/forms/TouchSelectionMenuForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenuForm.ui.qml
diff --git a/examples/webenginequick/customdialogs/forms/forms.qmlproject b/tests/manual/examples/quick/customdialogs/forms/forms.qmlproject
index b06afaaf1..b06afaaf1 100644
--- a/examples/webenginequick/customdialogs/forms/forms.qmlproject
+++ b/tests/manual/examples/quick/customdialogs/forms/forms.qmlproject
diff --git a/examples/webenginequick/customdialogs/icon.svg b/tests/manual/examples/quick/customdialogs/icon.svg
index 48271180b..48271180b 100644
--- a/examples/webenginequick/customdialogs/icon.svg
+++ b/tests/manual/examples/quick/customdialogs/icon.svg
diff --git a/examples/webenginequick/customdialogs/index.html b/tests/manual/examples/quick/customdialogs/index.html
index d5de2827c..d5de2827c 100644
--- a/examples/webenginequick/customdialogs/index.html
+++ b/tests/manual/examples/quick/customdialogs/index.html
diff --git a/examples/webenginequick/customdialogs/main.cpp b/tests/manual/examples/quick/customdialogs/main.cpp
index c114ea935..c114ea935 100644
--- a/examples/webenginequick/customdialogs/main.cpp
+++ b/tests/manual/examples/quick/customdialogs/main.cpp
diff --git a/examples/webenginequick/customdialogs/main.qml b/tests/manual/examples/quick/customdialogs/main.qml
index d0cb6f324..d0cb6f324 100644
--- a/examples/webenginequick/customdialogs/main.qml
+++ b/tests/manual/examples/quick/customdialogs/main.qml
diff --git a/examples/webenginequick/customdialogs/server.cpp b/tests/manual/examples/quick/customdialogs/server.cpp
index efb870618..efb870618 100644
--- a/examples/webenginequick/customdialogs/server.cpp
+++ b/tests/manual/examples/quick/customdialogs/server.cpp
diff --git a/examples/webenginequick/customdialogs/server.h b/tests/manual/examples/quick/customdialogs/server.h
index 563465013..563465013 100644
--- a/examples/webenginequick/customdialogs/server.h
+++ b/tests/manual/examples/quick/customdialogs/server.h
diff --git a/examples/webenginequick/customdialogs/style.css b/tests/manual/examples/quick/customdialogs/style.css
index e4c25e7eb..e4c25e7eb 100644
--- a/examples/webenginequick/customdialogs/style.css
+++ b/tests/manual/examples/quick/customdialogs/style.css
diff --git a/tests/manual/examples/quick/customtouchhandle/CMakeLists.txt b/tests/manual/examples/quick/customtouchhandle/CMakeLists.txt
new file mode 100644
index 000000000..5d790a9e3
--- /dev/null
+++ b/tests/manual/examples/quick/customtouchhandle/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(customtouchhandle LANGUAGES CXX)
+ find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
+endif()
+
+qt_internal_add_manual_test(customtouchhandle
+ SOURCES main.cpp
+)
+
+set_target_properties(customtouchhandle PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(customtouchhandle PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineQuick
+)
+
+# Resources:
+set(qml_resource_files
+ "main.qml"
+)
+
+qt6_add_resources(customtouchhandle "qml"
+ PREFIX
+ "/"
+ FILES
+ ${qml_resource_files}
+)
+
diff --git a/examples/webenginequick/customtouchhandle/customtouchhandle.pro b/tests/manual/examples/quick/customtouchhandle/customtouchhandle.pro
index a74ef3146..a74ef3146 100644
--- a/examples/webenginequick/customtouchhandle/customtouchhandle.pro
+++ b/tests/manual/examples/quick/customtouchhandle/customtouchhandle.pro
diff --git a/examples/webenginequick/customtouchhandle/main.cpp b/tests/manual/examples/quick/customtouchhandle/main.cpp
index f1b70b024..f1b70b024 100644
--- a/examples/webenginequick/customtouchhandle/main.cpp
+++ b/tests/manual/examples/quick/customtouchhandle/main.cpp
diff --git a/examples/webenginequick/customtouchhandle/main.qml b/tests/manual/examples/quick/customtouchhandle/main.qml
index c40b4c73b..c40b4c73b 100644
--- a/examples/webenginequick/customtouchhandle/main.qml
+++ b/tests/manual/examples/quick/customtouchhandle/main.qml
diff --git a/examples/webenginequick/customtouchhandle/qml.qrc b/tests/manual/examples/quick/customtouchhandle/qml.qrc
index 5f6483ac3..5f6483ac3 100644
--- a/examples/webenginequick/customtouchhandle/qml.qrc
+++ b/tests/manual/examples/quick/customtouchhandle/qml.qrc
diff --git a/tests/manual/examples/quick/minimal/CMakeLists.txt b/tests/manual/examples/quick/minimal/CMakeLists.txt
new file mode 100644
index 000000000..39aaa1ea3
--- /dev/null
+++ b/tests/manual/examples/quick/minimal/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(minimal LANGUAGES CXX)
+ find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
+endif()
+
+qt_internal_add_manual_test(webengine-minimal-qml
+ SOURCES
+ main.cpp
+)
+
+set_target_properties(webengine-minimal-qml PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(webengine-minimal-qml PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineQuick
+)
+
+# Resources:
+set(qml_resource_files
+ "main.qml"
+)
+
+qt_add_resources(webengine-minimal-qml "qml"
+ PREFIX
+ "/"
+ FILES
+ ${qml_resource_files}
+)
diff --git a/examples/webenginequick/minimal/main.cpp b/tests/manual/examples/quick/minimal/main.cpp
index 47b3e146a..16466ae06 100644
--- a/examples/webenginequick/minimal/main.cpp
+++ b/tests/manual/examples/quick/minimal/main.cpp
@@ -17,4 +17,3 @@ int main(int argc, char *argv[])
return app.exec();
}
-
diff --git a/examples/webenginequick/minimal/main.qml b/tests/manual/examples/quick/minimal/main.qml
index a8733a8c8..a8733a8c8 100644
--- a/examples/webenginequick/minimal/main.qml
+++ b/tests/manual/examples/quick/minimal/main.qml
diff --git a/examples/webenginequick/minimal/minimal.pro b/tests/manual/examples/quick/minimal/minimal.pro
index acca6477c..acca6477c 100644
--- a/examples/webenginequick/minimal/minimal.pro
+++ b/tests/manual/examples/quick/minimal/minimal.pro
diff --git a/examples/webenginequick/minimal/qml.qrc b/tests/manual/examples/quick/minimal/qml.qrc
index 0ff3892d9..0ff3892d9 100644
--- a/examples/webenginequick/minimal/qml.qrc
+++ b/tests/manual/examples/quick/minimal/qml.qrc
diff --git a/tests/manual/examples/quick/webengineaction/CMakeLists.txt b/tests/manual/examples/quick/webengineaction/CMakeLists.txt
new file mode 100644
index 000000000..563e3c9df
--- /dev/null
+++ b/tests/manual/examples/quick/webengineaction/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(webengineaction LANGUAGES CXX)
+ find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineQuick)
+endif()
+
+qt_internal_add_manual_test(webengineaction
+ SOURCES
+ main.cpp
+ utils.h
+)
+
+set_target_properties(webengineaction PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(webengineaction PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineQuick
+)
+
+# Resources:
+set(qml_resource_files
+ "main.qml"
+)
+
+qt_add_resources(webengineaction "qml"
+ PREFIX
+ "/"
+ FILES
+ ${qml_resource_files}
+)
diff --git a/examples/webenginequick/webengineaction/main.cpp b/tests/manual/examples/quick/webengineaction/main.cpp
index e685a715c..a7bfaaf36 100644
--- a/examples/webenginequick/webengineaction/main.cpp
+++ b/tests/manual/examples/quick/webengineaction/main.cpp
@@ -1,8 +1,11 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+#include "utils.h"
+
#include <QGuiApplication>
#include <QQmlApplicationEngine>
+#include <QQmlContext>
#include <QtWebEngineQuick/qtwebenginequickglobal.h>
int main(int argc, char *argv[])
@@ -13,6 +16,9 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
+ Utils utils;
+
+ engine.rootContext()->setContextProperty("utils", &utils);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
diff --git a/examples/webenginequick/webengineaction/main.qml b/tests/manual/examples/quick/webengineaction/main.qml
index 149484340..a1483b126 100644
--- a/examples/webenginequick/webengineaction/main.qml
+++ b/tests/manual/examples/quick/webengineaction/main.qml
@@ -50,7 +50,7 @@ ApplicationWindow {
text: webEngineView.url
selectByMouse: true
- onEditingFinished: webEngineView.url = text
+ onEditingFinished: webEngineView.url = utils.fromUserInput(text)
}
ToolButton {
diff --git a/examples/webenginequick/webengineaction/qml.qrc b/tests/manual/examples/quick/webengineaction/qml.qrc
index 5f6483ac3..5f6483ac3 100644
--- a/examples/webenginequick/webengineaction/qml.qrc
+++ b/tests/manual/examples/quick/webengineaction/qml.qrc
diff --git a/tests/manual/examples/quick/webengineaction/utils.h b/tests/manual/examples/quick/webengineaction/utils.h
new file mode 100644
index 000000000..d9a803907
--- /dev/null
+++ b/tests/manual/examples/quick/webengineaction/utils.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QUrl>
+
+class Utils : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE static QUrl fromUserInput(const QString &userInput);
+};
+
+inline QUrl Utils::fromUserInput(const QString &userInput)
+{
+ QFileInfo fileInfo(userInput);
+ if (fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ return QUrl::fromUserInput(userInput);
+}
+
+#endif // UTILS_H
diff --git a/tests/manual/examples/quick/webengineaction/webengineaction.pro b/tests/manual/examples/quick/webengineaction/webengineaction.pro
new file mode 100644
index 000000000..9286604a1
--- /dev/null
+++ b/tests/manual/examples/quick/webengineaction/webengineaction.pro
@@ -0,0 +1,8 @@
+TEMPLATE = app
+
+QT += webenginequick
+
+HEADERS += utils.h
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc
diff --git a/tests/manual/examples/widgets/CMakeLists.txt b/tests/manual/examples/widgets/CMakeLists.txt
new file mode 100644
index 000000000..d853ba634
--- /dev/null
+++ b/tests/manual/examples/widgets/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(minimal)
diff --git a/tests/manual/examples/widgets/minimal/CMakeLists.txt b/tests/manual/examples/widgets/minimal/CMakeLists.txt
new file mode 100644
index 000000000..6351aaa90
--- /dev/null
+++ b/tests/manual/examples/widgets/minimal/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(minimal LANGUAGES CXX)
+ find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
+ endif()
+
+qt_internal_add_manual_test(minimal-widgets
+ SOURCES
+ main.cpp
+)
+
+set_target_properties(minimal-widgets PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(minimal-widgets PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+)
diff --git a/examples/webenginewidgets/minimal/main.cpp b/tests/manual/examples/widgets/minimal/main.cpp
index 86c04e721..86c04e721 100644
--- a/examples/webenginewidgets/minimal/main.cpp
+++ b/tests/manual/examples/widgets/minimal/main.cpp
diff --git a/examples/webenginewidgets/minimal/minimal.pro b/tests/manual/examples/widgets/minimal/minimal.pro
index 849f4b9b6..849f4b9b6 100644
--- a/examples/webenginewidgets/minimal/minimal.pro
+++ b/tests/manual/examples/widgets/minimal/minimal.pro
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
deleted file mode 100644
index edf95846c..000000000
--- a/tests/manual/manual.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += \
- widgets \
- quick
-
-!qtHaveModule(webenginewidgets): SUBDIRS -= widgets
diff --git a/tests/manual/quick/quick.pro b/tests/manual/quick/quick.pro
deleted file mode 100644
index 8522763f8..000000000
--- a/tests/manual/quick/quick.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += \
- faviconbrowser \
- touchbrowser
diff --git a/tests/manual/quick/touchbrowser/CMakeLists.txt b/tests/manual/quick/touchbrowser/CMakeLists.txt
index c211ba8e6..d4064c05e 100644
--- a/tests/manual/quick/touchbrowser/CMakeLists.txt
+++ b/tests/manual/quick/touchbrowser/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
cmake_minimum_required(VERSION 3.16)
project(touchbrowser LANGUAGES CXX)
@@ -15,7 +18,7 @@ qt_internal_add_manual_test(touchbrowser
main.cpp
utils.h
${SOURCES}
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::GuiPrivate
Qt::Quick
Qt::WebEngineQuick
diff --git a/tests/manual/quick/touchbrowser/touchmockingapplication.cpp b/tests/manual/quick/touchbrowser/touchmockingapplication.cpp
index 4fad86d33..2a17757dc 100644
--- a/tests/manual/quick/touchbrowser/touchmockingapplication.cpp
+++ b/tests/manual/quick/touchbrowser/touchmockingapplication.cpp
@@ -66,10 +66,10 @@ bool TouchMockingApplication::notify(QObject* target, QEvent* event)
if (event->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(event)->key() == Qt::Key_Control) {
foreach (int id, m_heldTouchPoints)
if (m_touchPoints.contains(id) && !QGuiApplication::mouseButtons().testFlag(Qt::MouseButton(id))) {
- QMutableEventPoint::setState(m_touchPoints[id], QEventPoint::Released);
+ QMutableEventPoint::from(m_touchPoints[id]).setState(QEventPoint::Released);
m_heldTouchPoints.remove(id);
} else
- QMutableEventPoint::setState(m_touchPoints[id], QEventPoint::Stationary);
+ QMutableEventPoint::from(m_touchPoints[id]).setState(QEventPoint::Stationary);
sendTouchEvent(window, m_heldTouchPoints.isEmpty() ? QEvent::TouchEnd : QEvent::TouchUpdate, static_cast<QKeyEvent*>(event)->timestamp());
}
@@ -78,18 +78,18 @@ bool TouchMockingApplication::notify(QObject* target, QEvent* event)
const QMouseEvent* const mouseEvent = static_cast<QMouseEvent*>(event);
QEventPoint touchPoint;
- QMutableEventPoint::setPressure(touchPoint, 1);
+ QMutableEventPoint::from(touchPoint).setPressure(1);
QEvent::Type touchType = QEvent::None;
switch (mouseEvent->type()) {
case QEvent::MouseButtonPress:
- QMutableEventPoint::setId(touchPoint, mouseEvent->button());
+ QMutableEventPoint::from(touchPoint).setId(mouseEvent->button());
if (m_touchPoints.contains(touchPoint.id())) {
- QMutableEventPoint::setState(touchPoint, QEventPoint::Updated);
+ QMutableEventPoint::from(touchPoint).setState(QEventPoint::Updated);
touchType = QEvent::TouchUpdate;
} else {
- QMutableEventPoint::setState(touchPoint, QEventPoint::Pressed);
+ QMutableEventPoint::from(touchPoint).setState(QEventPoint::Pressed);
// Check if more buttons are held down than just the event triggering one.
if (mouseEvent->buttons() > mouseEvent->button())
touchType = QEvent::TouchUpdate;
@@ -107,8 +107,8 @@ bool TouchMockingApplication::notify(QObject* target, QEvent* event)
return true;
}
touchType = QEvent::TouchUpdate;
- QMutableEventPoint::setId(touchPoint, mouseEvent->buttons());
- QMutableEventPoint::setState(touchPoint, QEventPoint::Updated);
+ QMutableEventPoint::from(touchPoint).setId(mouseEvent->buttons());
+ QMutableEventPoint::from(touchPoint).setState(QEventPoint::Updated);
break;
case QEvent::MouseButtonRelease:
// Check if any buttons are still held down after this event.
@@ -116,8 +116,8 @@ bool TouchMockingApplication::notify(QObject* target, QEvent* event)
touchType = QEvent::TouchUpdate;
else
touchType = QEvent::TouchEnd;
- QMutableEventPoint::setId(touchPoint, mouseEvent->button());
- QMutableEventPoint::setState(touchPoint, QEventPoint::Released);
+ QMutableEventPoint::from(touchPoint).setId(mouseEvent->button());
+ QMutableEventPoint::from(touchPoint).setState(QEventPoint::Released);
break;
case QEvent::MouseButtonDblClick:
// Eat double-clicks, their accompanying press event is all we need.
@@ -146,7 +146,7 @@ bool TouchMockingApplication::notify(QObject* target, QEvent* event)
// Update states for all other touch-points
for (QHash<int, QEventPoint>::iterator it = m_touchPoints.begin(), end = m_touchPoints.end(); it != end; ++it) {
if (!(it.value().id() & touchPoint.id()))
- QMutableEventPoint::setState(it.value(), QEventPoint::Stationary);
+ QMutableEventPoint::from(it.value()).setState(QEventPoint::Stationary);
}
Q_ASSERT(touchType != QEvent::None);
@@ -177,18 +177,18 @@ void TouchMockingApplication::updateTouchPoint(const QMouseEvent* mouseEvent, QE
// but since the canvas translates touch events we actually need to pass
// the screen position as the scene position to deliver the appropriate
// coordinates to the target.
- QMutableEventPoint::setPosition(touchPoint, mouseEvent->position());
- QMutableEventPoint::setScenePosition(touchPoint, mouseEvent->globalPosition());
+ QMutableEventPoint::from(touchPoint).setPosition(mouseEvent->position());
+ QMutableEventPoint::from(touchPoint).setScenePosition(mouseEvent->globalPosition());
if (touchPoint.state() == QEventPoint::Pressed)
- QMutableEventPoint::setScenePosition(touchPoint, mouseEvent->scenePosition());
+ QMutableEventPoint::from(touchPoint).setScenePosition(mouseEvent->scenePosition());
else {
const QEventPoint& oldTouchPoint = m_touchPoints[mouseButton];
- QMutableEventPoint::setGlobalLastPosition(touchPoint, oldTouchPoint.globalPosition());
+ QMutableEventPoint::from(touchPoint).setGlobalLastPosition(oldTouchPoint.globalPosition());
}
// Update current touch-point.
- QMutableEventPoint::setId(touchPoint, mouseButton);
+ QMutableEventPoint::from(touchPoint).setId(mouseButton);
m_touchPoints.insert(mouseButton, touchPoint);
}
diff --git a/tests/manual/widgets/inputmethods/CMakeLists.txt b/tests/manual/widgets/inputmethods/CMakeLists.txt
index 4bc6e76db..acd5bca50 100644
--- a/tests/manual/widgets/inputmethods/CMakeLists.txt
+++ b/tests/manual/widgets/inputmethods/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
cmake_minimum_required(VERSION 3.16)
project(inputmethods LANGUAGES CXX)
@@ -13,7 +16,7 @@ qt_internal_add_manual_test(inputmethods
referenceview.cpp
testview.cpp
webview.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Core
Qt::Gui
Qt::Test
diff --git a/tests/manual/widgets/inputmethods/colorpicker.h b/tests/manual/widgets/inputmethods/colorpicker.h
index 171c0186b..0b6b3257a 100644
--- a/tests/manual/widgets/inputmethods/colorpicker.h
+++ b/tests/manual/widgets/inputmethods/colorpicker.h
@@ -7,8 +7,10 @@
#include <QColor>
#include <QWidget>
+QT_BEGIN_NAMESPACE
class QLineEdit;
class QPushButton;
+QT_END_NAMESPACE
class ColorPicker : public QWidget
{
diff --git a/tests/manual/widgets/inputmethods/controlview.h b/tests/manual/widgets/inputmethods/controlview.h
index f6b3e7fe6..caa08593f 100644
--- a/tests/manual/widgets/inputmethods/controlview.h
+++ b/tests/manual/widgets/inputmethods/controlview.h
@@ -8,12 +8,15 @@
#include <QTextCharFormat>
#include <QWidget>
-class ColorPicker;
+QT_BEGIN_NAMESPACE
class QComboBox;
class QLabel;
class QLineEdit;
class QPushButton;
class QSpinBox;
+QT_END_NAMESPACE
+
+class ColorPicker;
class ControlView : public QWidget
{
diff --git a/tests/manual/widgets/inputmethods/testview.h b/tests/manual/widgets/inputmethods/testview.h
index feb512cde..b99e60d75 100644
--- a/tests/manual/widgets/inputmethods/testview.h
+++ b/tests/manual/widgets/inputmethods/testview.h
@@ -7,8 +7,10 @@
#include <QTextCharFormat>
#include <QWidget>
+QT_BEGIN_NAMESPACE
class QPushButton;
class QTableView;
+QT_END_NAMESPACE
class TestView : public QWidget
{
diff --git a/tests/manual/widgets/webgl/CMakeLists.txt b/tests/manual/widgets/webgl/CMakeLists.txt
index 9eaa50c00..034a06a79 100644
--- a/tests/manual/widgets/webgl/CMakeLists.txt
+++ b/tests/manual/widgets/webgl/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
cmake_minimum_required(VERSION 3.16)
project(webgl LANGUAGES CXX)
@@ -8,7 +11,7 @@ qt_internal_add_manual_test(webgl
GUI
SOURCES
main.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
diff --git a/tests/manual/widgets/widgets.pro b/tests/manual/widgets/widgets.pro
deleted file mode 100644
index 34e88f0e3..000000000
--- a/tests/manual/widgets/widgets.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE= subdirs
-
-SUBDIRS += \
- inputmethods \
- webgl
diff --git a/tests/quicktestbrowser/ApplicationRoot.qml b/tests/quicktestbrowser/ApplicationRoot.qml
deleted file mode 100644
index 74e913ba5..000000000
--- a/tests/quicktestbrowser/ApplicationRoot.qml
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.1
-import QtWebEngine 1.1
-
-QtObject {
- id: root
-
- property bool thirdPartyCookiesEnabled: true
-
- property QtObject testProfile: WebEngineProfile {
- storageName: "Test"
- }
-
- property QtObject otrProfile: WebEngineProfile {
- offTheRecord: true
- }
-
- property Component browserWindowComponent: BrowserWindow {
- applicationRoot: root
- onClosing: destroy()
- }
- property Component browserDialogComponent: BrowserDialog {
- onClosing: destroy()
- }
- function createWindow(profile) {
- var newWindow = browserWindowComponent.createObject(root)
- newWindow.currentWebView.profile = profile
- profile.downloadRequested.connect(newWindow.onDownloadRequested)
- profile.presentNotification.connect(newWindow.onPresentNotification)
- return newWindow
- }
- function createDialog(profile) {
- var newDialog = browserDialogComponent.createObject(root)
- newDialog.currentWebView.profile = profile
- return newDialog
- }
- function load(url) {
- var browserWindow = createWindow(testProfile)
- browserWindow.currentWebView.url = url
- }
-}
diff --git a/tests/quicktestbrowser/BrowserDialog.qml b/tests/quicktestbrowser/BrowserDialog.qml
deleted file mode 100644
index a896223dc..000000000
--- a/tests/quicktestbrowser/BrowserDialog.qml
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.1
-import QtQuick.Window 2.2
-import QtWebEngine 1.1
-
-Window {
- property alias currentWebView: webView
- flags: Qt.Dialog
- width: 800
- height: 600
- visible: true
- onClosing: destroy()
- WebEngineView {
- id: webView
- anchors.fill: parent
- }
-}
diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml
deleted file mode 100644
index 699e877a9..000000000
--- a/tests/quicktestbrowser/BrowserWindow.qml
+++ /dev/null
@@ -1,507 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.1
-import QtWebEngine 1.2
-
-import QtQuick.Controls 1.0
-import QtQuick.Controls.Styles 1.0
-import QtQuick.Layouts 1.0
-import QtQuick.Window 2.1
-import QtQuick.Controls.Private 1.0
-import Qt.labs.settings 1.0
-import QtQuick.Dialogs 1.2
-
-ApplicationWindow {
- id: browserWindow
- property QtObject applicationRoot
- property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item.webView : null
- property int previousVisibility: Window.Windowed
-
- property bool isFullScreen: visibility == Window.FullScreen
- onIsFullScreenChanged: {
- // This is for the case where the system forces us to leave fullscreen.
- if (currentWebView && !isFullScreen) {
- currentWebView.state = ""
- if (currentWebView.isFullScreen) {
- currentWebView.fullScreenCancelled()
- fullScreenNotification.hide()
- }
- }
- }
-
- height: 600
- width: 800
- visible: true
- title: currentWebView && currentWebView.title
-
- Settings {
- id : appSettings
- property alias autoLoadImages: loadImages.checked;
- property alias javaScriptEnabled: javaScriptEnabled.checked;
- property alias errorPageEnabled: errorPageEnabled.checked;
- property alias pluginsEnabled: pluginsEnabled.checked;
- property alias thirdPartyCookiesEnabled: thirdPartyCookiesEnabled.checked;
- }
-
- // Make sure the Qt.WindowFullscreenButtonHint is set on OS X.
- Component.onCompleted: flags = flags | Qt.WindowFullscreenButtonHint
-
- // Create a styleItem to determine the platform.
- // When using style "mac", ToolButtons are not supposed to accept focus.
- StyleItem { id: styleItem }
- property bool platformIsMac: styleItem.style == "mac"
-
- Action {
- shortcut: "Ctrl+D"
- onTriggered: {
- downloadView.visible = !downloadView.visible
- }
- }
-
- Action {
- id: focus
- shortcut: "Ctrl+L"
- onTriggered: {
- addressBar.forceActiveFocus();
- addressBar.selectAll();
- }
- }
- Action {
- shortcut: "Ctrl+R"
- onTriggered: {
- if (currentWebView)
- currentWebView.reload()
- }
- }
- Action {
- shortcut: "Ctrl+T"
- onTriggered: {
- tabs.createEmptyTab(currentWebView.profile)
- tabs.currentIndex = tabs.count - 1
- addressBar.forceActiveFocus();
- addressBar.selectAll();
- }
- }
- Action {
- shortcut: "Ctrl+W"
- onTriggered: {
- if (tabs.count == 1)
- browserWindow.close()
- else
- tabs.removeTab(tabs.currentIndex)
- }
- }
-
- Action {
- shortcut: "Escape"
- onTriggered: {
- if (browserWindow.isFullScreen)
- browserWindow.visibility = browserWindow.previousVisibility
- }
- }
- Action {
- shortcut: "Ctrl+0"
- onTriggered: zoomController.reset()
- }
- Action {
- shortcut: "Ctrl+-"
- onTriggered: zoomController.zoomOut()
- }
- Action {
- shortcut: "Ctrl+="
- onTriggered: zoomController.zoomIn()
- }
-
- Menu {
- id: backHistoryMenu
-
- Instantiator {
- model: currentWebView && currentWebView.history.backItems
- MenuItem {
- text: model.title
- onTriggered: currentWebView.goBackOrForward(model.offset)
- }
-
- onObjectAdded: backHistoryMenu.insertItem(index, object)
- onObjectRemoved: backHistoryMenu.removeItem(object)
- }
- }
-
- Menu {
- id: forwardHistoryMenu
-
- Instantiator {
- model: currentWebView && currentWebView.history.forwardItems
- MenuItem {
- text: model.title
- onTriggered: currentWebView.goBackOrForward(model.offset)
- }
-
- onObjectAdded: forwardHistoryMenu.insertItem(index, object)
- onObjectRemoved: forwardHistoryMenu.removeItem(object)
- }
- }
-
- toolBar: ToolBar {
- id: navigationBar
- RowLayout {
- anchors.fill: parent;
- ButtonWithMenu {
- id: backButton
- iconSource: "icons/go-previous.png"
- enabled: currentWebView && currentWebView.canGoBack
- activeFocusOnTab: !browserWindow.platformIsMac
- onClicked: currentWebView.goBack()
- longPressMenu: backHistoryMenu
- }
- ButtonWithMenu {
- id: forwardButton
- iconSource: "icons/go-next.png"
- enabled: currentWebView && currentWebView.canGoForward
- activeFocusOnTab: !browserWindow.platformIsMac
- onClicked: currentWebView.goForward()
- longPressMenu: forwardHistoryMenu
- }
- ToolButton {
- id: reloadButton
- iconSource: currentWebView && currentWebView.loading ? "icons/process-stop.png" : "icons/view-refresh.png"
- onClicked: currentWebView && currentWebView.loading ? currentWebView.stop() : currentWebView.reload()
- activeFocusOnTab: !browserWindow.platformIsMac
- }
- TextField {
- id: addressBar
- Image {
- anchors.verticalCenter: addressBar.verticalCenter;
- x: 5
- z: 2
- id: faviconImage
- width: 16; height: 16
- source: currentWebView && currentWebView.icon
- }
- style: TextFieldStyle {
- padding {
- left: 26;
- }
- }
- focus: true
- Layout.fillWidth: true
- text: currentWebView && currentWebView.url
- onAccepted: currentWebView.url = utils.fromUserInput(text)
- }
- ToolButton {
- id: settingsMenuButton
- menu: Menu {
- MenuItem {
- id: loadImages
- text: "Autoload images"
- checkable: true
- checked: true
- }
- MenuItem {
- id: javaScriptEnabled
- text: "JavaScript On"
- checkable: true
- checked: true
- }
- MenuItem {
- id: errorPageEnabled
- text: "ErrorPage On"
- checkable: true
- checked: true
- }
- MenuItem {
- id: pluginsEnabled
- text: "Plugins On"
- checkable: true
- checked: true
- }
- MenuItem {
- id: thirdPartyCookiesEnabled
- text: "Third party cookies enabled"
- checkable: true
- checked: true
- onToggled: applicationRoot.thirdPartyCookiesEnabled = checked
- }
- MenuItem {
- id: offTheRecordEnabled
- text: "Off The Record"
- checkable: true
- checked: currentWebView.profile.offTheRecord
- onToggled: currentWebView.profile = checked ? otrProfile : testProfile;
- }
- MenuItem {
- id: httpDiskCacheEnabled
- text: "HTTP Disk Cache"
- checkable: !currentWebView.profile.offTheRecord
- checked: (currentWebView.profile.httpCacheType == WebEngineProfile.DiskHttpCache)
- onToggled: currentWebView.profile.httpCacheType = checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache;
- }
- }
- }
- }
- ProgressBar {
- id: progressBar
- height: 3
- anchors {
- left: parent.left
- top: parent.bottom
- right: parent.right
- leftMargin: -parent.leftMargin
- rightMargin: -parent.rightMargin
- }
- style: ProgressBarStyle {
- background: Item {}
- }
- z: -2;
- minimumValue: 0
- maximumValue: 100
- value: (currentWebView && currentWebView.loadProgress < 100) ? currentWebView.loadProgress : 0
- }
- }
-
- TabView {
- id: tabs
- function createEmptyTab(profile) {
- var tab = addTab("", tabComponent)
- // We must do this first to make sure that tab.active gets set so that tab.item gets instantiated immediately.
- tab.active = true
- tab.title = Qt.binding(function() { return tab.item.title })
- tab.item.webView.profile = profile
- return tab
- }
-
- anchors.fill: parent
- Component.onCompleted: createEmptyTab(testProfile)
-
- Component {
- id: tabComponent
- Item {
- property alias webView: webEngineView
- property alias title: webEngineView.title
- Action {
- shortcut: "Ctrl+F"
- onTriggered: {
- findBar.visible = !findBar.visible
- if (findBar.visible) {
- findTextField.forceActiveFocus()
- }
- }
- }
- FeaturePermissionBar {
- id: permBar
- view: webEngineView
- anchors {
- left: parent.left
- right: parent.right
- top: parent.top
- }
- z: 3
- }
-
- WebEngineView {
- id: webEngineView
-
- anchors {
- fill: parent
- top: permBar.bottom
- }
-
- focus: true
-
- states: [
- State {
- name: "FullScreen"
- PropertyChanges {
- target: tabs
- frameVisible: false
- tabsVisible: false
- }
- PropertyChanges {
- target: navigationBar
- visible: false
- }
- }
- ]
- settings.autoLoadImages: appSettings.autoLoadImages
- settings.javascriptEnabled: appSettings.javaScriptEnabled
- settings.errorPageEnabled: appSettings.errorPageEnabled
- settings.pluginsEnabled: appSettings.pluginsEnabled
-
- onCertificateError: {
- if (!acceptedCertificates.shouldAutoAccept(error)){
- error.defer()
- sslDialog.enqueue(error)
- } else{
- error.ignoreCertificateError()
- }
- }
-
- onNewWindowRequested: {
- if (!request.userInitiated)
- print("Warning: Blocked a popup window.")
- else if (request.destination == WebEngineView.NewViewInTab) {
- var tab = tabs.createEmptyTab(currentWebView.profile)
- tabs.currentIndex = tabs.count - 1
- request.openIn(tab.item.webView)
- } else if (request.destination == WebEngineView.NewViewInBackgroundTab) {
- var tab = tabs.createEmptyTab(currentWebView.profile)
- request.openIn(tab.item.webView)
- } else if (request.destination == WebEngineView.NewViewInDialog) {
- var dialog = applicationRoot.createDialog(currentWebView.profile)
- request.openIn(dialog.currentWebView)
- } else {
- var window = applicationRoot.createWindow(currentWebView.profile)
- request.openIn(window.currentWebView)
- }
- }
-
- onFullScreenRequested: {
- if (request.toggleOn) {
- webEngineView.state = "FullScreen"
- browserWindow.previousVisibility = browserWindow.visibility
- browserWindow.showFullScreen()
- fullScreenNotification.show()
- } else {
- webEngineView.state = ""
- browserWindow.visibility = browserWindow.previousVisibility
- fullScreenNotification.hide()
- }
- request.accept()
- }
-
- onFeaturePermissionRequested: {
- permBar.securityOrigin = securityOrigin;
- permBar.requestedFeature = feature;
- permBar.visible = true;
- }
- }
-
- Rectangle {
- id: findBar
- anchors.top: webEngineView.top
- anchors.right: webEngineView.right
- width: 240
- height: 35
- border.color: "lightgray"
- border.width: 1
- radius: 5
- visible: false
- color: browserWindow.color
-
- RowLayout {
- anchors.centerIn: findBar
- TextField {
- id: findTextField
- onAccepted: {
- webEngineView.findText(text)
- }
- }
- ToolButton {
- id: findBackwardButton
- iconSource: "icons/go-previous.png"
- onClicked: webEngineView.findText(findTextField.text, WebEngineView.FindBackward)
- }
- ToolButton {
- id: findForwardButton
- iconSource: "icons/go-next.png"
- onClicked: webEngineView.findText(findTextField.text)
- }
- ToolButton {
- id: findCancelButton
- iconSource: "icons/process-stop.png"
- onClicked: findBar.visible = false
- }
- }
- }
- }
- }
- }
-
- QtObject{
- id:acceptedCertificates
-
- property var acceptedUrls : []
-
- function shouldAutoAccept(certificateError){
- var domain = utils.domainFromString(certificateError.url)
- return acceptedUrls.indexOf(domain) >= 0
- }
- }
-
- MessageDialog {
- id: sslDialog
-
- property var certErrors: []
- icon: StandardIcon.Warning
- standardButtons: StandardButton.No | StandardButton.Yes
- title: "Server's certificate not trusted"
- text: "Do you wish to continue?"
- detailedText: "If you wish so, you may continue with an unverified certificate. " +
- "Accepting an unverified certificate means " +
- "you may not be connected with the host you tried to connect to.\n" +
- "Do you wish to override the security check and continue?"
- onYes: {
- var cert = certErrors.shift()
- var domain = utils.domainFromString(cert.url)
- acceptedCertificates.acceptedUrls.push(domain)
- cert.ignoreCertificateError()
- presentError()
- }
- onNo: reject()
- onRejected: reject()
-
- function reject(){
- certErrors.shift().rejectCertificate()
- presentError()
- }
- function enqueue(error){
- certErrors.push(error)
- presentError()
- }
- function presentError(){
- visible = certErrors.length > 0
- }
- }
-
- FullScreenNotification {
- id: fullScreenNotification
- }
-
- DownloadView {
- id: downloadView
- visible: false
- anchors.fill: parent
- }
-
- function onDownloadRequested(download) {
- downloadView.visible = true
- downloadView.append(download)
- download.accept()
- }
-
- MessageDialog {
- id: notificationDialog
- width: 200
- standardButtons: StandardButton.Ok
- }
-
- function onPresentNotification(notification) {
- notificationDialog.title = notification.title
- notificationDialog.text = notification.origin.toString() + '\n' + notification.message
- notificationDialog.open()
- }
-
- ZoomController {
- id: zoomController
- y: parent.mapFromItem(currentWebView, 0 , 0).y - 4
- anchors.right: parent.right
- width: (parent.width > 800) ? parent.width * 0.25 : 220
- anchors.rightMargin: (parent.width > 400) ? 100 : 0
- }
- Binding {
- target: currentWebView
- property: "zoomFactor"
- value: zoomController.zoomFactor
- }
-}
diff --git a/tests/quicktestbrowser/ButtonWithMenu.qml b/tests/quicktestbrowser/ButtonWithMenu.qml
deleted file mode 100644
index 56a4d3533..000000000
--- a/tests/quicktestbrowser/ButtonWithMenu.qml
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-
-// The QtQuick controls guys are slackers, so we need to make our own stuff
-
-ToolButton {
- id: root
- property Menu longPressMenu
- function showMenu() {
- longPressMenu.__popup(Qt.rect(0, root.height, 0, 0), 0)
- }
-
- Binding {
- target: longPressMenu
- property: "__visualItem"
- value: root
- }
-
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.LeftButton | Qt.RightButton
- onClicked: {
- if (mouse.button == Qt.RightButton)
- showMenu()
- else
- root.clicked()
- }
- onPressAndHold: showMenu()
- }
-}
diff --git a/tests/quicktestbrowser/DownloadView.qml b/tests/quicktestbrowser/DownloadView.qml
deleted file mode 100644
index f4834edad..000000000
--- a/tests/quicktestbrowser/DownloadView.qml
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.1
-import QtQuick.Controls 1.0
-import QtQuick.Controls.Styles 1.0
-import QtWebEngine 1.0
-import QtQuick.Layouts 1.0
-
-Rectangle {
- id: downloadView
- color: "lightgray"
-
- ListModel {
- id: downloadModel
- property var downloads: []
- }
-
- function append(download) {
- downloadModel.append(download)
- downloadModel.downloads.push(download)
- }
-
- Component {
- id: downloadItemDelegate
-
- Rectangle {
- width: listView.width
- height: childrenRect.height
- anchors.margins: 10
- radius: 3
- color: "transparent"
- border.color: "black"
- Rectangle {
- id: progressBar
-
- property real progress: downloadModel.downloads[index]
- ? downloadModel.downloads[index].receivedBytes / downloadModel.downloads[index].totalBytes : 0
-
- radius: 3
- color: width == listView.width ? "green" : "#2b74c7"
- width: listView.width * progress
- height: cancelButton.height
-
- Behavior on width {
- SmoothedAnimation { duration: 100 }
- }
- }
- Rectangle {
- anchors {
- left: parent.left
- right: parent.right
- leftMargin: 20
- }
- Label {
- id: label
- text: path
- anchors {
- verticalCenter: cancelButton.verticalCenter
- left: parent.left
- right: cancelButton.left
- }
- }
- Button {
- id: cancelButton
- anchors.right: parent.right
- iconSource: "icons/process-stop.png"
- onClicked: {
- var download = downloadModel.downloads[index]
-
- download.cancel()
-
- downloadModel.downloads = downloadModel.downloads.filter(function (el) {
- return el.id !== download.id;
- });
- downloadModel.remove(index)
- }
- }
- }
- }
-
- }
- ListView {
- id: listView
- anchors {
- topMargin: 10
- top: parent.top
- bottom: parent.bottom
- horizontalCenter: parent.horizontalCenter
- }
- width: parent.width - 20
- spacing: 5
-
- model: downloadModel
- delegate: downloadItemDelegate
-
- Text {
- visible: !listView.count
- horizontalAlignment: Text.AlignHCenter
- height: 30
- anchors {
- top: parent.top
- left: parent.left
- right: parent.right
- }
- font.pixelSize: 20
- text: "No active downloads."
- }
-
- Rectangle {
- color: "gray"
- anchors {
- bottom: parent.bottom
- left: parent.left
- right: parent.right
- }
- height: 30
- Button {
- id: okButton
- text: "OK"
- anchors.centerIn: parent
- onClicked: {
- downloadView.visible = false
- }
- }
- }
- }
-}
diff --git a/tests/quicktestbrowser/FeaturePermissionBar.qml b/tests/quicktestbrowser/FeaturePermissionBar.qml
deleted file mode 100644
index ca75875f5..000000000
--- a/tests/quicktestbrowser/FeaturePermissionBar.qml
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.1
-import QtQuick.Controls 1.0
-import QtWebEngine 1.1
-import QtQuick.Layouts 1.0
-
-Rectangle {
- property var requestedFeature;
- property url securityOrigin;
- property WebEngineView view;
-
- id: permissionBar
- visible: false
- height: acceptButton.height + 4
-
-
- function textForFeature(feature) {
- switch (feature) {
- case WebEngineView.Geolocation: return 'Allow %1 to access your location information?'
- case WebEngineView.MediaAudioCapture: return 'Allow %1 to access your microphone?'
- case WebEngineView.MediaVideoCapture: return 'Allow %1 to access your webcam?'
- case WebEngineView.MediaAudioVideoCapture: return 'Allow %1 to access your microphone and webcam?'
- case WebEngineView.DesktopVideoCapture: return 'Allow %1 to capture video of your desktop?'
- case WebEngineView.DesktopAudioVideoCapture: return 'Allow %1 to capture audio and video of your desktop?'
- case WebEngineView.Notifications: return 'Allow %1 to show notification on your desktop?'
- default: break
- }
- return 'Grant permission for %1 to unknown or unsupported feature [' + feature + ']?'
- }
-
- onRequestedFeatureChanged: {
- message.text = textForFeature(requestedFeature).arg(securityOrigin);
- }
-
- RowLayout {
- anchors {
- fill: permissionBar
- leftMargin: 5
- rightMargin: 5
- }
- Label {
- id: message
- Layout.fillWidth: true
- }
-
- Button {
- id: acceptButton
- text: "Accept"
- Layout.alignment: Qt.AlignRight
- onClicked: {
- view.grantFeaturePermission(securityOrigin, requestedFeature, true);
- permissionBar.visible = false;
- }
- }
-
- Button {
- text: "Deny"
- Layout.alignment: Qt.AlignRight
- onClicked: {
- view.grantFeaturePermission(securityOrigin, requestedFeature, false);
- permissionBar.visible = false
- }
- }
- }
-}
diff --git a/tests/quicktestbrowser/FullScreenNotification.qml b/tests/quicktestbrowser/FullScreenNotification.qml
deleted file mode 100644
index e48d6c646..000000000
--- a/tests/quicktestbrowser/FullScreenNotification.qml
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.5
-
-Rectangle {
- id: fullScreenNotification
- width: 500
- height: 40
- color: "white"
- radius: 7
-
- visible: false
- opacity: 0
-
- function show() {
- visible = true
- opacity = 1
- reset.start()
- }
-
- function hide() {
- reset.stop()
- opacity = 0
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: 750
- onStopped: {
- if (opacity == 0)
- visible = false
- }
- }
- }
-
- Timer {
- id: reset
- interval: 5000
- onTriggered: hide()
- }
-
- anchors.horizontalCenter: parent.horizontalCenter
- y: 125
-
- Text {
- id: message
- width: parent.width
-
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- wrapMode: Text.WordWrap
- elide: Text.ElideNone
- clip: true
-
- text: qsTr("You are now in fullscreen mode. Press ESC to quit!")
- }
-}
diff --git a/tests/quicktestbrowser/ZoomController.qml b/tests/quicktestbrowser/ZoomController.qml
deleted file mode 100644
index 2122c4365..000000000
--- a/tests/quicktestbrowser/ZoomController.qml
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Layouts 1.1
-
-Rectangle {
- property alias zoomFactor: slider.value ;
- function zoomIn() {
- visible = true
- visibilityTimer.restart()
- zoomFactor = zoomFactor + 0.25;
- }
- function zoomOut() {
- visible = true
- visibilityTimer.restart()
- zoomFactor = zoomFactor - 0.25;
- }
- function reset() { zoomFactor = 1.0 }
-
- width: 220
- height: 30
- color: palette.window
- visible: false
- radius: 4
-
- SystemPalette {
- id: palette
- }
- Timer {
- id: visibilityTimer
- interval: 3000
- repeat: false
- onTriggered: zoomController.visible = false
- }
-
- RowLayout {
- anchors.margins: 4
- anchors.fill: parent
- ToolButton {
- id: plusButton
- text: '+'
- onClicked: zoomIn()
- }
- ToolButton {
- text: '\u2014'
- id: minusButton
- onClicked: zoomOut()
- }
- Slider {
- id: slider
- maximumValue: 5.0
- minimumValue: 0.25
- Layout.fillWidth: true;
- stepSize: 0.05
- value: 1
- onValueChanged: visibilityTimer.restart()
- }
- Button {
- text: "Reset"
- onClicked: reset()
- }
- }
-}
diff --git a/tests/quicktestbrowser/main.cpp b/tests/quicktestbrowser/main.cpp
deleted file mode 100644
index c41eb2f56..000000000
--- a/tests/quicktestbrowser/main.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "utils.h"
-
-#ifndef QT_NO_WIDGETS
-#include <QtWidgets/QApplication>
-typedef QApplication Application;
-#else
-#include <QtGui/QGuiApplication>
-typedef QGuiApplication Application;
-#endif
-#include <QtQml/QQmlApplicationEngine>
-#include <QtQml/QQmlContext>
-#include <QtQml/QQmlComponent>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-#include <QtWebEngineQuick/QQuickWebEngineProfile>
-#include <QtWebEngineCore/qwebenginecookiestore.h>
-
-static QUrl startupUrl()
-{
- QUrl ret;
- QStringList args(qApp->arguments());
- args.takeFirst();
- for (const QString &arg : std::as_const(args)) {
- if (arg.startsWith(QLatin1Char('-')))
- continue;
- ret = Utils::fromUserInput(arg);
- if (ret.isValid())
- return ret;
- }
- return QUrl(QStringLiteral("http://qt.io/"));
-}
-
-int main(int argc, char **argv)
-{
- Application app(argc, argv);
-
- // Enable dev tools by default for the test browser
- if (qgetenv("QTWEBENGINE_REMOTE_DEBUGGING").isNull())
- qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "1337");
- QtWebEngineQuick::initialize();
-
- QQmlApplicationEngine appEngine;
- Utils utils;
- appEngine.rootContext()->setContextProperty("utils", &utils);
- appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
-
- QObject *rootObject = appEngine.rootObjects().first();
-
- QQuickWebEngineProfile *profile = new QQuickWebEngineProfile(rootObject);
-
- const QMetaObject *rootMeta = rootObject->metaObject();
- int index = rootMeta->indexOfProperty("thirdPartyCookiesEnabled");
- Q_ASSERT(index != -1);
- QMetaProperty thirdPartyCookiesProperty = rootMeta->property(index);
- profile->cookieStore()->setCookieFilter(
- [rootObject,&thirdPartyCookiesProperty](const QWebEngineCookieStore::FilterRequest &request)
- {
- return !request.thirdParty || thirdPartyCookiesProperty.read(rootObject).toBool();
- });
-
- index = rootMeta->indexOfProperty("testProfile");
- Q_ASSERT(index != -1);
- QMetaProperty profileProperty = rootMeta->property(index);
- profileProperty.write(rootObject, QVariant::fromValue(profile));
-
- QMetaObject::invokeMethod(rootObject, "load", Q_ARG(QVariant, startupUrl()));
-
- return app.exec();
-}
diff --git a/tests/quicktestbrowser/quicktestbrowser.pro b/tests/quicktestbrowser/quicktestbrowser.pro
deleted file mode 100644
index 304135836..000000000
--- a/tests/quicktestbrowser/quicktestbrowser.pro
+++ /dev/null
@@ -1,26 +0,0 @@
-requires(qtConfig(accessibility))
-
-TEMPLATE = app
-TARGET = quicktestbrowser
-
-macx: CONFIG -= app_bundle
-
-HEADERS = utils.h
-SOURCES = main.cpp
-
-OTHER_FILES += ApplicationRoot.qml \
- BrowserDialog.qml \
- BrowserWindow.qml \
- ButtonWithMenu.qml \
- ContextMenuExtras.qml \
- DownloadView.qml \
- FeaturePermissionBar.qml \
- FullScreenNotification.qml
-
-RESOURCES += resources.qrc
-
-QT += qml quick webenginequick
-
-qtHaveModule(widgets) {
- QT += widgets # QApplication is required to get native styling with QtQuickControls
-}
diff --git a/tests/quicktestbrowser/resources.qrc b/tests/quicktestbrowser/resources.qrc
deleted file mode 100644
index 8fbe286fb..000000000
--- a/tests/quicktestbrowser/resources.qrc
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
- <qresource prefix="/">
- <file>ApplicationRoot.qml</file>
- <file>BrowserDialog.qml</file>
- <file>BrowserWindow.qml</file>
- <file>FeaturePermissionBar.qml</file>
- <file>FullScreenNotification.qml</file>
- <file>ButtonWithMenu.qml</file>
- <file>DownloadView.qml</file>
- <file>ZoomController.qml</file>
- </qresource>
- <qresource prefix="icons">
- <!-- To the risk of this breaking more often, do not duplicate the resources since this application won't be deployed -->
- <file alias="go-next.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/go-next.png</file>
- <file alias="go-previous.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/go-previous.png</file>
- <file alias="process-stop.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/process-stop.png</file>
- <file alias="view-refresh.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/view-refresh.png</file>
- </qresource>
-</RCC>
diff --git a/tests/quicktestbrowser/utils.h b/tests/quicktestbrowser/utils.h
deleted file mode 100644
index 8521e9bf5..000000000
--- a/tests/quicktestbrowser/utils.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <QtCore/QFileInfo>
-#include <QtCore/QUrl>
-
-class Utils : public QObject {
- Q_OBJECT
-public:
- Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
- Q_INVOKABLE static QString domainFromString(const QString& urlString);
-};
-
-inline QUrl Utils::fromUserInput(const QString& userInput)
-{
- QFileInfo fileInfo(userInput);
- if (fileInfo.exists())
- return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
- return QUrl::fromUserInput(userInput);
-}
-
-inline QString Utils::domainFromString(const QString& urlString)
-{
- return QUrl::fromUserInput(urlString).host();
-}
-
-#endif // UTILS_H
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 0a968099c..8769d096d 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -55,6 +55,8 @@ def isInChromiumBlacklist(file_path):
and not file_path.startswith('chrome/browser/prefs/')
and not file_path.startswith('chrome/browser/printing/')
and not file_path.startswith('chrome/browser/profiles/incognito_helpers')
+ and not file_path.startswith('chrome/browser/profiles/profile_keyed_service_factory')
+ and not file_path.startswith('chrome/browser/profiles/profile_selections')
and not file_path.startswith('chrome/browser/push_messaging/')
and not file_path.startswith('chrome/browser/renderer_host/')
and not file_path.startswith('chrome/browser/share/core/')
@@ -147,23 +149,48 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/colorama')
or file_path.startswith('third_party/depot_tools')
or (file_path.startswith('third_party/node/node_modules/')
+ and not file_path.startswith('third_party/node/node_modules/@babel/')
and not file_path.startswith('third_party/node/node_modules/@types/d3')
and not file_path.startswith('third_party/node/node_modules/@types/trusted-types/')
+ and not file_path.startswith('third_party/node/node_modules/ansi-styles/')
+ and not file_path.startswith('third_party/node/node_modules/balanced-match/')
+ and not file_path.startswith('third_party/node/node_modules/brace-expansion/')
and not file_path.startswith('third_party/node/node_modules/cancel-token/')
+ and not file_path.startswith('third_party/node/node_modules/chalk/')
+ and not file_path.startswith('third_party/node/node_modules/color-convert/')
+ and not file_path.startswith('third_party/node/node_modules/color-name/')
+ and not file_path.startswith('third_party/node/node_modules/commander/')
+ and not file_path.startswith('third_party/node/node_modules/concat-map/')
and not file_path.startswith('third_party/node/node_modules/cssbeautify/')
+ and not file_path.startswith('third_party/node/node_modules/debug/')
+ and not file_path.startswith('third_party/node/node_modules/escape-string-regexp/')
+ and not file_path.startswith('third_party/node/node_modules/esutils/')
+ and not file_path.startswith('third_party/node/node_modules/function-bind/')
+ and not file_path.startswith('third_party/node/node_modules/globals/')
and not file_path.startswith('third_party/node/node_modules/has-ansi/')
+ and not file_path.startswith('third_party/node/node_modules/has-flag/')
+ and not file_path.startswith('third_party/node/node_modules/has/')
and not file_path.startswith('third_party/node/node_modules/indent/')
+ and not file_path.startswith('third_party/node/node_modules/is-core-module/')
and not file_path.startswith('third_party/node/node_modules/is-windows/')
+ and not file_path.startswith('third_party/node/node_modules/js-tokens/')
+ and not file_path.startswith('third_party/node/node_modules/jsesc/')
and not file_path.startswith('third_party/node/node_modules/jsonschema/')
and not file_path.startswith('third_party/node/node_modules/lodash.camelcase/')
and not file_path.startswith('third_party/node/node_modules/lodash.sortby/')
+ and not file_path.startswith('third_party/node/node_modules/minimatch/')
+ and not file_path.startswith('third_party/node/node_modules/ms/')
+ and not file_path.startswith('third_party/node/node_modules/path-is-inside/')
and not file_path.startswith('third_party/node/node_modules/polymer-analyzer/')
and not file_path.startswith('third_party/node/node_modules/polymer-css-build/')
+ and not file_path.startswith('third_party/node/node_modules/resolve/')
and not file_path.startswith('third_party/node/node_modules/rollup/')
and not file_path.startswith('third_party/node/node_modules/shady-css-parser/')
and not file_path.startswith('third_party/node/node_modules/source-map/')
and not file_path.startswith('third_party/node/node_modules/stable/')
+ and not file_path.startswith('third_party/node/node_modules/supports-color/')
and not file_path.startswith('third_party/node/node_modules/terser/')
+ and not file_path.startswith('third_party/node/node_modules/to-fast-properties/')
and not file_path.startswith('third_party/node/node_modules/tr46/')
and not file_path.startswith('third_party/node/node_modules/typescript/')
and not file_path.startswith('third_party/node/node_modules/vscode-uri/')
@@ -202,6 +229,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/sqlite/sqlite-src-')
or file_path.startswith('third_party/spirv-cross/spirv-cross/reference/')
or file_path.startswith('third_party/swiftshader/third_party/')
+ or file_path.startswith('third_party/tflite/')
or file_path.startswith('third_party/unrar')
or file_path.startswith('third_party/wayland')
or file_path.startswith('third_party/webgl')
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index 921e97f36..c8e37a6de 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -12,8 +12,8 @@ import json
import urllib3
import git_submodule as GitSubmodule
-chromium_version = '102.0.5005.177'
-chromium_branch = '5005'
+chromium_version = '108.0.5359.109'
+chromium_branch = '5359'
ninja_version = 'v1.8.2'
json_url = 'http://omahaproxy.appspot.com/all.json'