libaura-webview: Webseiten in AURA
libs/aura-webview bringt das AURA-Element WebView: eine vollwertige Chromium-Seite im Szenengraph, über das Chromium Embedded Framework (CEF). Die Seite ist per Touch bedienbar und spricht über einen WebChannel mit dem C++-Code. Eigenes JavaScript lässt sich in jede Seite einschleusen.
WebView {
id: page
url: "https://example.org"
script: "document.addEventListener('DOMContentLoaded', () => { ... })"
size: parent.width - 48, parent.height - 104
}
Beispiel und Tests: tests/ui-webview/webview.aura und tests/test_webview.cpp.
Bauen
| Option | Bedeutung |
|---|---|
-DAURA_WITH_WEBVIEW=ON |
baut libaura-webview, verlinkt sie in aura-view und aura_webview_tests (Preset webview). Standard: OFF. |
-DAURA_CEF_ROOT=<dir> |
nimmt eine entpackte CEF-Distribution, statt sie herunterzuladen |
AURA_CEF_VERSION |
die CEF-Version (Standard 156.0.14, Chromium 156.0.8078.48) |
- Download: Ohne
AURA_CEF_ROOTlädt der Build die „minimal“-Distribution vom Spotify-CDN (cef-builds.spotifycdn.com): etwa 330 MB (x86_64) bzw. 430 MB (arm64). Die SHA1-Prüfsummen stehen incmake/Cef.cmake. - Cache: Zum Entwickeln einmal z. B. nach
~/.cache/aura/cef/laden und entpacken, dann-DAURA_CEF_ROOT=~/.cache/aura/cef/cef_binary_<version>_<platform>_minimal. - Wrapper:
libcef_dll_wrapper(die C++-API über der C-API vonlibcef.so) baut der Build aus den Quellen der Distribution, mit unserem Compiler. - Laufzeitverzeichnis:
build/<preset>/cef/enthältlibcef.so, die Ressourcen (*.pak,icudtl.dat,v8_context_snapshot.bin,locales/) als Symlinks und das Hilfsprogrammaura-webview-helper. Programme findenlibcef.soüber ihren rpath; zur Laufzeit lässt sich das Verzeichnis mitAURA_WEBVIEW_DIRumstellen.
Aufbau
| Teil | Aufgabe |
|---|---|
WebViewNode (aura/webview/webview.h) |
der Knoten: rendert die Seite, leitet Touch weiter, WebChannel, Skripte |
aura-webview-helper |
die CEF-Unterprozesse (Renderer, GPU, Netzwerk). Im Renderer richtet er window.aura ein und führt die Skripte aus. Das main() der Anwendung bleibt frei von CEF. |
aura::ui::registerElementType (aura/ui/elements.h) |
Elementtypen anderer Bibliotheken für den Loader. aura-ui hängt so nicht von CEF ab. |
aura::post() (aura/core/tasks.h) |
übergibt Arbeit thread-sicher an den UI-Thread. Die Schleife arbeitet sie vor jedem Frame ab, der aura-view-Server bei jeder Anfrage (aura::runPosted()). |
- Rendering: CEF rendert ohne Fenster in Software (
ozone-platform=headless, ohne GPU) in einen BGRA-Puffer. Der Knoten zeichnet ihn als Skia-Bild, darüber offene Auswahllisten (<select>). Ein X11- oder Wayland-Server ist nicht nötig, das passt zum Kiosk mit KMS/DRM. - Threads: CEF läuft mit eigener Nachrichtenschleife (
multi_threaded_message_loop). Ein neues Bild weckt die Anwendung (Application::wakeUp), undaura-viewmerkt es anframeCount(). - Start: CEF startet erst mit der ersten WebView, der Browser mit dem ersten Zeichnen: Erst dann kennt der Knoten seine Größe. Eine nie gezeigte WebView kostet nichts.
- Eingabe: Drücken, Ziehen und Loslassen gehen als Touch-Ereignisse an die Seite. Chromium macht daraus Tippen und Scrollen mit Schwung. Links mit
target=_blanköffnen in derselben Ansicht. - Cache: je Prozess ein eigenes Verzeichnis
/tmp/aura-webview-<pid>(mitcef.log), dasshutdown()löscht. Cookies und Daten bleiben nicht über einen Neustart.
WebChannel und Skripte
Jede Seite hat window.aura, schon bevor ihre eigenen Skripte laufen.
const sum = await aura.call("add", 2, 3); // JavaScript -> C++, Promise
aura.on("cart", (value) => render(value)); // C++ -> JavaScript
#include "aura/webview/webview.h"
dialog->page->handle("add", [](const auto& args) {
return AuraJson(args[0].toInt() + args[1].toInt());
});
dialog->page->emit("cart", {{"items", 3}});
dialog->page->runJavaScript("document.body.style.zoom = 1.2");
dialog->page->addUserScript("window.kiosk = true;");
- Werte: JSON (
AuraJson). Die Argumente vonaura.callkommen als Array. - Handler: Sie laufen auf dem UI-Thread und dürfen den Szenengraph und den App-Zustand anfassen. Eine Exception lehnt das Promise mit ihrer Meldung ab, ebenso ein unbekannter Name.
emit,runJavaScript: wirken auf die gerade geladene Seite, sonst passiert nichts.- Skripte:
addUserScript()undscript:in AURA laufen in jedem neuen Dokument der Ansicht, im Hauptframe, vor den Skripten der Seite. Wird ein Skript hinzugefügt oderscriptgeändert, läuft es auch gleich in der aktuellen Seite. Ein Fehler darin landet in der Konsole der Seite und hält die übrigen Skripte nicht auf. - Transport: CEFs Message-Router (
auraQuery) für Aufrufe,ExecuteJavaScriptfür Ereignisse, Prozess-Nachrichten für die Skriptlisten.
Anwendung
int main(int argc, char** argv)
{
// vor dem ersten UI-Aufbau: WebView für den Loader;
// locale: Sprache von Chromium (Standard en-US)
aura::webview::setup(argc, argv, {.locale = "de"});
...
aura::webview::shutdown(); // schließt alle Browser, beendet CEF
}
aura-view initialisiert CEF, wenn es mit WebView gebaut ist (aura::webview setzt dann das Präprozessor-Symbol AURA_WITH_WEBVIEW). Ohne die Bibliothek meldet der Loader „element type 'WebView' is not part of this program“ und nimmt die kompilierte Fassung. Eine Datei mit WebView lässt sich nur kompilieren, wenn das Programm aura::webview linkt.
Vorschau (aura-view, VS Code)
- Gebaut mit WebView:
aura-viewzeigt WebViews im Fenster, bei--renderund im Server. --render: wartet, bis die Seite 1,5 s lang nicht mehr neu gezeichnet hat (höchstens 20 s).- Server: Solange eine WebView offen ist, meldet er
animating, und die Erweiterung fragt etwa alle 33 ms nach einem Bild. Eine Antwort enthält nur dann ein PNG, wenn Chromium neu gezeichnet hat. - Bedienen: Ein Klick ist ein Tippen. Mit gedrückter Maus ziehen scrollt, dafür ist der Befehl
moveneu. Die Wiedergabe-Pause der Vorschau hält auch die Seite an. - Einstellung: Das
aura-viewder Vorschau (aura.preview.command) muss mit WebView gebaut sein.
Tests
aura_webview_tests (tests/test_webview.cpp, tests/ui-webview/webview.aura) baut einen Dialog mit WebView einmal kompiliert und einmal über den Loader. Er lädt eine data:-Seite, ohne Netz, und prüft:
- das Ergebnis von
aura.call, - Fehler und unbekannte Handler,
- das Skript aus AURA,
emitundrunJavaScript,- die Pixel der Seite im Knoten.
Laufzeit und Integration
- Das Zielsystem benötigt die Systembibliotheken der verwendeten CEF-Distribution sowie deren Ressourcen und Locales.
- Die Integration startet CEF derzeit mit
no_sandbox. Das muss bei der Auswahl und Einbindung von Webinhalten berücksichtigt werden. - Touch-Interaktion wird an Chromium weitergeleitet; Tastatur-, IME- und Skalierungsanforderungen sind für die konkrete Anwendung zu prüfen.
- Die CEF-Distribution enthält Chromium und weitere Drittkomponenten. Ihre Lizenzhinweise gehören zur Distribution; siehe Dependencies & Lizenzen.
docs/aura-webview.md · Markdown herunterladen