Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Koreader page turn buttons do not switch with rotation #9223

Closed
wxletter opened this issue Jun 16, 2022 · 48 comments
Closed

Koreader page turn buttons do not switch with rotation #9223

wxletter opened this issue Jun 16, 2022 · 48 comments
Labels
Android firmware User patch available Request is odd, specific, or complicated to do properly - but a user patch is provided

Comments

@wxletter
Copy link

wxletter commented Jun 16, 2022

  • KOReader version: 2022.5.1
  • Device: MOAAN MIX7, it's an e-ink reader running Android 11, with physical volume control buttons

Issue

I enabled page turn with volume control buttons in Koreader and it works but for one problem. When I hold MIX7 with my right hand I can turn page forward with upper button and turn page backward with lower button which is fine. When I hold MIX7 with my left hand, the page rotates automatically but the page turn buttons "reversed" - page turn forward with lower button and backward with upper button, i.e. the button functions do not switch with device and page rotation.

It seems that turn page forward/backward is fixed to the volume up/down button and do not switch with rotation. I tried with some other apps (like Kindle app) without this problem.

I found this thread (#6842) about adding "rotation_map" config in koreader/frontend/device/input.lua, but unfortunately I'm not able to access koreader/frontend folder - at least this folder is not accessible without root on MIX7

Steps to reproduce

  1. hold MIX7 with right hand and open koreader
  2. turn page with volume buttons
  3. hold it with left hand, and the page turn buttons are "reversed" due to rotation
crash.log

crash.log

@NiLuJe NiLuJe added the Android label Jun 17, 2022
@pazos pazos changed the title Koreader page turn button switch with rotation Koreader page turn buttons do not switch with rotation Jun 17, 2022
@wxletter
Copy link
Author

Anyone can help on this?
I think it would happen on any Android device with volume control buttons

@wxletter
Copy link
Author

This problem also exists in the newly released 2022.06 version

@pazos
Copy link
Member

pazos commented Jun 24, 2022

Anyone can help on this?

We rely on motivated contributors. Hopefully somebody will do it. If not you can do it. That's how every contributor started :)

This problem also exists in the newly released 2022.06 version

And will exist in every version until this ticket is closed and hence the problem solved ;)

@wxletter
Copy link
Author

We rely on motivated contributors. Hopefully somebody will do it. If not you can do it. That's how every contributor started :)

I intended to resolve this problem by changing some config file or so, but unfortunately I don't know much about Android and those .lua files... will dig deeper to see how/what I can do about it.

@wxletter
Copy link
Author

