Files
racket-webview/scrbl/rktwebview-api.scrbl

708 lines
18 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 initialization and event processing, version and memory-management utility
functions, http(s)-context management, window management, navigation and content loading,
JavaScript execution and native dialogs.
@section{Basic Types}
@subsection{Window and Context Handles}
The API uses integer handles for windows and contexts.A value of type @tt{rktwebview_t} identifies
a single webview window and of type @tt{rkt_wv_context_t} identifies a http(s) context. Both
are typedefs of @tt{int}.
@subsection{Returned data, data for events and resultcodes}
The following type is used for communication of data, version information and events.
All possible data that is communicated is assembled in this one type that will be
allocated by the API and must be released by the API user, using a call to
@tt{rkt_webview_free_data()}.
@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. A version field
is a struct of integer numbers:
@verbatim|{
typedef struct {
int qt_major;
int qt_minor;
int qt_patch;
int api_major;
int api_minor;
int api_patch;
} rkt_version_t;
}|
Events are always for webview windows and consist of the webview handle along with
an event. This event is always a Utf-8 JSON string. In this JSON string, the @tt{"event"}}
item holds the name of the event that is triggered.
@verbatim|{
typedef struct {
rktwebview_t wv;
char *event;
} rkt_event_t;
}|
Returned data (mostly as a result of Javascript calls) consists of a result code and
a JSON encoded value. See following struct.
@verbatim|{
typedef struct {
result_t result;
char *value;
} rkt_js_result_t;
}|
Many functions return a value of type @tt{result_t}. The possible enumeration values
can be found in @tt{rktwebview.h}. Most important are the values @tt{no_result_yet}, which
is for internal use and equals @tt{-1}; @tt{oke = 0}, which tells that everything went alright,
and all values @tt{>0} indicate some kind of failure.
@subsection{Window state}
Window state is represented by @tt{window_state_t}. The following values are used:
@tt{invalid = -1}, represents an invalid window state, @tt{normal = 0x00} and @tt{normal_active = 0x10},
window shown in normal state (0x00). All windows that are active, i.e. have focus for user input, will
have bit 5 set to 1. Other states: @tt{minimized = 0x01}, @tt{maximized = 0x02} or @tt{0x12},
@tt{hidden = 0x03}.
@subsection{Messagebox types}
Message boxes use the type @tt{rkt_messagetype_t} to indicate the type of message to present:
@tt{info = 1} for information, @tt{error = 2} for error messages, @tt{warning = 3} for warnings,
@tt{yes_no = 4} for questions that can be answered by 'yes' or 'no' and @tt{oke_cancel} for messages
that can be answered by 'oke' or 'cancel'.
@subsection{Callback functions for events}
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 management}
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}.}
]