From 4cc620b7028ddfb4b54841d8d5d0142a0ac79f76 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 1 Sep 2023 22:51:41 +0200 Subject: [PATCH] VirtualKeyboard: Revamp visibility handling (#10852) Move as much of the state tracking as possible inside VirtualKeyboard itself. InputDialog unfortunately needs an internal tracking of this state because it needs to know about it *before* the VK is shown, so we have to keep a bit of duplication in there, although we do try much harder to keep everything in sync (at least at function call edges), and to keep the damage contained to, essentially, the toggle button's handler. (Followup to #10803 & #10850) --- .../apps/reader/modules/readerstyletweak.lua | 6 +- frontend/ui/widget/inputdialog.lua | 138 +++++++++++++----- frontend/ui/widget/inputtext.lua | 71 +++++---- frontend/ui/widget/multiinputdialog.lua | 8 +- frontend/ui/widget/physicalkeyboard.lua | 7 + frontend/ui/widget/virtualkeyboard.lua | 44 ++++++ plugins/texteditor.koplugin/main.lua | 16 +- 7 files changed, 209 insertions(+), 81 deletions(-) diff --git a/frontend/apps/reader/modules/readerstyletweak.lua b/frontend/apps/reader/modules/readerstyletweak.lua index eb747fd0d..0a7bc5e23 100644 --- a/frontend/apps/reader/modules/readerstyletweak.lua +++ b/frontend/apps/reader/modules/readerstyletweak.lua @@ -920,10 +920,10 @@ function ReaderStyleTweak:editBookTweak(touchmenu_instance) end end end, - -- Set/save view and cursor position callback + -- Store/retrieve view and cursor position callback view_pos_callback = function(top_line_num, charpos) - -- This same callback is called with no argument to get initial position, - -- and with arguments to give back final position when closed. + -- This same callback is called with no arguments on init to retrieve the stored initial position, + -- and with arguments to store the final position on close. if top_line_num and charpos then self.book_style_tweak_last_edit_pos = {top_line_num, charpos} else diff --git a/frontend/ui/widget/inputdialog.lua b/frontend/ui/widget/inputdialog.lua index d53412f61..907381624 100644 --- a/frontend/ui/widget/inputdialog.lua +++ b/frontend/ui/widget/inputdialog.lua @@ -141,7 +141,7 @@ local InputDialog = FocusManager:extend{ add_scroll_buttons = false, -- add scroll Up/Down buttons to first row of buttons add_nav_bar = false, -- append a row of page navigation buttons -- note that the text widget can be scrolled with Swipe North/South even when no button - keyboard_hidden = false, -- start with keyboard hidden in full fullscreen mode + keyboard_visible = true, -- whether we start with the keyboard visible or not (i.e., our caller skipped onShowKeyboard) -- needs add_nav_bar to have a Show keyboard button to get it back scroll_by_pan = false, -- allow scrolling by lines with Pan (= Swipe, but wait a bit at end -- of gesture before releasing) (may conflict with movable) @@ -162,8 +162,8 @@ local InputDialog = FocusManager:extend{ edited_callback = nil, -- Called on each text modification -- For use by TextEditor plugin: - view_pos_callback = nil, -- Called with no arg to get initial top_line_num/charpos, - -- called with (top_line_num, charpos) to give back position on close. + view_pos_callback = nil, -- Called with no args on init to retrieve top_line_num/charpos (however the caller chooses to do so, e.g., some will store it in a LuaSettings), + -- called with (top_line_num, charpos) on close to let the callback do its thing so that the no args branch spits back useful data.. -- Set to false if movable gestures conflicts with subwidgets gestures is_movable = true, @@ -189,6 +189,7 @@ local InputDialog = FocusManager:extend{ alignment_strict = false, -- for internal use + _keyboard_was_visible = nil, -- previous kb visibility state _text_modified = false, -- previous known modified status _top_line_num = nil, _charpos = nil, @@ -216,7 +217,7 @@ function InputDialog:init() self.text_width = self.text_width or math.floor(self.width * 0.9) end if self.readonly then -- hide keyboard if we can't edit - self.keyboard_hidden = true + self.keyboard_visible = false end if self.fullscreen or self.add_nav_bar then self.deny_keyboard_hiding = true @@ -299,10 +300,7 @@ function InputDialog:init() local text_height = input_widget:getTextHeight() local line_height = input_widget:getLineHeight() local input_pad_height = input_widget:getSize().h - text_height - local keyboard_height = 0 - if not self.keyboard_hidden then - keyboard_height = input_widget:getKeyboardDimen().h - end + local keyboard_height = self.keyboard_visible and input_widget:getKeyboardDimen().h or 0 input_widget:onCloseWidget() -- free() textboxwidget and keyboard -- Find out available height local available_height = self.screen_height @@ -331,9 +329,14 @@ function InputDialog:init() end end if self.view_pos_callback then - -- Get initial cursor and top line num from callback - -- (will work in case of re-init as these are saved by onClose() - self._top_line_num, self._charpos = self.view_pos_callback() + -- Retrieve cursor position and top line num from our callback. + -- Mainly used for runtime re-inits. + -- c.f., our onClose handler for the other end of this. + -- *May* return nils, in which case, we do *not* want to override our caller's values! + local top_line_num, charpos = self.view_pos_callback() + if top_line_num and charpos then + self._top_line_num, self._charpos = top_line_num, charpos + end end self._input_widget = self.inputtext_class:new{ text = self.input, @@ -368,7 +371,6 @@ function InputDialog:init() scroll_by_pan = self.scroll_by_pan, cursor_at_end = self.cursor_at_end, readonly = self.readonly, - manage_keyboard_state = not self.add_nav_bar, -- we handle keyboard toggle ourselve if nav_bar parent = self, is_text_edited = self._text_modified, top_line_num = self._top_line_num, @@ -423,8 +425,7 @@ function InputDialog:init() } frame = self.movable end - local keyboard_height = self.keyboard_hidden and 0 - or self._input_widget:getKeyboardDimen().h + local keyboard_height = self.keyboard_visible and self._input_widget:getKeyboardDimen().h or 0 self[1] = CenterContainer:new{ dimen = Geom:new{ w = self.screen_width, @@ -449,6 +450,11 @@ function InputDialog:init() self:addWidget(widget, true) end end + + -- If we're fullscreen without a keyboard, make sure only the toggle button can show the keyboard... + if self.fullscreen and not self.keyboard_visible then + self:lockKeyboard(true) + end end function InputDialog:addWidget(widget, re_init) @@ -474,13 +480,13 @@ function InputDialog:getAddedWidgetAvailableWidth() return self._input_widget.width end +-- Close the keyboard if we tap anywhere outside of the keyboard (that isn't an input field, where it would be caught via InputText:onTapTextBox) function InputDialog:onTap() + -- This is slightly more fine-grained than VK's own visibility lock, hence the duplication... if self.deny_keyboard_hiding then return end - if self._input_widget.onCloseKeyboard then - self._input_widget:onCloseKeyboard() - end + self:onCloseKeyboard() end function InputDialog:getInputText() @@ -525,24 +531,79 @@ function InputDialog:onCloseWidget() end function InputDialog:onShowKeyboard(ignore_first_hold_release) - if not self.readonly and not self.keyboard_hidden then - self._input_widget:onShowKeyboard(ignore_first_hold_release) - end + -- NOTE: There's no VirtualKeyboard widget instantiated at all when readonly, + -- and our input widget handles that itself, so we don't need any guards here. + -- (In which case, isKeyboardVisible will return `nil`, same as if we had a VK instantiated but *never* shown). + self._input_widget:onShowKeyboard(ignore_first_hold_release) + -- There's a bit of a chicken or egg issue in init where we would like to check the actual keyboard's visibility state, + -- but the widget might not exist or be shown yet, so we'll just have to keep this in sync... + self.keyboard_visible = self._input_widget:isKeyboardVisible() +end + +function InputDialog:onCloseKeyboard() + self._input_widget:onCloseKeyboard() + self.keyboard_visible = self._input_widget:isKeyboardVisible() +end + +function InputDialog:isKeyboardVisible() + return self._input_widget:isKeyboardVisible() end -function InputDialog:toggleKeyboard(force_hide) - if force_hide and self.keyboard_hidden then return end - self.keyboard_hidden = not self.keyboard_hidden +function InputDialog:lockKeyboard(toggle) + return self._input_widget:lockKeyboard(toggle) +end + +-- NOTE: Only called by fullscreen and/or add_nav_bar codepaths +-- We do not currently have !fullscreen add_nav_bar callers... +function InputDialog:toggleKeyboard(force_toggle) + -- Remember the *current* visibility, as the following close will reset it + local visible = self:isKeyboardVisible() + + -- When we forcibly close the keyboard, remember its current visiblity state, so that we can properly restore it later. + -- (This is used by some buttons in fullscreen mode, where we might want to keep the original keyboard hidden when popping up a new one for another InputDialog). + if force_toggle == false then + -- NOTE: visible will be nil between our own init and a show of the keyboard, which is precisely what happens when we *hide* the keyboard. + self._keyboard_was_visible = visible == true + end + self.input = self:getInputText() -- re-init with up-to-date text self:onClose() -- will close keyboard and save view position self:free() + + if force_toggle == false and not visible then + -- Already hidden, bye! + return + end + + -- Init needs to know the keyboard's visibility state *before* the widget is actually shown... + if force_toggle == true then + self.keyboard_visible = true + elseif force_toggle == false then + self.keyboard_visible = false + elseif self._keyboard_was_visible ~= nil then + self.keyboard_visible = self._keyboard_was_visible + self._keyboard_was_visible = nil + else + self.keyboard_visible = not visible + end self:init() - if not self.keyboard_hidden then + + -- NOTE: If we ever have non-fullscreen add_nav_bar callers, it might make sense *not* to lock the keyboard there? + if self.keyboard_visible then + self:lockKeyboard(false) self:onShowKeyboard() + else + self:onCloseKeyboard() + -- Prevent InputText:onTapTextBox from opening the keyboard back up on top of our buttons + self:lockKeyboard(true) end + + -- Make sure we refresh the nav bar, as it will have moved, and it belongs to us, not to VK or our input widget... + self:refreshButtons() end function InputDialog:onKeyboardHeightChanged() + local visible = self:isKeyboardVisible() self.input = self:getInputText() -- re-init with up-to-date text self:onClose() -- will close keyboard and save view position self._input_widget:onCloseWidget() -- proper cleanup of InputText and its keyboard @@ -555,8 +616,11 @@ function InputDialog:onKeyboardHeightChanged() self:free() -- Restore original text_height (or reset it if none to force recomputing it) self.text_height = self.orig_text_height or nil + + -- Same deal as in toggleKeyboard... + self.keyboard_visible = visible self:init() - if not self.keyboard_hidden then + if self.keyboard_visible then self:onShowKeyboard() end -- Our position on screen has probably changed, so have the full screen refreshed @@ -573,14 +637,16 @@ function InputDialog:onCloseDialog() end function InputDialog:onClose() + -- Tell our input widget to poke its text widget so that we'll pickup up to date values + self._input_widget:resyncPos() -- Remember current view & position in case of re-init self._top_line_num = self._input_widget.top_line_num self._charpos = self._input_widget.charpos if self.view_pos_callback then - -- Give back top line num and cursor position + -- This lets the caller store/process the current top line num and cursor position via this callback self.view_pos_callback(self._top_line_num, self._charpos) end - self._input_widget:onCloseKeyboard() + self:onCloseKeyboard() end function InputDialog:refreshButtons() @@ -764,7 +830,7 @@ function InputDialog:_addScrollButtons(nav_bar) -- Also add Keyboard hide/show button if we can if self.fullscreen and not self.readonly then table.insert(row, { - text = self.keyboard_hidden and "↑⌨" or "↓⌨", + text = self.keyboard_visible and "↓⌨" or "↑⌨", id = "keyboard", callback = function() self:toggleKeyboard() @@ -776,8 +842,7 @@ function InputDialog:_addScrollButtons(nav_bar) table.insert(row, { text = _("Find"), callback = function() - local keyboard_hidden_state = not self.keyboard_hidden - self:toggleKeyboard(true) -- hide text editor keyboard + self:toggleKeyboard(false) -- hide text editor keyboard local input_dialog input_dialog = InputDialog:new{ title = _("Enter text to search for"), @@ -790,21 +855,20 @@ function InputDialog:_addScrollButtons(nav_bar) id = "close", callback = function() UIManager:close(input_dialog) - self.keyboard_hidden = keyboard_hidden_state self:toggleKeyboard() end, }, { text = _("Find first"), callback = function() - self:findCallback(keyboard_hidden_state, input_dialog, true) + self:findCallback(input_dialog, true) end, }, { text = _("Find next"), is_enter_default = true, callback = function() - self:findCallback(keyboard_hidden_state, input_dialog) + self:findCallback(input_dialog) end, }, }, @@ -829,8 +893,7 @@ function InputDialog:_addScrollButtons(nav_bar) table.insert(row, { text = _("Go"), callback = function() - local keyboard_hidden_state = not self.keyboard_hidden - self:toggleKeyboard(true) -- hide text editor keyboard + self:toggleKeyboard(false) -- hide text editor keyboard local cur_line_num, last_line_num = self._input_widget:getLineNums() local input_dialog input_dialog = InputDialog:new{ @@ -846,7 +909,6 @@ function InputDialog:_addScrollButtons(nav_bar) id = "close", callback = function() UIManager:close(input_dialog) - self.keyboard_hidden = keyboard_hidden_state self:toggleKeyboard() end, }, @@ -857,7 +919,6 @@ function InputDialog:_addScrollButtons(nav_bar) local new_line_num = tonumber(input_dialog:getInputText()) if new_line_num and new_line_num >= 1 and new_line_num <= last_line_num then UIManager:close(input_dialog) - self.keyboard_hidden = keyboard_hidden_state self:toggleKeyboard() self._input_widget:moveCursorToCharPos(self._input_widget:getLineCharPos(new_line_num)) end @@ -939,11 +1000,10 @@ function InputDialog:_addScrollButtons(nav_bar) end end -function InputDialog:findCallback(keyboard_hidden_state, input_dialog, find_first) +function InputDialog:findCallback(input_dialog, find_first) self.search_value = input_dialog:getInputText() if self.search_value == "" then return end UIManager:close(input_dialog) - self.keyboard_hidden = keyboard_hidden_state self:toggleKeyboard() local start_pos = find_first and 1 or self._charpos + 1 local char_pos = util.stringSearch(self.input, self.search_value, self.case_sensitive, start_pos) diff --git a/frontend/ui/widget/inputtext.lua b/frontend/ui/widget/inputtext.lua index e1e21ec4f..5ccf45b8d 100644 --- a/frontend/ui/widget/inputtext.lua +++ b/frontend/ui/widget/inputtext.lua @@ -32,9 +32,8 @@ local InputText = InputContainer:extend{ focused = true, parent = nil, -- parent dialog that will be set dirty edit_callback = nil, -- called with true when text modified, false on init or text re-set - scroll_callback = nil, -- called with (low, high) when view is scrolled (cf ScrollTextWidget) + scroll_callback = nil, -- called with (low, high) when view is scrolled (c.f., ScrollTextWidget) scroll_by_pan = false, -- allow scrolling by lines with Pan (needs scroll=true) - manage_keyboard_state = true, -- manage keyboard hidden/shown state width = nil, height = nil, -- when nil, will be set to original text height (possibly @@ -54,7 +53,10 @@ local InputText = InputContainer:extend{ auto_para_direction = false, alignment_strict = false, + readonly = nil, -- will not support a Keyboard widget if true + -- for internal use + keyboard = nil, -- Keyboard widget (either VirtualKeyboard or PhysicalKeyboard) text_widget = nil, -- Text Widget for cursor movement, possibly a ScrollTextWidget charlist = nil, -- table of individual chars from input string charpos = nil, -- position of the cursor, where a new char would be inserted @@ -65,7 +67,6 @@ local InputText = InputContainer:extend{ for_measurement_only = nil, -- When the widget is a one-off used to compute text height do_select = false, -- to start text selection selection_start_pos = nil, -- selection start position - is_keyboard_hidden = true, -- to be able to show the keyboard again when it was hidden. (On init, it's the caller's responsibility to call onShowKeyboard, as far as we're concerned, it's hidden) } -- These may be (internally) overloaded as needed, depending on Device capabilities. @@ -73,6 +74,11 @@ function InputText:initEventListener() end function InputText:onFocus() end function InputText:onUnfocus() end +-- Resync our position state with our text widget's actual state +function InputText:resyncPos() + self.charpos, self.top_line_num = self.text_widget:getCharPos() +end + local function initTouchEvents() if Device:isTouchDevice() then function InputText:initEventListener() @@ -133,8 +139,8 @@ local function initTouchEvents() if self.parent.onSwitchFocus then self.parent:onSwitchFocus(self) else - if self.is_keyboard_hidden and self.manage_keyboard_state then - self:onShowKeyboard() + if self.keyboard then + self.keyboard:showKeyboard() end end -- zh keyboard with candidates shown here has _frame_textwidget.dimen = nil. @@ -144,7 +150,7 @@ local function initTouchEvents() local x = ges.pos.x - self._frame_textwidget.dimen.x - textwidget_offset local y = ges.pos.y - self._frame_textwidget.dimen.y - textwidget_offset self.text_widget:moveCursorToXY(x, y, true) -- restrict_to_view=true - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end return true end @@ -512,7 +518,7 @@ function InputText:initTextBox(text, char_added) } end -- Get back possibly modified charpos and virtual_line_num - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() self._frame_textwidget = FrameContainer:new{ bordersize = self.bordersize, @@ -676,22 +682,27 @@ dbg:guard(InputText, "onTextInput", end) function InputText:onShowKeyboard(ignore_first_hold_release) - Device:startTextInput() - - if self.is_keyboard_hidden or not self.manage_keyboard_state then - self.keyboard.ignore_first_hold_release = ignore_first_hold_release - UIManager:show(self.keyboard) - self.is_keyboard_hidden = false + if self.keyboard then + self.keyboard:showKeyboard(ignore_first_hold_release) end return true end function InputText:onCloseKeyboard() - Device:stopTextInput() + if self.keyboard then + self.keyboard:hideKeyboard() + end +end + +function InputText:isKeyboardVisible() + if self.keyboard then + return self.keyboard:isVisible() + end +end - if not self.is_keyboard_hidden or not self.manage_keyboard_state then - UIManager:close(self.keyboard) - self.is_keyboard_hidden = true +function InputText:lockKeyboard(toggle) + if self.keyboard then + return self.keyboard:lockVisibility(toggle) end end @@ -873,71 +884,71 @@ end function InputText:leftChar() if self.charpos == 1 then return end self.text_widget:moveCursorLeft() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:rightChar() if self.charpos > #self.charlist then return end self.text_widget:moveCursorRight() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:goToStartOfLine() local new_pos = select(1, self:getStringPos({"\n", "\r"}, {"\n", "\r"})) self.text_widget:moveCursorToCharPos(new_pos) - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:goToEndOfLine() local new_pos = select(2, self:getStringPos({"\n", "\r"}, {"\n", "\r"})) + 1 self.text_widget:moveCursorToCharPos(new_pos) - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:goToHome() self.text_widget:moveCursorHome() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:goToEnd() self.text_widget:moveCursorEnd() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:moveCursorToCharPos(char_pos) self.text_widget:moveCursorToCharPos(char_pos) - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:upLine() self.text_widget:moveCursorUp() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:downLine() if #self.charlist == 0 then return end -- Avoid cursor moving within a hint. self.text_widget:moveCursorDown() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:scrollDown() self.text_widget:scrollDown() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:scrollUp() self.text_widget:scrollUp() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:scrollToTop() self.text_widget:scrollToTop() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:scrollToBottom() self.text_widget:scrollToBottom() - self.charpos, self.top_line_num = self.text_widget:getCharPos() + self:resyncPos() end function InputText:clear() diff --git a/frontend/ui/widget/multiinputdialog.lua b/frontend/ui/widget/multiinputdialog.lua index df3a9aa66..2c002ab20 100644 --- a/frontend/ui/widget/multiinputdialog.lua +++ b/frontend/ui/widget/multiinputdialog.lua @@ -218,7 +218,9 @@ end function MultiInputDialog:onSwitchFocus(inputbox) -- unfocus current inputbox self._input_widget:unfocus() - self._input_widget:onCloseKeyboard() + -- and close its existing keyboard (via InputDialog's thin wrapper around _input_widget's own method) + self:onCloseKeyboard() + UIManager:setDirty(nil, function() return "ui", self.dialog_frame.dimen end) @@ -226,7 +228,9 @@ function MultiInputDialog:onSwitchFocus(inputbox) -- focus new inputbox self._input_widget = inputbox self._input_widget:focus() - self._input_widget:onShowKeyboard() + + -- Make sure we have a (new) visible keyboard + self:onShowKeyboard() end return MultiInputDialog diff --git a/frontend/ui/widget/physicalkeyboard.lua b/frontend/ui/widget/physicalkeyboard.lua index b16f1af4d..c47a52b3c 100644 --- a/frontend/ui/widget/physicalkeyboard.lua +++ b/frontend/ui/widget/physicalkeyboard.lua @@ -169,4 +169,11 @@ function PhysicalKeyboard:setupNumericMappingUI() self.dimen = keyboard_frame:getSize() end +-- Match VirtualKeyboard's API to ease caller's life +function PhysicalKeyboard:lockVisibility() end +function PhysicalKeyboard:setVisibility() end +function PhysicalKeyboard:isVisible() return true end +function PhysicalKeyboard:showKeyboard() end +function PhysicalKeyboard:hideKeyboard() end + return PhysicalKeyboard diff --git a/frontend/ui/widget/virtualkeyboard.lua b/frontend/ui/widget/virtualkeyboard.lua index 84771c89e..d982ce772 100644 --- a/frontend/ui/widget/virtualkeyboard.lua +++ b/frontend/ui/widget/virtualkeyboard.lua @@ -755,6 +755,8 @@ end local VirtualKeyboard = FocusManager:extend{ name = "VirtualKeyboard", + visible = nil, + lock_visibility = false, covers_footer = true, modal = true, disable_double_tap = true, @@ -929,11 +931,53 @@ end function VirtualKeyboard:onShow() self:_refresh(true) + self.visible = true + Device:startTextInput() return true end function VirtualKeyboard:onCloseWidget() self:_refresh(true) + self.visible = false + -- NOTE: This effectively stops SDL text input when a keyboard is hidden (... but navigational stuff still works). + -- If you instead wanted it to be enabled as long as an input dialog is displayed, regardless of VK's state, + -- this could be moved to InputDialog's onShow/onCloseWidget handlers (but, it would allow input on unfocused fields). + -- NOTE: But something more complex, possibly based on an in-class ref count would have to be implemented in order to be able to deal + -- with multiple InputDialogs being shown and closed in asymmetric fashion... Ugh. + Device:stopTextInput() +end + +function VirtualKeyboard:lockVisibility(toggle) + self.lock_visibility = toggle +end + +function VirtualKeyboard:setVisibility(toggle) + if self.lock_visibility then + return + end + + if toggle then + UIManager:show(self) + else + self:onClose() + end +end + +function VirtualKeyboard:isVisible() + return self.visible +end + +function VirtualKeyboard:showKeyboard(ignore_first_hold_release) + if not self:isVisible() then + self.ignore_first_hold_release = ignore_first_hold_release + self:setVisibility(true) + end +end + +function VirtualKeyboard:hideKeyboard() + if self:isVisible() then + self:setVisibility(false) + end end function VirtualKeyboard:initLayer(layer) diff --git a/plugins/texteditor.koplugin/main.lua b/plugins/texteditor.koplugin/main.lua index 5f4eb65b0..8c2f34364 100644 --- a/plugins/texteditor.koplugin/main.lua +++ b/plugins/texteditor.koplugin/main.lua @@ -545,13 +545,13 @@ function TextEditor:editFile(file_path, readonly) cursor_at_end = false, readonly = readonly, add_nav_bar = true, - keyboard_hidden = not self.show_keyboard_on_start, + keyboard_visible = self.show_keyboard_on_start, -- InputDialog will enforce false if readonly scroll_by_pan = true, buttons = {buttons_first_row}, - -- Set/save view and cursor position callback + -- Store/retrieve view and cursor position callback view_pos_callback = function(top_line_num, charpos) - -- This same callback is called with no argument to get initial position, - -- and with arguments to give back final position when closed. + -- This same callback is called with no arguments on init to retrieve the stored initial position, + -- and with arguments to store the final position on close. if top_line_num and charpos then self.last_view_pos[file_path] = {top_line_num, charpos} else @@ -572,7 +572,7 @@ function TextEditor:editFile(file_path, readonly) end, -- File saving callback save_callback = function(content, closing) -- Will add Save/Close buttons - if self.readonly then + if readonly then -- We shouldn't be called if read-only, but just in case return false, _("File is read only") end @@ -641,8 +641,10 @@ Do you want to keep this file as empty, or do you prefer to delete it? } UIManager:show(input) - input:onShowKeyboard() - -- Note about self.readonly: + if self.show_keyboard_on_start and not readonly then + input:onShowKeyboard() + end + -- Note about readonly: -- We might have liked to still show keyboard even if readonly, just -- to use the arrow keys for line by line scrolling with cursor. -- But it's easier to just let InputDialog and InputText do their