I found the key code of my Android e-ink reader (by running adb shell and logcat | grep "keycode”): the upper button's key code is "24" and the lower's is "25" (when they're on the right side of the device). I tested with putting a file named "event_map.lua" in koreader/settings with the below contents:

return { [25] = "RPgBack", [24] = "RPgFwd", }

So is there any way to return the above values when I'm holding the device with my right hand, and return [25] = "RPgFwd" and [24] = "RPgBack" when I'm holding it with my left hand (buttons on the left)? i.e. how to define if/else statements with rotation?

@poire-z
Copy link
Contributor

poire-z commented Jun 27, 2022

Looks like there is already some code that should deal with that (and your keys):

-- NOTE: When looking at the device in Portrait mode, that's assuming PgBack is on TOP, and PgFwd on the BOTTOM
rotation_map = {
[framebuffer.ORIENTATION_PORTRAIT] = {},
[framebuffer.ORIENTATION_LANDSCAPE] = { Up = "Right", Right = "Down", Down = "Left", Left = "Up", LPgBack = "LPgFwd", LPgFwd = "LPgBack", RPgBack = "RPgFwd", RPgFwd = "RPgBack" },
[framebuffer.ORIENTATION_PORTRAIT_ROTATED] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right", LPgFwd = "LPgBack", LPgBack = "LPgFwd", RPgFwd = "RPgBack", RPgBack = "RPgFwd" },
[framebuffer.ORIENTATION_LANDSCAPE_ROTATED] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" }
},

-- take device rotation into account
if self.rotation_map[self.device.screen:getRotationMode()][keycode] then
keycode = self.rotation_map[self.device.screen:getRotationMode()][keycode]
end

@wxletter
Copy link
Author

Looks like there is already some code that should deal with that (and your keys):

-- NOTE: When looking at the device in Portrait mode, that's assuming PgBack is on TOP, and PgFwd on the BOTTOM
rotation_map = {
[framebuffer.ORIENTATION_PORTRAIT] = {},
[framebuffer.ORIENTATION_LANDSCAPE] = { Up = "Right", Right = "Down", Down = "Left", Left = "Up", LPgBack = "LPgFwd", LPgFwd = "LPgBack", RPgBack = "RPgFwd", RPgFwd = "RPgBack" },
[framebuffer.ORIENTATION_PORTRAIT_ROTATED] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right", LPgFwd = "LPgBack", LPgBack = "LPgFwd", RPgFwd = "RPgBack", RPgBack = "RPgFwd" },
[framebuffer.ORIENTATION_LANDSCAPE_ROTATED] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" }
},

-- take device rotation into account
if self.rotation_map[self.device.screen:getRotationMode()][keycode] then
keycode = self.rotation_map[self.device.screen:getRotationMode()][keycode]
end

Thanks @poire-z, but I'm not able to access koreader/frontend folder without root on my device, so I'm trying to find a way to deal with this problem without hacking it. Is there a way to make rotation_map and the codes work without accessing/editing files in koreader/frontend?

@poire-z
Copy link
Contributor

poire-z commented Jun 27, 2022

I don't mean you should hack these files. I'm mentionning that support for switching buttons when the device is rotated is already there, and that your use case should already be supported.
If it is not, we (actually, somebody else than me, because I'm not familiar with all the input stuff) should try to understand why it doesn't work for you. (May be that is just for Kobo/Kindle, and on Android, it is not at play as all this should be handled by Android?)
But may be check in the various menus (under the Gear icon probably) if there is an option to enable/disable gyroscope/buttons stuff.

@pazos
Copy link
Member

pazos commented Jun 27, 2022

I don't mean you should hack these files. I'm mentionning that support for switching buttons when the device is rotated is already there, and that your use case should already be supported.

Indeed, the bits of logic are there and should work at least for devices that start in portrait mode.

android's getRotationMode returns one of this four numbers which are exactly the same as https://github.com/koreader/koreader-base/blob/master/ffi/framebuffer.lua#L72-L76

@wxletter
Copy link
Author

I understand, by "hacking" I mean to get root privilege of the Android device, since I'm not able to access koreader/frontend folder without root privilege, neither with Android file explorer nor with adb. It seems that if I can get my hands on koreader/frontend folder and the files it SHOULD work.

@wxletter
Copy link
Author

Are you sure there's a folder named "frontend" under "sdcard/koreader" in Android? I can't see folder "frontend" and I tried to create a folder named "frontend" in folder "koreader" and succeeded.

@Frenzie
Copy link
Member

Frenzie commented Jun 28, 2022

/sdcard/koreader is just the settings. The program itself usually lives in /data/app/etc.

@wxletter
Copy link
Author

Oh... so "koreader/frontend" is not the "koreader" folder I can see under "sdcard" but rather in /data/app/etc. then it's another story of Android, sadly to say that it's probably not what I can resolve regarding this device's os.

@Frenzie
Copy link
Member

Frenzie commented Jun 28, 2022

More or less. In principle it's not excessively hard to take the APK file on your PC, change a few files and then sign it, though it's quite awkward.

@wxletter
Copy link
Author

More or less. In principle it's not excessively hard to take the APK file on your PC, change a few files and then sign it, though it's quite awkward.

Many thanks Frenzie, maybe awkward as it seems but it's probably the easiest way for me to resolve this problem, will try.

@CrazyCoder
Copy link
Contributor

I noticed this issue on the Onyx Leaf 2 Android device which has hardware page turn buttons.

What happens is that the framework does the rotation for the buttons automatically, which works for all the system and third-party apps.

KOReader is too smart, detests that the screen is rotated and does it again, reversing what the framework did.

I replaced the code with [framebuffer.ORIENTATION_PORTRAIT_ROTATED] = {} to disable KOReader rotation and it now works as expected.

What we need is a setting that will disable automatic rotation for hardware buttons in KOReader (easy) or a special Quirk for devices that do the rotation automatically (harder, needs verifying on real hardware).

I also tested with the patched framework which disables framework processing of the hardware buttons, and KOReader works just fine without any modifications to input.lua (but you lose automatic button rotation in all the other apps).

@NiLuJe
Copy link
Member

NiLuJe commented Nov 16, 2022

What we need is a setting that will disable automatic rotation for hardware buttons in KOReader (easy) or a special Quirk for devices that do the rotation automatically (harder, needs verifying on real hardware).

c.f., 43b021d (from #9691) ;).

@wxletter
Copy link
Author

I replaced the code with [framebuffer.ORIENTATION_PORTRAIT_ROTATED] = {} to disable KOReader rotation and it now works as expected.

That's great to know @CrazyCoder, however since I'm not able to "root" my device I cannot touch input.lua, do you know if there's any other way to change this setting?

@CrazyCoder
Copy link
Contributor

@wxletter If you don't have root, you can build your own copy of KOReader from sources with this modification, sign it with your own keys, uninstall the official KOReader and install your modded version instead. I did exactly that. The build guide is a bit outdated in some places, and you will likely face several issues not covered in the guide, but it's doable with some googling.

@CrazyCoder
Copy link
Contributor

@NiLuJe Yes, we need something like that for Android devices in general. Maybe add a developer/advanced option to disable it so that we don't have to patch KOReader until the proper fix is available?

@poire-z
Copy link
Contributor

poire-z commented Nov 16, 2022

Also see https://github.com/koreader/koreader/wiki/User-patches (which should work on Android) for this kind of quick hacking or replacing some existing property.

@NiLuJe
Copy link
Member

NiLuJe commented Nov 16, 2022

^ This. (You can nil it at any time after Device has been initialized).

@CrazyCoder
Copy link
Contributor

CrazyCoder commented Nov 16, 2022

I've made a patch and it works! Thanks for the tips. Place the file inside koreader/patches on the device storage.

2-disable-hw-button-rotation.lua

@wxletter
Copy link
Author

I've made a patch and it works! Thanks for the tips. Place the file inside koreader/patches on the device storage.

2-disable-hw-button-rotation.lua

I placed 2-disable-hw-button-rotation.lua under sdcard/koreader/patches and it's still the same, do I need to add/edit other files that'll be referenced by this .lua file?

@NiLuJe
Copy link
Member

NiLuJe commented Nov 17, 2022

  • KOReader version: 2022.5.1

You need to update to a current release ;).

@wxletter
Copy link
Author

  • KOReader version: 2022.5.1

You need to update to a current release ;).

I forgot to mention that I uninstalled 2022.5.1, installed 2022.10 and then placed 2-disable-hw-button-rotation.lua under sdcard/koreader/patches, and the keys still work as before, couldn't figure it out.

@pazos
Copy link
Member

pazos commented Nov 17, 2022

You will need to figure out what happens with adb.

First check that the patch is applied without errors.

If that's the case then double check the key events your device produces. See #5761 (comment)

@innocenat
Copy link

innocenat commented Nov 23, 2022

I poked around the code and found that the patch actually didn't work, at least in the latest version.

Because the patch just does Device.input.rotation_map = nil, in the latest version, it get re-set by the Input script because it now has nil check.

if not self.rotation_map then
self.rotation_map = {
[framebuffer.ORIENTATION_PORTRAIT] = {},
[framebuffer.ORIENTATION_LANDSCAPE] = { Up = "Right", Right = "Down", Down = "Left", Left = "Up", LPgBack = "LPgFwd", LPgFwd = "LPgBack", RPgBack = "RPgFwd", RPgFwd = "RPgBack" },
[framebuffer.ORIENTATION_PORTRAIT_ROTATED] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right", LPgFwd = "LPgBack", LPgBack = "LPgFwd", RPgFwd = "RPgBack", RPgBack = "RPgFwd" },
[framebuffer.ORIENTATION_LANDSCAPE_ROTATED] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" }
}
end

Instead, I just remapped it to be entirely blank and it works beautifully on my Boox Leaf 2.

local logger = require("logger")
local Device = require("device")
Device.input.rotation_map = {
    [0] = {},
    [1] = {},
    [2] = {},
    [3] = {},
}
logger.info("Hardware button rotation disabled by user patch")

@NiLuJe
Copy link
Member

NiLuJe commented Nov 23, 2022

I did mention that the patch would have to run after Device's init (it's the only codepath instantiating Input, and both are singletons).

