Files
racket-webview/scrbl/rktwebview-api.scrbl
2026-03-16 20:04:30 +01:00

785 lines
19 KiB
Racket

#lang scribble/manual
@title{API Reference for @tt{rktwebview_qt}}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
@italic{For use with Racket FFI}
@section{Overview}
@tt{rktwebview_qt} exposes a small C-compatible API for creating and controlling
Qt-based webviews from Racket through the FFI.
The public interface is declared in @tt{rktwebview.h}. Its implementation in
@tt{rktwebview.cpp} mainly forwards requests to the internal Qt runtime.
The API consists of:
@itemlist[#:style 'compact
@item{initialization and event processing}
@item{version and memory-management helpers}
@item{browser-context management}
@item{window creation and lifecycle control}
@item{navigation and content loading}
@item{JavaScript execution}
@item{window-state manipulation}
@item{native dialogs}
]
@section{Basic Types}
@subsection{Window and Context Handles}
The API uses integer handles for windows and browser contexts.
@verbatim|{
typedef int rktwebview_t;
typedef int rkt_wv_context_t;
}|
A value of type @tt{rktwebview_t} identifies a single webview window.
A value of type @tt{rkt_wv_context_t} identifies a browser context.
@subsection{Returned Data Objects}
Some API calls return a pointer to a heap-allocated @tt{rkt_data_t} value.
@verbatim|{
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;
}|
The @tt{kind} field determines which member of the union is valid.
@subsubsection{Version Data}
@verbatim|{
typedef struct {
int qt_major;
int qt_minor;
int qt_patch;
int api_major;
int api_minor;
int api_patch;
} rkt_version_t;
}|
Version data is returned by @tt{rkt_webview_version}.
@subsubsection{Event Data}
@verbatim|{
typedef struct {
rktwebview_t wv;
char *event;
} rkt_event_t;
}|
Event data is delivered to the registered callback when the backend emits an
event for a window.
The @tt{event} field is a UTF-8 JSON string allocated by the native side.
@subsubsection{JavaScript Result Data}
@verbatim|{
typedef struct {
result_t result;
char *value;
} rkt_js_result_t;
}|
JavaScript result data is returned by @tt{rkt_webview_call_js}.
The @tt{value} field contains a UTF-8 JSON string describing the result of the
JavaScript evaluation.
@subsection{Result Codes}
Many functions return a value of type @tt{result_t}.
@verbatim|{
typedef enum {
no_result_yet = -1,
oke = 0,
set_html_failed = 1,
set_navigate_failed = 2,
eval_js_failed = 3,
no_devtools_on_platform = 4,
no_delegate_for_context = 5,
webview_missing_dependency = 6,
webview_canceled = 7,
webview_invalid_state = 8,
webview_invalid_argument = 9,
webview_unspecified = 10,
webview_dispatch_failed = 11,
move_failed = 12,
resize_failed = 13,
choose_dir_failed = 14,
open_file_failed = 15,
save_file_failed = 16,
failed = 17
} result_t;
}|
In the current implementation, the most commonly returned values are:
@itemlist[#:style 'compact
@item{@tt{oke} for success}
@item{@tt{set_html_failed} for @tt{rkt_webview_set_html}}
@item{@tt{set_navigate_failed} for @tt{rkt_webview_set_url}}
@item{@tt{eval_js_failed} for JavaScript execution failure}
@item{@tt{move_failed} for failed move requests}
@item{@tt{resize_failed} for failed resize requests}
@item{@tt{failed} for general window-operation failure}
]
@subsection{Window States}
Window state is represented by @tt{window_state_t}.
@verbatim|{
typedef enum {
invalid = -1,
normal = 0,
minimized = 1,
maximized = 2,
hidden = 3,
normal_active = 16,
maximized_active = 18
} window_state_t;
}|
This type is returned by @tt{rkt_webview_window_state}.
@subsection{Message Box Types}
Message boxes use the type @tt{rkt_messagetype_t}.
@verbatim|{
typedef enum {
info = 1,
error = 2,
warning = 3,
yes_no = 4,
oke_cancel = 5
} rkt_messagetype_t;
}|
@subsection{Event Callback Type}
A window is created with an event callback of the following type:
@verbatim|{
typedef void (*event_cb_t)(rkt_data_t *);
}|
The callback receives a pointer to a @tt{rkt_data_t} whose @tt{kind} is
@tt{event}.
The callback argument must eventually be released by calling
@tt{rkt_webview_free_data}.
@subsection{Memory Ownership}
The following functions return heap-allocated @tt{rkt_data_t *} values:
@itemlist[#:style 'compact
@item{@tt{rkt_webview_version}}
@item{@tt{rkt_webview_call_js}}
@item{the event callback receives event values allocated by the native side}
]
Such values must be released by calling:
@verbatim|{
void rkt_webview_free_data(rkt_data_t *d);
}|
This function frees both the outer structure and any string data owned by it.
@section{Initialization and Event Processing}
@subsection{@tt{rkt_webview_init}}
@verbatim|{
void rkt_webview_init();
}|
Initializes the global runtime if it has not already been initialized.
This function is idempotent. The implementation checks whether the global
runtime already exists before constructing it.
Most public API functions call @tt{rkt_webview_init} automatically before doing
their work, so explicit initialization is optional but harmless.
@subsection{@tt{rkt_webview_process_events}}
@verbatim|{
void rkt_webview_process_events(int for_ms);
}|
Processes Qt events for approximately @tt{for_ms} milliseconds.
The implementation repeatedly sleeps briefly and then calls the internal Qt
event-processing routine. This function is important for keeping windows
responsive and for delivering callbacks such as:
@itemlist[#:style 'compact
@item{window lifecycle events}
@item{page-load events}
@item{JavaScript-originated events}
@item{dialog completion events}
]
Applications embedding this backend are expected to call this function
regularly.
@section{Version and Utility Functions}
@subsection{@tt{rkt_webview_version}}
@verbatim|{
rkt_data_t *rkt_webview_version();
}|
Returns a newly allocated @tt{rkt_data_t} whose @tt{kind} is @tt{version}.
The returned structure contains:
@itemlist[#:style 'compact
@item{the Qt version used to build the backend}
@item{the API version declared by the backend}
]
The returned value must be released with @tt{rkt_webview_free_data}.
@subsection{@tt{rkt_webview_free_data}}
@verbatim|{
void rkt_webview_free_data(rkt_data_t *d);
}|
Frees a @tt{rkt_data_t} that was allocated by the backend.
The function inspects @tt{d->kind} and frees any owned string data before
freeing the outer object.
@subsection{@tt{rkt_webview_set_ou_token}}
@verbatim|{
void rkt_webview_set_ou_token(rktwebview_t wv, const char *token);
}|
Associates an Organizational Unit token with the window.
During certificate-error handling, self-signed certificates whose
Organizational Unit matches this token may be accepted automatically.
This function does not return a status code.
@subsection{Developer Tools}
@subsubsection{@tt{rkt_webview_open_devtools}}
@verbatim|{
result_t rkt_webview_open_devtools(rktwebview_t wv);
}|
Opens a DevTools window associated with the given webview.
In the current implementation this function returns:
@itemlist[#:style 'compact
@item{@tt{oke} on success}
@item{@tt{eval_js_failed} on failure}
]
Even though the @tt{result_t} enumeration contains
@tt{no_devtools_on_platform}, the implementation currently maps failure to
@tt{eval_js_failed}.
@section{HTTP(s) Contexts}
@subsection{@tt{rkt_webview_new_context}}
@verbatim|{
rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js,
const char *optional_server_cert_pem);
}|
Creates a new http(s) context and returns its context handle.
A context corresponds to a Qt WebEngine profile and may be shared by multiple
windows.
Arguments:
@itemlist[#:style 'compact
@item{@tt{boilerplate_js}: JavaScript source code to inject into pages}
@item{@tt{optional_server_cert_pem}: optional PEM-encoded certificate to trust}
]
Behavior:
@itemlist[#:style 'compact
@item{A fresh profile is created.}
@item{The backend injects built-in event-bridge JavaScript into the profile.}
@item{The supplied @tt{boilerplate_js} is also injected at document-ready time.}
@item{If a certificate string is supplied, it is added as an additional
trusted certificate.}
]
The returned context handle can be passed to @tt{rkt_webview_create}.
@section{Window Creation and Lifecycle}
@subsection{@tt{rkt_webview_create}}
@verbatim|{
int rkt_webview_create(rkt_wv_context_t context,
rktwebview_t parent,
event_cb_t js_event_cb);
}|
Creates a new window in the given context.
Arguments:
@itemlist[#:style 'compact
@item{@tt{context}: the context handle returned by
@tt{rkt_webview_new_context}}
@item{@tt{parent}: a parent window handle, or a 0 value when no parent
is intended}
@item{@tt{js_event_cb}: callback used for all events emitted by this window}
]
Returns a window handle on success.
The window is shown on success. When the parent window exists, the window
will be a modal window to the parent.
The callback receives event notifications for that window, including page
events, geometry changes, JavaScript-originated events, and dialog results.
@subsection{@tt{rkt_webview_close}}
@verbatim|{
void rkt_webview_close(rktwebview_t wv);
}|
Requests the window to close.
The implementation closes the window through the internal Qt command path.
When a close completes, a @tt{"closed"} event is emitted to the callback.
This should also be called in response to a 'can-close? event.
@subsection{@tt{rkt_webview_valid}}
@verbatim|{
bool rkt_webview_valid(rktwebview_t wv);
}|
Returns @tt{#t} when the given window handle currently exists and is known to
the runtime, and @tt{#f} otherwise.
@section{Window Configuration}
@subsection{@tt{rkt_webview_set_title}}
@verbatim|{
result_t rkt_webview_set_title(rktwebview_t wv, const char *title);
}|
Sets the native title of the window.
Returns @tt{oke} on success and @tt{failed} on failure.
@section{Navigation and Content Loading}
@subsection{@tt{rkt_webview_set_url}}
@verbatim|{
result_t rkt_webview_set_url(rktwebview_t wv, const char *url);
}|
Navigates the window to the given URL.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} on success}
@item{@tt{set_navigate_failed} on failure}
]
A successful or failed load eventually also produces a @tt{"page-loaded"} event.
@subsection{@tt{rkt_webview_set_html}}
@verbatim|{
result_t rkt_webview_set_html(rktwebview_t wv, const char *html);
}|
Loads the given HTML string directly into the window.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} on success}
@item{@tt{set_html_failed} on failure}
]
A successful or failed load eventually also produces a @tt{"page-loaded"} event.
@section{JavaScript Execution}
@subsection{@tt{rkt_webview_run_js}}
@verbatim|{
result_t rkt_webview_run_js(rktwebview_t wv, const char *js);
}|
Executes JavaScript in the page without returning a value to the caller.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} on success}
@item{@tt{eval_js_failed} on failure}
]
This function is suitable for side-effecting JavaScript.
@subsection{@tt{rkt_webview_call_js}}
@verbatim|{
rkt_data_t *rkt_webview_call_js(rktwebview_t wv, const char *js);
}|
Executes JavaScript and returns a newly allocated @tt{rkt_data_t} whose
@tt{kind} is @tt{js_result}.
The returned @tt{js_result.value} field contains a compact JSON string.
The implementation wraps the supplied code in a small JavaScript function and
returns a JSON object of the form:
@verbatim|{
{"oke": true|false, "result": ..., "exn": ...}
}|
The outer native result code is stored in @tt{js_result.result}:
@itemlist[#:style 'compact
@item{@tt{oke} when the wrapped JavaScript completed successfully, @tt{result} will contain the javascript result. }
@item{@tt{eval_js_failed} when the wrapped JavaScript reported failure, @tt{exn} will contain the javascript exception information.}
]
The returned value must be released with @tt{rkt_webview_free_data}.
The javascript code is executed as part of an anonymous function and must always end with a @tt{return} statement to return the result.
@section{Window Geometry and Visibility}
@subsection{@tt{rkt_webview_move}}
@verbatim|{
result_t rkt_webview_move(rktwebview_t wv, int x, int y);
}|
Moves the window to the given screen position.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} on success}
@item{@tt{move_failed} on failure}
]
@subsection{@tt{rkt_webview_resize}}
@verbatim|{
result_t rkt_webview_resize(rktwebview_t wv, int width, int height);
}|
Resizes the window to the given dimensions.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} on success}
@item{@tt{resize_failed} on failure}
]
@subsection{@tt{rkt_webview_hide}}
@verbatim|{
result_t rkt_webview_hide(rktwebview_t w);
}|
Hides the window.
Returns @tt{oke} on success and @tt{failed} on failure.
@subsection{@tt{rkt_webview_show}}
@verbatim|{
result_t rkt_webview_show(rktwebview_t w);
}|
Shows the window.
Returns @tt{oke} on success and @tt{failed} on failure.
@subsection{@tt{rkt_webview_show_normal}}
@verbatim|{
result_t rkt_webview_show_normal(rktwebview_t w);
}|
Restores the window to the normal state.
Returns @tt{oke} on success and @tt{failed} on failure.
@subsection{@tt{rkt_webview_present}}
@verbatim|{
result_t rkt_webview_present(rktwebview_t w);
}|
Requests that the window be presented to the user.
Returns @tt{oke} on success and @tt{failed} on failure.
@subsection{@tt{rkt_webview_maximize}}
@verbatim|{
result_t rkt_webview_maximize(rktwebview_t w);
}|
Maximizes the window.
Returns @tt{oke} on success and @tt{failed} on failure.
@subsection{@tt{rkt_webview_minimize}}
@verbatim|{
result_t rkt_webview_minimize(rktwebview_t w);
}|
Minimizes the window.
Returns @tt{oke} on success and @tt{failed} on failure.
@subsection{@tt{rkt_webview_window_state}}
@verbatim|{
window_state_t rkt_webview_window_state(rktwebview_t w);
}|
Returns the current state of the window.
Possible results include:
@itemlist[#:style 'compact
@item{@tt{normal}}
@item{@tt{minimized}}
@item{@tt{maximized}}
@item{@tt{hidden}}
@item{@tt{normal_active}}
@item{@tt{maximized_active}}
@item{@tt{invalid} when no valid state can be reported}
]
@section{Native Dialogs}
The dialog functions display native Qt dialogs and report the user's choice by
emitting events through the window callback.
@subsection{@tt{rkt_webview_choose_dir}}
@verbatim|{
result_t rkt_webview_choose_dir(rktwebview_t w,
const char *title,
const char *base_dir);
}|
Opens a directory-selection dialog.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} if the dialog was shown}
@item{@tt{failed} if the window handle is invalid}
]
On completion the callback receives one of these events:
@itemlist[#:style 'compact
@item{@tt{"choose-dir-ok"}}
@item{@tt{"choose-dir-cancel"}}
]
For the @tt{"choose-dir-ok"} event, the JSON payload includes fields such as
the chosen path and current directory.
@subsection{@tt{rkt_webview_file_open}}
@verbatim|{
result_t rkt_webview_file_open(rktwebview_t w,
const char *title,
const char *base_dir,
const char *permitted_exts);
}|
Opens a file-open dialog.
The @tt{permitted_exts} argument is passed to Qt as a filter string using the
usual @tt{";;"} separator format.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} if the dialog was shown}
@item{@tt{failed} if the window handle is invalid}
]
On completion the callback receives one of these events:
@itemlist[#:style 'compact
@item{@tt{"file-open-ok"}}
@item{@tt{"file-open-cancel"}}
]
@subsection{@tt{rkt_webview_file_save}}
@verbatim|{
result_t rkt_webview_file_save(rktwebview_t w,
const char *title,
const char *base_dir,
const char *permitted_exts);
}|
Opens a file-save dialog.
The @tt{permitted_exts} argument is passed to Qt as a filter string using the
usual @tt{";;"} separator format.
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} if the dialog was shown}
@item{@tt{failed} if the window handle is invalid}
]
On completion the callback receives one of these events:
@itemlist[#:style 'compact
@item{@tt{"file-save-ok"}}
@item{@tt{"file-save-cancel"}}
]
@subsection{@tt{rkt_webview_message_box}}
@verbatim|{
result_t rkt_webview_message_box(rktwebview_t w,
const char *title,
const char *message,
const char *submessage,
rkt_messagetype_t type);
}|
Shows a native message box.
Arguments:
@itemlist[#:style 'compact
@item{@tt{title}: window title of the message box}
@item{@tt{message}: main message}
@item{@tt{submessage}: supplementary message text}
@item{@tt{type}: one of @tt{info}, @tt{error}, @tt{warning},
@tt{yes_no}, or @tt{oke_cancel}}
]
Returns:
@itemlist[#:style 'compact
@item{@tt{oke} if the dialog was shown}
@item{@tt{failed} if the window handle is invalid}
]
The callback receives one of the following events, depending on the chosen
button:
@itemlist[#:style 'compact
@item{@tt{"msgbox-ok"}}
@item{@tt{"msgbox-cancel"}}
@item{@tt{"msgbox-yes"}}
@item{@tt{"msgbox-no"}}
]
@section{Event Model}
The callback passed to @tt{rkt_webview_create} receives JSON-encoded events.
The implementation emits events such as:
@itemlist[#:style 'compact
@item{@tt{"show"}}
@item{@tt{"hide"}}
@item{@tt{"move"}}
@item{@tt{"resize"}}
@item{@tt{"closed"}}
@item{@tt{"can-close?"}}
@item{@tt{"page-loaded"}}
@item{@tt{"navigation-request"}}
@item{@tt{"link-hovered"}}
@item{@tt{"js-evt"}}
@item{dialog result events such as @tt{"choose-dir-ok"} and @tt{"msgbox-yes"}}
]
The precise JSON structure depends on the event kind. Examples include:
@itemlist[#:style 'compact
@item{@tt{"page-loaded"} with an @tt{"oke"} field}
@item{@tt{"move"} with @tt{"x"} and @tt{"y"}}
@item{@tt{"resize"} with @tt{"w"} and @tt{"h"}}
@item{@tt{"navigation-request"} with @tt{"url"} and @tt{"type"}}
@item{@tt{"link-hovered"} with @tt{"url"}}
@item{@tt{"js-evt"} with a nested @tt{"js-evt"} object containing the
original JavaScript payload}
]
@section{Typical Usage Pattern}
A typical embedding sequence is:
@itemlist[#:style 'compact
@item{Create a context with @tt{rkt_webview_new_context}.}
@item{Create a window with @tt{rkt_webview_create}.}
@item{Load content with @tt{rkt_webview_set_url} or @tt{rkt_webview_set_html}.}
@item{Interact with the page using @tt{rkt_webview_run_js} or
@tt{rkt_webview_call_js}.}
@item{Call @tt{rkt_webview_process_events} regularly to keep the UI alive.}
@item{Release all returned @tt{rkt_data_t *} values with
@tt{rkt_webview_free_data}.}
]