From d59c837714e8648d4be58d736c13e9c242d28af5 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Sun, 28 Jul 2024 01:19:40 +0200 Subject: [PATCH] Kobo: Refactor various aspects of the Kaleido/MTK support (#12221) * UIManager: Let the fb backend deal with Kaleido wfm promotion. This fixes a number of quirks that poisoned the refresh queue with spurious full-screen refreshes. See https://github.com/koreader/koreader-base/pull/1865 for more details. * This also means we now disable Kaleido waveform modes when color rendering is disabled (remember to trash your thumbnail cache if you don't want to mix color w/ grayscale thumbnails, though). * UIManager: Merge refreshes that share an edge, because that was driving me nuts (and would have most likely been merged by the kernel anyway). A perfect test-case is the FM, which trips two separate refreshes because of its title bar. * ReaderFlipping: Use sensible dimensions, so that we only refresh the icon's region. * ReaderBookmark: Only refresh the dogear instead of the whole page when toggling bookmarks. * NetworkSetting: Make it a real boy, so it consistently refreshes properly on dismiss instead of relying on UIManager saving the day. * Kobo: Aggressively prevent *both* suspend & standby while MTK devices are plugged-in, as both will horribly implode the kernel (we previously only prevent standby while charging). * Kobo: Switch to 8bpp on B&W MTK devices (or when color rendering is disabled on Kaleido panels). --- base | 2 +- frontend/apps/filemanager/filemanagermenu.lua | 2 +- .../apps/reader/modules/readerbookmark.lua | 10 ++++- frontend/apps/reader/modules/readerdogear.lua | 26 ++++++----- .../apps/reader/modules/readerflipping.lua | 11 ++--- .../apps/reader/modules/readerhighlight.lua | 4 +- .../apps/reader/modules/readerrolling.lua | 2 +- frontend/apps/reader/modules/readerview.lua | 13 ++---- frontend/device/kobo/device.lua | 22 ++++++++++ .../ui/elements/screen_color_menu_table.lua | 9 +++- frontend/ui/geometry.lua | 28 +++++++++++- frontend/ui/screensaver.lua | 2 +- frontend/ui/uimanager.lua | 44 ++++++++----------- .../ui/widget/container/leftcontainer.lua | 4 +- .../ui/widget/container/rightcontainer.lua | 6 +-- frontend/ui/widget/imageviewer.lua | 3 +- frontend/ui/widget/networksetting.lua | 5 ++- frontend/ui/widget/screensaverwidget.lua | 2 +- platform/kobo/koreader.sh | 11 +++-- plugins/coverbrowser.koplugin/listmenu.lua | 20 ++++----- reader.lua | 10 ++--- 21 files changed, 149 insertions(+), 87 deletions(-) diff --git a/base b/base index b820ba51d..d57f85950 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit b820ba51df06766493db6852eed86baa9021e971 +Subproject commit d57f85950fbe2efa4931e3cc1e2c92c07ccf96f3 diff --git a/frontend/apps/filemanager/filemanagermenu.lua b/frontend/apps/filemanager/filemanagermenu.lua index 17556a121..fbdeb6687 100644 --- a/frontend/apps/filemanager/filemanagermenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -551,7 +551,7 @@ To: }, }, } - if Device:isKobo() and not Device:isSunxi() then + if Device:isKobo() and not Device:isSunxi() and not Device:hasColorScreen() then table.insert(self.menu_items.developer_options.sub_item_table, { text = _("Disable forced 8-bit pixel depth"), checked_func = function() diff --git a/frontend/apps/reader/modules/readerbookmark.lua b/frontend/apps/reader/modules/readerbookmark.lua index bd531a721..b181858ba 100644 --- a/frontend/apps/reader/modules/readerbookmark.lua +++ b/frontend/apps/reader/modules/readerbookmark.lua @@ -310,9 +310,15 @@ end function ReaderBookmark:onToggleBookmark() self:toggleBookmark() - self.view.footer:onUpdateFooter(self.view.footer_visible) self.view.dogear:onSetDogearVisibility(not self.view.dogear_visible) - UIManager:setDirty(self.view.dialog, "ui") + -- Refresh the dogear first, because it might inherit ReaderUI refresh hints. + UIManager:setDirty(self.view.dialog, function() + return "ui", + self.view.dogear:getRefreshRegion() + end) + -- And ask for a footer refresh, in case we have bookmark_count enabled. + -- Assuming the footer is visible, it'll request a refresh regardless, but the EPDC should optimize it out if no content actually changed. + self.view.footer:onUpdateFooter(self.view.footer_visible) return true end diff --git a/frontend/apps/reader/modules/readerdogear.lua b/frontend/apps/reader/modules/readerdogear.lua index f7f2f8b74..8c20fc2b1 100644 --- a/frontend/apps/reader/modules/readerdogear.lua +++ b/frontend/apps/reader/modules/readerdogear.lua @@ -20,6 +20,7 @@ function ReaderDogear:init() self.dogear_min_size = math.ceil(math.min(Screen:getWidth(), Screen:getHeight()) * (1/40)) self.dogear_max_size = math.ceil(math.min(Screen:getWidth(), Screen:getHeight()) * (1/32)) self.dogear_size = nil + self.icon = nil self.dogear_y_offset = 0 self.top_pad = nil self:setupDogear() @@ -35,16 +36,17 @@ function ReaderDogear:setupDogear(new_dogear_size) if self[1] then self[1]:free() end + self.icon = IconWidget:new{ + icon = "dogear.alpha", + rotation_angle = BD.mirroredUILayout() and 90 or 0, + width = self.dogear_size, + height = self.dogear_size, + alpha = true, -- Keep the alpha layer intact + } self.top_pad = VerticalSpan:new{width = self.dogear_y_offset} self.vgroup = VerticalGroup:new{ self.top_pad, - IconWidget:new{ - icon = "dogear.alpha", - rotation_angle = BD.mirroredUILayout() and 90 or 0, - width = self.dogear_size, - height = self.dogear_size, - alpha = true, -- Keep the alpha layer intact - } + self.icon, } self[1] = RightContainer:new{ dimen = Geom:new{w = Screen:getWidth(), h = self.dogear_y_offset + self.dogear_size}, @@ -111,11 +113,13 @@ function ReaderDogear:onChangeViewMode() end function ReaderDogear:resetLayout() - local new_screen_width = Screen:getWidth() - if new_screen_width == self._last_screen_width then return end - self._last_screen_width = new_screen_width + -- NOTE: RightContainer aligns to the right of its *own* width... + self[1].dimen.w = Screen:getWidth() +end - self[1].dimen.w = new_screen_width +function ReaderDogear:getRefreshRegion() + -- We can't use self.dimen because of the width/height quirks of Left/RightContainer, so use the IconWidget's... + return self.icon.dimen end function ReaderDogear:onSetDogearVisibility(visible) diff --git a/frontend/apps/reader/modules/readerflipping.lua b/frontend/apps/reader/modules/readerflipping.lua index 037448a99..3179dbe78 100644 --- a/frontend/apps/reader/modules/readerflipping.lua +++ b/frontend/apps/reader/modules/readerflipping.lua @@ -43,15 +43,16 @@ function ReaderFlipping:init() dimen = Geom:new{w = Screen:getWidth(), h = self.flipping_widget:getSize().h}, self.flipping_widget, } - self:resetLayout() end function ReaderFlipping:resetLayout() - local new_screen_width = Screen:getWidth() - if new_screen_width == self._last_screen_width then return end - self._last_screen_width = new_screen_width + -- NOTE: LeftContainer aligns to the left of its *own* width (and will handle RTL mirroring, so we can't cheat)... + self[1].dimen.w = Screen:getWidth() +end - self[1].dimen.w = new_screen_width +function ReaderFlipping:getRefreshRegion() + -- We can't use self.dimen because of the width/height quirks of Left/RightContainer, so use the IconWidget's... + return self[1][1].dimen end function ReaderFlipping:getRollingRenderingStateIconWidget() diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index c86c7d49e..4ad4d09f8 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -1214,7 +1214,7 @@ function ReaderHighlight:_resetHoldTimer(clear) self.long_hold_reached_action = function() self.long_hold_reached = true -- Have ReaderView redraw and refresh ReaderFlipping and our state icon, avoiding flashes - UIManager:setDirty(self.dialog, "ui", self.view.flipping.dimen) + UIManager:setDirty(self.dialog, "ui", self.view.flipping:getRefreshRegion()) end end -- Unschedule if already set @@ -1251,7 +1251,7 @@ function ReaderHighlight:_resetHoldTimer(clear) if self.long_hold_reached then self.long_hold_reached = false -- Have ReaderView redraw and refresh ReaderFlipping with our state icon removed - UIManager:setDirty(self.dialog, "ui", self.view.flipping.dimen) + UIManager:setDirty(self.dialog, "ui", self.view.flipping:getRefreshRegion()) end end diff --git a/frontend/apps/reader/modules/readerrolling.lua b/frontend/apps/reader/modules/readerrolling.lua index 9d0b122b8..d1e3b371d 100644 --- a/frontend/apps/reader/modules/readerrolling.lua +++ b/frontend/apps/reader/modules/readerrolling.lua @@ -1863,7 +1863,7 @@ function ReaderRolling:setupRerenderingAutomation() if self.rendering_state ~= prev_state then logger.dbg("_stepRerenderingAutomation", prev_state, ">", self.rendering_state) -- Have ReaderView redraw and refresh ReaderFlipping and our state icon, avoiding flashes - UIManager:setDirty(self.view.dialog, "ui", self.view.flipping.dimen) + UIManager:setDirty(self.view.dialog, "ui", self.view.flipping:getRefreshRegion()) end if reschedule then UIManager:scheduleIn(1, self._stepRerenderingAutomation) diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index abde48688..456272efc 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -264,10 +264,6 @@ function ReaderView:paintTo(bb, x, y) if self.ui.paging then if self.document.hw_dithering then self.dialog.dithered = true - -- Assume we're going to be showing colorful stuff on kaleido panels... - if Device:hasKaleidoWfm() then - UIManager:setDirty(nil, "color") - end end else -- Whereas for CRe, @@ -278,15 +274,14 @@ function ReaderView:paintTo(bb, x, y) -- Which is why we remember the stats of the *previous* page. self.img_count, self.img_coverage = img_count, img_coverage if img_coverage >= 0.075 or coverage_diff >= 0.075 then - self.dialog.dithered = true + -- Request dithering on the actual page with image content + if img_coverage >= 0.075 then + self.dialog.dithered = true + end -- Request a flashing update while we're at it, but only if it's the first time we're painting it if self.state.drawn == false and G_reader_settings:nilOrTrue("refresh_on_pages_with_images") then UIManager:setDirty(nil, "full") end - -- On Kaleido panels, we'll want to use GCC16 on the actual image, always... - if Device:hasKaleidoWfm() and img_coverage >= 0.075 then - UIManager:setDirty(nil, "color") - end end self.state.drawn = true end diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index 21410049e..d982615cc 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -1230,6 +1230,14 @@ end --- The function to put the device into standby, with enabled touchscreen. -- max_duration ... maximum time for the next standby, can wake earlier (e.g. Tap, Button ...) function Kobo:standby(max_duration) + -- On MTK, any suspend/standby attempt while plugged-in will hang the kernel... -_-" + -- NOTE: isCharging is still true while isCharged! + if self:isMTK() and self.powerd:isCharging() then + logger.info("Kobo standby: skipping the standby request for now: device is plugged in and would otherwise crash!") + + return + end + -- NOTE: Switch to the performance CPU governor, in order to speed up the resume process so as to lower its latency cost... -- (It won't have any impact on power efficiency *during* suspend, so there's not really any drawback). self:performanceCPUGovernor() @@ -1301,6 +1309,20 @@ function Kobo:standby(max_duration) end function Kobo:suspend() + -- On MTK, any suspend/standby attempt while plugged-in will hang the kernel... -_-" + -- NOTE: isCharging is still true while isCharged! + if self:isMTK() and self.powerd:isCharging() then + logger.info("Kobo suspend: skipping the suspend request for now: device is plugged in and would otherwise crash!") + + -- Do the usual scheduling dance, so we get a chance to fire the UnexpectedWakeupLimit event... + UIManager:unschedule(self.checkUnexpectedWakeup) + self.unexpected_wakeup_count = self.unexpected_wakeup_count + 1 + logger.dbg("Kobo suspend: scheduling unexpected wakeup guard") + UIManager:scheduleIn(15, self.checkUnexpectedWakeup, self) + + return + end + logger.info("Kobo suspend: going to sleep . . .") UIManager:unschedule(self.checkUnexpectedWakeup) -- NOTE: Sleep as little as possible here, sleeping has a tendency to make diff --git a/frontend/ui/elements/screen_color_menu_table.lua b/frontend/ui/elements/screen_color_menu_table.lua index bfcf6583f..9801326d5 100644 --- a/frontend/ui/elements/screen_color_menu_table.lua +++ b/frontend/ui/elements/screen_color_menu_table.lua @@ -1,5 +1,6 @@ +local Device = require("device") local Event = require("ui/event") -local Screen = require("device").screen +local Screen = Device.screen local UIManager = require("ui/uimanager") local CanvasContext = require("document/canvascontext") local _ = require("gettext") @@ -15,5 +16,11 @@ return { G_reader_settings:saveSetting("color_rendering", new_val) CanvasContext:setColorRenderingEnabled(new_val) UIManager:broadcastEvent(Event:new("ColorRenderingUpdate")) + -- On color Kobos, we can use this opportunity to swap to 8bpp, so, request a restart. + -- NOTE: Unfortunately, that doesn't help alleviate moire effect on affected patterns, + -- so I guess that comes from some physical aspect of the screen layers... + if Device:isKobo() and Device:hasColorScreen() then + UIManager:askForRestart() + end end } diff --git a/frontend/ui/geometry.lua b/frontend/ui/geometry.lua index 792806bca..dc8362ae4 100644 --- a/frontend/ui/geometry.lua +++ b/frontend/ui/geometry.lua @@ -183,7 +183,7 @@ function Geom:intersect(rect_b) end --[[-- -Returns true if self does not share any area with rect_b +Returns true if self does not share any area or edge with rect_b @tparam Geom rect_b ]] @@ -208,6 +208,32 @@ function Geom:intersectWith(rect_b) return not self:notIntersectWith(rect_b) end +--[[-- +Returns true if self does not share any area with rect_b + +@tparam Geom rect_b +]] +function Geom:notOpenIntersectWith(rect_b) + if not rect_b or rect_b:area() == 0 then return true end + + if (self.x > (rect_b.x + rect_b.w)) + or (self.y > (rect_b.y + rect_b.h)) + or (rect_b.x > (self.x + self.w)) + or (rect_b.y > (self.y + self.h)) then + return true + end + return false +end + +--[[-- +Returns true if self geom shares area or an edge with rect_b. + +@tparam Geom rect_b +]] +function Geom:openIntersectWith(rect_b) + return not self:notOpenIntersectWith(rect_b) +end + --[[-- Set size of dimension or rectangle to size of given dimension/rectangle. diff --git a/frontend/ui/screensaver.lua b/frontend/ui/screensaver.lua index 801ae97a8..080bfeaeb 100644 --- a/frontend/ui/screensaver.lua +++ b/frontend/ui/screensaver.lua @@ -690,7 +690,7 @@ function Screensaver:show() self.screensaver_widget.modal = true self.screensaver_widget.dithered = true - UIManager:show(self.screensaver_widget, Device:hasKaleidoWfm() and "color" or "full") + UIManager:show(self.screensaver_widget, "full") end -- Setup the gesture lock through an additional invisible widget, so that it works regardless of the configuration. diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index cf793280d..b33d8f223 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -138,7 +138,7 @@ For more details about refreshtype, refreshregion & refreshdither see the descri If refreshtype is omitted, no refresh will be enqueued at this time. @param widget a @{ui.widget.widget|widget} object -@string refreshtype `"color"`, `"colortext"`, `"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"` (optional) +@string refreshtype `"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"` (optional) @param refreshregion a rectangle @{ui.geometry.Geom|Geom} object (optional, requires refreshtype to be set) @int x horizontal screen offset (optional, `0` if omitted) @int y vertical screen offset (optional, `0` if omitted) @@ -195,7 +195,7 @@ For more details about refreshtype, refreshregion & refreshdither see the descri If refreshtype is omitted, no extra refresh will be enqueued at this time, leaving only those from the uncovered widgets. @param widget a @{ui.widget.widget|widget} object -@string refreshtype `"color"`, `"colortext"`, `"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"` (optional) +@string refreshtype `"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"` (optional) @param refreshregion a rectangle @{ui.geometry.Geom|Geom} object (optional, requires refreshtype to be set) @bool refreshdither `true` if the refresh requires dithering (optional, requires refreshtype to be set) @see setDirty @@ -464,10 +464,6 @@ It just appends stuff to the paint and/or refresh queues. Here's a quick rundown of what each refreshtype should be used for: -* `color`: high-fidelity flashing refresh for color image content on Kaleido panels. - Maps to partial on unsupported devices, as such, better used conditionally behind a Device:hasKaleidoWfm check. -* `colortext`: REAGL refresh for color text (e.g., highlights) on Kaleido panels. - Maps to partial on unsupported devices, as such, better used conditionally behind a Device:hasKaleidoWfm check. * `full`: high-fidelity flashing refresh (e.g., large images). Highest quality, but highest latency. Don't abuse if you only want a flash (in this case, prefer `flashui` or `flashpartial`). @@ -566,7 +562,7 @@ UIManager:setDirty(self.widget, "partial", Geom:new{x=10,y=10,w=100,h=50}) UIManager:setDirty(self.widget, function() return "ui", self.someelement.dimen end) @param widget a window-level widget object, `"all"`, or `nil` -@param refreshtype `"color"`, `"colortext"`, `"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"` (or a lambda, see description above) +@param refreshtype `"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"` (or a lambda, see description above) @param refreshregion a rectangle @{ui.geometry.Geom|Geom} object (optional, omitting it means the region will cover the full screen) @bool refreshdither `true` if widget requires dithering (optional) ]] @@ -1058,7 +1054,7 @@ function UIManager:getElapsedTimeSinceBoot() end -- precedence of refresh modes: -local refresh_modes = { a2 = 1, fast = 2, ui = 3, partial = 4, ["[ui]"] = 5, ["[partial]"] = 6, flashui = 7, flashpartial = 8, full = 9, colortext = 10, color = 11 } +local refresh_modes = { a2 = 1, fast = 2, ui = 3, partial = 4, ["[ui]"] = 5, ["[partial]"] = 6, flashui = 7, flashpartial = 8, full = 9 } -- NOTE: We might want to introduce a "force_a2" that points to fast, but has the highest priority, -- for the few cases where we might *really* want to enforce fast (for stuff like panning or skimming?). -- refresh methods in framebuffer implementation @@ -1072,8 +1068,6 @@ local refresh_methods = { flashui = Screen.refreshFlashUI, flashpartial = Screen.refreshFlashPartial, full = Screen.refreshFull, - colortext = Screen.refreshColorText, - color = Screen.refreshColor, } --[[ @@ -1111,7 +1105,7 @@ Widgets call this in their `paintTo()` method in order to notify UIManager that a certain part of the screen is to be refreshed. @string mode - refresh mode (`"color"`, `"colortext"`, `"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"`) + refresh mode (`"full"`, `"flashpartial"`, `"flashui"`, `"[partial]"`, `"[ui]"`, `"partial"`, `"ui"`, `"fast"`, `"a2"`) @param region A rectangle @{ui.geometry.Geom|Geom} object that specifies the region to be updated. Optional, update will affect whole screen if not specified. @@ -1124,23 +1118,21 @@ UIManager that a certain part of the screen is to be refreshed. ]] function UIManager:_refresh(mode, region, dither) if not mode then - -- If we're trying to float a dither hint up from a lower widget after a close, mode might be nil... - -- So use the lowest priority refresh mode (short of fast, because that'd do half-toning). - if dither then - mode = "ui" - else - -- Otherwise, this is most likely from a `show` or `close` that wasn't passed specific refresh details, - -- (which is the vast majority of them), in which case we drop it to avoid enqueuing a useless full-screen refresh. - return - end + -- This is most likely from a `show` or `close` that wasn't passed specific refresh details, + -- (which is the vast majority of them), in which case we drop it to avoid enqueuing a useless full-screen refresh. + return end + -- Downgrade all refreshes to "fast" when ReaderPaging or ReaderScrolling have set this flag if self.currently_scrolling then mode = "fast" end + + -- Reset the refresh counter on any explicit full refresh if not region and mode == "full" then - self.refresh_count = 0 -- reset counter on explicit full refresh + self.refresh_count = 0 end + -- Handle downgrading flashing modes to non-flashing modes, according to user settings. -- NOTE: Do it before "full" promotion and collision checks/update_mode. if G_reader_settings:isTrue("avoid_flashing_ui") then @@ -1191,9 +1183,9 @@ function UIManager:_refresh(mode, region, dither) -- as well as a few actually effective merges -- (e.g., the disappearance of a selection HL with the following menu update). for i, refresh in ipairs(self._refresh_stack) do - -- Check for collision with refreshes that are already enqueued - -- NOTE: intersect *means* intersect: we won't merge edge-to-edge regions (but the EPDC probably will). - if region:intersectWith(refresh.region) then + -- Check for collisions with refreshes that are already enqueued. + -- NOTE: We use the open range variant, as we want to combine rectangles that share an edge (like the EPDC). + if region:openIntersectWith(refresh.region) then -- combine both refreshes' regions local combined = region:combine(refresh.region) -- update the mode, if needed @@ -1291,8 +1283,8 @@ function UIManager:_repaint() end self._refresh_func_stack = {} - -- we should have at least one refresh if we did repaint. If we don't, we - -- add one now and log a warning if we are debugging + -- We should have at least one refresh if we did repaint. + -- If we don't, add one now and log a warning if we are debugging. if dirty and not self._refresh_stack[1] then logger.dbg("no refresh got enqueued. Will do a partial full screen refresh, which might be inefficient") self:_refresh("partial") diff --git a/frontend/ui/widget/container/leftcontainer.lua b/frontend/ui/widget/container/leftcontainer.lua index e003825ed..27d60c21a 100644 --- a/frontend/ui/widget/container/leftcontainer.lua +++ b/frontend/ui/widget/container/leftcontainer.lua @@ -19,7 +19,9 @@ function LeftContainer:paintTo(bb, x, y) if BD.mirroredUILayout() and self.allow_mirroring then x = x + (self.dimen.w - contentSize.w) -- as in RightContainer end - self[1]:paintTo(bb, x , y + math.floor((self.dimen.h - contentSize.h)/2)) + self.dimen.x = x + self.dimen.y = y + math.floor((self.dimen.h - contentSize.h)/2) + self[1]:paintTo(bb, self.dimen.x, self.dimen.y) end return LeftContainer diff --git a/frontend/ui/widget/container/rightcontainer.lua b/frontend/ui/widget/container/rightcontainer.lua index 29eef6245..3763ccd40 100644 --- a/frontend/ui/widget/container/rightcontainer.lua +++ b/frontend/ui/widget/container/rightcontainer.lua @@ -20,9 +20,9 @@ function RightContainer:paintTo(bb, x, y) x = x + (self.dimen.w - contentSize.w) -- else: keep x, as in LeftContainer end - self[1]:paintTo(bb, - x, - y + math.floor((self.dimen.h - contentSize.h)/2)) + self.dimen.x = x + self.dimen.y = y + math.floor((self.dimen.h - contentSize.h)/2) + self[1]:paintTo(bb, self.dimen.x, self.dimen.y) end return RightContainer diff --git a/frontend/ui/widget/imageviewer.lua b/frontend/ui/widget/imageviewer.lua index ccba02649..e3d76cdaa 100644 --- a/frontend/ui/widget/imageviewer.lua +++ b/frontend/ui/widget/imageviewer.lua @@ -369,7 +369,8 @@ function ImageViewer:update() self.main_frame.radius = not self.fullscreen and 8 or nil -- NOTE: We use UI instead of partial, because we do NOT want to end up using a REAGL waveform... - local wfm_mode = Device:hasKaleidoWfm() and "color" or "ui" + -- ...except on Kaleido panels ;). + local wfm_mode = Device:hasKaleidoWfm() and "partial" or "ui" -- NOTE: Disabling dithering here makes for a perfect test-case of how well it works: -- page turns will show color quantization artefacts (i.e., banding) like crazy, -- while a long touch will trigger a dithered, flashing full-refresh that'll make everything shiny :). diff --git a/frontend/ui/widget/networksetting.lua b/frontend/ui/widget/networksetting.lua index 2ed25ddb9..8e35700f4 100644 --- a/frontend/ui/widget/networksetting.lua +++ b/frontend/ui/widget/networksetting.lua @@ -458,7 +458,7 @@ function NetworkSetting:init() self.pagination:setProgress(curr_page/total_pages) -- self.page_text:setText(curr_page .. "/" .. total_pages) UIManager:setDirty(self, function() - return "ui", self.dimen + return "ui", self.popup.dimen end) end }, @@ -496,7 +496,7 @@ function NetworkSetting:init() if connected_item ~= nil then obtainIP() if G_reader_settings:nilOrTrue("auto_dismiss_wifi_scan") then - UIManager:close(self, "ui", self.dimen) + UIManager:close(self) end UIManager:show(InfoMessage:new{ text = T(_("Connected to network %1"), BD.wrap(connected_item.display_ssid)), @@ -527,6 +527,7 @@ function NetworkSetting:onCloseWidget() if not NetworkMgr.pending_connectivity_check then NetworkMgr.pending_connection = false end + UIManager:setDirty(nil, "ui", self.popup.dimen) end return NetworkSetting diff --git a/frontend/ui/widget/screensaverwidget.lua b/frontend/ui/widget/screensaverwidget.lua index ec88637f8..473f5cc05 100644 --- a/frontend/ui/widget/screensaverwidget.lua +++ b/frontend/ui/widget/screensaverwidget.lua @@ -54,7 +54,7 @@ end function ScreenSaverWidget:onShow() UIManager:setDirty(self, function() - return Device:hasKaleidoWfm() and "color" or "full", self.main_frame.dimen + return "full", self.main_frame.dimen end) return true end diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index a67efad4d..fd8a2e041 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -332,12 +332,17 @@ ko_do_fbdepth() { fi # On color panels, we target 32bpp for, well, color, and sane addressing (it also happens to be their default) ;o). - # Also, the current lineup of MTK + Kaleido devices doesn't even *support* switching to 8bpp anymore. eval "$(./fbink -e | tr ';' '\n' | grep -e hasColorPanel | tr '\n' ';')" # shellcheck disable=SC2154 if [ "${hasColorPanel}" = "1" ]; then - echo "Switching fb bitdepth to 32bpp & rotation to Portrait" >>crash.log 2>&1 - ./fbdepth -d 32 -R UR >>crash.log 2>&1 + # If color rendering has been disabled by the user, switch to 8bpp to completely skip CFA processing + if grep -q '\["color_rendering"\] = false' 'settings.reader.lua' 2>/dev/null; then + echo "Switching fb bitdepth to 8bpp (to disable CFA) & rotation to Portrait" >>crash.log 2>&1 + ./fbdepth -d 8 -R UR >>crash.log 2>&1 + else + echo "Switching fb bitdepth to 32bpp & rotation to Portrait" >>crash.log 2>&1 + ./fbdepth -d 32 -R UR >>crash.log 2>&1 + fi return fi diff --git a/plugins/coverbrowser.koplugin/listmenu.lua b/plugins/coverbrowser.koplugin/listmenu.lua index 42b384225..9dc26c605 100644 --- a/plugins/coverbrowser.koplugin/listmenu.lua +++ b/plugins/coverbrowser.koplugin/listmenu.lua @@ -239,16 +239,16 @@ function ListMenuItem:update() height_overflow_show_ellipsis = true, } widget = OverlapGroup:new{ - dimen = dimen, + dimen = dimen:copy(), LeftContainer:new{ - dimen = dimen, + dimen = dimen:copy(), HorizontalGroup:new{ HorizontalSpan:new{ width = pad_width }, wleft, } }, RightContainer:new{ - dimen = dimen, + dimen = dimen:copy(), HorizontalGroup:new{ wright, HorizontalSpan:new{ width = pad_width }, @@ -639,7 +639,7 @@ function ListMenuItem:update() end local wmain = LeftContainer:new{ - dimen = dimen, + dimen = dimen:copy(), VerticalGroup:new{ wtitle, wauthors, @@ -648,7 +648,7 @@ function ListMenuItem:update() -- Build the final widget widget = OverlapGroup:new{ - dimen = dimen, + dimen = dimen:copy(), } if self.do_cover_image then -- add left widget @@ -673,13 +673,13 @@ function ListMenuItem:update() end -- add padded main widget table.insert(widget, LeftContainer:new{ - dimen = dimen, + dimen = dimen:copy(), wmain }) -- add right widget if wright then table.insert(widget, RightContainer:new{ - dimen = dimen, + dimen = dimen:copy(), HorizontalGroup:new{ wright, HorizontalSpan:new{ width = wright_right_padding }, @@ -758,7 +758,7 @@ function ListMenuItem:update() fontsize_no_bookinfo = fontsize_no_bookinfo - fontsize_dec_step until text_widget:getSize().h <= dimen.h widget = LeftContainer:new{ - dimen = dimen, + dimen = dimen:copy(), HorizontalGroup:new{ HorizontalSpan:new{ width = Screen:scaleBySize(10) }, text_widget @@ -766,10 +766,10 @@ function ListMenuItem:update() } if wright then -- last read date, in History, even for deleted files widget = OverlapGroup:new{ - dimen = dimen, + dimen = dimen:copy(), widget, RightContainer:new{ - dimen = dimen, + dimen = dimen:copy(), HorizontalGroup:new{ wright, HorizontalSpan:new{ width = wright_right_padding }, diff --git a/reader.lua b/reader.lua index d4769f5b0..6fe9489d5 100755 --- a/reader.lua +++ b/reader.lua @@ -202,14 +202,14 @@ if G_reader_settings:isTrue("color_rendering") and not Device:hasColorScreen() t text = _("Color rendering is mistakenly enabled on your grayscale device.\nThis will subtly break some features, and adversely affect performance."), cancel_text = _("Ignore"), cancel_callback = function() - return + return end, ok_text = _("Disable"), ok_callback = function() - local Event = require("ui/event") - G_reader_settings:delSetting("color_rendering") - CanvasContext:setColorRenderingEnabled(false) - UIManager:broadcastEvent(Event:new("ColorRenderingUpdate")) + local Event = require("ui/event") + G_reader_settings:delSetting("color_rendering") + CanvasContext:setColorRenderingEnabled(false) + UIManager:broadcastEvent(Event:new("ColorRenderingUpdate")) end, }) end