@innocenat
Copy link

With all respect to you as a project member on this wonderful software, there are no simple documentation as to which patch number run before or after Device init, and whether there even is one for after Device init.

My intention of posting the alternative patch is to help other people with the same problem who may stumbled upon this issue :)

@NiLuJe
Copy link
Member

NiLuJe commented Nov 23, 2022

https://github.com/koreader/koreader/wiki/User-patches#installation :? (i.e., 2-).

The nil approach currently does require a nightly though (it landed after the 2022.10 release), which is most likely your original issue ;).

@innocenat
Copy link

innocenat commented Nov 23, 2022

That page mention nothing of where Device is initialised. I would guess you know since, well, you are a project member, but we (the one who isn't familiar with koreader but want to use them properly) don't.

Also am I missing something or when someone ask that the aforementioned patch (with nil) doesn't work, you suggested them to update to the current version, which is 2022.10, which you also know doesn't fix said problem?

@NiLuJe
Copy link
Member

NiLuJe commented Nov 23, 2022

That page mention nothing of where Device is initialised. I would guess you know since, well, you are a project member, but we (the one who isn't familiar with koreader but want to use them properly) don't.

True enough, although process of elimination and common sense would get you there anyway since "not early" was kind of the point ;).

Also am I missing something or when someone ask that the aforementioned patch (with nil) doesn't work, you suggested them to update to the current version, which is 2022.10, which you also know doesn't fix said problem?

Yup, I possibly thought it made it in 2022.10 in my original answer, which is why I clarified here.

@wxletter
Copy link
Author

Instead, I just remapped it to be entirely blank and it works beautifully on my Boox Leaf 2.

local logger = require("logger")
local Device = require("device")
Device.input.rotation_map = {
    [0] = {},
    [1] = {},
    [2] = {},
    [3] = {},
}
logger.info("Hardware button rotation disabled by user patch")

Thanks so much @innocenat , this saved my world.
And then I run into another issue.
In the system settings I configured the upper button (no matter how I hold the device) for next page and lower button for previous page, this setting works find for other apps but is reversed for KOreader: when I press the up button KOreader turns to previous page and lower button to next page. The rotation map works fine, just the 2 button functions are reversed in KOreader. Could this be fixed easily? If no then I'll live with it, no big deal :)

@NiLuJe
Copy link
Member

NiLuJe commented Nov 24, 2022

@wxletter: c.f., the keymapping section of https://github.com/koreader/koreader/wiki/Android-tips-and-tricks

@wxletter
Copy link
Author

I read this thread but couldn't figure out how/what to do due to my poor knowledge of .lua and how KOerader works...
This reversed button issue has gone away after I restarted KOreader several times, don't know why but now it works perfectly fine with the config provided by @innocenat

@wxletter
Copy link
Author

Hope this can be fixed with future releases, or I'm not sure for how long the patch file will survive :)

@pazos
Copy link
Member

pazos commented Nov 24, 2022

Hope this can be fixed with future releases, or I'm not sure for how long the patch file will survive :)

There's nothing to fix. Please use the patch and comment here if some day it stops working.

@pazos pazos closed this as completed Nov 24, 2022
@pazos pazos added firmware User patch available Request is odd, specific, or complicated to do properly - but a user patch is provided labels Nov 24, 2022
@Denisuu
Copy link

Denisuu commented Dec 24, 2022

I'm a bit confused on how I can get this to work. I also have the Onyx Leaf 2 with KOreader version v2022.11

Placing 2-disable-hw-button-rotation.lua under koreader/patches/ doesn't work.

Do I need to make a folder koreader/frontend/device/, then put input.lua in there and modify lines 264 - 271? Do I need both the patch and the modified input.lua? Do I need to use KoReader 2022.10 or below?

@NiLuJe
Copy link
Member

NiLuJe commented Dec 24, 2022

The patch should behave, although only on 2022.11; the latest nightlies would require a different patch (c.f., my latest merge).

@Denisuu
Copy link

Denisuu commented Dec 24, 2022

I re-installed the latest APK from Github, it's working now!
Thanks everyone, happy holidays!

@NiLuJe
Copy link
Member

NiLuJe commented Dec 25, 2022

And now that I'm back home, for nightlies post-#9935 or releases >= 2022.12, this patch becomes

local logger = require("logger")
local Device = require("device")
Device.input:disableRotationMap()
logger.info("Hardware button rotation disabled by user patch")

Barring any future API changes, the variant posted in #9223 (comment) will still work, too (because it's essentially what the new method does ;p)!

@Denisuu
Copy link

Denisuu commented Dec 25, 2022

I don't think I understood post-#9935 fully. You do need root access and modify the files below right?

Leaf2:/ # find /data -name "input.lua"                                                                                                                                                       
/data/data/org.koreader.launcher/files/frontend/device/input.lua

Not just make a folder /sdcard/koreader/frontend/device/ and put input.lua in there.

The current patch doesn't work with v2022.11 from F-Droid only with the one from GitHub.

Thanks for checking!

@NiLuJe
Copy link
Member

NiLuJe commented Dec 25, 2022

User-patches are disabled in the F-Droid flavor (per F-Droid restrictions about "no runtime code modification") ;).

