mobile fixes

This commit is contained in:
bryanthaboi
2026-07-31 23:47:28 -04:00
parent 9bcfdb1f0d
commit a33f3b1ceb
3 changed files with 40 additions and 21 deletions
+8 -4
View File
@@ -476,10 +476,14 @@ function love.mousepressed(x, y, button, istouch)
-- meant two choose() calls and two stacked SAF picker activities: the
-- player picked their ROM, the top picker closed, and the second was still
-- underneath asking for it again, which is the "import the file twice"
-- in #553. Filtering on istouch rather than on the OS keeps a real mouse
-- (DeX, a Chromebook, a USB mouse) working, which an Android-wide return
-- would have broken.
if istouch then return end
-- in #553. Filtering on istouch keeps a real mouse (DeX, a Chromebook, a
-- USB mouse) working, which an Android-wide return would have broken.
--
-- ANDROID ONLY, and the OS test is load bearing: love.touchpressed above
-- returns early on iOS and never forwards, so there the synthesized mouse
-- press is the ONLY event the launcher gets. Filtering istouch on both
-- killed every tap on iOS outright.
if istouch and love.system.getOS() == "Android" then return end
return Importer:mousepressed(x, y, button)
end
if editorMode and EditorApp.mousepressed then
+10 -14
View File
@@ -1017,7 +1017,6 @@ function RomImporter:chooseMod()
else
self.pickPending = true
self.pickTimer = 0
self.pickElapsed = 0
end
return
end
@@ -1082,7 +1081,6 @@ function RomImporter:chooseSaveImport(version)
else
self.pickPending = true
self.pickTimer = 0
self.pickElapsed = 0
end
return
end
@@ -1121,7 +1119,6 @@ function RomImporter:exportSave(version)
if love.system.createFile and love.system.createFile(suggested) then
self.pickPending = true
self.pickTimer = 0
self.pickElapsed = 0
self.saveNotice[version] = { ok = true,
text = "Pick where to save " .. suggested .. "..." }
else
@@ -1177,7 +1174,6 @@ function RomImporter:choose(version)
else
self.pickPending = true
self.pickTimer = 0
self.pickElapsed = 0
end
return
end
@@ -1225,18 +1221,18 @@ end
-- for the next tap to find, which is what made users import twice and
-- what made it look random: it depends on memory pressure (#553).
--
-- Disarms after PICK_TIMEOUT so a cancelled picker (which delivers nothing,
-- ever) does not leave this scanning the save directory for the whole session.
local PICK_TIMEOUT = 120
-- Deliberately NO timeout. A version of this disarmed the poll after 120s so a
-- cancelled picker would stop scanning, which was wrong on iOS: the picker there
-- is an in-process modal sheet, so update() keeps running while it is open and
-- the window burned down while the player was still browsing Files. The pick
-- then landed with nothing armed to consume it, and because every path here is
-- silent on success the import just did not happen, with no error shown. A
-- half-second directory listing on a menu screen is far cheaper than an import
-- that vanishes, so the poll stays armed until something is actually consumed.
function RomImporter:_pollPickedFiles(dt)
if not self.pickPending then return end
if self.workState == "working" then return end
self.pickElapsed = (self.pickElapsed or 0) + dt
if self.pickElapsed > PICK_TIMEOUT then
self.pickPending, self.pickElapsed = nil, nil
return
end
self.pickTimer = (self.pickTimer or 0) + dt
if self.pickTimer < 0.5 then return end
self.pickTimer = 0
@@ -1246,7 +1242,7 @@ function RomImporter:_pollPickedFiles(dt)
local pickError = love.filesystem.read("pick_error.txt")
if pickError then
love.filesystem.remove("pick_error.txt")
self.pickPending, self.pickElapsed = nil, nil
self.pickPending = nil
self.modNotice = { ok = false, text = pickError }
self.notice = { version = self.chooseVersion or "red",
status = "File import failed:", detail = pickError }
@@ -1263,7 +1259,7 @@ function RomImporter:_pollPickedFiles(dt)
end
end
if found then
self.pickPending, self.pickElapsed = nil, nil
self.pickPending = nil
self:focus(true)
end
end
+22 -3
View File
@@ -96,9 +96,13 @@ local fired = false
ri3.focus = function(self, f) if f then fired = true end end
ri3:_pollPickedFiles(0.6)
check(not fired, "an empty save dir consumes nothing")
check(ri3.pickPending, "and stays armed while it is still within the timeout")
ri3:_pollPickedFiles(200)
check(not ri3.pickPending, "a cancelled pick disarms instead of polling forever")
check(ri3.pickPending, "and stays armed, waiting for the pick to land")
-- No timeout on purpose: a 120s disarm silently dropped iOS imports, because the
-- picker there is an in-process sheet and update() keeps running while the
-- player browses Files. Staying armed costs a directory listing; disarming cost
-- the import, with no error shown.
ri3:_pollPickedFiles(600)
check(ri3.pickPending, "and is still armed after a long browse in the picker")
-- 5. A pick that is still importing must not be double-started.
saveDir = { ["picked_mod.zip"] = "PK\003\004" }
@@ -131,6 +135,21 @@ contract:choose("red")
check(picks == 2,
"choose() still reopens the picker per call (#420/#442 contract, got " .. picks .. ")")
-- 7. iOS taps must survive the Android double-fire guard. love.touchpressed in
-- main.lua returns early on iOS and never forwards, so the synthesized
-- love.mousepressed is the ONLY event the launcher gets there. Filtering
-- istouch on both platforms killed every tap on iOS. The guard is Android
-- only, and this pins the asymmetry the guard depends on.
local touchForwardsToImporter = {
Android = true, -- love.touchpressed -> Importer:mousepressed
iOS = false, -- returns early; mousepressed(istouch=true) is the only path
}
for os, forwards in pairs(touchForwardsToImporter) do
local dropSynthesized = (os == "Android")
check(dropSynthesized == forwards,
os .. ": the synthesized mouse press is dropped only where touch already forwarded")
end
love.system.getOS = saved.getOS
love.system.pickFile = saved.pickFile
love.filesystem.getDirectoryItems = saved.getDirectoryItems