From dc59391632219e71a756a6123952d8e1f1d0eea6 Mon Sep 17 00:00:00 2001 From: yparitcher Date: Fri, 23 Jul 2021 07:27:12 -0400 Subject: [PATCH] Dispatcher: use UIManager:sendEvent instead of the current instance (#7999) This fixes inheritance issues when changing documents. Also allow "Go to page" in FM. --- doc/Events.md | 1 + frontend/dispatcher.lua | 64 +++++++++++++++--------------- plugins/gestures.koplugin/main.lua | 2 +- plugins/profiles.koplugin/main.lua | 2 +- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/doc/Events.md b/doc/Events.md index 4a347155f..b9816d84f 100644 --- a/doc/Events.md +++ b/doc/Events.md @@ -10,6 +10,7 @@ to a widget, you can simply invoke the handleEvent method like the following: ```lua widget_foo:handleEvent(Event:new("Timeout")) ``` +If the widget can be destroyed during the event you should call @{ui.uimanager:sendEvent|UIManager:sendEvent} to propagate the event from the topmost widget or @{ui.uimanager:broadcastEvent|UIManager:broadcastEvent} to send the event to all widgets. Events are passed to child Widgets (or child containers) before their own handler sees them. See the implementation of WidgetContainer:handleEvent(). So a child widget, for instance a text input widget, gets the input events before the layout manager. The child widgets can "consume" an event by returning `true` from the event handler. Thus a text input widget just implements an input handler and consumes left/right presses, returning `true` in those cases. It can even make its return code dependent on whether the cursor is on the last position (do not consume press to right) or first position (do not consume press to left) to have proper focus movement in those cases. diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index 1c13c4bf2..ca273eb29 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -103,7 +103,7 @@ local settingsList = { last_page = {category="none", event="GoToEnd", title=_("Last page"), rolling=true, paging=true}, prev_bookmark = {category="none", event="GotoPreviousBookmarkFromPage", title=_("Previous bookmark"), rolling=true, paging=true}, next_bookmark = {category="none", event="GotoNextBookmarkFromPage", title=_("Next bookmark"), rolling=true, paging=true}, - go_to = {category="none", event="ShowGotoDialog", title=_("Go to page"), rolling=true, paging=true}, + go_to = {category="none", event="ShowGotoDialog", title=_("Go to page"), filemanager=true, rolling=true, paging=true}, skim = {category="none", event="ShowSkimtoDialog", title=_("Skim document"), rolling=true, paging=true}, back = {category="none", event="Back", title=_("Back"), rolling=true, paging=true}, previous_location = {category="none", event="GoBackLink", arg=true, title=_("Back to previous location"), rolling=true, paging=true}, @@ -616,47 +616,45 @@ arguments are: 2) the settings table 3) optionally a `gestures`object --]]-- -function Dispatcher:execute(ui, settings, gesture) +function Dispatcher:execute(settings, gesture) for k, v in pairs(settings) do if settingsList[k] ~= nil and (settingsList[k].conditions == nil or settingsList[k].conditions == true) then -- Be sure we don't send a document setting event if there's not yet or no longer a document - if ui.document or (not settingsList[k].paging and not settingsList[k].rolling) then - Notification:setNotifySource(Notification.SOURCE_DISPATCHER) - if settingsList[k].category == "none" then - if settingsList[k].arg ~= nil then - ui:handleEvent(Event:new(settingsList[k].event, settingsList[k].arg)) - else - ui:handleEvent(Event:new(settingsList[k].event)) - end - end - if settingsList[k].category == "absolutenumber" - or settingsList[k].category == "string" - then - ui:handleEvent(Event:new(settingsList[k].event, v)) - end - -- the event can accept a gesture object or an argument - if settingsList[k].category == "arg" then - local arg = gesture or settingsList[k].arg - ui:handleEvent(Event:new(settingsList[k].event, arg)) + Notification:setNotifySource(Notification.SOURCE_DISPATCHER) + if settingsList[k].category == "none" then + if settingsList[k].arg ~= nil then + UIManager:sendEvent(Event:new(settingsList[k].event, settingsList[k].arg)) + else + UIManager:sendEvent(Event:new(settingsList[k].event)) end - -- the event can accept a gesture object or a number - if settingsList[k].category == "incrementalnumber" then - local arg = v ~= 0 and v or gesture or 0 - ui:handleEvent(Event:new(settingsList[k].event, arg)) - end - if ui.document and settingsList[k].configurable then - local value = v - if type(v) ~= "number" then - for i, r in ipairs(settingsList[k].args) do - if v == r then value = settingsList[k].configurable.values[i] break end - end + end + if settingsList[k].category == "absolutenumber" + or settingsList[k].category == "string" + then + UIManager:sendEvent(Event:new(settingsList[k].event, v)) + end + -- the event can accept a gesture object or an argument + if settingsList[k].category == "arg" then + local arg = gesture or settingsList[k].arg + UIManager:sendEvent(Event:new(settingsList[k].event, arg)) + end + -- the event can accept a gesture object or a number + if settingsList[k].category == "incrementalnumber" then + local arg = v ~= 0 and v or gesture or 0 + UIManager:sendEvent(Event:new(settingsList[k].event, arg)) + end + if settingsList[k].configurable then + local value = v + if type(v) ~= "number" then + for i, r in ipairs(settingsList[k].args) do + if v == r then value = settingsList[k].configurable.values[i] break end end - ui:handleEvent(Event:new("ConfigChange", settingsList[k].configurable.name, value)) end + UIManager:sendEvent(Event:new("ConfigChange", settingsList[k].configurable.name, value)) end end + Notification:resetNotifySource() end - Notification:resetNotifySource() end return Dispatcher diff --git a/plugins/gestures.koplugin/main.lua b/plugins/gestures.koplugin/main.lua index 9fd5b251b..29c0b7581 100644 --- a/plugins/gestures.koplugin/main.lua +++ b/plugins/gestures.koplugin/main.lua @@ -1085,7 +1085,7 @@ function Gestures:gestureAction(action, ges) return else self.ui:handleEvent(Event:new("HandledAsSwipe")) - Dispatcher:execute(self.ui, action_list, ges) + Dispatcher:execute(action_list, ges) end return true end diff --git a/plugins/profiles.koplugin/main.lua b/plugins/profiles.koplugin/main.lua index b4a58af0b..13eea1cf2 100644 --- a/plugins/profiles.koplugin/main.lua +++ b/plugins/profiles.koplugin/main.lua @@ -113,7 +113,7 @@ function Profiles:getSubMenuItems() hold_keep_menu_open = false, sub_item_table = sub_items, hold_callback = function() - Dispatcher:execute(self.ui, self.data[k]) + Dispatcher:execute(self.data[k]) end, }) end