Skip to content

Fix: restore default white background fallback in Button:init (app-wide crash) - #12

Open
jperon wants to merge 1 commit into
bateast:mainfrom
jperon:fix/button-default-background
Open

Fix: restore default white background fallback in Button:init (app-wide crash)#12
jperon wants to merge 1 commit into
bateast:mainfrom
jperon:fix/button-default-background

Conversation

@jperon

@jperon jperon commented Jul 20, 2026

Copy link
Copy Markdown

The problem

button.lua does:

local Button = require("ui/widget/button")
function Button:init() ... end

In Lua, require caches modules and always returns the same table. So this redefinition doesn't create a subclass local to kochess: it replaces the init method of the Button widget shared by the whole of KOReader. Once the chess board has been opened once in a session, every button in the application (menus, dialogs, etc.) uses this patched version, even outside the plugin.

This copy of the original code dropped the fallback to a default white background:

-- kochess's current version (button.lua)
self.frame = FrameContainer:new{
    ...
    background = self.background,  -- stays nil when no custom background is provided
    radius = self.radius,
    ...
}

whereas the original Button:init (frontend/ui/widget/button.lua) computes:

local background_color, border_color, radius
if self.background then -- colored button
    background_color = self.background
    border_color = background_color
    radius = self.radius or Size.radius.button
else
    background_color = Blitbuffer.COLOR_WHITE
    radius = self.radius
end

As a result, any "default" button (without a custom background) created anywhere else in KOReader after the chess board has been opened ends up with self.frame.background == nil. On the first tap on such a button, the highlight-feedback animation (flash_ui, enabled by default) crashes the whole app:

frontend/ui/widget/button.lua:406: attempt to index field 'background' (a nil value)

(Button:_doFeedbackHighlight calls self[1].background:invert() without checking that background isn't nil.)

Observed reproduction

On an Android e-reader (Bigme B6), after opening a chess game, the app consistently crashed when confirming any dialog (e.g. "Set as default" in the reader's configuration menu), without leaving a usable crash.log, since this is an uncaught Lua error rather than a native crash.

The fix

This PR restores the original fallback logic for background_color/border_color/radius, so that kochess's Button:init stays functionally equivalent to KOReader's for buttons without a custom background, while keeping kochess's own specifics (e.g. alpha support on IconWidget).

Longer term, it would probably be better for kochess to avoid monkey-patching the shared ui/widget/button module altogether (e.g. by extending Button via Button:extend{} instead of reassigning Button.init), so that any future divergence from upstream KOReader doesn't reintroduce this kind of app-wide regression. I haven't touched that architecture here, to keep the fix minimal and focused on the observed bug.

Button:init() overrides KOReader's shared ui/widget/button module
(module caching means this patches the global Button class, affecting
every button in the app, not just kochess's own widgets). This copy
dropped the fallback that sets background to COLOR_WHITE and computes
border/radius when no custom background is provided, leaving
self.frame.background nil for any default (uncolored) button created
anywhere in KOReader after the chess board has been opened once.

That nil background then crashes any button tap application-wide as
soon as flash_ui highlighting runs, since Button:_doFeedbackHighlight
calls self[1].background:invert() unconditionally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant