ScreenSaver: Minor refactor to avoid code duplication and weird rotation shenanigans (#8943)

* Handle said rotation shenanigans inside ScreenSaver & ScreenSaverWidget, which allows a more targeted approach; and prevents said rotation from affecting other widgets. (Also, gets rid of duplicated code).
* Handle the corner-case or exiting early from a "keep on screen for n sec" screensaver better, by unscheduling the extra refresh, since an early tap took care of that already.
reviewable/pr8962/r1
NiLuJe 2 years ago committed by GitHub
parent 158f4be724
commit 2aa310a931
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -268,10 +268,6 @@ function Device:onPowerEvent(ev)
end
end
self:resume()
-- Restore to previous rotation mode, if need be.
if self.orig_rotation_mode then
self.screen:setRotationMode(self.orig_rotation_mode)
end
Screensaver:close()
if self:needsScreenRefreshAfterResume() then
UIManager:scheduleIn(1, function() self.screen:refreshFull() end)
@ -293,40 +289,7 @@ function Device:onPowerEvent(ev)
logger.dbg("Suspending...")
-- Add the current state of the SleepCover flag...
logger.dbg("Sleep cover is", self.is_cover_closed and "closed" or "open")
-- Let Screensaver set its widget up, so we get accurate info down the line in case fallbacks kick in...
Screensaver:setup()
-- Mostly always suspend in Portrait/Inverted Portrait mode...
-- ... except when we just show an InfoMessage or when the screensaver
-- is disabled, as it plays badly with Landscape mode (c.f., #4098 and #5290).
-- We also exclude full-screen widgets that work fine in Landscape mode,
-- like ReadingProgress and BookStatus (c.f., #5724)
if Screensaver:modeExpectsPortrait() then
self.orig_rotation_mode = self.screen:getRotationMode()
-- Leave Portrait & Inverted Portrait alone, that works just fine.
if bit.band(self.orig_rotation_mode, 1) == 1 then
-- i.e., only switch to Portrait if we're currently in *any* Landscape orientation (odd number)
self.screen:setRotationMode(self.screen.ORIENTATION_PORTRAIT)
else
self.orig_rotation_mode = nil
end
-- On eInk, if we're using a screensaver mode that shows an image,
-- flash the screen to white first, to eliminate ghosting.
if self:hasEinkScreen() and Screensaver:modeIsImage() then
if Screensaver:withBackground() then
self.screen:clear()
end
self.screen:refreshFull()
-- On Kobo, on sunxi SoCs with a recent kernel, wait a tiny bit more to avoid weird refresh glitches...
if self:isKobo() and self:isSunxi() then
ffiUtil.usleep(150 * 1000)
end
end
else
-- nil it, in case user switched ScreenSaver modes during our lifetime.
self.orig_rotation_mode = nil
end
Screensaver:show()
-- NOTE: show() will return well before the refresh ioctl is even *sent*:
-- the only thing it's done is *enqueued* the refresh in UIManager's stack.

@ -228,36 +228,7 @@ function Kindle:intoScreenSaver()
if self:supportsScreensaver() then
-- NOTE: Meaning this is not a SO device ;)
local Screensaver = require("ui/screensaver")
-- NOTE: Pilefered from Device:onPowerEvent @ frontend/device/generic/device.lua
-- Let Screensaver set its widget up, so we get accurate info down the line in case fallbacks kick in...
Screensaver:setup()
-- Mostly always suspend in Portrait/Inverted Portrait mode...
-- ... except when we just show an InfoMessage or when the screensaver
-- is disabled, as it plays badly with Landscape mode (c.f., #4098 and #5290).
-- We also exclude full-screen widgets that work fine in Landscape mode,
-- like ReadingProgress and BookStatus (c.f., #5724)
if Screensaver:modeExpectsPortrait() then
self.orig_rotation_mode = self.screen:getRotationMode()
-- Leave Portrait & Inverted Portrait alone, that works just fine.
if bit.band(self.orig_rotation_mode, 1) == 1 then
-- i.e., only switch to Portrait if we're currently in *any* Landscape orientation (odd number)
self.screen:setRotationMode(self.screen.ORIENTATION_PORTRAIT)
else
self.orig_rotation_mode = nil
end
-- On eInk, if we're using a screensaver mode that shows an image,
-- flash the screen to white first, to eliminate ghosting.
if self:hasEinkScreen() and Screensaver:modeIsImage() then
if Screensaver:withBackground() then
self.screen:clear()
end
self.screen:refreshFull()
end
else
-- nil it, in case user switched ScreenSaver modes during our lifetime.
self.orig_rotation_mode = nil
end
Screensaver:show()
else
-- Let the native system handle screensavers on SO devices...
@ -276,10 +247,6 @@ function Kindle:outofScreenSaver()
if self.screen_saver_mode == true then
if self:supportsScreensaver() then
local Screensaver = require("ui/screensaver")
-- Restore to previous rotation mode, if need be.
if self.orig_rotation_mode then
self.screen:setRotationMode(self.orig_rotation_mode)
end
Screensaver:close()
-- And redraw everything in case the framework managed to screw us over...
local UIManager = require("ui/uimanager")

@ -21,8 +21,9 @@ local UIManager = require("ui/uimanager")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger")
local _ = require("gettext")
local ffiUtil = require("ffi/util")
local T = ffiUtil.template
local Screen = Device.screen
local T = require("ffi/util").template
-- Default settings
if G_reader_settings:hasNot("screensaver_show_message") then
@ -564,6 +565,39 @@ function Screensaver:show()
return
end
-- We mostly always suspend in Portrait/Inverted Portrait mode...
-- ... except when we just show an InfoMessage or when the screensaver
-- is disabled, as it plays badly with Landscape mode (c.f., #4098 and #5290).
-- We also exclude full-screen widgets that work fine in Landscape mode,
-- like ReadingProgress and BookStatus (c.f., #5724)
if self:modeExpectsPortrait() then
Device.orig_rotation_mode = Screen:getRotationMode()
-- Leave Portrait & Inverted Portrait alone, that works just fine.
if bit.band(Device.orig_rotation_mode, 1) == 1 then
-- i.e., only switch to Portrait if we're currently in *any* Landscape orientation (odd number)
Screen:setRotationMode(Screen.ORIENTATION_PORTRAIT)
else
Device.orig_rotation_mode = nil
end
-- On eInk, if we're using a screensaver mode that shows an image,
-- flash the screen to white first, to eliminate ghosting.
if Device:hasEinkScreen() and self:modeIsImage() then
if self:withBackground() then
Screen:clear()
end
Screen:refreshFull()
-- On Kobo, on sunxi SoCs with a recent kernel, wait a tiny bit more to avoid weird refresh glitches...
if Device:isKobo() and Device:isSunxi() then
ffiUtil.usleep(150 * 1000)
end
end
else
-- nil it, in case user switched ScreenSaver modes during our lifetime.
Device.orig_rotation_mode = nil
end
-- Build the main widget for the effective mode, all the sanity checks were handled in setup
local widget = nil
if self.screensaver_type == "cover" then
@ -712,6 +746,18 @@ function Screensaver:show()
end
end
function Screensaver:close_widget()
logger.dbg("close screensaver")
if self.screensaver_widget then
UIManager:close(self.screensaver_widget)
self.screensaver_widget = nil
end
if self.delayed_close then
self.delayed_close = nil
end
end
function Screensaver:close()
if self.screensaver_widget == nil then
return
@ -720,19 +766,10 @@ function Screensaver:close()
local screensaver_delay = G_reader_settings:readSetting("screensaver_delay")
local screensaver_delay_number = tonumber(screensaver_delay)
if screensaver_delay_number then
UIManager:scheduleIn(screensaver_delay_number, function()
logger.dbg("close screensaver")
if self.screensaver_widget then
UIManager:close(self.screensaver_widget)
self.screensaver_widget = nil
end
end)
UIManager:scheduleIn(screensaver_delay_number, self.close_widget, self)
self.delayed_close = true
elseif screensaver_delay == "disable" then
logger.dbg("close screensaver")
if self.screensaver_widget then
UIManager:close(self.screensaver_widget)
self.screensaver_widget = nil
end
self:close_widget()
else
logger.dbg("tap to exit from screensaver")
end

@ -72,6 +72,13 @@ function ScreenSaverWidget:onTap(_, ges)
end
function ScreenSaverWidget:onClose()
-- If we happened to shortcut a delayed close via user input, unschedule it to avoid a spurious refresh.
local Screensaver = require("ui/screensaver")
if Screensaver.delayed_close then
UIManager:unschedule(Screensaver.close_widget)
Screensaver.delayed_close = nil
end
UIManager:close(self)
return true
end
@ -82,8 +89,15 @@ function ScreenSaverWidget:onAnyKeyPressed()
end
function ScreenSaverWidget:onCloseWidget()
-- Restore to previous rotation mode, if need be.
if Device.orig_rotation_mode then
Screen:setRotationMode(Device.orig_rotation_mode)
Device.orig_rotation_mode = nil
end
-- Make it full-screen (self.main_frame.dimen might be in a different orientation, and it's already full-screen anyway...)
UIManager:setDirty(nil, function()
return "full", self.main_frame.dimen
return "full"
end)
-- Will come after the Resume event, iff screensaver_delay is set.

Loading…
Cancel
Save