Compare commits

..

2 Commits

Author SHA1 Message Date
schroda
8fbc8fd3d4 Fix automatic chapter downloads (#2098)
The returned result rows of the inserted chapters did not have the up-to-date "last_modified_at".
This caused "downloadNewChapters" to not be able to correctly detect unread chapters. it included the newly inserted ones, leading to exiting early due to having unread chapters.

Regression 811e15162b

fixes #2097
2026-06-08 14:21:57 -04:00
Constantin Piber
c81020dbb1 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
2026-06-08 14:21:47 -04:00
5 changed files with 34 additions and 18 deletions

View File

@@ -68,6 +68,7 @@ import org.cef.handler.CefLoadHandler
import org.cef.handler.CefLoadHandlerAdapter
import org.cef.handler.CefMessageRouterHandlerAdapter
import org.cef.handler.CefPermissionHandler
import org.cef.handler.CefRenderHandlerAdapter
import org.cef.handler.CefRequestHandler
import org.cef.handler.CefRequestHandlerAdapter
import org.cef.handler.CefResourceHandler
@@ -82,10 +83,13 @@ import org.cef.network.CefPostDataElement
import org.cef.network.CefRequest
import org.cef.network.CefResponse
import org.koin.mp.KoinPlatformTools
import java.awt.Rectangle
import java.io.BufferedWriter
import java.io.File
import java.io.IOException
import java.nio.ByteBuffer
import java.util.concurrent.Executor
import javax.swing.JPanel
import kotlin.math.min
import kotlin.reflect.KFunction
import kotlin.reflect.full.declaredMemberFunctions
@@ -97,6 +101,7 @@ class KcefWebViewProvider(
private val settings = KcefWebSettings()
private var viewClient = WebViewClient()
private var chromeClient = WebChromeClient()
private val renderHandler = RenderHandler()
private val mappings: MutableList<FunctionMapping> = mutableListOf()
private val urlHttpMapping: MutableMap<String, String> = mutableMapOf()
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(
javaScriptInterfaces: Map<String, Any>?,
privateBrowsing: Boolean,
@@ -617,7 +637,7 @@ class KcefWebViewProvider(
kcefClient!!
.createBrowser(
loadUrl,
CefRendering.OFFSCREEN,
CefRendering.CefRenderingWithHandler(renderHandler, JPanel()),
false,
).apply {
// NOTE: Without this, we don't seem to be receiving any events
@@ -642,7 +662,7 @@ class KcefWebViewProvider(
kcefClient!!
.createBrowser(
url,
CefRendering.OFFSCREEN,
CefRendering.CefRenderingWithHandler(renderHandler, JPanel()),
false,
).apply {
// NOTE: Without this, we don't seem to be receiving any events
@@ -676,7 +696,7 @@ class KcefWebViewProvider(
kcefClient!!
.createBrowser(
url,
CefRendering.OFFSCREEN,
CefRendering.CefRenderingWithHandler(renderHandler, JPanel()),
false,
).apply {
// 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).
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`).
Note that on some systems (e.g. Ubuntu), the JNI libraries are not automatically found, see below.
To have a functional WebView, some X11 dependencies are required for rendering Chromium.
These include `libxrender`, `libxcomposite` `libxdamage`, `libxkbcommon` and `libxtst`.
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 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.
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
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
jwt = "com.auth0:java-jwt:4.5.2"

View File

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

View File

@@ -194,7 +194,7 @@ object Chapter {
}
// new chapters after they have been added to the database for auto downloads
val insertedChapters = mutableListOf<ChapterDataClass>()
val insertedChapterIds = mutableListOf<Int>()
val chaptersToInsert = mutableListOf<ChapterDataClass>() // do not yet have an ID from the database
val chaptersToUpdate = mutableListOf<ChapterDataClass>()
@@ -309,7 +309,7 @@ object Chapter {
}
}
}
}.forEach { insertedChapters.add(ChapterTable.toDataClass(it)) }
}.forEach { insertedChapterIds.add(it[ChapterTable.id].value) }
}
if (chaptersToUpdate.isNotEmpty()) {
@@ -354,6 +354,13 @@ object Chapter {
}
if (manga.inLibrary) {
// We have to query the inserted chapters to get the up-to-date data. I.e. "last_modified_at" is not returned by the insert statement, due to being set by a DB trigger
val insertedChapters =
transaction {
ChapterTable.selectAll().where { ChapterTable.id inList insertedChapterIds }.map(
ChapterTable::toDataClass,
)
}
downloadNewChapters(mangaId, currentLatestChapterNumber, numberOfCurrentChapters, insertedChapters)
}