From 397211644de48eb87742152a74c8f112f0b9d1cf Mon Sep 17 00:00:00 2001 From: poire-z Date: Mon, 25 Nov 2019 14:31:54 +0100 Subject: [PATCH] Keyboard: properly handle keyboard layout height change The japanese keyboard being taller than the others, when switching to/from it from/to another layout: - re-init InputDialog for proper sizing and positionning - refresh the whole screen, to remove any trace of a previous taller keyboard Also add calls to :free() here and there to free keyboard keys' TextWidgets' XText C objects without waiting for GC. --- frontend/ui/widget/inputdialog.lua | 26 +++++++++++++++++++++++++- frontend/ui/widget/inputtext.lua | 7 +++++++ frontend/ui/widget/virtualkeyboard.lua | 21 ++++++++++++++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/frontend/ui/widget/inputdialog.lua b/frontend/ui/widget/inputdialog.lua index b7c1b7445..5cbf3e970 100644 --- a/frontend/ui/widget/inputdialog.lua +++ b/frontend/ui/widget/inputdialog.lua @@ -288,6 +288,15 @@ function InputDialog:init() self.button_table, } + -- Remember provided text_height if any (to restore it on keyboard height change) + if self.orig_text_height == nil then + if self.text_height then + self.orig_text_height = self.text_height + else + self.orig_text_height = false + end + end + -- InputText if not self.text_height or self.fullscreen then -- We need to find the best height to avoid screen overflow @@ -306,7 +315,7 @@ function InputDialog:init() if not self.keyboard_hidden then keyboard_height = input_widget:getKeyboardDimen().h end - input_widget:free() + input_widget:onCloseWidget() -- free() textboxwidget and keyboard -- Find out available height local available_height = Screen:getHeight() - 2*self.border_size @@ -471,6 +480,21 @@ function InputDialog:onShowKeyboard(ignore_first_hold_release) end end +function InputDialog:onKeyboardHeightChanged() + 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 + self:free() + -- Restore original text_height (or reset it if none to force recomputing it) + self.text_height = self.orig_text_height or nil + self:init() + if not self.keyboard_hidden then + self:onShowKeyboard() + end + -- Our position on screen has probably changed, so have the full screen refreshed + UIManager:setDirty("all", "flashui") +end + function InputDialog:onClose() -- Remember current view & position in case of re-init self._top_line_num = self._input_widget.top_line_num diff --git a/frontend/ui/widget/inputtext.lua b/frontend/ui/widget/inputtext.lua index 7d8935553..cec05ac2e 100644 --- a/frontend/ui/widget/inputtext.lua +++ b/frontend/ui/widget/inputtext.lua @@ -406,6 +406,13 @@ function InputText:onCloseKeyboard() UIManager:close(self.keyboard) end +function InputText:onCloseWidget() + if self.keyboard then + self.keyboard:free() + end + self:free() +end + function InputText:getTextHeight() return self.text_widget:getTextHeight() end diff --git a/frontend/ui/widget/virtualkeyboard.lua b/frontend/ui/widget/virtualkeyboard.lua index b371f7a1c..b0b1cab4b 100644 --- a/frontend/ui/widget/virtualkeyboard.lua +++ b/frontend/ui/widget/virtualkeyboard.lua @@ -148,7 +148,7 @@ function VirtualKey:init() file = self.icon, scale_factor = 0, -- keep icon aspect ratio height = icon_height, - width = icon_height * 100, -- to fit height when ensuring a/r + width = self.width - 2*self.bordersize, } else label_widget = TextWidget:new{ @@ -394,6 +394,7 @@ function VirtualKeyPopup:onClose() end function VirtualKeyPopup:onCloseWidget() + self:free() UIManager:setDirty(nil, function() return "ui", self[1][1].dimen end) @@ -698,9 +699,18 @@ function VirtualKeyboard:getKeyboardLayout() end function VirtualKeyboard:setKeyboardLayout(layout) + local prev_keyboard_height = self.dimen and self.dimen.h G_reader_settings:saveSetting("keyboard_layout", layout) self:init() - self:_refresh(true) + if prev_keyboard_height and self.dimen.h ~= prev_keyboard_height then + self:_refresh(true, true) + -- Keyboard height change: notify parent (InputDialog) + if self.inputbox and self.inputbox.parent and self.inputbox.parent.onKeyboardHeightChanged then + self.inputbox.parent:onKeyboardHeightChanged() + end + else + self:_refresh(true) + end end function VirtualKeyboard:onClose() @@ -713,11 +723,15 @@ function VirtualKeyboard:onPressKey() return true end -function VirtualKeyboard:_refresh(want_flash) +function VirtualKeyboard:_refresh(want_flash, fullscreen) local refresh_type = "ui" if want_flash then refresh_type = "flashui" end + if fullscreen then + UIManager:setDirty("all", refresh_type) + return + end UIManager:setDirty(self, function() return refresh_type, self[1][1].dimen end) @@ -757,6 +771,7 @@ function VirtualKeyboard:initLayer(layer) end function VirtualKeyboard:addKeys() + self:free() -- free previous keys' TextWidgets self.layout = {} local base_key_width = math.floor((self.width - (#self.KEYS[1] + 1)*self.key_padding - 2*self.padding)/#self.KEYS[1]) local base_key_height = math.floor((self.height - (#self.KEYS + 1)*self.key_padding - 2*self.padding)/#self.KEYS)