CEF: Remove jogl and jogamp deps by implementing a no-op renderer (#2095)

* CEF: Remove jogl and jogamp deps by implementing a no-op renderer

* Update readme
This commit is contained in:
Constantin Piber
2026-06-08 20:21:47 +02:00
committed by GitHub
parent 348d525b00
commit c81020dbb1
4 changed files with 25 additions and 16 deletions

View File

@@ -68,6 +68,7 @@ import org.cef.handler.CefLoadHandler
import org.cef.handler.CefLoadHandlerAdapter import org.cef.handler.CefLoadHandlerAdapter
import org.cef.handler.CefMessageRouterHandlerAdapter import org.cef.handler.CefMessageRouterHandlerAdapter
import org.cef.handler.CefPermissionHandler import org.cef.handler.CefPermissionHandler
import org.cef.handler.CefRenderHandlerAdapter
import org.cef.handler.CefRequestHandler import org.cef.handler.CefRequestHandler
import org.cef.handler.CefRequestHandlerAdapter import org.cef.handler.CefRequestHandlerAdapter
import org.cef.handler.CefResourceHandler import org.cef.handler.CefResourceHandler
@@ -82,10 +83,13 @@ import org.cef.network.CefPostDataElement
import org.cef.network.CefRequest import org.cef.network.CefRequest
import org.cef.network.CefResponse import org.cef.network.CefResponse
import org.koin.mp.KoinPlatformTools import org.koin.mp.KoinPlatformTools
import java.awt.Rectangle
import java.io.BufferedWriter import java.io.BufferedWriter
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.nio.ByteBuffer
import java.util.concurrent.Executor import java.util.concurrent.Executor
import javax.swing.JPanel
import kotlin.math.min import kotlin.math.min
import kotlin.reflect.KFunction import kotlin.reflect.KFunction
import kotlin.reflect.full.declaredMemberFunctions import kotlin.reflect.full.declaredMemberFunctions
@@ -97,6 +101,7 @@ class KcefWebViewProvider(
private val settings = KcefWebSettings() private val settings = KcefWebSettings()
private var viewClient = WebViewClient() private var viewClient = WebViewClient()
private var chromeClient = WebChromeClient() private var chromeClient = WebChromeClient()
private val renderHandler = RenderHandler()
private val mappings: MutableList<FunctionMapping> = mutableListOf() private val mappings: MutableList<FunctionMapping> = mutableListOf()
private val urlHttpMapping: MutableMap<String, String> = mutableMapOf() private val urlHttpMapping: MutableMap<String, String> = mutableMapOf()
private var initialRequestData: InitialRequestData? = null private var initialRequestData: InitialRequestData? = null
@@ -522,6 +527,21 @@ class KcefWebViewProvider(
} }
} }
private class RenderHandler : CefRenderHandlerAdapter() {
override fun getViewRect(browser: CefBrowser): Rectangle = Rectangle(0, 0, 1280, 2856)
override fun onPaint(
browser: CefBrowser,
popup: Boolean,
dirtyRects: Array<Rectangle>,
buffer: ByteBuffer,
width: Int,
height: Int,
) {
// do nothing
}
}
override fun init( override fun init(
javaScriptInterfaces: Map<String, Any>?, javaScriptInterfaces: Map<String, Any>?,
privateBrowsing: Boolean, privateBrowsing: Boolean,
@@ -617,7 +637,7 @@ class KcefWebViewProvider(
kcefClient!! kcefClient!!
.createBrowser( .createBrowser(
loadUrl, loadUrl,
CefRendering.OFFSCREEN, CefRendering.CefRenderingWithHandler(renderHandler, JPanel()),
false, false,
).apply { ).apply {
// NOTE: Without this, we don't seem to be receiving any events // NOTE: Without this, we don't seem to be receiving any events
@@ -642,7 +662,7 @@ class KcefWebViewProvider(
kcefClient!! kcefClient!!
.createBrowser( .createBrowser(
url, url,
CefRendering.OFFSCREEN, CefRendering.CefRenderingWithHandler(renderHandler, JPanel()),
false, false,
).apply { ).apply {
// NOTE: Without this, we don't seem to be receiving any events // NOTE: Without this, we don't seem to be receiving any events
@@ -676,7 +696,7 @@ class KcefWebViewProvider(
kcefClient!! kcefClient!!
.createBrowser( .createBrowser(
url, url,
CefRendering.OFFSCREEN, CefRendering.CefRenderingWithHandler(renderHandler, JPanel()),
false, false,
).apply { ).apply {
// NOTE: Without this, we don't seem to be receiving any events // NOTE: Without this, we don't seem to be receiving any events

View File

@@ -110,18 +110,13 @@ Download the latest `linux-x64`(x86_64) release from [the releases section](http
WebView support is implemented via [JCEF](https://github.com/JetBrains/jcef). WebView support is implemented via [JCEF](https://github.com/JetBrains/jcef).
This is optional, and is only necessary to support some extensions. This is optional, and is only necessary to support some extensions.
To have a functional WebView, several dependencies are required; aside from X11 libraries necessary for rendering Chromium, some JNI bindings are necessary: gluegen and jogl (found in Ubuntu as `libgluegen2-jni` and `libjogl2-jni`). To have a functional WebView, some X11 dependencies are required for rendering Chromium.
Note that on some systems (e.g. Ubuntu), the JNI libraries are not automatically found, see below. These include `libxrender`, `libxcomposite` `libxdamage`, `libxkbcommon` and `libxtst`.
A CEF server is launched on startup, which loads the X11 libraries. A CEF server is launched on startup, which loads the X11 libraries.
If those are missing, you should see "Could not load 'jcef' library". If those are missing, you should see "Could not load 'jcef' library".
If so, use `ldd ~/.local/share/Tachidesk/bin/kcef/libjcef.so | grep not` to figure out which libraries are not found on your system. If so, use `ldd ~/.local/share/Tachidesk/bin/kcef/libjcef.so | grep not` to figure out which libraries are not found on your system.
The JNI bindings are only loaded when a browser is actually launched.
This is done by extensions that rely on WebView, not by Suwayomi itself.
If there is a problem loading the JNI libraries, you should see a message indicating the library and the search path.
This search path includes the current working directory, if you do not want to modify system directories.
Refer to the [Dockerfile](https://github.com/Suwayomi/Suwayomi-Server-docker/blob/main/Dockerfile) for more details. Refer to the [Dockerfile](https://github.com/Suwayomi/Suwayomi-Server-docker/blob/main/Dockerfile) for more details.
Note that it is required to have an X session active and available to Suwayomi (i.e. `DISPLAY` is set). Note that it is required to have an X session active and available to Suwayomi (i.e. `DISPLAY` is set).

View File

@@ -158,8 +158,6 @@ cronUtils = "com.cronutils:cron-utils:9.2.1"
# Webview # Webview
jcef = { module = "org.jetbrains.intellij.deps.jcef:jcef", version.ref = "jcef" } jcef = { module = "org.jetbrains.intellij.deps.jcef:jcef", version.ref = "jcef" }
gluegen = "org.jogamp.gluegen:gluegen-rt:2.5.0"
jogl = "org.jogamp.jogl:jogl-all:2.5.0"
# User # User
jwt = "com.auth0:java-jwt:4.5.2" jwt = "com.auth0:java-jwt:4.5.2"

View File

@@ -37,10 +37,6 @@ dependencies {
implementation(libs.bundles.shared) implementation(libs.bundles.shared)
testImplementation(libs.bundles.sharedTest) testImplementation(libs.bundles.sharedTest)
// WebView
implementation(libs.gluegen)
implementation(libs.jogl)
// OkHttp // OkHttp
implementation(libs.bundles.okhttp) implementation(libs.bundles.okhttp)
implementation(libs.okio) implementation(libs.okio)