No, the post above was just a heads-up for patch users that this would need a different patch starting with the next release (or current nightlies).

You don't have access to the actual app code on Android (barring root access), and even if you do, that wouldn't survive an update, and is generally a terrible idea unless you know what you're doing, hence the patches ;).

@shin3c
Copy link

shin3c commented Mar 22, 2023

And now that I'm back home, for nightlies post-#9935 or releases >= 2022.12, this patch becomes

local logger = require("logger")
local Device = require("device")
Device.input:disableRotationMap()
logger.info("Hardware button rotation disabled by user patch")

Barring any future API changes, the variant posted in #9223 (comment) will still work, too (because it's essentially what the new method does ;p)!

This patch is still valid for Onyx Boox Leaf on version 2023.03.

@kesselborn
Copy link

for the Pocketbook Era I had to use the following patch (the others did not work correctly):

local logger = require("logger")
local Device = require("device")
Device.input.rotation_map = {
   [0] = { Up = "Up",  Right = "Right", Down = "Down",    Left = "Left", LPgFwd  = "LPgFwd", LPgBack = "LPgBack",  RPgFwd  = "RPgFwd", RPgBack = "RPgBack" },
   [1] = { Up = "Right", Right = "Down", Down = "Left",  Left = "Up",    LPgBack = "LPgFwd",  LPgFwd  = "LPgBack", RPgBack = "RPgFwd",  RPgFwd  = "RPgBack" },
   [2] = { Up = "Down",  Right = "Left", Down = "Up",    Left = "Right", LPgFwd  = "LPgBack", LPgBack = "LPgFwd",  RPgFwd  = "RPgBack", RPgBack = "RPgFwd" },
   [3] = { Up = "Left",  Right = "Up",   Down = "Right", Left = "Down" }
}
logger.info("Hardware button rotation disabled by user patch")

it could probably be simplified with empty {} for some positions, but it works and I am too lazy to mount/unmount for trying it out

@foxmean
Copy link

foxmean commented Feb 7, 2024

Is this possible to included in the future released? Because I installed KOreader from F-Droid, I cannot install this patch. My device is Boox Leaf 2 on firmware 2023-11-29_16-54_3.5_c3a890b73.

@foxmean
Copy link

foxmean commented Feb 7, 2024

Never mind. I've just download KOReader 2024.01 "Snowy Summit" directly and install plugin from @NiLuJe

And now that I'm back home, for nightlies post-#9935 or releases >= 2022.12, this patch becomes

local logger = require("logger")
local Device = require("device")
Device.input:disableRotationMap()
logger.info("Hardware button rotation disabled by user patch")

Barring any future API changes, the variant posted in #9223 (comment) will still work, too (because it's essentially what the new method does ;p)!

And it valid for Boox Leaf 2 on firmware 2023-11-29_16-54_3.5_c3a890b73.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android firmware User patch available Request is odd, specific, or complicated to do properly - but a user patch is provided
Projects
None yet
Development

No branches or pull requests