997 lines
20 KiB
Markdown
997 lines
20 KiB
Markdown
# Keluna
|
||
|
||
**Kotlin Embedded Local UI for Native Applications**
|
||
|
||
Keluna ist die Idee für ein leichtgewichtiges Framework zur Entwicklung nativer Desktop-Anwendungen für Linux, macOS und Windows mit **Kotlin/Native**.
|
||
|
||
Das Ziel ist eine Entwicklererfahrung ähnlich moderner Kotlin-UI-Frameworks, ohne dafür eine JVM, eine eigene Rendering-Engine oder einen mitgelieferten Browser zu benötigen.
|
||
|
||
Keluna kombiniert dafür drei grundlegende Konzepte:
|
||
|
||
- **Kotlin/Native** für Anwendungscode und Betriebssystemintegration
|
||
- ein **Vaadin-Flow-artiges Komponentenmodell** für die Beschreibung und Verwaltung der UI
|
||
- die vorhandene **System-WebView** des jeweiligen Betriebssystems als Rendering-Engine
|
||
|
||
Dadurch sollen kleine, schnell startende Desktop-Anwendungen entstehen, deren Anwendungscode nahezu vollständig in Kotlin geschrieben werden kann.
|
||
|
||
---
|
||
|
||
## Motivation
|
||
|
||
Für plattformübergreifende Desktop-Anwendungen existieren heute mehrere etablierte Ansätze.
|
||
|
||
### Electron
|
||
|
||
Electron bietet eine sehr komfortable Web-Entwicklungsumgebung, liefert jedoch Chromium und Node.js mit jeder Anwendung aus.
|
||
|
||
Selbst kleine Anwendungen erreichen dadurch schnell Größen von deutlich über 100 MB und benötigen vergleichsweise viel Arbeitsspeicher.
|
||
|
||
### Compose Multiplatform
|
||
|
||
Compose Multiplatform ermöglicht eine hervorragende Kotlin-Entwicklung, basiert auf dem Desktop jedoch auf der JVM und einer eigenen Rendering-Infrastruktur.
|
||
|
||
Dadurch entstehen ebenfalls relativ große Distributionen und zusätzliche Startkosten durch JVM und UI-Runtime.
|
||
|
||
### Tauri
|
||
|
||
Tauri vermeidet den eingebetteten Browser und verwendet stattdessen die WebView des Betriebssystems.
|
||
|
||
Dadurch können Anwendungen sehr klein bleiben.
|
||
|
||
Die typische Architektur besteht jedoch aus zwei Welten:
|
||
|
||
- TypeScript oder JavaScript für das Frontend
|
||
- Rust für den nativen Teil
|
||
|
||
### Qt
|
||
|
||
Qt ermöglicht kleine und schnelle Desktop-Anwendungen, verwendet traditionell jedoch C++.
|
||
|
||
Rust-Bindings verbessern diese Situation, dennoch bleibt Qt ein großes, eigenständiges UI-Ökosystem.
|
||
|
||
---
|
||
|
||
## Grundidee
|
||
|
||
Keluna soll einen anderen Weg gehen:
|
||
|
||
> Die Anwendung ist eine Kotlin/Native-Anwendung.
|
||
> Die System-WebView ist lediglich ihre Rendering-Engine.
|
||
|
||
Die Anwendung selbst lebt vollständig im nativen Kotlin-Prozess.
|
||
|
||
```text
|
||
┌──────────────────────────────────────────────┐
|
||
│ Kotlin/Native App │
|
||
│ │
|
||
│ Domain Model │
|
||
│ Application State │
|
||
│ Services │
|
||
│ UI Component Tree │
|
||
│ Event Handler │
|
||
│ OS Integration │
|
||
└─────────────────────┬────────────────────────┘
|
||
│
|
||
UI Synchronisation
|
||
│
|
||
kleines IPC-Protokoll
|
||
│
|
||
┌─────────────────────▼────────────────────────┐
|
||
│ JavaScript Runtime │
|
||
│ │
|
||
│ DOM Updates │
|
||
│ Event Forwarding │
|
||
│ Browser Interaction │
|
||
└─────────────────────┬────────────────────────┘
|
||
│
|
||
DOM
|
||
│
|
||
┌─────────────────────▼────────────────────────┐
|
||
│ System WebView │
|
||
│ │
|
||
│ Windows WebView2 │
|
||
│ macOS WKWebView │
|
||
│ Linux WebKitGTK │
|
||
└──────────────────────────────────────────────┘
|
||
```
|
||
|
||
Keluna bringt damit **keine eigene Browser-Engine** mit.
|
||
|
||
Ebenso benötigt Keluna:
|
||
|
||
- keine JVM
|
||
- kein Chromium-Bundle
|
||
- kein Node.js
|
||
- keine eigene GPU-Rendering-Engine
|
||
|
||
---
|
||
|
||
## Inspirationsquellen
|
||
|
||
Keluna kombiniert Ideen aus mehreren existierenden Frameworks, ohne eines davon direkt nachzubauen.
|
||
|
||
### Kotlin und Compose
|
||
|
||
Von Kotlin und Compose übernimmt Keluna vor allem die gewünschte Entwicklerergonomie:
|
||
|
||
- typsichere APIs
|
||
- Kotlin DSLs
|
||
- Properties und State
|
||
- deklarative UI-Beschreibung
|
||
- gute Integration mit Coroutines
|
||
- Gradle als Build-System
|
||
|
||
Ein Keluna-Programm könnte beispielsweise konzeptionell so aussehen:
|
||
|
||
```kotlin
|
||
window("Keluna Demo") {
|
||
verticalLayout {
|
||
textField("Repository")
|
||
|
||
button("Open") {
|
||
openRepository()
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
Die genaue API ist dabei noch offen.
|
||
|
||
Wichtig ist das Prinzip:
|
||
|
||
**Der Anwendungsentwickler soll möglichst ausschließlich Kotlin sehen.**
|
||
|
||
### Vaadin Flow
|
||
|
||
Von Vaadin Flow übernimmt Keluna die Idee eines **serverseitigen Komponentenbaums**.
|
||
|
||
Bei Vaadin existieren Komponenten als Java-Objekte auf dem Server. Änderungen an diesen Objekten werden mit dem DOM im Browser synchronisiert.
|
||
|
||
Keluna verwendet ein ähnliches Modell, jedoch ohne Netzwerk.
|
||
|
||
Bei einer Desktop-Anwendung befinden sich beide Seiten lokal:
|
||
|
||
```text
|
||
Vaadin Flow
|
||
|
||
Java Server
|
||
│
|
||
│ HTTP / WebSocket
|
||
▼
|
||
Browser
|
||
```
|
||
|
||
Keluna reduziert dieses Modell auf:
|
||
|
||
```text
|
||
Kotlin/Native
|
||
│
|
||
│ lokale WebView Bridge
|
||
▼
|
||
System WebView
|
||
```
|
||
|
||
Dadurch entfallen große Teile der Komplexität von Vaadin:
|
||
|
||
- HTTP
|
||
- WebSocket
|
||
- Sessions
|
||
- Reconnect
|
||
- Authentication zwischen Client und Server
|
||
- Netzwerk-Retry
|
||
- Cluster-Synchronisation
|
||
|
||
Übrig bleibt im Wesentlichen:
|
||
|
||
```text
|
||
Component Tree
|
||
│
|
||
▼
|
||
DOM Patch
|
||
│
|
||
▼
|
||
WebView
|
||
|
||
WebView
|
||
│
|
||
▼
|
||
Event
|
||
│
|
||
▼
|
||
Kotlin Handler
|
||
```
|
||
|
||
### Tauri
|
||
|
||
Von Tauri übernimmt Keluna vor allem das Prinzip:
|
||
|
||
> Nutze die Browser-Engine, die das Betriebssystem ohnehin bereitstellt.
|
||
|
||
Keluna verwendet deshalb unterschiedliche WebView-Implementierungen:
|
||
|
||
| Plattform | WebView |
|
||
|---|---|
|
||
| Windows | WebView2 |
|
||
| macOS | WKWebView |
|
||
| Linux | WebKitGTK |
|
||
|
||
Die WebView ist dabei kein eigenständiger Anwendungsteil.
|
||
|
||
Sie ist lediglich der Renderer für:
|
||
|
||
- HTML
|
||
- CSS
|
||
- Text
|
||
- Layout
|
||
- Form Controls
|
||
- SVG
|
||
- Animationen
|
||
|
||
---
|
||
|
||
## Architektur
|
||
|
||
Keluna könnte zunächst aus sechs grundlegenden Bereichen bestehen.
|
||
|
||
```text
|
||
keluna-core
|
||
keluna-ui
|
||
keluna-runtime
|
||
keluna-web
|
||
keluna-platform
|
||
keluna-components
|
||
```
|
||
|
||
### `keluna-core`
|
||
|
||
Enthält grundlegende Framework-Abstraktionen.
|
||
|
||
Beispielsweise:
|
||
|
||
```text
|
||
Component
|
||
Element
|
||
Property
|
||
State
|
||
Event
|
||
StateTree
|
||
```
|
||
|
||
Dieses Modul sollte weitgehend unabhängig von den konkreten Plattformen sein.
|
||
|
||
### `keluna-ui`
|
||
|
||
Enthält die Kotlin-API zur Beschreibung der Benutzeroberfläche.
|
||
|
||
Beispielsweise:
|
||
|
||
```text
|
||
Window
|
||
Layout
|
||
Button
|
||
TextField
|
||
Checkbox
|
||
Select
|
||
Table
|
||
Dialog
|
||
Tabs
|
||
Menu
|
||
```
|
||
|
||
Darauf baut die Kotlin-DSL auf.
|
||
|
||
### `keluna-runtime`
|
||
|
||
Verwaltet den Komponentenbaum und den Anwendungszustand.
|
||
|
||
Aufgaben sind unter anderem:
|
||
|
||
- Component Lifecycle
|
||
- State Management
|
||
- Event Dispatching
|
||
- Erkennung von Änderungen
|
||
- Erzeugung von DOM-Patches
|
||
- Synchronisation mit der WebView
|
||
|
||
### `keluna-web`
|
||
|
||
Enthält die kleine JavaScript-Runtime innerhalb der WebView.
|
||
|
||
Diese Runtime sollte bewusst minimal bleiben.
|
||
|
||
Ihre Aufgaben:
|
||
|
||
- DOM-Elemente erzeugen
|
||
- DOM-Properties ändern
|
||
- Elemente entfernen
|
||
- Events registrieren
|
||
- relevante Browser-Events an Kotlin weiterleiten
|
||
|
||
Beispielsweise könnte Kotlin intern folgende Instruktion erzeugen:
|
||
|
||
```json
|
||
{
|
||
"op": "set",
|
||
"node": 17,
|
||
"property": "textContent",
|
||
"value": "Open"
|
||
}
|
||
```
|
||
|
||
Oder:
|
||
|
||
```json
|
||
{
|
||
"op": "append",
|
||
"parent": 3,
|
||
"node": 17
|
||
}
|
||
```
|
||
|
||
Ein Klick könnte in Gegenrichtung übertragen werden:
|
||
|
||
```json
|
||
{
|
||
"node": 17,
|
||
"event": "click"
|
||
}
|
||
```
|
||
|
||
Das Protokoll sollte später vermutlich kompakter sein als JSON.
|
||
|
||
Für einen ersten Prototyp wäre JSON jedoch ideal.
|
||
|
||
---
|
||
|
||
## Plattform-Layer
|
||
|
||
Keluna benötigt für jedes Betriebssystem einen sehr kleinen nativen Adapter.
|
||
|
||
```text
|
||
keluna-platform
|
||
│
|
||
├── linux
|
||
│ ├── GTK
|
||
│ └── WebKitGTK
|
||
│
|
||
├── macos
|
||
│ ├── Cocoa
|
||
│ └── WKWebView
|
||
│
|
||
└── windows
|
||
├── Win32
|
||
└── WebView2
|
||
```
|
||
|
||
Die gemeinsame API könnte beispielsweise Funktionen bereitstellen wie:
|
||
|
||
```text
|
||
createWindow()
|
||
loadResource()
|
||
evaluateJavaScript()
|
||
receiveMessage()
|
||
showFileDialog()
|
||
setClipboard()
|
||
showNotification()
|
||
```
|
||
|
||
Die Anwendung selbst soll diese Plattformunterschiede normalerweise nicht sehen.
|
||
|
||
---
|
||
|
||
## Native Desktop-Funktionen
|
||
|
||
Keluna soll nicht nur eine Web-Anwendung in einem Fenster darstellen.
|
||
|
||
Der Kotlin-Prozess besitzt direkten Zugriff auf das Betriebssystem.
|
||
|
||
Dadurch können Anwendungen beispielsweise folgende Funktionen nutzen:
|
||
|
||
- Dateisystemzugriff
|
||
- native File Dialogs
|
||
- Clipboard
|
||
- Drag & Drop
|
||
- Notifications
|
||
- System Tray
|
||
- Menüleiste
|
||
- Prozesse starten
|
||
- lokale Sockets
|
||
- Git
|
||
- Credential Stores
|
||
- Betriebssysteminformationen
|
||
|
||
Diese Funktionen können als Kotlin-APIs bereitgestellt werden.
|
||
|
||
```text
|
||
Keluna Application
|
||
│
|
||
├── UI
|
||
│
|
||
├── Files
|
||
├── Process
|
||
├── Clipboard
|
||
├── Notifications
|
||
├── Dialogs
|
||
└── Platform APIs
|
||
```
|
||
|
||
---
|
||
|
||
## Verantwortlichkeit zwischen Kotlin und WebView
|
||
|
||
Nicht jede UI-Interaktion sollte den Kotlin-Prozess erreichen.
|
||
|
||
Lokale Browserfunktionen sollten möglichst lokal bleiben.
|
||
|
||
### WebView
|
||
|
||
Die WebView übernimmt beispielsweise:
|
||
|
||
- Hover
|
||
- CSS
|
||
- Animationen
|
||
- Scrolling
|
||
- Text Selection
|
||
- Focus-Darstellung
|
||
- Cursor
|
||
- einfache visuelle Interaktionen
|
||
|
||
### Kotlin
|
||
|
||
Kotlin übernimmt:
|
||
|
||
- Application State
|
||
- Navigation
|
||
- Business Logic
|
||
- Commands
|
||
- persistente UI-Zustände
|
||
- Dateisystem
|
||
- Prozesse
|
||
- Netzwerk
|
||
- Git
|
||
- Betriebssystemintegration
|
||
|
||
Dadurch bleibt die IPC-Schicht klein.
|
||
|
||
---
|
||
|
||
## State und Synchronisation
|
||
|
||
Der zentrale Bestandteil von Keluna wäre ein State Tree ähnlich dem Komponentenmodell von Vaadin Flow.
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
Window #1
|
||
└── VerticalLayout #2
|
||
├── TextField #3
|
||
├── Button #4
|
||
└── Label #5
|
||
```
|
||
|
||
Jede Komponente besitzt eine interne ID.
|
||
|
||
Ändert Kotlin beispielsweise:
|
||
|
||
```text
|
||
Label #5
|
||
"Ready"
|
||
↓
|
||
"Loading..."
|
||
```
|
||
|
||
muss lediglich folgende Änderung an die WebView übertragen werden:
|
||
|
||
```text
|
||
SET #5 textContent "Loading..."
|
||
```
|
||
|
||
Es wird nicht die gesamte Benutzeroberfläche neu aufgebaut.
|
||
|
||
---
|
||
|
||
## Event-Modell
|
||
|
||
Events laufen in Gegenrichtung.
|
||
|
||
Beispielsweise:
|
||
|
||
```text
|
||
WebView
|
||
Button #4 clicked
|
||
│
|
||
▼
|
||
IPC
|
||
│
|
||
▼
|
||
Keluna Runtime
|
||
│
|
||
▼
|
||
Kotlin callback
|
||
```
|
||
|
||
In der Anwendung könnte das beispielsweise so aussehen:
|
||
|
||
```kotlin
|
||
button("Open") {
|
||
openProject()
|
||
}
|
||
```
|
||
|
||
Keluna registriert intern lediglich:
|
||
|
||
```text
|
||
#4 → click → callback
|
||
```
|
||
|
||
---
|
||
|
||
## HTML und CSS
|
||
|
||
HTML und CSS sind Implementierungsdetails der Rendering-Schicht.
|
||
|
||
Der Entwickler muss sie nicht zwingend direkt verwenden.
|
||
|
||
Für fortgeschrittene Anwendungen sollte Keluna sie jedoch nicht verstecken.
|
||
|
||
Denkbar wären deshalb mehrere Ebenen:
|
||
|
||
```text
|
||
High Level
|
||
Keluna Components
|
||
|
||
↓
|
||
|
||
Keluna Element API
|
||
|
||
↓
|
||
|
||
HTML / CSS
|
||
|
||
↓
|
||
|
||
System WebView
|
||
```
|
||
|
||
Dadurch könnten Entwickler bei Bedarf eigene Web Components oder CSS einbinden.
|
||
|
||
---
|
||
|
||
## Custom Components
|
||
|
||
Neben Standardkomponenten sollte Keluna eigene Komponenten erlauben.
|
||
|
||
Beispielsweise:
|
||
|
||
```text
|
||
Graph
|
||
CodeEditor
|
||
Tree
|
||
MarkdownViewer
|
||
Terminal
|
||
Diagram
|
||
```
|
||
|
||
Solche Komponenten könnten aus:
|
||
|
||
- Kotlin
|
||
- HTML
|
||
- CSS
|
||
- etwas JavaScript
|
||
|
||
bestehen.
|
||
|
||
Für Spezialfälle könnte auch eine bestehende JavaScript-Komponente eingebettet werden.
|
||
|
||
Keluna soll JavaScript also nicht verbieten.
|
||
|
||
Es soll lediglich **für normale Anwendungsentwicklung nicht notwendig sein**.
|
||
|
||
---
|
||
|
||
## Packaging
|
||
|
||
Ein wichtiges Ziel von Keluna ist eine kleine Distribution.
|
||
|
||
Eine Anwendung besteht im Wesentlichen aus:
|
||
|
||
```text
|
||
Kotlin/Native executable
|
||
+
|
||
Keluna runtime
|
||
+
|
||
HTML/CSS/JS resources
|
||
```
|
||
|
||
Die Browser-Engine wird nicht mitgeliefert.
|
||
|
||
Auf den Plattformen wird stattdessen verwendet:
|
||
|
||
```text
|
||
Windows → WebView2
|
||
macOS → WKWebView
|
||
Linux → WebKitGTK
|
||
```
|
||
|
||
Unter Linux würden GTK und WebKitGTK typischerweise Paketabhängigkeiten darstellen.
|
||
|
||
Ein Debian-Paket könnte beispielsweise von diesen Systembibliotheken abhängen, anstatt sie selbst mitzubringen.
|
||
|
||
Dadurch sollte eine einfache Keluna-Anwendung potenziell im Bereich von **wenigen Megabyte bis niedrigen zweistelligen Megabyte** bleiben können.
|
||
|
||
Die tatsächliche Größe müsste durch einen Prototyp überprüft werden.
|
||
|
||
---
|
||
|
||
## Startzeit
|
||
|
||
Keluna benötigt:
|
||
|
||
- keine JVM-Initialisierung
|
||
- keinen Node-Prozess
|
||
- keinen Start eines eingebetteten Chromium
|
||
- keine eigene Grafik-Runtime
|
||
|
||
Der native Prozess startet lediglich die vorhandene WebView und lädt lokale Ressourcen.
|
||
|
||
Damit sollte die Startzeit eher in der Größenordnung kleiner nativer Anwendungen bzw. Tauri-Anwendungen liegen als bei Compose Desktop oder Electron.
|
||
|
||
Auch dies müsste frühzeitig durch einen Proof of Concept gemessen werden.
|
||
|
||
---
|
||
|
||
## Ziele
|
||
|
||
Keluna soll:
|
||
|
||
- Desktop-Anwendungen vollständig oder nahezu vollständig in Kotlin ermöglichen
|
||
- Kotlin/Native verwenden
|
||
- Linux, macOS und Windows unterstützen
|
||
- kleine Distributionen erzeugen
|
||
- schnell starten
|
||
- die vorhandene System-WebView verwenden
|
||
- keine eigene Rendering-Engine benötigen
|
||
- keinen Webserver starten
|
||
- keine JVM voraussetzen
|
||
- keine JavaScript-Anwendungsarchitektur erzwingen
|
||
- sich natürlich in Gradle und Kotlin Multiplatform integrieren
|
||
|
||
---
|
||
|
||
## Nicht-Ziele
|
||
|
||
Keluna soll zunächst ausdrücklich **kein**:
|
||
|
||
- Browser-Webframework
|
||
- Mobile-Framework
|
||
- eigener Browser
|
||
- eigener HTML-Renderer
|
||
- eigener GPU-Renderer
|
||
- Electron-Ersatz mit eingebettetem Chromium
|
||
- vollständiges Vaadin-Flow-Reimplementation
|
||
|
||
sein.
|
||
|
||
Ebenso sollte Keluna nicht versuchen, von Anfang an hunderte UI-Komponenten bereitzustellen.
|
||
|
||
---
|
||
|
||
## Ein mögliches MVP
|
||
|
||
Ein erster Proof of Concept benötigt überraschend wenig.
|
||
|
||
### Phase 1 – WebView
|
||
|
||
Für eine Plattform, beispielsweise Linux:
|
||
|
||
- Kotlin/Native Executable
|
||
- GTK-Fenster
|
||
- WebKitGTK-WebView
|
||
- lokale `index.html` laden
|
||
- JavaScript aus Kotlin aufrufen
|
||
- Nachricht von JavaScript an Kotlin senden
|
||
|
||
Damit wäre die technische Grundlage bewiesen.
|
||
|
||
### Phase 2 – Element Tree
|
||
|
||
Ein einfacher Kotlin-Elementbaum:
|
||
|
||
```text
|
||
Window
|
||
Column
|
||
Text
|
||
Button
|
||
```
|
||
|
||
Dieser erzeugt DOM-Strukturen.
|
||
|
||
### Phase 3 – Events
|
||
|
||
Browser-Events werden an Kotlin übertragen:
|
||
|
||
```text
|
||
click
|
||
change
|
||
input
|
||
keydown
|
||
```
|
||
|
||
### Phase 4 – State Synchronisation
|
||
|
||
Änderungen im Kotlin-Component-Tree erzeugen nur noch inkrementelle DOM-Patches.
|
||
|
||
### Phase 5 – weitere Plattformen
|
||
|
||
Implementierung von:
|
||
|
||
- WKWebView für macOS
|
||
- WebView2 für Windows
|
||
|
||
### Phase 6 – Desktop APIs
|
||
|
||
Erste native Funktionen:
|
||
|
||
- File Picker
|
||
- Clipboard
|
||
- Notifications
|
||
- Prozessstart
|
||
|
||
---
|
||
|
||
## Mögliche Modulstruktur
|
||
|
||
```text
|
||
keluna/
|
||
├── keluna-core
|
||
├── keluna-ui
|
||
├── keluna-runtime
|
||
├── keluna-components
|
||
├── keluna-web-runtime
|
||
├── keluna-platform-linux
|
||
├── keluna-platform-macos
|
||
├── keluna-platform-windows
|
||
└── keluna-gradle-plugin
|
||
```
|
||
|
||
Eine Anwendung könnte anschließend beispielsweise nur benötigen:
|
||
|
||
```text
|
||
keluna-core
|
||
keluna-components
|
||
keluna-platform
|
||
```
|
||
|
||
---
|
||
|
||
## Gradle-Integration
|
||
|
||
Langfristig sollte eine Keluna-Anwendung über ein Gradle-Plugin konfiguriert werden können.
|
||
|
||
Konzeptionell:
|
||
|
||
```kotlin
|
||
plugins {
|
||
kotlin("multiplatform")
|
||
id("dev.keluna.application")
|
||
}
|
||
|
||
keluna {
|
||
applicationName = "My Application"
|
||
mainClass = "MainKt"
|
||
}
|
||
```
|
||
|
||
Das Plugin könnte anschließend:
|
||
|
||
- Kotlin/Native Targets konfigurieren
|
||
- Web-Ressourcen bündeln
|
||
- native Abhängigkeiten konfigurieren
|
||
- Installer erzeugen
|
||
- Signing vorbereiten
|
||
- Plattformpakete bauen
|
||
|
||
---
|
||
|
||
## Entwicklungsmodell
|
||
|
||
Keluna könnte zwei Ebenen anbieten.
|
||
|
||
### High-Level
|
||
|
||
Für normale Anwendungen:
|
||
|
||
```text
|
||
Keluna Components
|
||
+
|
||
Kotlin State
|
||
+
|
||
Kotlin Event Handler
|
||
```
|
||
|
||
Der Entwickler benötigt keine Webkenntnisse.
|
||
|
||
### Low-Level
|
||
|
||
Für Spezialkomponenten:
|
||
|
||
```text
|
||
DOM
|
||
CSS
|
||
JavaScript
|
||
Web Components
|
||
```
|
||
|
||
Dadurch bleibt das Framework offen.
|
||
|
||
Eine komplexe Komponente wie ein Code-Editor könnte beispielsweise intern Monaco oder CodeMirror verwenden, während die restliche Anwendung vollständig in Kotlin bleibt.
|
||
|
||
---
|
||
|
||
## Designprinzipien
|
||
|
||
### Kotlin first
|
||
|
||
Die öffentliche API wird für Kotlin entworfen und nicht aus einer anderen Sprache übernommen.
|
||
|
||
### Native application first
|
||
|
||
Keluna ist kein Webframework, das zufällig Desktop-Fenster erzeugt.
|
||
|
||
Es ist ein Desktop-Framework, das Web-Technologie zum Rendern verwendet.
|
||
|
||
### System WebView instead of bundled browser
|
||
|
||
Der größte Baustein vieler Desktop-Webframeworks wird bewusst nicht ausgeliefert.
|
||
|
||
### Thin client
|
||
|
||
Die JavaScript-Runtime sollte möglichst klein und weitgehend zustandslos bleiben.
|
||
|
||
### Escape hatches
|
||
|
||
HTML, CSS und JavaScript bleiben erreichbar, wenn eine Anwendung sie benötigt.
|
||
|
||
### Incremental adoption
|
||
|
||
Eine Anwendung sollte mit wenigen Standardkomponenten beginnen können und später komplexere eigene Komponenten hinzufügen können.
|
||
|
||
### Measure early
|
||
|
||
Binary-Größe, RAM-Verbrauch und Startzeit sind zentrale Eigenschaften des Projekts und sollten von Anfang an automatisiert gemessen werden.
|
||
|
||
---
|
||
|
||
## Risiken
|
||
|
||
### Unterschiedliche WebView-Engines
|
||
|
||
Windows verwendet Chromium über WebView2.
|
||
|
||
macOS und Linux verwenden WebKit.
|
||
|
||
Dadurch können Unterschiede bei:
|
||
|
||
- CSS
|
||
- JavaScript
|
||
- Web APIs
|
||
- Rendering
|
||
|
||
auftreten.
|
||
|
||
Keluna sollte deshalb bewusst nur auf gut unterstützte Webstandards setzen.
|
||
|
||
### Linux-Abhängigkeiten
|
||
|
||
Linux besitzt keine so klar definierte System-WebView wie macOS.
|
||
|
||
WebKitGTK und GTK müssen auf dem Zielsystem vorhanden sein.
|
||
|
||
Distribution und Packaging müssen deshalb früh untersucht werden.
|
||
|
||
### Kotlin/Native Interop
|
||
|
||
Die Plattformadapter benötigen Interop mit:
|
||
|
||
- Win32 und COM
|
||
- Cocoa/Objective-C
|
||
- GTK und WebKitGTK
|
||
|
||
Dieser Bereich dürfte einer der technisch anspruchsvollsten Teile des Frameworks sein.
|
||
|
||
Er bleibt jedoch innerhalb des Frameworks verborgen und betrifft nicht den normalen Anwendungsentwickler.
|
||
|
||
### UI-State-Komplexität
|
||
|
||
Ein nativer Komponentenbaum klingt zunächst einfach.
|
||
|
||
Komplexität entsteht jedoch bei:
|
||
|
||
- Textfeldern während der Eingabe
|
||
- Selection
|
||
- Focus
|
||
- Cursorpositionen
|
||
- Drag & Drop
|
||
- großen Tabellen
|
||
- virtuellen Listen
|
||
|
||
Keluna sollte deshalb nicht versuchen, jeden Browserzustand permanent nach Kotlin zu spiegeln.
|
||
|
||
---
|
||
|
||
## Langfristige Perspektive
|
||
|
||
Keluna könnte langfristig drei Ebenen bilden:
|
||
|
||
```text
|
||
Keluna
|
||
│
|
||
┌───────────┴───────────┐
|
||
│ │
|
||
Kotlin Components Custom Components
|
||
│ │
|
||
└───────────┬───────────┘
|
||
│
|
||
Component Tree
|
||
│
|
||
Keluna Runtime
|
||
│
|
||
WebView
|
||
│
|
||
Native Platform
|
||
```
|
||
|
||
Damit entsteht ein ungewöhnliches Desktop-Modell:
|
||
|
||
> **Native application logic with web-based rendering, without turning the application itself into a web application.**
|
||
|
||
---
|
||
|
||
## Zusammenfassung
|
||
|
||
Keluna kombiniert drei bewährte Ideen:
|
||
|
||
### Kotlin/Native
|
||
|
||
für:
|
||
|
||
- Anwendungscode
|
||
- Domain-Logik
|
||
- State
|
||
- Betriebssystemzugriffe
|
||
|
||
### Vaadin-Flow-artiges Komponentenmodell
|
||
|
||
für:
|
||
|
||
- Component Tree
|
||
- Properties
|
||
- Events
|
||
- inkrementelle UI-Synchronisation
|
||
|
||
### Tauri-artige System-WebView-Nutzung
|
||
|
||
für:
|
||
|
||
- kleines Packaging
|
||
- schnelles Startup
|
||
- HTML/CSS-Rendering ohne eingebettetes Chromium
|
||
|
||
Das Ziel ist eine Desktop-Anwendung, die sich für den Entwickler wie eine normale Kotlin-Anwendung anfühlt:
|
||
|
||
```text
|
||
Kotlin
|
||
↓
|
||
Keluna
|
||
↓
|
||
System WebView
|
||
↓
|
||
Native Desktop
|
||
```
|
||
|
||
Der Browser ist dabei kein Teil der Anwendungsarchitektur.
|
||
|
||
Er ist lediglich der Renderer.
|
||
|
||
**Keluna – Kotlin Embedded Local UI for Native Applications.**
|