Skip to content

Instantly share code, notes, and snippets.

@faaarmer
Created January 25, 2026 05:58
Show Gist options
  • Select an option

  • Save faaarmer/31ba44f42e6242a835b6af0dc3f3c9be to your computer and use it in GitHub Desktop.

Select an option

Save faaarmer/31ba44f42e6242a835b6af0dc3f3c9be to your computer and use it in GitHub Desktop.
Koreader patch to block landscape rotations the gyro on Kobo Libra 2
--[[
User patch to disable landscape rotation on Kobo devices when using accelerometer-based auto-rotation.
This patch blocks landscape orientations (CLOCKWISE and COUNTER_CLOCKWISE) while allowing
portrait orientations (UPRIGHT and UPSIDE_DOWN).
Installation:
1. Create a 'patches' folder in your koreader directory if it doesn't exist
2. Save this file as: 2-portrait-only-rotation.lua
3. Place it in: /koreader/patches/
4. Restart KOReader
The patch will automatically be applied on startup.
Compatible with: KOReader 2025.10 and similar versions
Device: Kobo Libra 2 (and other Kobo devices)
Author: Custom patch for portrait-only auto-rotation
Version: 6.0 - Final
]]
local logger = require("logger")
local Device = require("device")
-- Get the C constants - they're in the ffi.C namespace, not a module
local ffi = require("ffi")
local C = ffi.C
-- Define the raw gyro sensor values based on actual testing
local MSC_RAW_GSENSOR_PORTRAIT_1 = 23 -- Portrait orientation 1
local MSC_RAW_GSENSOR_PORTRAIT_2 = 24 -- Portrait orientation 2
local MSC_RAW_GSENSOR_LANDSCAPE_1 = 25 -- Landscape orientation 1 (BLOCKED)
local MSC_RAW_GSENSOR_LANDSCAPE_2 = 26 -- Landscape orientation 2 (BLOCKED)
-- We need to wrap the Input's eventAdjustHook at the instance level
-- Store the original adjustEv function from the Input instance
local Input = Device.input
local originalAdjustEv = Input.eventAdjustHook
-- Create our filtering hook
Input.eventAdjustHook = function(self, ev)
-- Log all MSC_RAW events to see what we're getting
if ev.type == C.EV_MSC and ev.code == C.MSC_RAW then
logger.info("portrait-only-rotation: Raw gyro event detected, value:", ev.value)
-- Block landscape rotations at the raw sensor level
if ev.value == MSC_RAW_GSENSOR_LANDSCAPE_1 then
logger.info("portrait-only-rotation: BLOCKING LANDSCAPE_1 (value 25)")
return nil -- Block this event completely
elseif ev.value == MSC_RAW_GSENSOR_LANDSCAPE_2 then
logger.info("portrait-only-rotation: BLOCKING LANDSCAPE_2 (value 26)")
return nil -- Block this event completely
else
logger.info("portrait-only-rotation: Allowing rotation event value:", ev.value)
end
end
-- For all other events (including portrait rotations), call the original hook if it exists
if originalAdjustEv then
return originalAdjustEv(self, ev)
end
return ev
end
logger.info("portrait-only-rotation: User patch v6.0 loaded - landscape rotations will be blocked")
logger.info("portrait-only-rotation: Portrait modes: 23, 24 | Landscape modes (blocked): 25, 26")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment