Much work, using Qt 6.10 on Linux for better https support
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#define COMMAND_FILE_OPEN 20
|
||||
#define COMMAND_FILE_SAVE 21
|
||||
#define COMMAND_SET_OU_TOKEN 22
|
||||
#define COMMAND_SET_CERTIFICATE 23
|
||||
|
||||
class Command
|
||||
{
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#include "rktwebview.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QFile>
|
||||
|
||||
static int _argc;
|
||||
static char **_argv;
|
||||
|
||||
void eventCb(rkt_event_t *e)
|
||||
void eventCb(rkt_data_t *e)
|
||||
{
|
||||
printf("event: %s\n", e->event);
|
||||
rkt_webview_destroy_event(e);
|
||||
printf("event: %s\n", e->data.event.event);
|
||||
rkt_webview_free_data(e);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -20,7 +21,9 @@ int main(int argc, char *argv[])
|
||||
_argv = argv;
|
||||
|
||||
rkt_webview_init();
|
||||
wv1 = rkt_webview_create(0, eventCb);
|
||||
|
||||
wv1 = rkt_webview_create(0, eventCb, nullptr);
|
||||
|
||||
rkt_webview_move(wv1, 200, 300);
|
||||
rkt_webview_resize(wv1, 800, 600);
|
||||
rkt_webview_set_url(wv1, "https://wikipedia.org"); //"http://127.0.0.1:8083");
|
||||
@@ -35,23 +38,26 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (i == 3) {
|
||||
rkt_js_result_t *r = rkt_webview_call_js(wv1, "{ let a = 7 * 6; console.log('a = ' + a); return a; }");
|
||||
printf("rkt_js_result: %d: %s\n", r->result, r->value);
|
||||
rkt_data_t *r = rkt_webview_call_js(wv1, "{ let a = 7 * 6; console.log('a = ' + a); return a; }");
|
||||
printf("rkt_js_result: %d: %s\n", r->data.js_result.result, r->data.js_result.value);
|
||||
rkt_webview_free_data(r);
|
||||
}
|
||||
|
||||
if (i == 4) {
|
||||
rkt_js_result_t *r = rkt_webview_call_js(wv1, "let el = document.getElementById('hi');el.value = '10';");
|
||||
printf("rkt_js_result: %d: %s\n", r->result, r->value);
|
||||
rkt_data_t *r = rkt_webview_call_js(wv1, "let el = document.getElementById('hi');el.value = '10';");
|
||||
printf("rkt_js_result: %d: %s\n", r->data.js_result.result, r->data.js_result.value);
|
||||
rkt_webview_free_data(r);
|
||||
}
|
||||
|
||||
if (i == 6) {
|
||||
rkt_js_result_t *r = rkt_webview_call_js(wv1, "document.body.innerHTML = '<h1>Hi!</h1>'; return document.body.innerHTML;");
|
||||
printf("rkt_js_result: %d: %s\n", r->result, r->value);
|
||||
rkt_data_t *r = rkt_webview_call_js(wv1, "document.body.innerHTML = '<h1>Hi!</h1>'; return document.body.innerHTML;");
|
||||
printf("rkt_js_result: %d: %s\n", r->data.js_result.result, r->data.js_result.value);
|
||||
rkt_webview_free_data(r);
|
||||
}
|
||||
|
||||
|
||||
if (i == 10) {
|
||||
wv2 = rkt_webview_create(wv1, eventCb);
|
||||
wv2 = rkt_webview_create(wv1, eventCb, nullptr);
|
||||
rkt_webview_move(wv2, 400, 200);
|
||||
rkt_webview_resize(wv2, 800, 600);
|
||||
rkt_webview_set_url(wv2, "https://127.0.0.1");
|
||||
|
||||
@@ -32,10 +32,10 @@ void rkt_webview_init()
|
||||
}
|
||||
}
|
||||
|
||||
int rkt_webview_create(rktwebview_t parent, event_cb_t js_event_cb)
|
||||
int rkt_webview_create(rktwebview_t parent, event_cb_t js_event_cb, const char *optional_server_cert_pem)
|
||||
{
|
||||
rkt_webview_init();
|
||||
return handler->rktWebViewCreate(parent, js_event_cb);
|
||||
return handler->rktWebViewCreate(parent, js_event_cb, optional_server_cert_pem);
|
||||
}
|
||||
|
||||
void rkt_webview_close(rktwebview_t wv)
|
||||
@@ -66,10 +66,10 @@ result_t rkt_webview_run_js(rktwebview_t wv, const char *js)
|
||||
return r;
|
||||
}
|
||||
|
||||
rkt_js_result_t *rkt_webview_call_js(rktwebview_t wv, const char *js)
|
||||
rkt_data_t *rkt_webview_call_js(rktwebview_t wv, const char *js)
|
||||
{
|
||||
rkt_webview_init();
|
||||
rkt_js_result_t *r = handler->rktCallJs(wv, js);
|
||||
rkt_data_t *r = handler->rktCallJs(wv, js);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -95,22 +95,6 @@ void rkt_webview_process_events(int for_ms)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result_t rkt_webview_destroy_event(rkt_event_t *e)
|
||||
{
|
||||
free(e->event);
|
||||
free(e);
|
||||
return result_t::oke;
|
||||
}
|
||||
|
||||
result_t rkt_webview_destroy_js_result(rkt_js_result_t *r)
|
||||
{
|
||||
free(r->value);
|
||||
free(r);
|
||||
return result_t::oke;
|
||||
}
|
||||
|
||||
|
||||
result_t rkt_webview_move(rktwebview_t wv, int x, int y)
|
||||
{
|
||||
rkt_webview_init();
|
||||
@@ -184,19 +168,19 @@ result_t rkt_webview_set_title(rktwebview_t wv, const char *title)
|
||||
return handler->rktWindowSetTitle(wv, title);
|
||||
}
|
||||
|
||||
rkt_js_result_t *rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir)
|
||||
rkt_data_t *rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir)
|
||||
{
|
||||
rkt_webview_init();
|
||||
return handler->rktChooseDir(w, title, base_dir);
|
||||
}
|
||||
|
||||
rkt_js_result_t *rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
rkt_data_t *rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
{
|
||||
rkt_webview_init();
|
||||
return handler->rktFileOpen(w, title, base_dir, permitted_exts);
|
||||
}
|
||||
|
||||
rkt_js_result_t *rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
rkt_data_t *rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
{
|
||||
rkt_webview_init();
|
||||
return handler->rktFileSave(w, title, base_dir, permitted_exts);
|
||||
@@ -207,3 +191,31 @@ void rkt_webview_set_ou_token(rktwebview_t wv, const char *token)
|
||||
rkt_webview_init();
|
||||
handler->rktSetOUToken(wv, token);
|
||||
}
|
||||
|
||||
void rkt_webview_free_data(rkt_data_t *d)
|
||||
{
|
||||
if (d->kind == version) {
|
||||
free(d);
|
||||
} else if (d->kind == event) {
|
||||
free(d->data.event.event);
|
||||
free(d);
|
||||
} else if (d->kind == js_result) {
|
||||
free(d->data.js_result.value);
|
||||
free(d);
|
||||
} else {
|
||||
fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind);
|
||||
}
|
||||
}
|
||||
|
||||
rkt_data_t *rkt_webview_version()
|
||||
{
|
||||
rkt_data_t *d = static_cast<rkt_data_t *>(malloc(sizeof(rkt_data_t)));
|
||||
d->kind = version;
|
||||
d->data.version.api_major = RKT_WEBVIEW_API_MAJOR;
|
||||
d->data.version.api_minor = RKT_WEBVIEW_API_MINOR;
|
||||
d->data.version.api_patch = RKT_WEBVIEW_API_PATCH;
|
||||
d->data.version.qt_major = QT_VERSION_MAJOR;
|
||||
d->data.version.qt_minor = QT_VERSION_MINOR;
|
||||
d->data.version.qt_patch = QT_VERSION_PATCH;
|
||||
return d;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
#include "rktwebview_qt_global.h"
|
||||
|
||||
#define RKT_WEBVIEW_API_MAJOR 0
|
||||
#define RKT_WEBVIEW_API_MINOR 1
|
||||
#define RKT_WEBVIEW_API_PATCH 1
|
||||
|
||||
extern "C" {
|
||||
|
||||
typedef int rktwebview_t;
|
||||
@@ -12,8 +16,6 @@ typedef struct {
|
||||
char *event;
|
||||
} rkt_event_t;
|
||||
|
||||
typedef void (*event_cb_t)(rkt_event_t *);
|
||||
|
||||
typedef enum {
|
||||
no_result_yet = -1,
|
||||
oke = 0,
|
||||
@@ -51,27 +53,53 @@ typedef enum {
|
||||
maximized_active = 18
|
||||
} window_state_t;
|
||||
|
||||
typedef struct {
|
||||
int qt_major;
|
||||
int qt_minor;
|
||||
int qt_patch;
|
||||
int api_major;
|
||||
int api_minor;
|
||||
int api_patch;
|
||||
} rkt_version_t;
|
||||
|
||||
typedef enum {
|
||||
version = 1,
|
||||
event = 2,
|
||||
js_result = 3
|
||||
} rkt_data_kind_t;
|
||||
|
||||
typedef struct {
|
||||
rkt_data_kind_t kind;
|
||||
union {
|
||||
rkt_version_t version;
|
||||
rkt_event_t event;
|
||||
rkt_js_result_t js_result;
|
||||
} data;
|
||||
} rkt_data_t;
|
||||
|
||||
typedef void (*event_cb_t)(rkt_data_t *);
|
||||
|
||||
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(rktwebview_t parent, event_cb_t js_event_cb);
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_free_data(rkt_data_t *d);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_version();
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT int rkt_webview_create(rktwebview_t parent, event_cb_t js_event_cb, const char *optional_server_cert_pem);
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_close(rktwebview_t wv);
|
||||
RKTWEBVIEW_QT_EXPORT bool rkt_webview_valid(rktwebview_t wv);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_title(rktwebview_t wv, const char *title);
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_set_ou_token(rktwebview_t wv, const char *token);
|
||||
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_url(rktwebview_t wv, const char *url);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_html(rktwebview_t wv, const char *html);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_run_js(rktwebview_t wv, const char *js);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_call_js(rktwebview_t wv, const char *js);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_destroy_js_result(rkt_js_result_t *r);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_call_js(rktwebview_t wv, const char *js);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_open_devtools(rktwebview_t wv);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_destroy_event(rkt_event_t *e);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_move(rktwebview_t w, int x, int y);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_resize(rktwebview_t w, int width, int height);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_hide(rktwebview_t w);
|
||||
@@ -82,9 +110,9 @@ RKTWEBVIEW_QT_EXPORT result_t rkt_webview_maximize(rktwebview_t w);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_minimize(rktwebview_t w);
|
||||
RKTWEBVIEW_QT_EXPORT window_state_t rkt_webview_window_state(rktwebview_t w);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,14 @@
|
||||
#include "command.h"
|
||||
#include <QFileDialog>
|
||||
|
||||
static inline char *copyString(const char *s)
|
||||
{
|
||||
int l = strlen(s);
|
||||
char *cpy = static_cast<char *>(malloc(l + 1));
|
||||
memcpy(cpy, s, l + 1);
|
||||
return cpy;
|
||||
}
|
||||
|
||||
void Rktwebview_qt::processCommand(Command *cmd)
|
||||
{
|
||||
switch(cmd->cmd) {
|
||||
@@ -26,6 +34,9 @@ void Rktwebview_qt::processCommand(Command *cmd)
|
||||
void *f = cmd->args[1].value<void *>();
|
||||
event_cb_t js_event_cb = reinterpret_cast <event_cb_t>(f);
|
||||
|
||||
bool has_scp = cmd->args[2].toBool();
|
||||
QByteArray scp_pem = cmd->args[3].toByteArray();
|
||||
|
||||
WebviewWindow *p;
|
||||
if (_views.contains(parent)) {
|
||||
p = _views[parent];
|
||||
@@ -33,7 +44,7 @@ void Rktwebview_qt::processCommand(Command *cmd)
|
||||
p = nullptr;
|
||||
}
|
||||
|
||||
WebviewWindow *w = new WebviewWindow(p);
|
||||
WebviewWindow *w = new WebviewWindow(p, has_scp, scp_pem);
|
||||
WebViewQt *view = new WebViewQt(nextHandle(), w);
|
||||
w->addView(view, this);
|
||||
|
||||
@@ -359,13 +370,17 @@ int Rktwebview_qt::nextHandle()
|
||||
return h;
|
||||
}
|
||||
|
||||
int Rktwebview_qt::rktWebViewCreate(int parent, event_cb_t js_evt_cb)
|
||||
int Rktwebview_qt::rktWebViewCreate(int parent, event_cb_t js_evt_cb, const char *optional_server_cert_pem)
|
||||
{
|
||||
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);
|
||||
bool has_scp = (optional_server_cert_pem != nullptr);
|
||||
c.args.push_back(has_scp);
|
||||
QByteArray scp = (optional_server_cert_pem == nullptr) ? QByteArray("") : QByteArray(optional_server_cert_pem);
|
||||
c.args.push_back(scp);
|
||||
|
||||
postCommand(&c);
|
||||
|
||||
@@ -427,7 +442,7 @@ result_t Rktwebview_qt::rktSetHtml(rktwebview_t wv, const char *html)
|
||||
return r ? result_t::oke : result_t::set_html_failed;
|
||||
}
|
||||
|
||||
rkt_js_result_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js)
|
||||
rkt_data_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js)
|
||||
{
|
||||
Command c(COMMAND_CALL_JS);
|
||||
QString _js(js);
|
||||
@@ -436,9 +451,10 @@ rkt_js_result_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js)
|
||||
postCommand(&c);
|
||||
while(!c.done) { doEvents(); }
|
||||
|
||||
rkt_js_result_t *r = static_cast<rkt_js_result_t *>(malloc(sizeof(rkt_js_result_t)));
|
||||
r->result = c.js_result_ok ? result_t::oke : result_t::eval_js_failed;
|
||||
r->value = strdup(c.result.toString().toUtf8());
|
||||
rkt_data_t *r = static_cast<rkt_data_t *>(malloc(sizeof(rkt_data_t)));
|
||||
r->kind = js_result;
|
||||
r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::eval_js_failed;
|
||||
r->data.js_result.value = copyString(c.result.toString().toUtf8());
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -520,7 +536,7 @@ window_state_t Rktwebview_qt::rktWindowState(rktwebview_t w)
|
||||
return ws;
|
||||
}
|
||||
|
||||
rkt_js_result_t *Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const char *base_dir)
|
||||
rkt_data_t *Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const char *base_dir)
|
||||
{
|
||||
Command c(COMMAND_CHOOSE_DIR);
|
||||
c.args.push_back(w);
|
||||
@@ -537,15 +553,15 @@ rkt_js_result_t *Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title,
|
||||
|
||||
bool oke = c.js_result_ok;
|
||||
|
||||
rkt_js_result_t *r = static_cast<rkt_js_result_t *>(malloc(sizeof(rkt_js_result_t)));
|
||||
r->result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed;
|
||||
|
||||
r->value = strdup(c.result.toString().toUtf8());
|
||||
rkt_data_t *r = static_cast<rkt_data_t *>(malloc(sizeof(rkt_js_result_t)));
|
||||
r->kind = js_result;
|
||||
r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed;
|
||||
r->data.js_result.value = copyString(c.result.toString().toUtf8());
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
rkt_js_result_t *Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
rkt_data_t *Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
{
|
||||
Command c(COMMAND_FILE_OPEN);
|
||||
c.args.push_back(w);
|
||||
@@ -565,15 +581,15 @@ rkt_js_result_t *Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, c
|
||||
|
||||
bool oke = c.js_result_ok;
|
||||
|
||||
rkt_js_result_t *r = static_cast<rkt_js_result_t *>(malloc(sizeof(rkt_js_result_t)));
|
||||
r->result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed;
|
||||
|
||||
r->value = strdup(c.result.toString().toUtf8());
|
||||
rkt_data_t *r = static_cast<rkt_data_t *>(malloc(sizeof(rkt_data_t)));
|
||||
r->kind = js_result;
|
||||
r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed;
|
||||
r->data.js_result.value = copyString(c.result.toString().toUtf8());
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
rkt_js_result_t *Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
rkt_data_t *Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
|
||||
{
|
||||
Command c(COMMAND_FILE_SAVE);
|
||||
c.args.push_back(w);
|
||||
@@ -593,10 +609,10 @@ rkt_js_result_t *Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, c
|
||||
|
||||
bool oke = c.js_result_ok;
|
||||
|
||||
rkt_js_result_t *r = static_cast<rkt_js_result_t *>(malloc(sizeof(rkt_js_result_t)));
|
||||
r->result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed;
|
||||
|
||||
r->value = strdup(c.result.toString().toUtf8());
|
||||
rkt_data_t *r = static_cast<rkt_data_t *>(malloc(sizeof(rkt_data_t)));
|
||||
r->kind = js_result;
|
||||
r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::choose_dir_failed;
|
||||
r->data.js_result.value = copyString(c.result.toString().toUtf8());
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -672,11 +688,12 @@ void Rktwebview_qt::triggerEvent(rktwebview_t wv, const QString &msg)
|
||||
{
|
||||
if (_view_js_callbacks.contains(wv)) {
|
||||
event_cb_t js_event_cb = _view_js_callbacks[wv];
|
||||
char *evt = strdup(msg.toUtf8().constData());
|
||||
rkt_event_t *e = static_cast<rkt_event_t *>(malloc(sizeof(rkt_event_t)));
|
||||
e->wv = wv;
|
||||
e->event = evt;
|
||||
js_event_cb(e);
|
||||
char *evt = copyString(msg.toUtf8().constData());
|
||||
rkt_data_t *d = static_cast<rkt_data_t *>(malloc(sizeof(rkt_data_t)));
|
||||
d->kind = rkt_data_kind_t::event;
|
||||
d->data.event.wv = wv;
|
||||
d->data.event.event = evt;
|
||||
js_event_cb(d);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,21 +743,29 @@ void Rktwebview_qt::customEvent(QEvent *event)
|
||||
|
||||
void Rktwebview_qt::doEvents()
|
||||
{
|
||||
//_app->processEvents();
|
||||
if (_evt_loop_depth == 0) {
|
||||
//QTime ct = QTime::currentTime();
|
||||
//QTime expire = QTime::currentTime().addMSecs(2);
|
||||
//while(QTime::currentTime() <= expire) {
|
||||
_app->processEvents();
|
||||
//}
|
||||
|
||||
// Qt 6.10 --> this leads to a core dump
|
||||
// together with the stopEventloop stuff.
|
||||
// Qt 6.4 seem stable.
|
||||
/*if (_evt_loop_depth == 0) {
|
||||
_evt_loop_depth += 1;
|
||||
_evt_loop_timer.setSingleShot(true);
|
||||
_evt_loop_timer.start(2);
|
||||
//_evt_loop.exec();
|
||||
_app->exec();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void Rktwebview_qt::stopEventloop()
|
||||
{
|
||||
//_evt_loop.exit(0);
|
||||
_app->exit(0);
|
||||
_evt_loop_depth -= 1;
|
||||
//_app->exit(0);
|
||||
//_evt_loop_depth -= 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -760,15 +785,18 @@ Rktwebview_qt::Rktwebview_qt(Rktwebview_qt **handler) :
|
||||
connect(&_process_events, &QTimer::timeout, this, &Rktwebview_qt::processJsEventQueues);
|
||||
_process_events.start(5);
|
||||
|
||||
connect(&_evt_loop_timer, &QTimer::timeout, this, &Rktwebview_qt::stopEventloop);
|
||||
// See Qt 6.10 remark at doEvents.
|
||||
//connect(&_evt_loop_timer, &QTimer::timeout, this, &Rktwebview_qt::stopEventloop);
|
||||
|
||||
//const auto *eventDispatcher = QThread::currentThread()->eventDispatcher();
|
||||
//QObject::connect(eventDispatcher, &QAbstractEventDispatcher::aboutToBlock,
|
||||
// QThread::currentThread(), []{
|
||||
// if (QThread::currentThread()->loopLevel() == 0)
|
||||
// QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
|
||||
// }
|
||||
// );
|
||||
// Because we are using processEvents only (Qt 6.10), we need this dispatcher to
|
||||
// handle deferred Deletes.
|
||||
const auto *eventDispatcher = QThread::currentThread()->eventDispatcher();
|
||||
QObject::connect(eventDispatcher, &QAbstractEventDispatcher::aboutToBlock,
|
||||
QThread::currentThread(), []{
|
||||
if (QThread::currentThread()->loopLevel() == 0)
|
||||
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
|
||||
}
|
||||
);
|
||||
|
||||
*_handler = nullptr;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
public:
|
||||
int nextHandle();
|
||||
public:
|
||||
int rktWebViewCreate(int parent, event_cb_t js_evt_cb);
|
||||
int rktWebViewCreate(int parent, event_cb_t js_evt_cb, const char *optional_server_cert_pem);
|
||||
void rktWebViewClose(int wv);
|
||||
void rktSetOUToken(rktwebview_t wv, const char *ou_token);
|
||||
void rktQuit();
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
result_t rktSetUrl(rktwebview_t wv, const char *url);
|
||||
result_t rktSetHtml(rktwebview_t wv, const char *html);
|
||||
result_t rktRunJs(rktwebview_t wv, const char *js);
|
||||
rkt_js_result_t *rktCallJs(rktwebview_t wv, const char *js);
|
||||
rkt_data_t *rktCallJs(rktwebview_t wv, const char *js);
|
||||
|
||||
result_t rktMove(rktwebview_t wv, int x, int y);
|
||||
result_t rktResize(rktwebview_t wv, int w, int h);
|
||||
@@ -85,9 +85,9 @@ public:
|
||||
result_t rktShowNormalWindow(rktwebview_t w);
|
||||
window_state_t rktWindowState(rktwebview_t w);
|
||||
|
||||
rkt_js_result_t *rktChooseDir(rktwebview_t w, const char *title, const char *base_dir);
|
||||
rkt_js_result_t * rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
rkt_js_result_t * rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
rkt_data_t *rktChooseDir(rktwebview_t w, const char *title, const char *base_dir);
|
||||
rkt_data_t *rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
rkt_data_t *rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
||||
|
||||
result_t rktWindowSetTitle(rktwebview_t wv, const char *title);
|
||||
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
|
||||
public:
|
||||
Rktwebview_qt(Rktwebview_qt **handler);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <QJsonDocument>
|
||||
|
||||
WebViewQt::WebViewQt(int id, WebviewWindow *window)
|
||||
: QWebEngineView(window)
|
||||
: QWebEngineView(window->profile(), window)
|
||||
{
|
||||
_id = id;
|
||||
_window = window;
|
||||
|
||||
@@ -10,13 +10,37 @@
|
||||
#include <QJsonObject>
|
||||
#include <QWebEngineScriptCollection>
|
||||
#include <QWebEngineScript>
|
||||
#include <QWebEngineProfile>
|
||||
#include <QWebEngineProfileBuilder>
|
||||
#include <QWebEnginePage>
|
||||
#include <QMoveEvent>
|
||||
#include <QWindow>
|
||||
#include <QWebEngineProfileBuilder>
|
||||
|
||||
|
||||
WebviewWindow::WebviewWindow(WebviewWindow *parent)
|
||||
/*
|
||||
static void displ(QSslCertificate & cert, QSslCertificate::SubjectInfo &a) {
|
||||
QStringList issuerInfo = cert.issuerInfo(a);
|
||||
int i, N;
|
||||
printf("%d\n", a);
|
||||
for(i = 0, N = issuerInfo.size(); i < N; i++) {
|
||||
printf("%d[%d]: %s\n", a, i, issuerInfo[i].toUtf8().constData());
|
||||
}
|
||||
};
|
||||
|
||||
static void displ1(QSslCertificate &cert, QList<QSslCertificate::SubjectInfo > l) {
|
||||
int i, N;
|
||||
for(i = 0, N = l.size(); i < N; i++) {
|
||||
displ(cert, l[i]);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
WebviewWindow::WebviewWindow(WebviewWindow *parent, bool has_scp, QByteArray scp_pem)
|
||||
: QMainWindow{parent}
|
||||
{
|
||||
static int profile_nr = 0;
|
||||
|
||||
_view = nullptr;
|
||||
_must_close = false;
|
||||
|
||||
@@ -27,6 +51,22 @@ WebviewWindow::WebviewWindow(WebviewWindow *parent)
|
||||
_moved = 0;
|
||||
_resized = 0;
|
||||
|
||||
QWebEngineProfileBuilder b;
|
||||
if (has_scp) {
|
||||
profile_nr += 1;
|
||||
char buf[100];
|
||||
sprintf(buf, "profile-%d", profile_nr);
|
||||
QString name(buf);
|
||||
QSslCertificate cert(scp_pem);
|
||||
|
||||
QList<QSslCertificate> certs;
|
||||
certs.append(cert);
|
||||
b.setAdditionalTrustedCertificates(certs);
|
||||
_profile = b.createProfile(name);
|
||||
} else {
|
||||
_profile = QWebEngineProfile::defaultProfile();
|
||||
}
|
||||
|
||||
if (parent != nullptr) {
|
||||
setWindowModality(Qt::WindowModality::WindowModal);
|
||||
setWindowFlag(Qt::WindowType::Dialog, true);
|
||||
@@ -36,9 +76,63 @@ WebviewWindow::WebviewWindow(WebviewWindow *parent)
|
||||
connect(&_move_timer, &QTimer::timeout, this, &WebviewWindow::triggerMove);
|
||||
}
|
||||
|
||||
void WebviewWindow::navigationRequested(QWebEngineNavigationRequest &req)
|
||||
{
|
||||
if (req.navigationType() == QWebEngineNavigationRequest::NavigationType::TypedNavigation) {
|
||||
req.accept();
|
||||
} else {
|
||||
EventContainer e("navigation-request");
|
||||
|
||||
e["url"] = req.url().toString();
|
||||
|
||||
QString type;
|
||||
switch (req.navigationType()) {
|
||||
case QWebEngineNavigationRequest::NavigationType::LinkClickedNavigation: type = "link-clicked";
|
||||
break;
|
||||
case QWebEngineNavigationRequest::NavigationType::TypedNavigation: type = "typed";
|
||||
break;
|
||||
case QWebEngineNavigationRequest::NavigationType::FormSubmittedNavigation: type = "form-submit";
|
||||
break;
|
||||
case QWebEngineNavigationRequest::NavigationType::BackForwardNavigation: type = "back-or-forward";
|
||||
break;
|
||||
case QWebEngineNavigationRequest::NavigationType::ReloadNavigation: type = "reload";
|
||||
break;
|
||||
case QWebEngineNavigationRequest::NavigationType::RedirectNavigation: type = "redirect";
|
||||
break;
|
||||
default: type = "other";
|
||||
break;
|
||||
}
|
||||
|
||||
e["type"] = type;
|
||||
_container->triggerEvent(_view->id(), e);
|
||||
|
||||
req.reject();
|
||||
}
|
||||
}
|
||||
|
||||
void WebviewWindow::handleCertificate(const QWebEngineCertificateError &certificateError)
|
||||
{
|
||||
/*
|
||||
QList<QSslCertificate> certs = _view->page()->profile()->additionalTrustedCertificates();
|
||||
|
||||
auto dodisp = [](QList<QSslCertificate> certs)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < certs.size(); i++) {
|
||||
QSslCertificate cert = certs[i];
|
||||
QList<QSslCertificate::SubjectInfo> attrs;
|
||||
attrs.append(QSslCertificate::Organization);
|
||||
attrs.append(QSslCertificate::OrganizationalUnitName);
|
||||
attrs.append(QSslCertificate::CountryName);
|
||||
attrs.append(QSslCertificate::CommonName);
|
||||
displ1(cert, attrs);
|
||||
}
|
||||
};
|
||||
dodisp(certs);
|
||||
dodisp(certificateError.certificateChain());
|
||||
*/
|
||||
|
||||
fprintf(stderr, "Certificate Error: %s\n", certificateError.description().toUtf8().constData());
|
||||
QList<QSslCertificate> chain = certificateError.certificateChain();
|
||||
int i;
|
||||
for(i = 0; i < chain.size(); i++) {
|
||||
@@ -88,6 +182,7 @@ void WebviewWindow::closeEvent(QCloseEvent *evt)
|
||||
EventContainer e("closed");
|
||||
_container->triggerEvent(_view->id(), e);
|
||||
_container->removeView(_view->id());
|
||||
_view->deleteLater();
|
||||
this->deleteLater();
|
||||
if (_devtools != nullptr) {
|
||||
_devtools->deleteLater();
|
||||
@@ -131,7 +226,14 @@ void WebviewWindow::addView(WebViewQt *v, Rktwebview_qt *c)
|
||||
_view = v;
|
||||
this->setCentralWidget(v);
|
||||
|
||||
QWebEnginePage *page = _view->page();
|
||||
QWebEnginePage *page;
|
||||
|
||||
if (_profile == nullptr) {
|
||||
page = _view->page();
|
||||
} else {
|
||||
page = new QWebEnginePage(_profile, this);
|
||||
_view->setPage(page);
|
||||
}
|
||||
|
||||
// Inject event handling code for the javascript side
|
||||
QWebEngineScriptCollection &col = page->scripts();
|
||||
@@ -160,6 +262,8 @@ void WebviewWindow::addView(WebViewQt *v, Rktwebview_qt *c)
|
||||
connect(page, &QWebEnginePage::loadStarted, this, [this]() {
|
||||
_container->onPageLoad(_view->id());
|
||||
});
|
||||
connect(page, &QWebEnginePage::navigationRequested, this, &WebviewWindow::navigationRequested);
|
||||
|
||||
connect(page, &QWebEnginePage::certificateError, this, &WebviewWindow::handleCertificate);
|
||||
}
|
||||
|
||||
@@ -231,6 +335,11 @@ void WebviewWindow::triggerMove()
|
||||
_container->triggerEvent(_view->id(), xy);
|
||||
}
|
||||
|
||||
QWebEngineProfile *WebviewWindow::profile()
|
||||
{
|
||||
return _profile;
|
||||
}
|
||||
|
||||
void WebviewWindow::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
_w = event->size().width();
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
#include <QWebEngineCertificateError>
|
||||
#include <QWebEngineProfile>
|
||||
#include <QWebEngineNavigationRequest>
|
||||
|
||||
class WebViewQt;
|
||||
class Rktwebview_qt;
|
||||
@@ -33,8 +35,11 @@ private:
|
||||
|
||||
QString _ou_token;
|
||||
|
||||
QWebEngineProfile *_profile;
|
||||
|
||||
private slots:
|
||||
void handleCertificate(const QWebEngineCertificateError &certificateError);
|
||||
void navigationRequested(QWebEngineNavigationRequest &req);
|
||||
|
||||
public slots:
|
||||
void processJsEvents();
|
||||
@@ -60,12 +65,15 @@ public:
|
||||
void openDevTools();
|
||||
|
||||
public:
|
||||
explicit WebviewWindow(WebviewWindow *parent = nullptr);
|
||||
explicit WebviewWindow(WebviewWindow *parent, bool has_scp, QByteArray scp_pem);
|
||||
|
||||
private slots:
|
||||
void triggerResize();
|
||||
void triggerMove();
|
||||
|
||||
public:
|
||||
QWebEngineProfile *profile();
|
||||
|
||||
signals:
|
||||
|
||||
// QWidget interface
|
||||
|
||||
Reference in New Issue
Block a user