initialization and cleanup

This commit is contained in:
2026-03-17 15:42:03 +01:00
parent 7c3b780ae9
commit c50267120a
9 changed files with 209 additions and 216 deletions

View File

@@ -20,67 +20,71 @@ int main(int argc, char *argv[])
_argc = argc;
_argv = argv;
rkt_webview_init();
int k = 0;
while(k < 2) {
rkt_webview_init();
int context = rkt_webview_new_context("console.log('boilerplate!');", nullptr);
int context = rkt_webview_new_context("console.log('boilerplate!');", nullptr);
wv1 = rkt_webview_create(context, 0, eventCb);
wv1 = rkt_webview_create(context, 0, eventCb);
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");
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");
int i = 0;
while(i < 35) {
printf("Waiting...%d\n", i);
rkt_webview_process_events(1000);
k += 1;
int i = 0;
while(i < 10) {
printf("Waiting...%d\n", i);
rkt_webview_process_events(1000);
if (i == 6) {
rkt_webview_open_devtools(wv1);
if (i == 6) {
rkt_webview_open_devtools(wv1);
}
if (i == 3) {
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_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_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 == 7) {
result_t r = rkt_webview_message_box(wv1, "This is a title", "This is my message", "This is my submessage", rkt_messagetype_t::yes_no);
}
if (i == 10) {
wv2 = rkt_webview_create(context, wv1, eventCb);
rkt_webview_move(wv2, 400, 200);
rkt_webview_resize(wv2, 800, 600);
rkt_webview_set_url(wv2, "https://127.0.0.1");
}
if (i > 10) {
char buf[1000];
sprintf(buf, "{ let obj = { e: 'test', i: %d }; window.rkt_send_event(obj); }", i);
rkt_webview_run_js(wv1, buf);
}
if (i == 15) {
rkt_webview_close(wv2);
}
i += 1;
}
if (i == 3) {
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_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_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 == 7) {
result_t r = rkt_webview_message_box(wv1, "This is a title", "This is my message", "This is my submessage", rkt_messagetype_t::yes_no);
}
if (i == 10) {
wv2 = rkt_webview_create(context, wv1, eventCb);
rkt_webview_move(wv2, 400, 200);
rkt_webview_resize(wv2, 800, 600);
rkt_webview_set_url(wv2, "https://127.0.0.1");
}
if (i > 10) {
char buf[1000];
sprintf(buf, "{ let obj = { e: 'test', i: %d }; window.rkt_send_event(obj); }", i);
rkt_webview_run_js(wv1, buf);
}
if (i == 15) {
rkt_webview_close(wv2);
}
i += 1;
rkt_webview_close(wv1);
rkt_webview_cleanup();
}
rkt_webview_close(wv2);
}

View File

@@ -24,11 +24,55 @@ uint64_t current_ms() {
Rktwebview_qt *handler = nullptr;
void rkt_webview_cleanup()
{
if (handler != nullptr) {
rkt_webview_process_events(100);
//QTimer app_quit;
//QObject::connect(&app_quit, &QTimer::timeout, handler->app(), &QApplication::quit, Qt::ConnectionType::QueuedConnection);
//app_quit.setSingleShot(true);
//app_quit.start(250);
//handler->app()->exec();
//fprintf(stderr, "cleanup: handler = %p\n", handler);
// TODO
// Do not delete the QApplication, although it will result in QThreadStorage warnings.
// If the app is deleted, QtWebEngineProfileBuilder->createProfile will memory corrupt.
//handler->deleteApp();
//delete handler;
//handler = nullptr;
//fprintf(stderr, "cleanup: handler = %p\n", handler);
}
}
void rkt_webview_init()
{
if (handler == nullptr) {
handler = new Rktwebview_qt(&handler);
handler->doEvents();
//fprintf(stderr, "init: handler = %p\n", handler);
handler = new Rktwebview_qt();
//fprintf(stderr, "init: handler = %p\n", handler);
}
if (handler->app() == nullptr) {
handler->initApp();
//QTimer app_exit;
//QObject::connect(&app_exit, &QTimer::timeout, handler->app(), []() {
// handler->app()->exit(0);
//}, Qt::ConnectionType::QueuedConnection);
//app_exit.setSingleShot(true);
//app_exit.start(250);
//QApplication *a = handler->app();
//a->exec();
}
}

View File

@@ -89,6 +89,7 @@ typedef struct {
typedef void (*event_cb_t)(rkt_data_t *);
RKTWEBVIEW_QT_EXPORT void rkt_webview_init();
RKTWEBVIEW_QT_EXPORT void rkt_webview_cleanup();
RKTWEBVIEW_QT_EXPORT void rkt_webview_process_events(int for_ms);
RKTWEBVIEW_QT_EXPORT void rkt_webview_free_data(rkt_data_t *d);
RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_version();

View File

@@ -29,11 +29,6 @@ static inline char *copyString(const char *s)
void Rktwebview_qt::processCommand(Command *cmd)
{
switch(cmd->cmd) {
case COMMAND_QUIT: {
_app->quit();
cmd->done = true;
}
break;
case COMMAND_CREATE: {
rkt_wv_context_t context = cmd->args[0].toInt();
rktwebview_t parent = cmd->args[1].toInt();
@@ -80,6 +75,11 @@ void Rktwebview_qt::processCommand(Command *cmd)
_views.remove(wv);
w->closeView();
cmd->result = true;
while(w->isVisible()) {
doEvents();
}
_view_js_callbacks.remove(wv);
delete w;
} else {
cmd->result = false;
}
@@ -630,7 +630,7 @@ result_t Rktwebview_qt::fileDlg(rktwebview_t w, const char *title, const char *b
QStringList l = dlg->selectedFiles();
QString file;
if (l.size() > 0) {
file = dlg->selectedFiles().first();
file = l[0];
}
EventContainer e(evt_ok);
@@ -817,19 +817,41 @@ void Rktwebview_qt::triggerEvent(rktwebview_t wv, const QString &msg)
}
}
void Rktwebview_qt::rktQuit()
void Rktwebview_qt::execApp()
{
QList<int> keys = _views.keys();
int i;
for(i = 0; i < keys.size(); i++) {
int view_handle = keys[i];
rktWebViewClose(view_handle);
}
_app->exec();
}
QApplication *Rktwebview_qt::app()
{
return _app;
}
void Rktwebview_qt::deleteApp()
{
delete _app;
_app = nullptr;
}
void Rktwebview_qt::initApp()
{
_app = new QApplication(_argc, _argv);
// See Qt 6.10 remark at doEvents.
//connect(&_evt_loop_timer, &QTimer::timeout, this, &Rktwebview_qt::stopEventloop);
// 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);
}
);
Command c(COMMAND_QUIT);
postCommand(&c);
while(!c.done) { doEvents(); }
}
void Rktwebview_qt::runJs(rktwebview_t wv, const char *js)
@@ -889,35 +911,17 @@ void Rktwebview_qt::stopEventloop()
}
Rktwebview_qt::Rktwebview_qt(Rktwebview_qt **handler) :
QObject()
Rktwebview_qt::Rktwebview_qt() : QObject()
{
_argc = 1;
_argv[0] = const_cast<char *>("Rktwebview_qt");
_context_counter = 0;
_current_handle = 0;
_handler = handler;
_evt_loop_depth = 0;
_app = new QApplication(_argc, _argv);
// See Qt 6.10 remark at doEvents.
//connect(&_evt_loop_timer, &QTimer::timeout, this, &Rktwebview_qt::stopEventloop);
// 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;
_app = nullptr;
}
Rktwebview_qt::~Rktwebview_qt()
@@ -934,4 +938,6 @@ Rktwebview_qt::~Rktwebview_qt()
QWebEngineProfile *p = _contexts[c_keys[i]];
delete p;
}
delete _app;
}

