Add support for embedding native html elements using QWindow::fromWinId(). WId is an emscripten::val *, e.g. a pointer to val which holds a html element. The element can be created either from C++ using emscripten::val, or from JavaScript. User code owns the val * as usual for WId; ownership is not passed to the QWindow instance. Set QWasmWindow::m_window to be the native element when fromWinId() is used, and skip the rest of the QWasmWindow implementation in that case: We don't need to install event handlers or provide accessibility elements. Make key and pointer event handlers stop propagation only if the event was not accepted. This makes sure that input events reach the embedded native element. Limit setPointerCapture calls to when the event is targeted for Qt elements only. Determining the true target can be a bit tricky when shadow DOM is in use since the browsers may retarget the event. Use composedPath() to get the true event target. Task-number: QTBUG-128804 Task-number: QTBUG-128732 Change-Id: I5ce66e93bacb06abfd042916687cd45fc9588c51 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
93 lines
2.7 KiB
C++
93 lines
2.7 KiB
C++
// Copyright (C) 2024 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
|
#include <QtWidgets>
|
|
|
|
#include <emscripten.h>
|
|
#include <emscripten/val.h>
|
|
|
|
using emscripten::val;
|
|
using emscripten::EM_VAL;
|
|
|
|
|
|
val createInputElemet(std::string subtype)
|
|
{
|
|
val document = val::global("document");
|
|
val input = document.call<val>("createElement", std::string("input"));
|
|
input.set("type", subtype);
|
|
return input;
|
|
}
|
|
|
|
EM_JS(EM_VAL, createCalendar, (), {
|
|
var calendar = document.createElement("calendar-date");
|
|
calendar.innerHTML = "<calendar-month></calendar-month>";
|
|
return Emval.toHandle(calendar);
|
|
});
|
|
|
|
val createCallyElemet()
|
|
{
|
|
static bool initializedCalendarComponent = []{
|
|
return EM_ASM_INT(
|
|
console.log("Loading calendar module");
|
|
var script = document.createElement('script');
|
|
script.src = "https://unpkg.com/cally";
|
|
script.type = "module";
|
|
document.head.appendChild(script);
|
|
console.log(script);
|
|
return true;
|
|
);
|
|
}();
|
|
Q_ASSERT(initializedCalendarComponent);
|
|
|
|
return val::take_ownership(createCalendar());
|
|
}
|
|
|
|
class ForeginWindowContainer : public QWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
ForeginWindowContainer() {
|
|
|
|
QCheckBox *test = new QCheckBox("Qt CheckBox");
|
|
test->setGeometry(20, 20, 150, 20);
|
|
test->setParent(this);
|
|
|
|
m_calendarInput = std::make_unique<val>(createInputElemet("date"));
|
|
m_colorPickerInput = std::make_unique<val>(createInputElemet("color"));
|
|
|
|
QWindow *calendarWindow = QWindow::fromWinId(WId(m_calendarInput.get()));
|
|
QWindow *colorPickerWindow = QWindow::fromWinId(WId(m_colorPickerInput.get()));
|
|
|
|
QWidget *calendarContainer = QWidget::createWindowContainer(calendarWindow, this);
|
|
calendarContainer->setGeometry(20, 50, 300, 40);
|
|
|
|
QWidget *colorPickerContainer = QWidget::createWindowContainer(colorPickerWindow, this);
|
|
colorPickerContainer->setGeometry(20, 90, 300, 40);
|
|
|
|
val callyCalendarElement = createCallyElemet();
|
|
QWindow *callyWindow =QWindow::fromWinId(WId(new val(callyCalendarElement)));
|
|
QWidget *callyContainer = QWidget::createWindowContainer(callyWindow, this);
|
|
callyContainer->setGeometry(20, 130, 300, 400);
|
|
}
|
|
|
|
~ForeginWindowContainer() {
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<val> m_calendarInput;
|
|
std::unique_ptr<val> m_colorPickerInput;
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
QApplication app(argc, argv);
|
|
|
|
QGuiApplication::styleHints()->setColorScheme(Qt::ColorScheme::Light);
|
|
|
|
ForeginWindowContainer container;
|
|
container.showNormal();
|
|
|
|
return app.exec();
|
|
}
|
|
|
|
#include "main.moc"
|