From 66754e30688c9736947a680212409c037a438a6a Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Thu, 26 May 2016 23:32:41 -0700 Subject: [PATCH 1/3] ignore kobo build --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bcf7e344c..accf69fef 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ koreader-android-arm-linux-androideabi koreader-kindle-legacy-arm-kindle-linux-gnueabi koreader-kindle-arm-linux-gnueabi koreader-kobo-arm-linux-gnueabihf* +koreader-kobo-arm-kobo-linux-gnueabi koreader-emulator-i686-w64-mingw32 koreader-emulator-x86_64-linux-gnu koreader-emulator-x86_64-pc-linux-gnu From ac03cd241fc0c6b6b68fa67b9026aaa4a5677c48 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 29 May 2016 19:36:51 -0700 Subject: [PATCH 2/3] fm(fix): close filemanager before showReader This removes filemanager from UI widget stack so it does not listen to events sent to the reader. Before this patch, screenshot event will be sent to filemanager. --- frontend/apps/filemanager/filemanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index c670774a0..49b0cac8e 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -89,6 +89,7 @@ function FileManager:init() self.file_chooser = file_chooser function file_chooser:onFileSelect(file) -- luacheck: ignore + FileManager.instance:onClose() local ReaderUI = require("apps/reader/readerui") ReaderUI:showReader(file) return true From a92a88e063ef20bf35249dc3665edadb020d4297 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 29 May 2016 21:57:27 -0700 Subject: [PATCH 3/3] uimanager(fix): check active widgets in the correct order --- frontend/ui/uimanager.lua | 32 +++++++++++---- spec/unit/uimanager_spec.lua | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 9 deletions(-) diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 0509f54ac..9ae907ac3 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -381,19 +381,33 @@ end -- transmit an event to an active widget function UIManager:sendEvent(event) if #self._window_stack == 0 then return end + + local top_widget = self._window_stack[#self._window_stack] -- top level widget has first access to the event - if self._window_stack[#self._window_stack].widget:handleEvent(event) then + if top_widget.widget:handleEvent(event) then return end - - -- if the event is not consumed, active widgets can access it - for _, widget in ipairs(self._window_stack) do - if widget.widget.is_always_active then - if widget.widget:handleEvent(event) then return end + if top_widget.widget.active_widgets then + for _, active_widget in ipairs(top_widget.widget.active_widgets) do + if active_widget:handleEvent(event) then return end end - if widget.widget.active_widgets then - for _, active_widget in ipairs(widget.widget.active_widgets) do - if active_widget:handleEvent(event) then return end + end + + -- if the event is not consumed, active widgets (from top to bottom) can + -- access it. NOTE: _window_stack can shrink on close event + local checked_widgets = {top_widget} + for i = #self._window_stack-1, 1, -1 do + local widget = self._window_stack[i] + if checked_widgets[widget] == nil then + if widget.widget.is_always_active then + checked_widgets[widget] = true + if widget.widget:handleEvent(event) then return end + end + if widget.widget.active_widgets then + checked_widgets[widget] = true + for _, active_widget in ipairs(widget.widget.active_widgets) do + if active_widget:handleEvent(event) then return end + end end end end diff --git a/spec/unit/uimanager_spec.lua b/spec/unit/uimanager_spec.lua index e74ed26ba..1b2a530dd 100644 --- a/spec/unit/uimanager_spec.lua +++ b/spec/unit/uimanager_spec.lua @@ -191,4 +191,83 @@ describe("UIManager spec", function() UIManager.auto_suspend_action) Device.isKobo = old_is_kobo end) + + it("should check active widgets in order", function() + local call_signals = {false, false, false} + UIManager._window_stack = { + { + widget = { + is_always_active = true, + handleEvent = function() + call_signals[1] = true + return true + end + } + }, + { + widget = { + is_always_active = true, + handleEvent = function() + call_signals[2] = true + return true + end + } + }, + { + widget = { + is_always_active = true, + handleEvent = function() + call_signals[3] = true + return true + end + } + }, + {widget = {handleEvent = function()end}}, + } + + UIManager:sendEvent("foo") + assert.falsy(call_signals[1]) + assert.falsy(call_signals[2]) + assert.truthy(call_signals[3]) + end) + + it("should handle stack change when checking for active widgets", function() + -- this senario should only happen when other active widgets + -- are closed by the one widget's handleEvent + + local call_signals = {0, 0, 0} + UIManager._window_stack = { + { + widget = { + is_always_active = true, + handleEvent = function() + call_signals[1] = call_signals[1] + 1 + end + } + }, + { + widget = { + is_always_active = true, + handleEvent = function() + call_signals[2] = call_signals[2] + 1 + end + } + }, + { + widget = { + is_always_active = true, + handleEvent = function() + call_signals[3] = call_signals[3] + 1 + table.remove(UIManager._window_stack, 2) + end + } + }, + {widget = {handleEvent = function()end}}, + } + + UIManager:sendEvent("foo") + assert.is.same(call_signals[1], 1) + assert.is.same(call_signals[2], 0) + assert.is.same(call_signals[3], 1) + end) end)