diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index e5c85b640..60c625e42 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -29,7 +29,6 @@ local UIManager = { event_handlers = nil, - _running = true, _now = time.now(), _window_stack = {}, _task_queue = {}, @@ -68,7 +67,11 @@ function UIManager:init() self:nextTick(function() Device:saveSettings() Device:powerOff() - self:quit(Device:isKobo() and 88) + if Device:isKobo() then + self:quit(88) + else + self:quit() + end end) end self.reboot_action = function() @@ -81,11 +84,19 @@ function UIManager:init() self:nextTick(function() Device:saveSettings() Device:reboot() - self:quit(Device:isKobo() and 88) + if Device:isKobo() then + self:quit(88) + else + self:quit() + end end) end Device:_setEventHandlers(self) + + -- A simple wrapper for UIManager:quit() + -- This may be overwritten by setRunForeverMode(); for testing purposes + self._gated_quit = self.quit end --[[-- @@ -116,7 +127,6 @@ function UIManager:show(widget, refreshtype, refreshregion, x, y, refreshdither) end logger.dbg("show widget:", widget.id or widget.name or tostring(widget)) - self._running = true local window = {x = x or 0, y = y or 0, widget = widget} -- put this window on top of the topmost non-modal window for i = #self._window_stack, 0, -1 do @@ -728,13 +738,16 @@ function UIManager:isWidgetShown(widget) end --- Signals to quit. +-- An exit_code of false is not allowed. function UIManager:quit(exit_code) - if not self._running then return end - logger.info("quitting uimanager with exit code:", exit_code or 0) - self._exit_code = exit_code + if exit_code == false then + logger.err("UIManager:quit() called with false") + return + end + -- Also honor older exit codes; default to 0 + self._exit_code = exit_code or self._exit_code or 0 + logger.info("quitting uimanager with exit code:", self._exit_code) self._task_queue_dirty = false - self._running = false - self._run_forever = nil for i = #self._window_stack, 1, -1 do table.remove(self._window_stack, i) end @@ -749,6 +762,21 @@ function UIManager:quit(exit_code) self.looper:close() self.looper = nil end + return self._exit_code +end +dbg:guard(UIManager, 'quit', + function(self, exit_code) + assert(exit_code ~= false, "exit_code == false is not supported") + end) + +-- Disable automatic UIManager quit; for testing purposes +function UIManager:setRunForeverMode() + self._gated_quit = function() return false end +end + +-- Enable automatic UIManager quit; for testing purposes +function UIManager:unsetRunForeverMode() + self._gated_quit = self.quit end --[[-- @@ -1345,10 +1373,11 @@ function UIManager:handleInput() --]] -- stop when we have no window to show - if not self._window_stack[1] and not self._run_forever then + if not self._window_stack[1] then logger.info("no dialog left to show") - self:quit() - return nil + if self:_gated_quit() ~= false then + return nil + end end self:_repaint() @@ -1446,8 +1475,6 @@ This is the main loop of the UI controller. It is intended to manage input events and delegate them to dialogs. --]] function UIManager:run() - self._running = true - -- Tell PowerD that we're ready Device:getPowerDevice():readyUI() @@ -1455,9 +1482,9 @@ function UIManager:run() -- currently there is no Turbo support for Windows -- use our own main loop if not self.looper then - while self._running do + repeat self:handleInput() - end + until self._exit_code else self.looper:add_callback(function() self:handleInput() end) self.looper:start() @@ -1466,12 +1493,6 @@ function UIManager:run() return self._exit_code end --- run uimanager forever for testing purpose -function UIManager:runForever() - self._run_forever = true - return self:run() -end - --[[-- Executes all the operations of a suspension (i.e., sleep) request. diff --git a/spec/unit/autofrontlight_spec.lua b/spec/unit/autofrontlight_spec.lua index 416f641fb..3ee300832 100644 --- a/spec/unit/autofrontlight_spec.lua +++ b/spec/unit/autofrontlight_spec.lua @@ -45,7 +45,7 @@ describe("AutoFrontlight widget tests", function() close() UIManager = require("ui/uimanager") - UIManager._run_forever = true + UIManager:setRunForeverMode() requireBackgroundRunner() class = dofile("plugins/autofrontlight.koplugin/main.lua") diff --git a/spec/unit/autosuspend_spec.lua b/spec/unit/autosuspend_spec.lua index a0492d3cc..79745306c 100644 --- a/spec/unit/autosuspend_spec.lua +++ b/spec/unit/autosuspend_spec.lua @@ -13,7 +13,7 @@ describe("AutoSuspend", function() Device.input.waitEvent = function() end local UIManager = require("ui/uimanager") stub(UIManager, "suspend") - UIManager._run_forever = true + UIManager:setRunForeverMode() G_reader_settings:saveSetting("auto_suspend_timeout_seconds", 10) require("mock_time"):install() -- Reset UIManager:getTime() @@ -71,7 +71,7 @@ describe("AutoSuspend", function() Device.input.waitEvent = function() end local UIManager = require("ui/uimanager") stub(UIManager, "poweroff_action") - UIManager._run_forever = true + UIManager:setRunForeverMode() G_reader_settings:saveSetting("autoshutdown_timeout_seconds", 10) require("mock_time"):install() -- Reset UIManager:getTime() diff --git a/spec/unit/background_runner_spec.lua b/spec/unit/background_runner_spec.lua index 550fd1886..1210be294 100644 --- a/spec/unit/background_runner_spec.lua +++ b/spec/unit/background_runner_spec.lua @@ -12,7 +12,7 @@ describe("BackgroundRunner widget tests", function() MockTime = require("mock_time") MockTime:install() UIManager = require("ui/uimanager") - UIManager._run_forever = true + UIManager:setRunForeverMode() requireBackgroundRunner() end) diff --git a/spec/unit/background_task_plugin_spec.lua b/spec/unit/background_task_plugin_spec.lua index 71bb2c6d0..3c72c8f6c 100644 --- a/spec/unit/background_task_plugin_spec.lua +++ b/spec/unit/background_task_plugin_spec.lua @@ -9,7 +9,7 @@ describe("BackgroundTaskPlugin", function() MockTime:install() local Device = require("device") Device.input.waitEvent = function() end - UIManager._run_forever = true + UIManager:setRunForeverMode() requireBackgroundRunner() -- Monkey patch this method to notify BackgroundRunner -- as it is not accessible to UIManager in these tests diff --git a/spec/unit/httpclient_spec.lua b/spec/unit/httpclient_spec.lua index a9df16fc7..506d35cc9 100644 --- a/spec/unit/httpclient_spec.lua +++ b/spec/unit/httpclient_spec.lua @@ -35,6 +35,7 @@ describe("HTTP client module #notest #nocov", function() url = url, }, response_callback) end - UIManager:runForever() + UIManager:setRunForeverMode() + UIManager:run() end) end) diff --git a/spec/unit/readerlink_spec.lua b/spec/unit/readerlink_spec.lua index e94e0fca8..7ee42ab80 100644 --- a/spec/unit/readerlink_spec.lua +++ b/spec/unit/readerlink_spec.lua @@ -28,6 +28,7 @@ describe("ReaderLink module", function() it("should jump to links in pdf page mode", function() UIManager:quit() + UIManager._exit_code = nil local readerui = ReaderUI:new{ dimen = Screen:getSize(), document = DocumentRegistry:openDocument(sample_pdf), @@ -44,6 +45,7 @@ describe("ReaderLink module", function() it("should jump to links in pdf scroll mode", function() UIManager:quit() + UIManager._exit_code = nil local readerui = ReaderUI:new{ dimen = Screen:getSize(), document = DocumentRegistry:openDocument(sample_pdf), @@ -78,6 +80,7 @@ describe("ReaderLink module", function() it("should be able to go back after link jump in pdf page mode", function() UIManager:quit() + UIManager._exit_code = nil local readerui = ReaderUI:new{ dimen = Screen:getSize(), document = DocumentRegistry:openDocument(sample_pdf), @@ -96,6 +99,7 @@ describe("ReaderLink module", function() it("should be able to go back after link jump in pdf scroll mode", function() UIManager:quit() + UIManager._exit_code = nil local readerui = ReaderUI:new{ dimen = Screen:getSize(), document = DocumentRegistry:openDocument(sample_pdf), @@ -116,6 +120,7 @@ describe("ReaderLink module", function() it("should be able to go back to the same position after link jump in pdf scroll mode", function() UIManager:quit() + UIManager._exit_code = nil local expected_page_states = { { gamma = 1, diff --git a/spec/unit/spore_spec.lua b/spec/unit/spore_spec.lua index f1d4c2990..a8cf17592 100644 --- a/spec/unit/spore_spec.lua +++ b/spec/unit/spore_spec.lua @@ -102,7 +102,8 @@ describe("Lua Spore modules with async http request #notest #nocov", function() client:enable("Format.JSON") client:enable("AsyncHTTP", {thread = co}) coroutine.resume(co) - UIManager:runForever() + UIManager:setRunForeverMode() + UIManager:run() end) it("should complete POST request", function() @@ -117,6 +118,7 @@ describe("Lua Spore modules with async http request #notest #nocov", function() client:enable("Format.JSON") client:enable("AsyncHTTP", {thread = co}) coroutine.resume(co) - UIManager:runForever() + UIManager:setRunForeverMode() + UIManager:run() end) end)