UIManager: avoid painting widgets covered by a full screen widget (#3770)

Navigating the TOC, viewing a full screen image, browsing
reading stats... would call paintTo() on ReaderUI (so, asking
the engine to render the page) or FileManager (so, rendering cover
images) even though their content is hidden.
Widgets registering to UIManager have to explicitely states
they cover the full screen (UIManager can't know, parts of their
dimen may be transparent, e.g. if it is a CenterContainer).
This commit is contained in:
poire-z
2018-03-17 23:02:32 +01:00
committed by GitHub
parent 50a96ce2b2
commit 5e47a83e6a
11 changed files with 32 additions and 1 deletions

View File

@@ -775,6 +775,7 @@ function FileManager:showFiles(path, focused_file)
restoreScreenMode()
local file_manager = FileManager:new{
dimen = Screen:getSize(),
covers_fullscreen = true, -- hint for UIManager:_repaint()
root_path = path,
focused_file = focused_file,
onExit = function()

View File

@@ -128,6 +128,7 @@ function FileManagerHistory:onShowHist()
ui = self.ui,
width = Screen:getWidth(),
height = Screen:getHeight(),
covers_fullscreen = true, -- hint for UIManager:_repaint()
is_borderless = true,
is_popout = false,
onMenuHold = self.onMenuHold,

View File

@@ -61,6 +61,7 @@ function OPDSCatalog:showCatalog()
logger.dbg("show OPDS catalog")
UIManager:show(OPDSCatalog:new{
dimen = Screen:getSize(),
covers_fullscreen = true, -- hint for UIManager:_repaint()
onExit = function()
--UIManager:quit()
end

View File

@@ -235,6 +235,7 @@ function ReaderBookmark:onShowBookmark()
self.bookmark_menu = CenterContainer:new{
dimen = Screen:getSize(),
covers_fullscreen = true, -- hint for UIManager:_repaint()
bm_menu,
}

View File

@@ -335,6 +335,7 @@ function ReaderToc:onShowToc()
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
covers_fullscreen = true, -- hint for UIManager:_repaint()
toc_menu,
}

View File

@@ -467,6 +467,7 @@ function ReaderUI:doShowReader(file, provider)
G_reader_settings:saveSetting("lastfile", file)
local reader = ReaderUI:new{
dimen = Screen:getSize(),
covers_fullscreen = true, -- hint for UIManager:_repaint()
document = document,
}
UIManager:show(reader)

View File

@@ -141,6 +141,7 @@ function Screensaver:show(event, fallback_message)
UIManager:close(self.left_msg)
self.left_msg = nil
end
local covers_fullscreen = true -- hint for UIManager:_repaint()
local overlay_message
local prefix = event and event.."_" or "" -- "", "poweroff_" or "reboot_"
local screensaver_type = G_reader_settings:readSetting(prefix.."screensaver_type")
@@ -255,6 +256,7 @@ function Screensaver:show(event, fallback_message)
local screensaver_message = G_reader_settings:readSetting(prefix.."screensaver_message")
if not self:whiteBackground() then
background = nil -- no background filling, let book text visible
covers_fullscreen = false
end
if screensaver_message == nil then
screensaver_message = fallback_message or default_screensaver_message
@@ -275,6 +277,7 @@ function Screensaver:show(event, fallback_message)
self.left_msg = ScreenSaverWidget:new{
widget = widget,
background = background,
covers_fullscreen = covers_fullscreen,
}
self.left_msg.modal = true
-- refresh whole screen for other types

View File

@@ -621,11 +621,26 @@ function UIManager:_repaint()
-- will trigger a refresh if set.
local dirty = false
for _, widget in ipairs(self._window_stack) do
-- We don't need to call paintTo() on widgets that are under
-- a widget that covers the full screen
local start_idx = 1
for i = #self._window_stack, 1, -1 do
if self._window_stack[i].widget.covers_fullscreen then
start_idx = i
if i > 1 then
logger.dbg("not painting", i-1, "covered widget(s)")
end
break
end
end
for i = start_idx, #self._window_stack do
local widget = self._window_stack[i]
-- paint if current widget or any widget underneath is dirty
if dirty or self._dirty[widget.widget] then
-- pass hint to widget that we got when setting widget dirty
-- the widget can use this to decide which parts should be refreshed
logger.dbg("painting widget:", widget.widget.name or widget.widget.id or tostring(widget))
widget.widget:paintTo(Screen.bb, widget.x, widget.y, self._dirty[widget.widget])
-- and remove from list after painting

View File

@@ -93,6 +93,7 @@ function BookStatusWidget:init()
end
local screen_size = Screen:getSize()
self.covers_fullscreen = true -- hint for UIManager:_repaint()
self[1] = FrameContainer:new{
width = screen_size.w,
height = screen_size.h,

View File

@@ -100,6 +100,9 @@ function ImageViewer:init()
Swipe = { GestureRange:new{ ges = "swipe", range = range } },
}
end
if self.fullscreen then
self.covers_fullscreen = true -- hint for UIManager:_repaint()
end
self:update()
end

View File

@@ -278,6 +278,9 @@ function KeyValuePage:init()
w = self.width or Screen:getWidth(),
h = self.height or Screen:getHeight(),
}
if self.dimen.w == Screen:getWidth() and self.dimen.h == Screen:getHeight() then
self.covers_fullscreen = true -- hint for UIManager:_repaint()
end
if Device:hasKeys() then
self.key_events = {