#include "webviewwindow.h" #include "webviewqt.h" #include "rktwebview_qt.h" #include "rktutils.h" #include "command.h" #include #include #include #include #include #include #include WebviewWindow::WebviewWindow(QWidget *parent) : QMainWindow{parent} { _view = nullptr; _must_close = false; _devtools = nullptr; _window_created = false; _moved = 0; _resized = 0; connect(&_resize_timer, &QTimer::timeout, this, &WebviewWindow::triggerResize); connect(&_move_timer, &QTimer::timeout, this, &WebviewWindow::triggerMove); } void WebviewWindow::processJsEvents() { QWebEnginePage *p = _view->page(); p->runJavaScript("if (window.rkt_get_events) { window.rkt_get_events(); } else { JSON.stringify([]); }", [this](const QVariant &v) { QString s = v.toString(); QJsonParseError err; QJsonDocument doc(QJsonDocument::fromJson(s.toUtf8(), &err)); if (err.error == QJsonParseError::NoError) { QJsonArray a = doc.array(); int i, N; for(i = 0, N = a.size(); i < N; i++) { QJsonObject js_evt = a[i].toObject(); EventContainer e("js-evt"); e["js-evt"] = js_evt; this->_container->triggerEvent(_view->id(), e); } } else { } } ); } void WebviewWindow::closeEvent(QCloseEvent *evt) { if (_must_close) { EventContainer e("closed"); _container->triggerEvent(_view->id(), e); _container->removeView(_view->id()); this->deleteLater(); if (_devtools != nullptr) { _devtools->deleteLater(); } } else { evt->ignore(); EventContainer e("can-close?"); _container->triggerEvent(_view->id(), e); } } void WebviewWindow::closeView() { _must_close = true; close(); } bool WebviewWindow::windowCreated() { return _window_created; } int WebviewWindow::moveCount() { return _moved; } int WebviewWindow::resizeCount() { return _resized; } void WebviewWindow::addView(WebViewQt *v, Rktwebview_qt *c) { _container = c; _view = v; this->setCentralWidget(v); QWebEnginePage *page = _view->page(); // Inject event handling code for the javascript side QWebEngineScriptCollection &col = page->scripts(); QWebEngineScript evt_script; evt_script.setInjectionPoint(QWebEngineScript::DocumentReady); evt_script.setName("rkt_webview_event_handling"); evt_script.setSourceCode( "window.rkt_event_queue = [];\n" "window.rkt_send_event = function(obj) {\n" " console.log('Sending event: ' + obj);\n" " window.rkt_event_queue.push(obj);\n" "};\n" "window.rkt_get_events = function() {\n" " let q = window.rkt_event_queue;\n" " window.rkt_event_queue = [];\n" " let json_q = JSON.stringify(q);\n" " return json_q;\n" "};\n" "console.log('We have set:');\n" "console.log('window.rkt_event_queue:');\n" "console.log(window.rkt_event_queue);\n" "console.log('window.rkt_send_event:');\n" "console.log(window.rkt_send_event);\n" "console.log('window.rkt_get_events:');\n" "console.log(window.rkt_get_events);\n" ); evt_script.setWorldId(QWebEngineScript::ApplicationWorld); //col.insert(evt_script); connect(page, &QWebEnginePage::loadFinished, this, [this](bool ok) { _container->pageLoaded(_view->id(), ok); }); connect(page, &QWebEnginePage::loadStarted, this, [this]() { _container->onPageLoad(_view->id()); }); } WebViewQt *WebviewWindow::view() { return _view; } void WebviewWindow::runJs(const QString &js) { QWebEnginePage *p = _view->page(); p->runJavaScript(js); } void WebviewWindow::callJs(const QString &js, Command *c) { QWebEnginePage *p = _view->page(); QString _js = QString("{\n") + " let f = function() {\n" + " " + js + "\n" + " };\n" + " try {\n" + " let obj = { oke: true, result: f(), exn: false };\n" + " obj;\n" + " } catch(e) {\n" + " let obj = { oke: false, result: false, exn: e.message };\n" + " obj;\n" + " }\n" + "}"; p->runJavaScript(_js, [c](const QVariant &v) { c->result = v; QJsonObject obj = v.toJsonObject(); bool ok = obj["oke"].toBool(); c->js_result_ok = ok; c->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact)); c->done = true; }); } void WebviewWindow::openDevTools() { _devtools = new QMainWindow(this); QWebEngineView *devtools_view = new QWebEngineView(_devtools); _devtools->setCentralWidget(devtools_view); _devtools->resize(800, 600); _devtools->show(); _view->page()->setDevToolsPage(devtools_view->page()); connect(_devtools, &WebviewWindow::destroyed, this, [this](QObject *) { _devtools = nullptr; }); } void WebviewWindow::moveEvent(QMoveEvent *event) { _x = event->pos().x(); _y = event->pos().y(); _move_timer.setSingleShot(true); _move_timer.start(500); _moved += 1; //triggerMove(); } void WebviewWindow::triggerMove() { EventContainer xy("move"); xy["x"] = _x; xy["y"] = _y; _container->triggerEvent(_view->id(), xy); } void WebviewWindow::resizeEvent(QResizeEvent *event) { _w = event->size().width(); _h = event->size().height(); _resize_timer.setSingleShot(true); _resize_timer.start(500); _resized += 1; //triggerResize(); } void WebviewWindow::triggerResize() { EventContainer s("resize"); s["w"] = _w; s["h"] = _h; _container->triggerEvent(_view->id(), s); } void WebviewWindow::showEvent(QShowEvent *event) { _window_created = true; EventContainer show("show"); _container->triggerEvent(_view->id(), show); } void WebviewWindow::hideEvent(QHideEvent *event) { if (!_must_close) { EventContainer hide("hide"); _container->triggerEvent(_view->id(), hide); } }