diff options
-rw-r--r-- | src/buildtools/configure.json | 17 | ||||
-rw-r--r-- | src/core/file_picker_controller.cpp | 12 | ||||
-rw-r--r-- | src/core/ozone/BUILD.gn | 5 | ||||
-rw-r--r-- | src/core/ozone/ozone_platform_qt.cpp | 71 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 6 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.h | 1 | ||||
-rw-r--r-- | src/core/web_engine_context_threads.cpp | 2 | ||||
-rw-r--r-- | tests/auto/quick/qmltests/data/tst_filePicker.qml | 21 | ||||
-rw-r--r-- | tests/auto/widgets/loadsignals/tst_loadsignals.cpp | 4 |
9 files changed, 127 insertions, 12 deletions
diff --git a/src/buildtools/configure.json b/src/buildtools/configure.json index 0ea575c35..ba42c2c3f 100644 --- a/src/buildtools/configure.json +++ b/src/buildtools/configure.json @@ -56,6 +56,12 @@ { "type": "pkgConfig", "args": "xtst" } ] }, + "webengine-xkbfile": { + "label": "xkbfile", + "sources": [ + { "type": "pkgConfig", "args": "xkbfile" } + ] + }, "webengine-nss": { "label": "nss >= 3.26", "sources": [ @@ -493,6 +499,11 @@ "condition": "libs.webengine-xtst", "output": [ "privateFeature" ] }, + "webengine-system-xkbfile": { + "label": "xkbfile", + "condition": "libs.webengine-xkbfile", + "output": [ "privateFeature" ] + }, "webengine-system-gn": { "label": "Use System Gn", "autoDetect": "false", @@ -541,7 +552,8 @@ && features.webengine-system-xcursor && features.webengine-system-xi && features.webengine-system-xproto-gl - && features.webengine-system-xtst", + && features.webengine-system-xtst + && features.webengine-system-xkbfile", "output": [ "privateFeature" ] }, "webengine-jumbo-build": { @@ -787,7 +799,8 @@ "webengine-system-xcursor", "webengine-system-xi", "webengine-system-xproto-gl", - "webengine-system-xtst" + "webengine-system-xtst", + "webengine-system-xkbfile" ] }, { diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp index d8b5b520e..02d40a054 100644 --- a/src/core/file_picker_controller.cpp +++ b/src/core/file_picker_controller.cpp @@ -95,7 +95,7 @@ void FilePickerController::accepted(const QStringList &files) if (urlString.startsWith("file:")) { base::FilePath filePath = toFilePath(urlString).NormalizePathSeparators(); std::vector<base::FilePath::StringType> pathComponents; - // Splits the file URL into host name, path and file name. + // Splits the file URL into scheme, host name, path and file name. filePath.GetComponents(&pathComponents); QString absolutePath; @@ -107,7 +107,7 @@ void FilePickerController::accepted(const QStringList &files) if (scheme.size() > 5) { #if defined(OS_WIN) // There is no slash at the end of the file scheme and it is valid on Windows: file:C:/ - if (scheme.at(5).isLetter() && scheme.at(6) != ':') { + if (scheme.size() == 7 && scheme.at(5).isLetter() && scheme.at(6) == ':') { absolutePath += scheme.at(5) + ":/"; } else { #endif @@ -194,9 +194,13 @@ ASSERT_ENUMS_MATCH(FilePickerController::Save, blink::mojom::FileChooserParams_M void FilePickerController::filesSelectedInChooser(const QStringList &filesList) { QStringList files(filesList); + base::FilePath baseDir; if (d_ptr->mode == UploadFolder && !filesList.isEmpty() - && QFileInfo(filesList.first()).isDir()) // Enumerate the directory + && QFileInfo(filesList.first()).isDir()) { + // Enumerate the directory files = listRecursively(QDir(filesList.first())); + baseDir = toFilePath(filesList.first()); + } std::vector<blink::mojom::FileChooserFileInfoPtr> chooser_files; for (const auto &file : qAsConst(files)) { @@ -208,7 +212,7 @@ void FilePickerController::filesSelectedInChooser(const QStringList &filesList) d_ptr->listener->FileSelectionCanceled(); else d_ptr->listener->FileSelected(std::move(chooser_files), - /* FIXME? */ base::FilePath(), + baseDir, static_cast<blink::mojom::FileChooserParams::Mode>(d_ptr->mode)); } diff --git a/src/core/ozone/BUILD.gn b/src/core/ozone/BUILD.gn index 4d27f8877..a01728842 100644 --- a/src/core/ozone/BUILD.gn +++ b/src/core/ozone/BUILD.gn @@ -1,6 +1,7 @@ # Copyright 2016 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. +import("//ui/base/ui_features.gni") source_set("qt") { sources = [ @@ -18,4 +19,8 @@ source_set("qt") { ] defines = [ "OZONE_IMPLEMENTATION" ] + + if (use_xkbcommon && use_x11) { + libs = [ "xkbfile" ] + } } diff --git a/src/core/ozone/ozone_platform_qt.cpp b/src/core/ozone/ozone_platform_qt.cpp index 9db5b9986..c547cf783 100644 --- a/src/core/ozone/ozone_platform_qt.cpp +++ b/src/core/ozone/ozone_platform_qt.cpp @@ -40,9 +40,12 @@ #include "ozone_platform_qt.h" #if defined(USE_OZONE) +#include "ui/base/buildflags.h" #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" #include "ui/base/ime/input_method.h" #include "ui/display/types/native_display_delegate.h" +#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" +#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h" #include "ui/ozone/common/stub_client_native_pixmap_factory.h" #include "ui/ozone/common/stub_overlay_manager.h" #include "ui/ozone/public/gpu_platform_support_host.h" @@ -56,6 +59,16 @@ #include "surface_factory_qt.h" #include "platform_window_qt.h" +#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11) +#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> + +extern void *GetQtXDisplay(); +#endif // BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11) + namespace ui { namespace { @@ -86,6 +99,11 @@ private: std::unique_ptr<InputController> input_controller_; std::unique_ptr<OverlayManagerOzone> overlay_manager_; +#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11) + XkbEvdevCodes m_xkbEvdevCodeConverter; +#endif + std::unique_ptr<KeyboardLayoutEngine> m_keyboardLayoutEngine; + DISALLOW_COPY_AND_ASSIGN(OzonePlatformQt); }; @@ -135,12 +153,65 @@ std::unique_ptr<display::NativeDisplayDelegate> OzonePlatformQt::CreateNativeDis return nullptr; } +#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11) +static std::string getCurrentKeyboardLayout() +{ + Display *dpy = static_cast<Display *>(GetQtXDisplay()); + if (dpy == nullptr) + return std::string(); + + XkbStateRec state; + if (XkbGetState(dpy, XkbUseCoreKbd, &state) != 0) + return std::string(); + + XkbRF_VarDefsRec vdr; + if (XkbRF_GetNamesProp(dpy, nullptr, &vdr) == 0) + return std::string(); + + char *layout = strtok(vdr.layout, ","); + for (int i = 0; i < state.group; i++) { + layout = strtok(nullptr, ","); + if (layout == nullptr) + return std::string(); + } + + char *variant = strtok(vdr.variant, ","); + if (!variant) + return layout; + + for (int i = 0; i < state.group; i++) { + variant = strtok(nullptr, ","); + if (variant == nullptr) + return layout; + } + + std::string layoutWithVariant = layout; + layoutWithVariant = layoutWithVariant.append("-"); + layoutWithVariant = layoutWithVariant.append(variant); + return layoutWithVariant; +} +#endif // BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11) + void OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &) { overlay_manager_.reset(new StubOverlayManager()); cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone()); gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost()); input_controller_ = CreateStubInputController(); + +#if BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11) + std::string layout = getCurrentKeyboardLayout(); + if (layout.empty()) { + m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>(); + } else { + m_keyboardLayoutEngine = std::make_unique<XkbKeyboardLayoutEngine>(m_xkbEvdevCodeConverter); + m_keyboardLayoutEngine->SetCurrentLayoutByName(layout); + } +#else + m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>(); +#endif // BUILDFLAG(USE_XKBCOMMON) && defined(USE_X11) + + KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(m_keyboardLayoutEngine.get()); } void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &) diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index a35ab1b2d..04d0ceda1 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -77,6 +77,7 @@ #include "ui/events/event.h" #include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" +#include "ui/events/keycodes/dom/dom_keyboard_layout_map.h" #include "ui/gfx/image/image_skia.h" #if defined(USE_OZONE) @@ -994,6 +995,11 @@ void RenderWidgetHostViewQt::FocusedNodeChanged(bool is_editable_node, const gfx } } +base::flat_map<std::string, std::string> RenderWidgetHostViewQt::GetKeyboardLayoutMap() +{ + return ui::GenerateDomKeyboardLayoutMap(); +} + void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostView *view) { DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)->IsRenderWidgetHostViewChildFrame()); diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 7e7b13fda..1d61d46a5 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -143,6 +143,7 @@ public: const viz::FrameSinkId &GetFrameSinkId() const override; const viz::LocalSurfaceId &GetLocalSurfaceId() const override; void FocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen) override; + base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override; void TakeFallbackContentFrom(content::RenderWidgetHostView *view) override; void EnsureSurfaceSynchronizedForWebTest() override; diff --git a/src/core/web_engine_context_threads.cpp b/src/core/web_engine_context_threads.cpp index 5f9e345f7..5aa4c3e1e 100644 --- a/src/core/web_engine_context_threads.cpp +++ b/src/core/web_engine_context_threads.cpp @@ -84,7 +84,7 @@ struct GpuThreadControllerQt : content::GpuThreadController if (s_gpuProcessDestroyed) return; - s_gpuProcess = std::make_unique<content::GpuProcess>(base::ThreadPriority::DISPLAY); + s_gpuProcess = std::make_unique<content::GpuProcess>(base::ThreadPriority::NORMAL); auto gpuInit = std::make_unique<gpu::GpuInit>(); gpuInit->InitializeInProcess(base::CommandLine::ForCurrentProcess(), gpuPreferences); auto childThread = new content::GpuChildThread(params, std::move(gpuInit)); diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml index 4313c8d9e..5b963c7bf 100644 --- a/tests/auto/quick/qmltests/data/tst_filePicker.qml +++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml @@ -157,6 +157,16 @@ TestWebEngineView { webEngineView.url = Qt.resolvedUrl("directoryupload.html") verify(webEngineView.waitForLoadSucceeded()) + webEngineView.runJavaScript( + "let relativePathCount = 0;" + + "document.getElementById('upfile').addEventListener('change', function(event) {" + + " let files = event.target.files;" + + " for (let i = 0; i < files.length; i++) {" + + " if (files[i].webkitRelativePath != '')" + + " relativePathCount++;" + + " }" + + "}, false);") + FilePickerParams.selectFiles = true FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("../data")) @@ -164,6 +174,11 @@ TestWebEngineView { tryCompare(FilePickerParams, "filePickerOpened", true) // Check that the title is a file list (eg. "test1.html,test2.html") tryVerify(function() { return webEngineView.title.match("^([^,]+,)+[^,]+$"); }) + + var relativePathCount = 0; + runJavaScript("relativePathCount", function(result) { relativePathCount = result; }); + // The number of files in data directory may vary + tryVerify(function() { return relativePathCount > 0; }); } function test_reject() { @@ -227,15 +242,15 @@ TestWebEngineView { { tag: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", input: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", expected: "test.txt"}, { tag: "file://applib/products/a-b/abc_1/t.est/test.txt", input: "file://applib/products/a-b/abc_1/t.est/test.txt", expected: "test.txt"}, { tag: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", input: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", expected: "test.txt"}, - { tag: "file:C:/test.txt", input: "file:C:/test.txt", expected: "test.tx"}, - { tag: "file:/C:/test.txt", input: "file:/C:/test.txt", expected: "test.tx"}, + { tag: "file:C:/test.txt", input: "file:C:/test.txt", expected: "test.txt"}, + { tag: "file:/C:/test.txt", input: "file:/C:/test.txt", expected: "test.txt"}, { tag: "file://C:/test.txt", input: "file://C:/test.txt", expected: "Failed to Upload"}, { tag: "file:///C:test.txt", input: "file:///C:test.txt", expected: "Failed to Upload"}, { tag: "file:///C:/test.txt", input: "file:///C:/test.txt", expected: "test.txt"}, { tag: "file:///C:\\test.txt", input: "file:///C:\\test.txt", expected: "test.txt"}, { tag: "file:\\//C:/test.txt", input: "file:\\//C:/test.txt", expected: "test.txt"}, { tag: "file:\\\\/C:\\test.txt", input: "file:\\\\/C:\\test.txt", expected: "test.txt"}, - { tag: "\\\\?\\C:/test.txt", input: "\\\\?\\C:/test.txt", expected: "test.tx"}, + { tag: "\\\\?\\C:/test.txt", input: "\\\\?\\C:/test.txt", expected: "test.txt"}, ]; } diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp index a0fa97e02..fe01bede4 100644 --- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp +++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp @@ -135,8 +135,8 @@ void tst_LoadSignals::init() void tst_LoadSignals::clickLink(QPoint linkPos) { // Simulate left-clicking on link. - QTRY_VERIFY(view.focusWidget()); - QWidget *renderWidget = view.focusWidget(); + QTRY_VERIFY(view.focusProxy()); + QWidget *renderWidget = view.focusProxy(); QTest::mouseClick(renderWidget, Qt::LeftButton, {}, linkPos); } |