Much work, using Qt 6.10 on Linux for better https support

This commit is contained in:
2026-03-11 17:57:55 +01:00
parent 989c3d328a
commit 7d234bc834
16 changed files with 541 additions and 217 deletions

View File

@@ -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;
}