diff --git a/frontend/apps/filemanager/filemanagermenu.lua b/frontend/apps/filemanager/filemanagermenu.lua index 1f1000e5c..58ce7dccf 100644 --- a/frontend/apps/filemanager/filemanagermenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -66,6 +66,7 @@ end FileManagerMenu.onPhysicalKeyboardConnected = FileManagerMenu.registerKeyEvents +-- NOTE: FileManager emits a SetDimensions on init, it's our only caller function FileManagerMenu:initGesListener() if not Device:isTouchDevice() then return end @@ -968,10 +969,11 @@ function FileManagerMenu:onShowMenu(tab_index) end function FileManagerMenu:onCloseFileManagerMenu() - if not self.menu_container then return end + if not self.menu_container then return true end local last_tab_index = self.menu_container[1].last_index G_reader_settings:saveSetting("filemanagermenu_tab_index", last_tab_index) UIManager:close(self.menu_container) + self.menu_container = nil return true end @@ -1009,11 +1011,14 @@ function FileManagerMenu:onSwipeShowMenu(ges) end function FileManagerMenu:onSetDimensions(dimen) - self:onCloseFileManagerMenu() - -- update listening according to new screen dimen - if Device:isTouchDevice() then - self:initGesListener() + -- This widget doesn't support in-place layout updates, so, close & reopen + if self.menu_container then + self:onCloseFileManagerMenu() + self:onShowMenu() end + + -- update gesture zones according to new screen dimen + self:initGesListener() end function FileManagerMenu:onMenuSearch() diff --git a/frontend/apps/reader/modules/readerconfig.lua b/frontend/apps/reader/modules/readerconfig.lua index 89ca40a94..6d09f25fa 100644 --- a/frontend/apps/reader/modules/readerconfig.lua +++ b/frontend/apps/reader/modules/readerconfig.lua @@ -158,11 +158,11 @@ function ReaderConfig:onSwipeShowConfigMenu(ges) end end +-- For some reason, things are fine and dandy without any of this for rotations, but we need it for actual resizes... function ReaderConfig:onSetDimensions(dimen) - -- since we cannot redraw config_dialog with new size, we close - -- the old one on screen size change if self.config_dialog then - self.config_dialog:closeDialog() + -- init basically calls update & initGesListener and nothing else, which is exactly what we want. + self.config_dialog:init() end end diff --git a/frontend/apps/reader/modules/readermenu.lua b/frontend/apps/reader/modules/readermenu.lua index a12a219f6..029491786 100644 --- a/frontend/apps/reader/modules/readermenu.lua +++ b/frontend/apps/reader/modules/readermenu.lua @@ -95,7 +95,7 @@ function ReaderMenu:getPreviousFile() return require("readhistory"):getPreviousFile(self.ui.document.file) end -function ReaderMenu:onReaderReady() +function ReaderMenu:initGesListener() if not Device:isTouchDevice() then return end local DTAP_ZONE_MENU = G_defaults:readSetting("DTAP_ZONE_MENU") @@ -179,6 +179,8 @@ function ReaderMenu:onReaderReady() }) end +ReaderMenu.onReaderReady = ReaderMenu.initGesListener + function ReaderMenu:setUpdateItemTable() for _, widget in pairs(self.registered_widgets) do local ok, err = pcall(widget.addToMainMenu, widget, self.menu_items) @@ -456,16 +458,24 @@ function ReaderMenu:onShowMenu(tab_index) end function ReaderMenu:onCloseReaderMenu() - if self.menu_container then - self.last_tab_index = self.menu_container[1].last_index - self:onSaveSettings() - UIManager:close(self.menu_container) - end + if not self.menu_container then return true end + self.last_tab_index = self.menu_container[1].last_index + self:onSaveSettings() + UIManager:close(self.menu_container) + self.menu_container = nil return true end function ReaderMenu:onSetDimensions(dimen) - self:onCloseReaderMenu() + -- This widget doesn't support in-place layout updates, so, close & reopen + if self.menu_container then + self:onCloseReaderMenu() + self:onShowMenu() + end + + -- update gesture zones according to new screen dimen + -- (On CRe, this will get called a second time by ReaderReady once the document is reloaded). + self:initGesListener() end function ReaderMenu:onCloseDocument() diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index f1169bca8..807226b00 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -815,12 +815,32 @@ end function ReaderView:onSetRotationMode(rotation) if rotation ~= nil then - if rotation == Screen:getRotationMode() then + local old_rotation = Screen:getRotationMode() + if rotation == old_rotation then return true end + + -- NOTE: We cannot rely on getScreenMode, as it actually checks the screen dimensions, instead of the rotation mode. + -- (i.e., it returns how the screen *looks* like, not how it's oriented relative to its native layout). + -- This would horribly break if you started in Portrait (both rotation and visually), + -- then resized your window to a Landscape layout *without* changing the rotation. + -- If you then attempted to switch to a Landscape *rotation*, it would mistakenly think the layout hadn't changed! + -- So, instead, as we're concerned with *rotation* layouts, just compare the two. + -- We use LinuxFB-style constants, so, Portraits are even, Landscapes are odds, making this trivial. + local matching_orientation = bit.band(rotation, 1) == bit.band(old_rotation, 1) + + if rotation ~= old_rotation and matching_orientation then + -- No layout change, just rotate & repaint with a flash + Screen:setRotationMode(rotation) + UIManager:setDirty(self.dialog, "full") + Notification:notify(T(_("Rotation mode set to: %1"), optionsutil:getOptionText("SetRotationMode", rotation))) + return true + end + Screen:setRotationMode(rotation) end - UIManager:setDirty(self.dialog, "full") + + UIManager:setDirty(nil, "full") -- SetDimensions will only request a partial, we want a flash local new_screen_size = Screen:getSize() self.ui:handleEvent(Event:new("SetDimensions", new_screen_size)) self.ui:onScreenResize(new_screen_size) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index 8f3b6a8ae..5da55ebdf 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -984,39 +984,37 @@ end --- (Translation should be done via registerEventAdjustHook in Device implementations). --- This needs to be called *via handleGyroEv* in a handleMiscEv implementation (c.f., Kobo, Kindle or PocketBook). function Input:handleMiscGyroEv(ev) - local rotation_mode, screen_mode + local rotation if ev.value == C.DEVICE_ROTATED_UPRIGHT then -- i.e., UR - rotation_mode = framebuffer.DEVICE_ROTATED_UPRIGHT - screen_mode = "portrait" + rotation = framebuffer.DEVICE_ROTATED_UPRIGHT elseif ev.value == C.DEVICE_ROTATED_CLOCKWISE then -- i.e., CW - rotation_mode = framebuffer.DEVICE_ROTATED_CLOCKWISE - screen_mode = "landscape" + rotation = framebuffer.DEVICE_ROTATED_CLOCKWISE elseif ev.value == C.DEVICE_ROTATED_UPSIDE_DOWN then -- i.e., UD - rotation_mode = framebuffer.DEVICE_ROTATED_UPSIDE_DOWN - screen_mode = "portrait" + rotation = framebuffer.DEVICE_ROTATED_UPSIDE_DOWN elseif ev.value == C.DEVICE_ROTATED_COUNTER_CLOCKWISE then -- i.e., CCW - rotation_mode = framebuffer.DEVICE_ROTATED_COUNTER_CLOCKWISE - screen_mode = "landscape" + rotation = framebuffer.DEVICE_ROTATED_COUNTER_CLOCKWISE else -- Discard FRONT/BACK return end - local old_rotation_mode = self.device.screen:getRotationMode() + local old_rotation = self.device.screen:getRotationMode() if self.device:isGSensorLocked() then - local old_screen_mode = self.device.screen:getScreenMode() - if rotation_mode and rotation_mode ~= old_rotation_mode and screen_mode == old_screen_mode then + local matching_orientation = bit.band(rotation, 1) == bit.band(old_rotation, 1) + if rotation and rotation ~= old_rotation and matching_orientation then -- Cheaper than a full SetRotationMode event, as we don't need to re-layout anything. - self.device.screen:setRotationMode(rotation_mode) + self.device.screen:setRotationMode(rotation) UIManager:onRotation() end else - if rotation_mode and rotation_mode ~= old_rotation_mode then - return Event:new("SetRotationMode", rotation_mode) + if rotation and rotation ~= old_rotation then + -- NOTE: We do *NOT* send a broadcast manually, and instead rely on the main loop's sendEvent: + -- this ensures that only widgets that actually know how to handle a rotation will do so ;). + return Event:new("SetRotationMode", rotation) end end end diff --git a/frontend/ui/widget/configdialog.lua b/frontend/ui/widget/configdialog.lua index e01dbbb90..d4ff3bfa4 100644 --- a/frontend/ui/widget/configdialog.lua +++ b/frontend/ui/widget/configdialog.lua @@ -897,9 +897,7 @@ function ConfigDialog:init() end end -function ConfigDialog:updateConfigPanel(index) - -end +function ConfigDialog:updateConfigPanel(index) end function ConfigDialog:update() self:moveFocusTo(1, 1) -- reset selected for re-created layout