Skip to content

Commit 4005bf6

Browse files
authored
Slightly less crappy Nightmode (koreader#4871)
Companion PR to koreader/koreader-base#884 * Basically flags devices known to be stable when using PxP inversion. * Plus, random fix for koreader#4870 ;). * A few FrontLight tweaks & cleanups on Kobo: * Moved the Kobo-specific startup status insanity to Kobo-specific init * Made turnOff/turnOn frontlight do a smooth ramp down/up * On Kobo, use turnOff/turnOn for suspend/resume, to get that smooth toggle * On Kobo, for NaturalLight w/ a mixer, only set warmth for setWarmth, and only set Brightness for setBrightness, otherwise, it tried to set both with not in-sync values, which made the FL widget jittery.
1 parent 8466af2 commit 4005bf6

19 files changed

+181
-122
lines changed

frontend/apps/filemanager/filemanagermenu.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ function FileManagerMenu:setUpdateItemTable()
257257
}
258258
if Device:isKobo() then
259259
table.insert(self.menu_items.developer_options.sub_item_table, {
260-
text = _("Disable forced 8-bit color space"),
260+
text = _("Disable forced 8-bit pixel depth"),
261261
checked_func = function()
262262
return G_reader_settings:isTrue("dev_startup_no_fbdepth")
263263
end,

frontend/apps/reader/modules/readerfrontlight.lua

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function ReaderFrontLight:init()
3838
end
3939

4040
function ReaderFrontLight:onAdjust(arg, ges)
41-
if not Device.hasFrontlight() then return true end
41+
if not Device:hasFrontlight() then return true end
4242
local powerd = Device:getPowerDevice()
4343
logger.dbg("frontlight intensity", powerd:frontlightIntensity())
4444
local step = math.ceil(#self.steps * ges.distance / self.gestureScale)
@@ -65,7 +65,7 @@ function ReaderFrontLight:onAdjust(arg, ges)
6565
end
6666

6767
function ReaderFrontLight:onShowIntensity()
68-
if not Device.hasFrontlight() then return true end
68+
if not Device:hasFrontlight() then return true end
6969
local powerd = Device:getPowerDevice()
7070
local new_text
7171
if powerd:isFrontlightOff() then

frontend/apps/reader/modules/readergesture.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ function ReaderGesture:gestureAction(action, ges)
844844
elseif action == "toc" then
845845
self.ui:handleEvent(Event:new("ShowToc"))
846846
elseif action == "night_mode" then
847-
local night_mode = G_reader_settings:readSetting("night_mode") or false
847+
local night_mode = G_reader_settings:isTrue("night_mode")
848848
Screen:toggleNightMode()
849849
UIManager:setDirty("all", "full")
850850
G_reader_settings:saveSetting("night_mode", not night_mode)

frontend/device/cervantes/powerd.lua

+3-7
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ function CervantesPowerD:init()
6363
self.initial_is_fl_on = true
6464
self.autowarmth_job_running = false
6565

66-
if self.device.hasFrontlight() then
67-
if self.device.hasNaturalLight() then
66+
if self.device:hasFrontlight() then
67+
if self.device:hasNaturalLight() then
6868
local nl_config = G_reader_settings:readSetting("natural_light_config")
6969
if nl_config then
7070
for key,val in pairs(nl_config) do
@@ -86,7 +86,7 @@ function CervantesPowerD:init()
8686
end
8787

8888
function CervantesPowerD:saveSettings()
89-
if self.device.hasFrontlight() then
89+
if self.device:hasFrontlight() then
9090
-- Store BasePowerD values into settings (and not our hw_intensity, so
9191
-- that if frontlight was toggled off, we save and restore the previous
9292
-- untoggled intensity and toggle state at next startup)
@@ -121,10 +121,6 @@ function CervantesPowerD:isFrontlightOnHW()
121121
return self.hw_intensity > 0
122122
end
123123

124-
function CervantesPowerD:turnOffFrontlightHW()
125-
self:_setIntensity(0) -- will call setIntensityHW(0)
126-
end
127-
128124
function CervantesPowerD:setIntensityHW(intensity)
129125
if self.fl == nil then return end
130126
if self.fl_warmth == nil then

frontend/device/generic/device.lua

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ local Device = {
3131
hasClipboard = yes, -- generic internal clipboard on all devices
3232
hasEinkScreen = yes,
3333
canHWDither = no,
34+
canHWInvert = no,
3435
hasColorScreen = no,
3536
hasBGRFrameBuffer = no,
3637
canToggleGSensor = no,

frontend/device/generic/powerd.lua

+9-24
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,9 @@ function BasePowerD:new(o)
1717
self.__index = self
1818
assert(o.fl_min < o.fl_max)
1919
if o.init then o:init() end
20-
if o.device and o.device.hasFrontlight() then
20+
if o.device and o.device:hasFrontlight() then
2121
o.fl_intensity = o:frontlightIntensityHW()
2222
o:_decideFrontlightState()
23-
-- Note added by @Frenzie 2017-10-08
24-
-- I believe this should be `if isKobo()`, or better yet that the entire
25-
-- block should be moved to `KoboPowerD:init()` because afaik that is the
26-
-- only platform where the system doesn't provide trustworthy frontlight
27-
-- information. But to be absolutely sure that I don't break anything (and I
28-
-- don't want to spend any time on this atm) I'm temporarily excluding only
29-
-- Android where this behavior is known to be problematic.
30-
-- See discussion in https://github.com/koreader/koreader/issues/3118#issuecomment-334995879
31-
if not o.device:isAndroid() then
32-
if o:isFrontlightOn() then
33-
o:turnOnFrontlightHW()
34-
else
35-
o:turnOffFrontlightHW()
36-
end
37-
end
3823
end
3924
return o
4025
end
@@ -63,7 +48,7 @@ end
6348

6449
function BasePowerD:_decideFrontlightState()
6550
assert(self ~= nil)
66-
assert(self.device.hasFrontlight())
51+
assert(self.device:hasFrontlight())
6752
self.is_fl_on = self:isFrontlightOnHW()
6853
end
6954

@@ -73,14 +58,14 @@ end
7358

7459
function BasePowerD:frontlightIntensity()
7560
assert(self ~= nil)
76-
if not self.device.hasFrontlight() then return 0 end
61+
if not self.device:hasFrontlight() then return 0 end
7762
if self:isFrontlightOff() then return 0 end
7863
return self.fl_intensity
7964
end
8065

8166
function BasePowerD:toggleFrontlight()
8267
assert(self ~= nil)
83-
if not self.device.hasFrontlight() then return false end
68+
if not self.device:hasFrontlight() then return false end
8469
if self:isFrontlightOn() then
8570
return self:turnOffFrontlight()
8671
else
@@ -90,20 +75,20 @@ end
9075

9176
function BasePowerD:turnOffFrontlight()
9277
assert(self ~= nil)
93-
if not self.device.hasFrontlight() then return end
78+
if not self.device:hasFrontlight() then return end
9479
if self:isFrontlightOff() then return false end
95-
self.is_fl_on = false
9680
self:turnOffFrontlightHW()
81+
self.is_fl_on = false
9782
return true
9883
end
9984

10085
function BasePowerD:turnOnFrontlight()
10186
assert(self ~= nil)
102-
if not self.device.hasFrontlight() then return end
87+
if not self.device:hasFrontlight() then return end
10388
if self:isFrontlightOn() then return false end
10489
if self.fl_intensity == self.fl_min then return false end
105-
self.is_fl_on = true
10690
self:turnOnFrontlightHW()
91+
self.is_fl_on = true
10792
return true
10893
end
10994

@@ -135,7 +120,7 @@ function BasePowerD:normalizeIntensity(intensity)
135120
end
136121

137122
function BasePowerD:setIntensity(intensity)
138-
if not self.device.hasFrontlight() then return false end
123+
if not self.device:hasFrontlight() then return false end
139124
if intensity == self:frontlightIntensity() then return false end
140125
self.fl_intensity = self:normalizeIntensity(intensity)
141126
self:_decideFrontlightState()

frontend/device/kindle/device.lua

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ local Kindle = Generic:new{
7575
-- NOTE: We can cheat by adding a platform-specific entry here, because the only code that will check for this is here.
7676
isSpecialOffers = isSpecialOffers(),
7777
hasOTAUpdates = yes,
78+
-- NOTE: HW inversion is generally safe on mxcfb Kindles
79+
canHWInvert = yes,
7880
}
7981

8082
function Kindle:initNetworkManager(NetworkMgr)
@@ -206,26 +208,30 @@ local Kindle2 = Kindle:new{
206208
hasKeyboard = yes,
207209
hasKeys = yes,
208210
hasDPad = yes,
211+
canHWInvert = no,
209212
}
210213

211214
local KindleDXG = Kindle:new{
212215
model = "KindleDXG",
213216
hasKeyboard = yes,
214217
hasKeys = yes,
215218
hasDPad = yes,
219+
canHWInvert = no,
216220
}
217221

218222
local Kindle3 = Kindle:new{
219223
model = "Kindle3",
220224
hasKeyboard = yes,
221225
hasKeys = yes,
222226
hasDPad = yes,
227+
canHWInvert = no,
223228
}
224229

225230
local Kindle4 = Kindle:new{
226231
model = "Kindle4",
227232
hasKeys = yes,
228233
hasDPad = yes,
234+
canHWInvert = no,
229235
}
230236

231237
local KindleTouch = Kindle:new{

frontend/device/kindle/powerd.lua

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function KindlePowerD:init()
1515
end
1616

1717
function KindlePowerD:frontlightIntensityHW()
18-
if not self.device.hasFrontlight() then return 0 end
18+
if not self.device:hasFrontlight() then return 0 end
1919
-- Kindle stock software does not use intensity file directly, so we need to read from its
2020
-- lipc property first.
2121
if self.lipc_handle ~= nil then
@@ -73,7 +73,7 @@ function KindlePowerD:_readFLIntensity()
7373
end
7474

7575
function KindlePowerD:afterResume()
76-
if not self.device.hasFrontlight() then
76+
if not self.device:hasFrontlight() then
7777
return
7878
end
7979
local UIManager = require("ui/uimanager")

frontend/device/kobo/device.lua

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ local Kobo = Generic:new{
3838
internal_storage_mount_point = "/mnt/onboard/",
3939
-- currently only the Aura One and Forma have coloured frontlights
4040
hasNaturalLight = no,
41+
-- HW inversion is generally safe on Kobo, except on a few baords/kernels
42+
canHWInvert = yes,
4143
}
4244

4345
-- TODO: hasKeys for some devices?
@@ -114,6 +116,8 @@ local KoboPhoenix = Kobo:new{
114116
display_dpi = 212,
115117
-- the bezel covers 12 pixels at the bottom:
116118
viewport = Geom:new{x=0, y=0, w=758, h=1012},
119+
-- NOTE: May have a buggy kernel, according to the nightmode hack...
120+
canHWInvert = no,
117121
}
118122

119123
-- Kobo Aura H2O2:

frontend/device/kobo/powerd.lua

+50-18
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ function KoboPowerD:init()
112112
self.initial_is_fl_on = true
113113
self.autowarmth_job_running = false
114114

115-
if self.device.hasFrontlight() then
115+
if self.device:hasFrontlight() then
116116
-- If this device has natural light (currently only KA1 & Forma)
117117
-- Use the SysFS interface, and ioctl otherwise.
118118
-- NOTE: On the Forma, nickel still appears to prefer using ntx_io to handle the FL,
119119
-- but it does use sysfs for the NL...
120-
if self.device.hasNaturalLight() then
120+
if self.device:hasNaturalLight() then
121121
local nl_config = G_reader_settings:readSetting("natural_light_config")
122122
if nl_config then
123123
for key,val in pairs(nl_config) do
@@ -138,11 +138,20 @@ function KoboPowerD:init()
138138
self:_syncKoboLightOnStart()
139139
end
140140
end
141+
-- See discussion in https://github.com/koreader/koreader/issues/3118#issuecomment-334995879
142+
-- for the reasoning behind this bit of insanity.
143+
if self:isFrontlightOnHW() then
144+
-- Use setIntensity to ensure it sets fl_intensity, and because we don't want the ramping behavior of turnOn
145+
self:setIntensity(self:frontlightIntensityHW())
146+
else
147+
-- Use setIntensityHW so as *NOT* to set fl_intensity, so toggle will still work.
148+
self:setIntensityHW(0)
149+
end
141150
end
142151
end
143152

144153
function KoboPowerD:saveSettings()
145-
if self.device.hasFrontlight() then
154+
if self.device:hasFrontlight() then
146155
-- Store BasePowerD values into settings (and not our hw_intensity, so
147156
-- that if frontlight was toggled off, we save and restore the previous
148157
-- untoggled intensity and toggle state at next startup)
@@ -201,10 +210,6 @@ function KoboPowerD:isFrontlightOnHW()
201210
return self.hw_intensity > 0
202211
end
203212

204-
function KoboPowerD:turnOffFrontlightHW()
205-
self:_setIntensity(0) -- will call setIntensityHW(0)
206-
end
207-
208213
function KoboPowerD:setIntensityHW(intensity)
209214
if self.fl == nil then return end
210215
if self.fl_warmth == nil then
@@ -271,25 +276,52 @@ function KoboPowerD:isChargingHW()
271276
return self:read_str_file(self.is_charging_file) == "Charging\n"
272277
end
273278

279+
function KoboPowerD:turnOffFrontlightHW()
280+
if self:isFrontlightOff() then
281+
return
282+
end
283+
local util = require("ffi/util")
284+
util.runInSubProcess(function()
285+
for i = 1,5 do
286+
self:_setIntensity(math.floor(self.fl_intensity - ((self.fl_intensity / 5) * i)))
287+
-- NOTE: We generally don't need to sleep when using sysfs as a backend...
288+
if not self.device:hasNaturalLight() then
289+
if (i < 5) then
290+
util.usleep(35 * 1000)
291+
end
292+
end
293+
end
294+
end, false, true)
295+
end
296+
function KoboPowerD:turnOnFrontlightHW()
297+
if self:isFrontlightOn() then
298+
return
299+
end
300+
local util = require("ffi/util")
301+
util.runInSubProcess(function()
302+
for i = 1,5 do
303+
self:_setIntensity(math.ceil(self.fl_min + ((self.fl_intensity / 5) * i)))
304+
if not self.device:hasNaturalLight() then
305+
if (i < 5) then
306+
util.usleep(35 * 1000)
307+
end
308+
end
309+
end
310+
end, false, true)
311+
end
312+
274313
-- Turn off front light before suspend.
275314
function KoboPowerD:beforeSuspend()
276315
if self.fl == nil then return end
277-
-- just turn off frontlight without remembering its state
278-
self.fl:setBrightness(0)
316+
-- Turn off the frontlight
317+
self:turnOffFrontlight()
279318
end
280319

281320
-- Restore front light state after resume.
282321
function KoboPowerD:afterResume()
283322
if self.fl == nil then return end
284-
-- just re-set it to self.hw_intensity that we haven't change on Suspend
285-
if self.fl_warmth == nil then
286-
self.fl:setBrightness(self.hw_intensity)
287-
else
288-
if self.auto_warmth then
289-
self:calculateAutoWarmth()
290-
end
291-
self.fl:setNaturalBrightness(self.hw_intensity, self.fl_warmth)
292-
end
323+
-- Turn the frontlight back on
324+
self:turnOnFrontlight()
293325
end
294326

295327
return KoboPowerD

frontend/device/pocketbook/powerd.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function PocketBookPowerD:init()
2222
end
2323

2424
function PocketBookPowerD:frontlightIntensityHW()
25-
if not self.device.hasFrontlight() then return 0 end
25+
if not self.device:hasFrontlight() then return 0 end
2626
return inkview.GetFrontlightState()
2727
end
2828

frontend/device/sony-prstux/powerd.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function SonyPRSTUX_PowerD:init()
1414
end
1515

1616
function SonyPRSTUX_PowerD:frontlightIntensityHW()
17-
if not self.device.hasFrontlight() then return 0 end
17+
if not self.device:hasFrontlight() then return 0 end
1818
end
1919

2020
function SonyPRSTUX_PowerD:setIntensityHW(intensity)

0 commit comments

Comments
 (0)