mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
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).
This commit is contained in:
2
base
2
base
Submodule base updated: b820ba51df...d57f85950f
@@ -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, {
|
table.insert(self.menu_items.developer_options.sub_item_table, {
|
||||||
text = _("Disable forced 8-bit pixel depth"),
|
text = _("Disable forced 8-bit pixel depth"),
|
||||||
checked_func = function()
|
checked_func = function()
|
||||||
|
|||||||
@@ -310,9 +310,15 @@ end
|
|||||||
|
|
||||||
function ReaderBookmark:onToggleBookmark()
|
function ReaderBookmark:onToggleBookmark()
|
||||||
self:toggleBookmark()
|
self:toggleBookmark()
|
||||||
self.view.footer:onUpdateFooter(self.view.footer_visible)
|
|
||||||
self.view.dogear:onSetDogearVisibility(not self.view.dogear_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
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ function ReaderDogear:init()
|
|||||||
self.dogear_min_size = math.ceil(math.min(Screen:getWidth(), Screen:getHeight()) * (1/40))
|
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_max_size = math.ceil(math.min(Screen:getWidth(), Screen:getHeight()) * (1/32))
|
||||||
self.dogear_size = nil
|
self.dogear_size = nil
|
||||||
|
self.icon = nil
|
||||||
self.dogear_y_offset = 0
|
self.dogear_y_offset = 0
|
||||||
self.top_pad = nil
|
self.top_pad = nil
|
||||||
self:setupDogear()
|
self:setupDogear()
|
||||||
@@ -35,16 +36,17 @@ function ReaderDogear:setupDogear(new_dogear_size)
|
|||||||
if self[1] then
|
if self[1] then
|
||||||
self[1]:free()
|
self[1]:free()
|
||||||
end
|
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.top_pad = VerticalSpan:new{width = self.dogear_y_offset}
|
||||||
self.vgroup = VerticalGroup:new{
|
self.vgroup = VerticalGroup:new{
|
||||||
self.top_pad,
|
self.top_pad,
|
||||||
IconWidget:new{
|
self.icon,
|
||||||
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[1] = RightContainer:new{
|
self[1] = RightContainer:new{
|
||||||
dimen = Geom:new{w = Screen:getWidth(), h = self.dogear_y_offset + self.dogear_size},
|
dimen = Geom:new{w = Screen:getWidth(), h = self.dogear_y_offset + self.dogear_size},
|
||||||
@@ -111,11 +113,13 @@ function ReaderDogear:onChangeViewMode()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function ReaderDogear:resetLayout()
|
function ReaderDogear:resetLayout()
|
||||||
local new_screen_width = Screen:getWidth()
|
-- NOTE: RightContainer aligns to the right of its *own* width...
|
||||||
if new_screen_width == self._last_screen_width then return end
|
self[1].dimen.w = Screen:getWidth()
|
||||||
self._last_screen_width = new_screen_width
|
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
|
end
|
||||||
|
|
||||||
function ReaderDogear:onSetDogearVisibility(visible)
|
function ReaderDogear:onSetDogearVisibility(visible)
|
||||||
|
|||||||
@@ -43,15 +43,16 @@ function ReaderFlipping:init()
|
|||||||
dimen = Geom:new{w = Screen:getWidth(), h = self.flipping_widget:getSize().h},
|
dimen = Geom:new{w = Screen:getWidth(), h = self.flipping_widget:getSize().h},
|
||||||
self.flipping_widget,
|
self.flipping_widget,
|
||||||
}
|
}
|
||||||
self:resetLayout()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function ReaderFlipping:resetLayout()
|
function ReaderFlipping:resetLayout()
|
||||||
local new_screen_width = Screen:getWidth()
|
-- NOTE: LeftContainer aligns to the left of its *own* width (and will handle RTL mirroring, so we can't cheat)...
|
||||||
if new_screen_width == self._last_screen_width then return end
|
self[1].dimen.w = Screen:getWidth()
|
||||||
self._last_screen_width = new_screen_width
|
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
|
end
|
||||||
|
|
||||||
function ReaderFlipping:getRollingRenderingStateIconWidget()
|
function ReaderFlipping:getRollingRenderingStateIconWidget()
|
||||||
|
|||||||
@@ -1214,7 +1214,7 @@ function ReaderHighlight:_resetHoldTimer(clear)
|
|||||||
self.long_hold_reached_action = function()
|
self.long_hold_reached_action = function()
|
||||||
self.long_hold_reached = true
|
self.long_hold_reached = true
|
||||||
-- Have ReaderView redraw and refresh ReaderFlipping and our state icon, avoiding flashes
|
-- 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
|
||||||
end
|
end
|
||||||
-- Unschedule if already set
|
-- Unschedule if already set
|
||||||
@@ -1251,7 +1251,7 @@ function ReaderHighlight:_resetHoldTimer(clear)
|
|||||||
if self.long_hold_reached then
|
if self.long_hold_reached then
|
||||||
self.long_hold_reached = false
|
self.long_hold_reached = false
|
||||||
-- Have ReaderView redraw and refresh ReaderFlipping with our state icon removed
|
-- 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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1863,7 +1863,7 @@ function ReaderRolling:setupRerenderingAutomation()
|
|||||||
if self.rendering_state ~= prev_state then
|
if self.rendering_state ~= prev_state then
|
||||||
logger.dbg("_stepRerenderingAutomation", prev_state, ">", self.rendering_state)
|
logger.dbg("_stepRerenderingAutomation", prev_state, ">", self.rendering_state)
|
||||||
-- Have ReaderView redraw and refresh ReaderFlipping and our state icon, avoiding flashes
|
-- 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
|
end
|
||||||
if reschedule then
|
if reschedule then
|
||||||
UIManager:scheduleIn(1, self._stepRerenderingAutomation)
|
UIManager:scheduleIn(1, self._stepRerenderingAutomation)
|
||||||
|
|||||||
@@ -264,10 +264,6 @@ function ReaderView:paintTo(bb, x, y)
|
|||||||
if self.ui.paging then
|
if self.ui.paging then
|
||||||
if self.document.hw_dithering then
|
if self.document.hw_dithering then
|
||||||
self.dialog.dithered = true
|
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
|
end
|
||||||
else
|
else
|
||||||
-- Whereas for CRe,
|
-- Whereas for CRe,
|
||||||
@@ -278,15 +274,14 @@ function ReaderView:paintTo(bb, x, y)
|
|||||||
-- Which is why we remember the stats of the *previous* page.
|
-- Which is why we remember the stats of the *previous* page.
|
||||||
self.img_count, self.img_coverage = img_count, img_coverage
|
self.img_count, self.img_coverage = img_count, img_coverage
|
||||||
if img_coverage >= 0.075 or coverage_diff >= 0.075 then
|
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
|
-- 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
|
if self.state.drawn == false and G_reader_settings:nilOrTrue("refresh_on_pages_with_images") then
|
||||||
UIManager:setDirty(nil, "full")
|
UIManager:setDirty(nil, "full")
|
||||||
end
|
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
|
end
|
||||||
self.state.drawn = true
|
self.state.drawn = true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1230,6 +1230,14 @@ end
|
|||||||
--- The function to put the device into standby, with enabled touchscreen.
|
--- 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 ...)
|
-- max_duration ... maximum time for the next standby, can wake earlier (e.g. Tap, Button ...)
|
||||||
function Kobo:standby(max_duration)
|
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...
|
-- 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).
|
-- (It won't have any impact on power efficiency *during* suspend, so there's not really any drawback).
|
||||||
self:performanceCPUGovernor()
|
self:performanceCPUGovernor()
|
||||||
@@ -1301,6 +1309,20 @@ function Kobo:standby(max_duration)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Kobo:suspend()
|
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 . . .")
|
logger.info("Kobo suspend: going to sleep . . .")
|
||||||
UIManager:unschedule(self.checkUnexpectedWakeup)
|
UIManager:unschedule(self.checkUnexpectedWakeup)
|
||||||
-- NOTE: Sleep as little as possible here, sleeping has a tendency to make
|
-- NOTE: Sleep as little as possible here, sleeping has a tendency to make
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
local Device = require("device")
|
||||||
local Event = require("ui/event")
|
local Event = require("ui/event")
|
||||||
local Screen = require("device").screen
|
local Screen = Device.screen
|
||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
local CanvasContext = require("document/canvascontext")
|
local CanvasContext = require("document/canvascontext")
|
||||||
local _ = require("gettext")
|
local _ = require("gettext")
|
||||||
@@ -15,5 +16,11 @@ return {
|
|||||||
G_reader_settings:saveSetting("color_rendering", new_val)
|
G_reader_settings:saveSetting("color_rendering", new_val)
|
||||||
CanvasContext:setColorRenderingEnabled(new_val)
|
CanvasContext:setColorRenderingEnabled(new_val)
|
||||||
UIManager:broadcastEvent(Event:new("ColorRenderingUpdate"))
|
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
|
end
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ function Geom:intersect(rect_b)
|
|||||||
end
|
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
|
@tparam Geom rect_b
|
||||||
]]
|
]]
|
||||||
@@ -208,6 +208,32 @@ function Geom:intersectWith(rect_b)
|
|||||||
return not self:notIntersectWith(rect_b)
|
return not self:notIntersectWith(rect_b)
|
||||||
end
|
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.
|
Set size of dimension or rectangle to size of given dimension/rectangle.
|
||||||
|
|
||||||
|
|||||||
@@ -690,7 +690,7 @@ function Screensaver:show()
|
|||||||
self.screensaver_widget.modal = true
|
self.screensaver_widget.modal = true
|
||||||
self.screensaver_widget.dithered = true
|
self.screensaver_widget.dithered = true
|
||||||
|
|
||||||
UIManager:show(self.screensaver_widget, Device:hasKaleidoWfm() and "color" or "full")
|
UIManager:show(self.screensaver_widget, "full")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Setup the gesture lock through an additional invisible widget, so that it works regardless of the configuration.
|
-- Setup the gesture lock through an additional invisible widget, so that it works regardless of the configuration.
|
||||||
|
|||||||
@@ -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.
|
If refreshtype is omitted, no refresh will be enqueued at this time.
|
||||||
|
|
||||||
@param widget a @{ui.widget.widget|widget} object
|
@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)
|
@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 x horizontal screen offset (optional, `0` if omitted)
|
||||||
@int y vertical 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.
|
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
|
@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)
|
@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)
|
@bool refreshdither `true` if the refresh requires dithering (optional, requires refreshtype to be set)
|
||||||
@see setDirty
|
@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:
|
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).
|
* `full`: high-fidelity flashing refresh (e.g., large images).
|
||||||
Highest quality, but highest latency.
|
Highest quality, but highest latency.
|
||||||
Don't abuse if you only want a flash (in this case, prefer `flashui` or `flashpartial`).
|
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)
|
UIManager:setDirty(self.widget, function() return "ui", self.someelement.dimen end)
|
||||||
|
|
||||||
@param widget a window-level widget object, `"all"`, or `nil`
|
@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)
|
@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)
|
@bool refreshdither `true` if widget requires dithering (optional)
|
||||||
]]
|
]]
|
||||||
@@ -1058,7 +1054,7 @@ function UIManager:getElapsedTimeSinceBoot()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- precedence of refresh modes:
|
-- 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,
|
-- 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?).
|
-- for the few cases where we might *really* want to enforce fast (for stuff like panning or skimming?).
|
||||||
-- refresh methods in framebuffer implementation
|
-- refresh methods in framebuffer implementation
|
||||||
@@ -1072,8 +1068,6 @@ local refresh_methods = {
|
|||||||
flashui = Screen.refreshFlashUI,
|
flashui = Screen.refreshFlashUI,
|
||||||
flashpartial = Screen.refreshFlashPartial,
|
flashpartial = Screen.refreshFlashPartial,
|
||||||
full = Screen.refreshFull,
|
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.
|
UIManager that a certain part of the screen is to be refreshed.
|
||||||
|
|
||||||
@string mode
|
@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
|
@param region
|
||||||
A rectangle @{ui.geometry.Geom|Geom} object that specifies the region to be updated.
|
A rectangle @{ui.geometry.Geom|Geom} object that specifies the region to be updated.
|
||||||
Optional, update will affect whole screen if not specified.
|
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)
|
function UIManager:_refresh(mode, region, dither)
|
||||||
if not mode then
|
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...
|
-- This is most likely from a `show` or `close` that wasn't passed specific refresh details,
|
||||||
-- So use the lowest priority refresh mode (short of fast, because that'd do half-toning).
|
-- (which is the vast majority of them), in which case we drop it to avoid enqueuing a useless full-screen refresh.
|
||||||
if dither then
|
return
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Downgrade all refreshes to "fast" when ReaderPaging or ReaderScrolling have set this flag
|
-- Downgrade all refreshes to "fast" when ReaderPaging or ReaderScrolling have set this flag
|
||||||
if self.currently_scrolling then
|
if self.currently_scrolling then
|
||||||
mode = "fast"
|
mode = "fast"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Reset the refresh counter on any explicit full refresh
|
||||||
if not region and mode == "full" then
|
if not region and mode == "full" then
|
||||||
self.refresh_count = 0 -- reset counter on explicit full refresh
|
self.refresh_count = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Handle downgrading flashing modes to non-flashing modes, according to user settings.
|
-- Handle downgrading flashing modes to non-flashing modes, according to user settings.
|
||||||
-- NOTE: Do it before "full" promotion and collision checks/update_mode.
|
-- NOTE: Do it before "full" promotion and collision checks/update_mode.
|
||||||
if G_reader_settings:isTrue("avoid_flashing_ui") then
|
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
|
-- as well as a few actually effective merges
|
||||||
-- (e.g., the disappearance of a selection HL with the following menu update).
|
-- (e.g., the disappearance of a selection HL with the following menu update).
|
||||||
for i, refresh in ipairs(self._refresh_stack) do
|
for i, refresh in ipairs(self._refresh_stack) do
|
||||||
-- Check for collision with refreshes that are already enqueued
|
-- Check for collisions with refreshes that are already enqueued.
|
||||||
-- NOTE: intersect *means* intersect: we won't merge edge-to-edge regions (but the EPDC probably will).
|
-- NOTE: We use the open range variant, as we want to combine rectangles that share an edge (like the EPDC).
|
||||||
if region:intersectWith(refresh.region) then
|
if region:openIntersectWith(refresh.region) then
|
||||||
-- combine both refreshes' regions
|
-- combine both refreshes' regions
|
||||||
local combined = region:combine(refresh.region)
|
local combined = region:combine(refresh.region)
|
||||||
-- update the mode, if needed
|
-- update the mode, if needed
|
||||||
@@ -1291,8 +1283,8 @@ function UIManager:_repaint()
|
|||||||
end
|
end
|
||||||
self._refresh_func_stack = {}
|
self._refresh_func_stack = {}
|
||||||
|
|
||||||
-- we should have at least one refresh if we did repaint. If we don't, we
|
-- We should have at least one refresh if we did repaint.
|
||||||
-- add one now and log a warning if we are debugging
|
-- If we don't, add one now and log a warning if we are debugging.
|
||||||
if dirty and not self._refresh_stack[1] then
|
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")
|
logger.dbg("no refresh got enqueued. Will do a partial full screen refresh, which might be inefficient")
|
||||||
self:_refresh("partial")
|
self:_refresh("partial")
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ function LeftContainer:paintTo(bb, x, y)
|
|||||||
if BD.mirroredUILayout() and self.allow_mirroring then
|
if BD.mirroredUILayout() and self.allow_mirroring then
|
||||||
x = x + (self.dimen.w - contentSize.w) -- as in RightContainer
|
x = x + (self.dimen.w - contentSize.w) -- as in RightContainer
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
return LeftContainer
|
return LeftContainer
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ function RightContainer:paintTo(bb, x, y)
|
|||||||
x = x + (self.dimen.w - contentSize.w)
|
x = x + (self.dimen.w - contentSize.w)
|
||||||
-- else: keep x, as in LeftContainer
|
-- else: keep x, as in LeftContainer
|
||||||
end
|
end
|
||||||
self[1]:paintTo(bb,
|
self.dimen.x = x
|
||||||
x,
|
self.dimen.y = y + math.floor((self.dimen.h - contentSize.h)/2)
|
||||||
y + math.floor((self.dimen.h - contentSize.h)/2))
|
self[1]:paintTo(bb, self.dimen.x, self.dimen.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
return RightContainer
|
return RightContainer
|
||||||
|
|||||||
@@ -369,7 +369,8 @@ function ImageViewer:update()
|
|||||||
self.main_frame.radius = not self.fullscreen and 8 or nil
|
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...
|
-- 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:
|
-- 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,
|
-- 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 :).
|
-- while a long touch will trigger a dithered, flashing full-refresh that'll make everything shiny :).
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ function NetworkSetting:init()
|
|||||||
self.pagination:setProgress(curr_page/total_pages)
|
self.pagination:setProgress(curr_page/total_pages)
|
||||||
-- self.page_text:setText(curr_page .. "/" .. total_pages)
|
-- self.page_text:setText(curr_page .. "/" .. total_pages)
|
||||||
UIManager:setDirty(self, function()
|
UIManager:setDirty(self, function()
|
||||||
return "ui", self.dimen
|
return "ui", self.popup.dimen
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
@@ -496,7 +496,7 @@ function NetworkSetting:init()
|
|||||||
if connected_item ~= nil then
|
if connected_item ~= nil then
|
||||||
obtainIP()
|
obtainIP()
|
||||||
if G_reader_settings:nilOrTrue("auto_dismiss_wifi_scan") then
|
if G_reader_settings:nilOrTrue("auto_dismiss_wifi_scan") then
|
||||||
UIManager:close(self, "ui", self.dimen)
|
UIManager:close(self)
|
||||||
end
|
end
|
||||||
UIManager:show(InfoMessage:new{
|
UIManager:show(InfoMessage:new{
|
||||||
text = T(_("Connected to network %1"), BD.wrap(connected_item.display_ssid)),
|
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
|
if not NetworkMgr.pending_connectivity_check then
|
||||||
NetworkMgr.pending_connection = false
|
NetworkMgr.pending_connection = false
|
||||||
end
|
end
|
||||||
|
UIManager:setDirty(nil, "ui", self.popup.dimen)
|
||||||
end
|
end
|
||||||
|
|
||||||
return NetworkSetting
|
return NetworkSetting
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ end
|
|||||||
|
|
||||||
function ScreenSaverWidget:onShow()
|
function ScreenSaverWidget:onShow()
|
||||||
UIManager:setDirty(self, function()
|
UIManager:setDirty(self, function()
|
||||||
return Device:hasKaleidoWfm() and "color" or "full", self.main_frame.dimen
|
return "full", self.main_frame.dimen
|
||||||
end)
|
end)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -332,12 +332,17 @@ ko_do_fbdepth() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# On color panels, we target 32bpp for, well, color, and sane addressing (it also happens to be their default) ;o).
|
# 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' ';')"
|
eval "$(./fbink -e | tr ';' '\n' | grep -e hasColorPanel | tr '\n' ';')"
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
if [ "${hasColorPanel}" = "1" ]; then
|
if [ "${hasColorPanel}" = "1" ]; then
|
||||||
echo "Switching fb bitdepth to 32bpp & rotation to Portrait" >>crash.log 2>&1
|
# If color rendering has been disabled by the user, switch to 8bpp to completely skip CFA processing
|
||||||
./fbdepth -d 32 -R UR >>crash.log 2>&1
|
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
|
return
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -239,16 +239,16 @@ function ListMenuItem:update()
|
|||||||
height_overflow_show_ellipsis = true,
|
height_overflow_show_ellipsis = true,
|
||||||
}
|
}
|
||||||
widget = OverlapGroup:new{
|
widget = OverlapGroup:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
LeftContainer:new{
|
LeftContainer:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
HorizontalGroup:new{
|
HorizontalGroup:new{
|
||||||
HorizontalSpan:new{ width = pad_width },
|
HorizontalSpan:new{ width = pad_width },
|
||||||
wleft,
|
wleft,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RightContainer:new{
|
RightContainer:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
HorizontalGroup:new{
|
HorizontalGroup:new{
|
||||||
wright,
|
wright,
|
||||||
HorizontalSpan:new{ width = pad_width },
|
HorizontalSpan:new{ width = pad_width },
|
||||||
@@ -639,7 +639,7 @@ function ListMenuItem:update()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local wmain = LeftContainer:new{
|
local wmain = LeftContainer:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
VerticalGroup:new{
|
VerticalGroup:new{
|
||||||
wtitle,
|
wtitle,
|
||||||
wauthors,
|
wauthors,
|
||||||
@@ -648,7 +648,7 @@ function ListMenuItem:update()
|
|||||||
|
|
||||||
-- Build the final widget
|
-- Build the final widget
|
||||||
widget = OverlapGroup:new{
|
widget = OverlapGroup:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
}
|
}
|
||||||
if self.do_cover_image then
|
if self.do_cover_image then
|
||||||
-- add left widget
|
-- add left widget
|
||||||
@@ -673,13 +673,13 @@ function ListMenuItem:update()
|
|||||||
end
|
end
|
||||||
-- add padded main widget
|
-- add padded main widget
|
||||||
table.insert(widget, LeftContainer:new{
|
table.insert(widget, LeftContainer:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
wmain
|
wmain
|
||||||
})
|
})
|
||||||
-- add right widget
|
-- add right widget
|
||||||
if wright then
|
if wright then
|
||||||
table.insert(widget, RightContainer:new{
|
table.insert(widget, RightContainer:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
HorizontalGroup:new{
|
HorizontalGroup:new{
|
||||||
wright,
|
wright,
|
||||||
HorizontalSpan:new{ width = wright_right_padding },
|
HorizontalSpan:new{ width = wright_right_padding },
|
||||||
@@ -758,7 +758,7 @@ function ListMenuItem:update()
|
|||||||
fontsize_no_bookinfo = fontsize_no_bookinfo - fontsize_dec_step
|
fontsize_no_bookinfo = fontsize_no_bookinfo - fontsize_dec_step
|
||||||
until text_widget:getSize().h <= dimen.h
|
until text_widget:getSize().h <= dimen.h
|
||||||
widget = LeftContainer:new{
|
widget = LeftContainer:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
HorizontalGroup:new{
|
HorizontalGroup:new{
|
||||||
HorizontalSpan:new{ width = Screen:scaleBySize(10) },
|
HorizontalSpan:new{ width = Screen:scaleBySize(10) },
|
||||||
text_widget
|
text_widget
|
||||||
@@ -766,10 +766,10 @@ function ListMenuItem:update()
|
|||||||
}
|
}
|
||||||
if wright then -- last read date, in History, even for deleted files
|
if wright then -- last read date, in History, even for deleted files
|
||||||
widget = OverlapGroup:new{
|
widget = OverlapGroup:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
widget,
|
widget,
|
||||||
RightContainer:new{
|
RightContainer:new{
|
||||||
dimen = dimen,
|
dimen = dimen:copy(),
|
||||||
HorizontalGroup:new{
|
HorizontalGroup:new{
|
||||||
wright,
|
wright,
|
||||||
HorizontalSpan:new{ width = wright_right_padding },
|
HorizontalSpan:new{ width = wright_right_padding },
|
||||||
|
|||||||
10
reader.lua
10
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."),
|
text = _("Color rendering is mistakenly enabled on your grayscale device.\nThis will subtly break some features, and adversely affect performance."),
|
||||||
cancel_text = _("Ignore"),
|
cancel_text = _("Ignore"),
|
||||||
cancel_callback = function()
|
cancel_callback = function()
|
||||||
return
|
return
|
||||||
end,
|
end,
|
||||||
ok_text = _("Disable"),
|
ok_text = _("Disable"),
|
||||||
ok_callback = function()
|
ok_callback = function()
|
||||||
local Event = require("ui/event")
|
local Event = require("ui/event")
|
||||||
G_reader_settings:delSetting("color_rendering")
|
G_reader_settings:delSetting("color_rendering")
|
||||||
CanvasContext:setColorRenderingEnabled(false)
|
CanvasContext:setColorRenderingEnabled(false)
|
||||||
UIManager:broadcastEvent(Event:new("ColorRenderingUpdate"))
|
UIManager:broadcastEvent(Event:new("ColorRenderingUpdate"))
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user