-
This commit is contained in:
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(rktwebview_qt LANGUAGES CXX)
|
||||
|
||||
set(QT_DEBUG_FIND_PACKAGE ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <chrono>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
//#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "rktwebview_qt.h"
|
||||
#include "webviewapp.h"
|
||||
@@ -18,10 +18,10 @@ uint64_t current_ms() {
|
||||
// Main C Interface
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int pipefd[2];
|
||||
static bool started = false;
|
||||
static pid_t webview_process;
|
||||
static bool cannot_fork_or_pipe = false;
|
||||
//static int pipefd[2];
|
||||
//static bool started = false;
|
||||
//static pid_t webview_process;
|
||||
//static bool cannot_fork_or_pipe = false;
|
||||
|
||||
Rktwebview_qt *handler = nullptr;
|
||||
|
||||
@@ -51,19 +51,21 @@ void rkt_webview_init()
|
||||
}
|
||||
}
|
||||
|
||||
int rkt_webview_create(int parent)
|
||||
int rkt_webview_create(int parent, void (*js_event_cb)(const char *))
|
||||
{
|
||||
//rkt_webview_init();
|
||||
return handler->rktWebViewCreate(parent);
|
||||
rkt_webview_init();
|
||||
return handler->rktWebViewCreate(parent, js_event_cb);
|
||||
}
|
||||
|
||||
void rkt_webview_close(int wv)
|
||||
{
|
||||
rkt_webview_init();
|
||||
handler->rktWebViewClose(wv);
|
||||
}
|
||||
|
||||
result_t rkt_webview_set_url(int wv, const char *url)
|
||||
{
|
||||
rkt_webview_init();
|
||||
result_t r = handler->rktSetUrl(wv, url);
|
||||
return r;
|
||||
}
|
||||
@@ -151,7 +153,7 @@ void rkt_webview_process_events(int for_ms)
|
||||
int64_t end_ms = start_ms + for_ms;
|
||||
|
||||
while (current_ms() < end_ms) {
|
||||
usleep(500); // sleep 0.5 ms
|
||||
QThread::usleep(500); // sleep 0.5 ms
|
||||
handler->doEvents();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ typedef enum {
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_init();
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_process_events(int for_ms);
|
||||
RKTWEBVIEW_QT_EXPORT int rkt_webview_create(int parent);
|
||||
RKTWEBVIEW_QT_EXPORT int rkt_webview_create(int parent, void (*js_event_cb)(const char *msg));
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_close(int wv);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_url(int wv, const char *url);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_html(int wv, const char *html);
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QSemaphore>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#define COMMAND_QUIT 1
|
||||
#define COMMAND_CLOSE 2
|
||||
@@ -25,9 +27,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static QString jsonString(QJsonObject obj)
|
||||
{
|
||||
QJsonDocument doc(obj);
|
||||
QString j = QString::fromUtf8(doc.toJson(QJsonDocument::JsonFormat::Compact));
|
||||
return j;
|
||||
}
|
||||
|
||||
void Rktwebview_qt::processCommands()
|
||||
{
|
||||
printf("COmmand processing\n");
|
||||
while(!_command_queue.empty()) {
|
||||
Command *cmd = _command_queue.dequeue();
|
||||
|
||||
@@ -39,6 +47,10 @@ void Rktwebview_qt::processCommands()
|
||||
break;
|
||||
case COMMAND_CREATE: {
|
||||
int parent = cmd->args[0].toInt();
|
||||
|
||||
void *f = cmd->args[1].value<void *>();
|
||||
void (*js_event_cb)(const char *msg) = reinterpret_cast <void(*)(const char *)>(f);
|
||||
|
||||
QWidget *p;
|
||||
if (_views.contains(parent)) {
|
||||
p = _views[parent];
|
||||
@@ -53,6 +65,7 @@ void Rktwebview_qt::processCommands()
|
||||
int id = view->id();
|
||||
|
||||
_views[id] = w;
|
||||
_view_js_callbacks[id] = js_event_cb;
|
||||
|
||||
w->show();
|
||||
|
||||
@@ -98,10 +111,9 @@ void Rktwebview_qt::processCommands()
|
||||
}
|
||||
}
|
||||
|
||||
void Rktwebview_qt::interruptEventLoop()
|
||||
void Rktwebview_qt::processJsEventQueue()
|
||||
{
|
||||
printf("Exeting application event loop\n");
|
||||
//_app->quit();
|
||||
|
||||
}
|
||||
|
||||
void Rktwebview_qt::removeView(int id)
|
||||
@@ -115,10 +127,13 @@ int Rktwebview_qt::nextHandle()
|
||||
return h;
|
||||
}
|
||||
|
||||
int Rktwebview_qt::rktWebViewCreate(int parent)
|
||||
int Rktwebview_qt::rktWebViewCreate(int parent, void (*js_evt_cb)(const char *))
|
||||
{
|
||||
Command c(COMMAND_CREATE);
|
||||
c.args.push_back(parent);
|
||||
void *function = reinterpret_cast<void *>(js_evt_cb);
|
||||
QVariant f(QVariant::fromValue(function));
|
||||
c.args.push_back(f);
|
||||
|
||||
_command_queue.enqueue(&c);
|
||||
|
||||
@@ -153,6 +168,30 @@ result_t Rktwebview_qt::rktSetUrl(rktwebview_t wv, const char *url)
|
||||
return r ? result_t::oke : result_t::set_navigate_failed;
|
||||
}
|
||||
|
||||
void Rktwebview_qt::pageLoaded(rktwebview_t w, bool ok)
|
||||
{
|
||||
// Inject event handling code for the javascript side
|
||||
runJs(w, "window.rkt_event_queue = [];\n"
|
||||
"window.rkt_send_event = function(obj) { window.rkt_event_queue.push(obj); };\n"
|
||||
"window.rkt_get_events = function() { "
|
||||
" let q = window.rkt_event_queue; "
|
||||
" window.rkt_event_queue = [];"
|
||||
" let json_q = JSON.stringify(q);"
|
||||
" return json_q;"
|
||||
"};");
|
||||
|
||||
// trigger page loaded.
|
||||
QJsonObject obj;
|
||||
obj["event"] = "page-loaded";
|
||||
obj["oke"] = ok;
|
||||
triggerEvent(w, jsonString(obj));
|
||||
}
|
||||
|
||||
void Rktwebview_qt::triggerEvent(rktwebview_t wv, const QString &msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Rktwebview_qt::rktQuit()
|
||||
{
|
||||
QList<int> keys = _views.keys();
|
||||
@@ -168,13 +207,18 @@ void Rktwebview_qt::rktQuit()
|
||||
while(!c.done) { doEvents(); }
|
||||
}
|
||||
|
||||
void Rktwebview_qt::runJs(rktwebview_t wv, const char *js)
|
||||
{
|
||||
if (_views.contains(wv)) {
|
||||
QString _js(js);
|
||||
WebViewQt *view = _views[wv]->view();
|
||||
view->runJs(_js);
|
||||
}
|
||||
}
|
||||
|
||||
void Rktwebview_qt::doEvents()
|
||||
{
|
||||
//_quit_event_loop.start(2000);
|
||||
//_app->exec();
|
||||
//processCommands();
|
||||
_app->processEvents();
|
||||
|
||||
}
|
||||
|
||||
Rktwebview_qt::Rktwebview_qt(Rktwebview_qt **handler) :
|
||||
@@ -189,8 +233,7 @@ Rktwebview_qt::Rktwebview_qt(Rktwebview_qt **handler) :
|
||||
|
||||
_app = new QApplication(_argc, _argv);
|
||||
connect(&_process_commands, &QTimer::timeout, this, &Rktwebview_qt::processCommands);
|
||||
connect(&_quit_event_loop, &QTimer::timeout, this, &Rktwebview_qt::interruptEventLoop);
|
||||
_process_commands.start(1000);
|
||||
_process_commands.start(10);
|
||||
|
||||
*_handler = nullptr;
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ private:
|
||||
QApplication *_app;
|
||||
rktwebview_t _current_handle;
|
||||
QHash<int, WebviewWindow *> _views;
|
||||
QHash<int, void(*)(const char *msg)> _view_js_callbacks;
|
||||
|
||||
QQueue<Command *> _command_queue;
|
||||
QTimer _process_commands;
|
||||
QTimer _quit_event_loop;
|
||||
|
||||
Rktwebview_qt **_handler;
|
||||
|
||||
@@ -36,7 +36,6 @@ private:
|
||||
|
||||
public slots:
|
||||
void processCommands();
|
||||
void interruptEventLoop();
|
||||
|
||||
public:
|
||||
void removeView(int id);
|
||||
@@ -44,17 +43,24 @@ public:
|
||||
public:
|
||||
int nextHandle();
|
||||
public:
|
||||
int rktWebViewCreate(int parent = 0); // threadsafe
|
||||
int rktWebViewCreate(int parent, void(*js_evt_cb)(const char *msg));
|
||||
void rktWebViewClose(int wv);
|
||||
void rktQuit();
|
||||
|
||||
void runJs(rktwebview_t wv, const char *js); // threadsafe
|
||||
item_t callJs(rktwebview_t wv, const char *js); // threadsafe
|
||||
void runJs(rktwebview_t wv, const char *js);
|
||||
item_t callJs(rktwebview_t wv, const char *js);
|
||||
|
||||
void setHtml(rktwebview_t wv, const char *html); // threadsafe
|
||||
void navigate(rktwebview_t wv, const char *url); // threadsafe
|
||||
void setHtml(rktwebview_t wv, const char *html);
|
||||
void navigate(rktwebview_t wv, const char *url);
|
||||
result_t rktSetUrl(rktwebview_t wv, const char *url);
|
||||
|
||||
public:
|
||||
// Events for the backend
|
||||
void pageLoaded(rktwebview_t w, bool ok);
|
||||
|
||||
public:
|
||||
void triggerEvent(rktwebview_t wv, const QString &msg);
|
||||
|
||||
public:
|
||||
void doEvents();
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "webviewqt.h"
|
||||
#include <QWebEnginePage>
|
||||
#include <QJsonDocument>
|
||||
|
||||
WebViewQt::WebViewQt(int id, QWidget *parent)
|
||||
: QWebEngineView(parent)
|
||||
@@ -11,9 +13,8 @@ int WebViewQt::id() const
|
||||
return _id;
|
||||
}
|
||||
|
||||
void WebViewQt::runJs(const char *js)
|
||||
QString WebViewQt::runJs(const QString &js)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
#define WEBVIEWQT_H
|
||||
|
||||
#include <QWebEngineView>
|
||||
#include <QTimer>
|
||||
|
||||
class WebViewQt : public QWebEngineView
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
int _id;
|
||||
|
||||
@@ -12,7 +14,11 @@ public:
|
||||
int id() const;
|
||||
|
||||
public:
|
||||
void runJs(const char *js);
|
||||
QString runJs(const QString &js);
|
||||
|
||||
signals:
|
||||
void pageLoaded(WebViewQt *, bool ok);
|
||||
|
||||
|
||||
public:
|
||||
WebViewQt(int id, QWidget *parent = nullptr);
|
||||
|
||||
@@ -2,6 +2,32 @@
|
||||
|
||||
#include "webviewqt.h"
|
||||
#include "rktwebview_qt.h"
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonObject>
|
||||
|
||||
void WebviewWindow::processJsEvents()
|
||||
{
|
||||
QWebEnginePage *p = _view->page();
|
||||
p->runJavaScript("window.getPendingEvents();",
|
||||
[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 evt = a[i].toObject();
|
||||
QJsonDocument doc_out(evt);
|
||||
QString msg = doc_out.toJson(QJsonDocument::JsonFormat::Compact);
|
||||
this->_container->triggerJsEvent(_view->id(), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void WebviewWindow::closeEvent(QCloseEvent *evt)
|
||||
{
|
||||
@@ -13,6 +39,11 @@ void WebviewWindow::addView(WebViewQt *v, Rktwebview_qt *c)
|
||||
_container = c;
|
||||
_view = v;
|
||||
this->setCentralWidget(v);
|
||||
|
||||
QWebEnginePage *page = _view->page();
|
||||
connect(page, &QWebEnginePage::loadFinished, this, [this](bool ok) {
|
||||
_container->pageLoaded(_view->id(), ok);
|
||||
});
|
||||
}
|
||||
|
||||
WebViewQt *WebviewWindow::view()
|
||||
@@ -24,4 +55,5 @@ WebviewWindow::WebviewWindow(QWidget *parent)
|
||||
: QMainWindow{parent}
|
||||
{
|
||||
_view = nullptr;
|
||||
connect(&_process_js_events, &QTimer::timeout, this, &WebviewWindow::processJsEvents);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define WEBVIEWWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
|
||||
class WebViewQt;
|
||||
class Rktwebview_qt;
|
||||
@@ -12,6 +13,10 @@ class WebviewWindow : public QMainWindow
|
||||
private:
|
||||
Rktwebview_qt *_container;
|
||||
WebViewQt *_view;
|
||||
QTimer _process_js_events;
|
||||
|
||||
public slots:
|
||||
void processJsEvents();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *evt);
|
||||
|
||||
Reference in New Issue
Block a user