mirror of
https://github.com/koreader/koreader
synced 2024-11-11 19:11:14 +00:00
UIManager: Handle covers_fullscreen properly in close (#6828)
* When closing a widget, stop sending setDirty call for widgets lower on the stack as soon as we hit a full-screen one. This prevents inflated refresh regions when closing stuff on top of a stack of multiple covers_fullscreen widgets (i.e., InfoMessages on top of the Favorites page on top of the FM, for instance). And, while we're there, also prevent getting infected by dithered widgets when they're below a non dithered full-screen widget (the exact same examples works, if the underlying FM page requires dithering).
This commit is contained in:
parent
982702fdc1
commit
8e1c6c8409
@ -425,6 +425,8 @@ function UIManager:close(widget, refreshtype, refreshregion, refreshdither)
|
||||
-- make it disabled by default and check if any widget wants it disabled or enabled
|
||||
Input.disable_double_tap = true
|
||||
local requested_disable_double_tap = nil
|
||||
local is_covered = false
|
||||
local start_idx = 1
|
||||
-- then remove all references to that widget on stack and refresh
|
||||
for i = #self._window_stack, 1, -1 do
|
||||
if self._window_stack[i].widget == widget then
|
||||
@ -432,12 +434,23 @@ function UIManager:close(widget, refreshtype, refreshregion, refreshdither)
|
||||
table.remove(self._window_stack, i)
|
||||
dirty = true
|
||||
else
|
||||
-- If anything else on the stack was dithered, honor the hint
|
||||
if self._window_stack[i].widget.dithered then
|
||||
-- If anything else on the stack not already hidden by (i.e., below) a fullscreen widget was dithered, honor the hint
|
||||
if self._window_stack[i].widget.dithered and not is_covered then
|
||||
refreshdither = true
|
||||
logger.dbg("Lower widget", self._window_stack[i].widget.name or self._window_stack[i].widget.id or tostring(self._window_stack[i].widget), "was dithered, honoring the dithering hint")
|
||||
end
|
||||
|
||||
-- Remember the uppermost widget that covers the full screen, so we don't bother calling setDirty on hidden (i.e., lower) widgets in the following dirty loop.
|
||||
-- _repaint already does that later on to skip the actual paintTo calls, so this ensures we limit the refresh queue to stuff that will actually get painted.
|
||||
if not is_covered and self._window_stack[i].widget.covers_fullscreen then
|
||||
is_covered = true
|
||||
start_idx = i
|
||||
logger.dbg("Lower widget", self._window_stack[i].widget.name or self._window_stack[i].widget.id or tostring(self._window_stack[i].widget), "covers the full screen")
|
||||
if i > 1 then
|
||||
logger.dbg("not refreshing", i-1, "covered widget(s)")
|
||||
end
|
||||
end
|
||||
|
||||
-- Set double tap to how the topmost specifying widget wants it
|
||||
if requested_disable_double_tap == nil and self._window_stack[i].widget.disable_double_tap ~= nil then
|
||||
requested_disable_double_tap = self._window_stack[i].widget.disable_double_tap
|
||||
@ -448,8 +461,8 @@ function UIManager:close(widget, refreshtype, refreshregion, refreshdither)
|
||||
Input.disable_double_tap = requested_disable_double_tap
|
||||
end
|
||||
if dirty and not widget.invisible then
|
||||
-- schedule remaining widgets to be painted
|
||||
for i = 1, #self._window_stack do
|
||||
-- schedule the remaining visible (i.e., uncovered) widgets to be painted
|
||||
for i = start_idx, #self._window_stack do
|
||||
self:setDirty(self._window_stack[i].widget)
|
||||
end
|
||||
self:_refresh(refreshtype, refreshregion, refreshdither)
|
||||
|
Loading…
Reference in New Issue
Block a user