From 5e47a83e6ac1239d3a296c8957819f719fed931c Mon Sep 17 00:00:00 2001 From: poire-z Date: Sat, 17 Mar 2018 23:02:32 +0100 Subject: [PATCH] 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). --- frontend/apps/filemanager/filemanager.lua | 1 + .../apps/filemanager/filemanagerhistory.lua | 1 + frontend/apps/opdscatalog/opdscatalog.lua | 1 + frontend/apps/reader/modules/readerbookmark.lua | 1 + frontend/apps/reader/modules/readertoc.lua | 1 + frontend/apps/reader/readerui.lua | 1 + frontend/ui/screensaver.lua | 3 +++ frontend/ui/uimanager.lua | 17 ++++++++++++++++- frontend/ui/widget/bookstatuswidget.lua | 1 + frontend/ui/widget/imageviewer.lua | 3 +++ frontend/ui/widget/keyvaluepage.lua | 3 +++ 11 files changed, 32 insertions(+), 1 deletion(-) diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index ccc55f895..f8254981f 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -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() diff --git a/frontend/apps/filemanager/filemanagerhistory.lua b/frontend/apps/filemanager/filemanagerhistory.lua index 7a0351040..2e0d67423 100644 --- a/frontend/apps/filemanager/filemanagerhistory.lua +++ b/frontend/apps/filemanager/filemanagerhistory.lua @@ -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, diff --git a/frontend/apps/opdscatalog/opdscatalog.lua b/frontend/apps/opdscatalog/opdscatalog.lua index e28b7828f..c5f2606e9 100644 --- a/frontend/apps/opdscatalog/opdscatalog.lua +++ b/frontend/apps/opdscatalog/opdscatalog.lua @@ -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 diff --git a/frontend/apps/reader/modules/readerbookmark.lua b/frontend/apps/reader/modules/readerbookmark.lua index dbca4d33d..bd70f6a14 100644 --- a/frontend/apps/reader/modules/readerbookmark.lua +++ b/frontend/apps/reader/modules/readerbookmark.lua @@ -235,6 +235,7 @@ function ReaderBookmark:onShowBookmark() self.bookmark_menu = CenterContainer:new{ dimen = Screen:getSize(), + covers_fullscreen = true, -- hint for UIManager:_repaint() bm_menu, } diff --git a/frontend/apps/reader/modules/readertoc.lua b/frontend/apps/reader/modules/readertoc.lua index f5c3ffac4..8f7473758 100644 --- a/frontend/apps/reader/modules/readertoc.lua +++ b/frontend/apps/reader/modules/readertoc.lua @@ -335,6 +335,7 @@ function ReaderToc:onShowToc() local menu_container = CenterContainer:new{ dimen = Screen:getSize(), + covers_fullscreen = true, -- hint for UIManager:_repaint() toc_menu, } diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 5132d6211..f1dd86901 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -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) diff --git a/frontend/ui/screensaver.lua b/frontend/ui/screensaver.lua index 787824ff9..ea2f455ed 100644 --- a/frontend/ui/screensaver.lua +++ b/frontend/ui/screensaver.lua @@ -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 diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 1bb787109..112ea1139 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -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 diff --git a/frontend/ui/widget/bookstatuswidget.lua b/frontend/ui/widget/bookstatuswidget.lua index 41f901451..d553a5fa8 100644 --- a/frontend/ui/widget/bookstatuswidget.lua +++ b/frontend/ui/widget/bookstatuswidget.lua @@ -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, diff --git a/frontend/ui/widget/imageviewer.lua b/frontend/ui/widget/imageviewer.lua index aa442301a..6a091fa97 100644 --- a/frontend/ui/widget/imageviewer.lua +++ b/frontend/ui/widget/imageviewer.lua @@ -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 diff --git a/frontend/ui/widget/keyvaluepage.lua b/frontend/ui/widget/keyvaluepage.lua index 40a65663d..7519d00a0 100644 --- a/frontend/ui/widget/keyvaluepage.lua +++ b/frontend/ui/widget/keyvaluepage.lua @@ -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 = {