documentation

This commit is contained in:
2026-03-16 20:04:30 +01:00
parent a7257a3492
commit 7c3b780ae9
14 changed files with 2424 additions and 583 deletions

View File

@@ -0,0 +1,447 @@
#lang scribble/manual
@title{Racket FFI Interface for @tt{rktwebview_qt}}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
@section{Overview}
The module @tt{racket-webview-qt.rkt} provides a Racket FFI wrapper around the
native @tt{rktwebview_qt} library. It loads the shared library, initializes the
native runtime, and exposes Racket functions for creating and controlling
webview windows.
The wrapper translates the low-level C interface into a Racket-oriented API
based on structures, callbacks, and ordinary Racket values.
The module provides:
@itemlist[#:style 'compact
@item{creation of HTTP(S) contexts}
@item{creation and management of webview windows}
@item{navigation and HTML loading}
@item{JavaScript execution}
@item{window geometry and visibility control}
@item{native dialogs}
@item{asynchronous event delivery}
@item{version and cleanup utilities}
]
@section{Requirements}
The native backend requires Qt version @tt{6.10.2} or newer.
The shared library @tt{rktwebview_qt} must therefore be built against Qt
@tt{6.10.2} or a compatible later release.
Earlier Qt versions are not supported.
@section{Module Initialization}
Loading the module performs several initialization steps automatically.
@itemlist[#:style 'compact
@item{determines the operating system and architecture}
@item{sets Qt runtime environment variables}
@item{loads the @tt{rktwebview_qt} shared library}
@item{initializes the native runtime}
@item{starts a background thread that processes native events}
]
Currently the wrapper supports the following platforms:
@itemlist[#:style 'compact
@item{@tt{'linux}}
@item{@tt{'windows}}
]
If the current system is unsupported, loading the module raises an error.
@section{Data Model}
@subsection{The @tt{rkt-wv} Structure}
Each webview window is represented by a transparent Racket structure.
@defstruct*[rkt-wv
([win exact-integer?]
[evt-queue any/c]
[callback procedure?]
[valid boolean?]
[close-callback procedure?])]{
Represents a webview instance managed by the Racket wrapper.
Fields:
@itemlist[#:style 'compact
@item{@tt{win}: the native integer window handle}
@item{@tt{evt-queue}: internal queue of pending event strings}
@item{@tt{callback}: user event callback}
@item{@tt{valid}: mutable flag indicating whether the wrapper considers the
window active}
@item{@tt{close-callback}: procedure invoked when the window is closed}
]
Although the structure is transparent, user code should normally treat it as
an opaque handle.
}
@defproc[(rkt-wv-win [wv rkt-wv?]) exact-integer?]{
Returns the native window handle associated with @racket[wv].
}
@section{HTTP(S) Contexts}
A context represents the shared HTTP(S) environment used by webviews.
Contexts correspond to native WebEngine profiles and determine properties such
as:
@itemlist[#:style 'compact
@item{cookies and cache}
@item{injected JavaScript}
@item{trusted certificates}
]
@defproc[(rkt-webview-new-context
[boilerplate-js string?]
[server-cert bytes?])
exact-integer?]{
Creates a new HTTP(S) context and returns its native identifier.
Arguments:
@itemlist[#:style 'compact
@item{@racket[boilerplate-js]: JavaScript source injected into pages}
@item{@racket[server-cert]: optional certificate data}
]
The returned context identifier can be passed to
@racket[rkt-webview-create] to create webviews within that context.
}
@section{Creating Webviews}
@defproc[(rkt-webview-create
[context exact-integer?]
[parent (or/c #f rkt-wv?)]
[evt-callback (-> rkt-wv? string? any)]
[close-callback (-> any)])
rkt-wv?]{
Creates a new webview window in the given HTTP(S) context.
Arguments:
@itemlist[#:style 'compact
@item{@racket[context]: context identifier returned by
@racket[rkt-webview-new-context]}
@item{@racket[parent]: optional parent webview}
@item{@racket[evt-callback]: procedure invoked for each event}
@item{@racket[close-callback]: procedure invoked when the window is closed}
]
The result is a new @racket[rkt-wv] structure.
Events generated by the native layer are delivered asynchronously through
@racket[evt-callback].
}
@section{Window Lifecycle}
@defproc[(rkt-webview-close [wv rkt-wv?]) boolean?]{
Requests that the webview window be closed.
The wrapper forwards the request to the native backend and schedules cleanup of
the event-processing loop.
Returns @racket[#t].
}
@defproc[(rkt-webview-valid? [wv rkt-wv?]) boolean?]{
Returns whether the webview still exists.
The wrapper first checks its internal validity flag and then queries the native
runtime.
}
@defproc[(rkt-webview-exit) void?]{
Closes all webviews and stops the background event-processing thread.
This function is also registered with the Racket plumber so that cleanup occurs
automatically when the process exits.
}
@section{Window Configuration}
@defproc[(rkt-webview-set-title! [wv rkt-wv?] [title string?])
symbol?]{
Sets the native window title.
Returns a result symbol such as:
@itemlist[#:style 'compact
@item{@racket['oke]}
@item{@racket['failed]}
]
}
@defproc[(rkt-webview-set-ou-token [wv rkt-wv?] [token string?])
boolean?]{
Associates an Organizational Unit token with the window.
This token may be used by the native layer when accepting certain
self-signed certificates.
}
@section{Navigation}
@defproc[(rkt-webview-set-url! [wv rkt-wv?] [url string?]) symbol?]{
Navigates the webview to the given URL.
Returns a result symbol such as:
@itemlist[#:style 'compact
@item{@racket['oke]}
@item{@racket['set_navigate_failed]}
]
}
@defproc[(rkt-webview-set-html! [wv rkt-wv?] [html string?]) symbol?]{
Loads HTML directly into the webview.
Returns a result symbol such as:
@itemlist[#:style 'compact
@item{@racket['oke]}
@item{@racket['set_html_failed]}
]
}
@section{JavaScript Execution}
@defproc[(rkt-webview-run-js [wv rkt-wv?] [js string?]) symbol?]{
Executes JavaScript without returning a value.
Returns a result symbol such as:
@itemlist[#:style 'compact
@item{@racket['oke]}
@item{@racket['eval_js_failed]}
]
}
@defproc[(rkt-webview-call-js [wv rkt-wv?] [js string?])
(list/c symbol? string?)]{
Executes JavaScript and returns:
@racketblock[
(list result value)
]
where:
@itemlist[#:style 'compact
@item{@racket[result] is the native result code}
@item{@racket[value] is a JSON string containing the returned data}
]
The JSON structure is generated by the native backend.
}
@section{Window Geometry}
@defproc[(rkt-webview-move [wv rkt-wv?] [x exact-integer?] [y exact-integer?])
symbol?]{
Moves the webview window to the given screen coordinates.
}
@defproc[(rkt-webview-resize
[wv rkt-wv?]
[width exact-integer?]
[height exact-integer?])
symbol?]{
Resizes the window.
}
@defproc[(rkt-webview-show [wv rkt-wv?]) symbol?]{
Shows the window.
}
@defproc[(rkt-webview-hide [wv rkt-wv?]) symbol?]{
Hides the window.
}
@defproc[(rkt-webview-show-normal [wv rkt-wv?]) symbol?]{
Restores the window to its normal state.
}
@defproc[(rkt-webview-maximize [wv rkt-wv?]) symbol?]{
Maximizes the window.
}
@defproc[(rkt-webview-minimize [wv rkt-wv?]) symbol?]{
Minimizes the window.
}
@defproc[(rkt-webview-present [wv rkt-wv?]) symbol?]{
Requests that the window be presented to the user.
}
@defproc[(rkt-webview-window-state [wv rkt-wv?]) symbol?]{
Returns the current window state.
Possible results include:
@itemlist[#:style 'compact
@item{@racket['normal]}
@item{@racket['minimized]}
@item{@racket['maximized]}
@item{@racket['hidden]}
]
}
@section{Developer Tools}
@defproc[(rkt-webview-open-devtools [wv rkt-wv?]) symbol?]{
Opens the browser developer tools window.
}
@section{Native Dialogs}
Dialog functions return immediately with a status code.
The users choice is delivered asynchronously through the event callback.
@defproc[(rkt-webview-choose-dir
[wv rkt-wv?]
[title string?]
[base-dir string?])
symbol?]{
Requests a directory-selection dialog.
}
@defproc[(rkt-webview-file-open
[wv rkt-wv?]
[title string?]
[base-dir string?]
[extensions string?])
symbol?]{
Requests a file-open dialog.
}
@defproc[(rkt-webview-file-save
[wv rkt-wv?]
[title string?]
[base-dir string?]
[extensions string?])
symbol?]{
Requests a file-save dialog.
}
@defproc[(rkt-webview-messagebox
[wv rkt-wv?]
[title string?]
[message string?]
[submessage string?]
[type symbol?])
symbol?]{
Shows a native message box.
}
@section{Event Delivery}
Each webview has an associated event callback.
The callback has the form:
@racketblock[
(λ (wv event-json) ...)
]
Arguments:
@itemlist[#:style 'compact
@item{@racket[wv]: the webview handle}
@item{@racket[event-json]: JSON event string from the native backend}
]
Typical event types include:
@itemlist[#:style 'compact
@item{@tt{"show"}}
@item{@tt{"hide"}}
@item{@tt{"move"}}
@item{@tt{"resize"}}
@item{@tt{"closed"}}
@item{@tt{"page-loaded"}}
@item{@tt{"navigation-request"}}
@item{@tt{"js-evt"}}
]
The wrapper does not parse the JSON payload.
@section{Version Information}
@defproc[(rkt-webview-version)
(list/c list? list?)]{
Returns version information for the native backend.
Example result:
@racketblock[
(list
(list 'webview-c-api 1 0 0)
(list 'qt 6 10 2))
]
}
@section{Example}
@racketblock[
(define ctx
(rkt-webview-new-context "" #""))
(define wv
(rkt-webview-create
ctx
#f
(λ (wv evt)
(displayln evt))
(λ ()
(displayln "closed"))))
(rkt-webview-set-title! wv "Example")
(rkt-webview-set-url! wv "https://example.org")
]
@section{Summary}
The FFI module provides a thin Racket interface to the native
@tt{rktwebview_qt} backend.
Key characteristics:
@itemlist[#:style 'compact
@item{thin wrapper around the native C API}
@item{asynchronous event delivery}
@item{JSON-based event payloads}
@item{simple Racket structures for webviews}
]