View File

@@ -38,8 +38,6 @@ private:
int _evt_loop_depth;
QTimer _evt_loop_timer;
Rktwebview_qt **_handler;
int _argc;
char *_argv[1];
@@ -57,6 +55,12 @@ private:
result_t fileDlg(rktwebview_t w, const char *title, const char *base, const char *filters, QFileDialog::FileMode mode, QFileDialog::AcceptMode am, QString evt_ok, QString evt_cancel);
public:
void execApp();
QApplication *app();
void deleteApp();
void initApp();
protected:
void customEvent(QEvent *event);
@@ -65,12 +69,12 @@ public:
public:
int nextHandle();
public:
rkt_wv_context_t newContext(const char *boilerplate_js, const char *optional_server_cert_pem);
int rktWebViewCreate(rkt_wv_context_t context, rktwebview_t parent, event_cb_t js_evt_cb);
void rktWebViewClose(int wv);
void rktSetOUToken(rktwebview_t wv, const char *ou_token);
void rktQuit();
result_t rktOpenDevtools(rktwebview_t wv);
result_t rktSetUrl(rktwebview_t wv, const char *url);
@@ -113,7 +117,7 @@ public:
void runCommandThread();
public:
Rktwebview_qt(Rktwebview_qt **handler);
Rktwebview_qt();
~Rktwebview_qt();
};

View File

@@ -179,6 +179,7 @@ void WebviewWindow::closeEvent(QCloseEvent *evt)
_view->deleteLater();
this->deleteLater();
if (_devtools != nullptr) {
_devtools->close();
_devtools->deleteLater();
}
} else {