mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-10 01:10:30 +00:00
Standardise how we discard "char" events
One common issue we get when a program exits after handling a "key" event is that it leaves the "char" event on the queue. This means that the shell (or whatever program we switch in to) then receives the "char" event, often displaying it to the screen. Previously we've got around this by doing sleep(0) before exiting the program. However, we also see this problem in edit's run handler script, and I'm less comfortable doing the same hack there. This adds a new internal discard_char function, which will either wait one tick or return when seeing a char/key_up event. Fixes #1705
This commit is contained in:
parent
ebeaa757a9
commit
033378333f
@ -0,0 +1,37 @@
|
||||
-- SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
|
||||
--
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
--[[- Utilities for working with events.
|
||||
|
||||
> [!DANGER]
|
||||
> This is an internal module and SHOULD NOT be used in your own code. It may
|
||||
> be removed or changed at any time.
|
||||
|
||||
@local
|
||||
]]
|
||||
|
||||
--[[-
|
||||
Attempt to discard a [`event!char`] event that may follow a [`event!key`] event.
|
||||
|
||||
This attempts to flush the event queue via a timer, stopping early if we observe
|
||||
another key or char event.
|
||||
|
||||
We flush the event queue by waiting a single tick. It is technically possible
|
||||
the key and char events will be delivered in different ticks, but it should be
|
||||
very rare, and not worth adding extra delay for.
|
||||
]]
|
||||
local function discard_char()
|
||||
local timer = os.startTimer(0)
|
||||
while true do
|
||||
local event, id = os.pullEvent()
|
||||
if event == "timer" and id == timer then break
|
||||
elseif event == "char" or event == "key" or event == "key_up" then
|
||||
os.cancelTimer(timer)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return { discard_char = discard_char }
|
@ -88,6 +88,7 @@ for i = 1, #wrapped do
|
||||
term.write(wrapped[i])
|
||||
end
|
||||
os.pullEvent('key')
|
||||
require "cc.internal.event".discard_char()
|
||||
]]
|
||||
|
||||
-- Menus
|
||||
|
@ -300,7 +300,7 @@ local menu_choices = {
|
||||
return false
|
||||
end,
|
||||
Exit = function()
|
||||
sleep(0) -- Super janky, but consumes stray "char" events from pressing Ctrl then E separately.
|
||||
require "cc.internal.event".discard_char() -- Consume stray "char" events from pressing Ctrl then E separately.
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ while true do
|
||||
offset = print_height - content_height
|
||||
draw()
|
||||
elseif param == keys.q then
|
||||
sleep(0) -- Super janky, but consumes stray "char" events.
|
||||
require "cc.internal.event".discard_char()
|
||||
break
|
||||
end
|
||||
elseif event == "mouse_scroll" then
|
||||
|
@ -0,0 +1,43 @@
|
||||
-- SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
--
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
local timeout = require "test_helpers".timeout
|
||||
|
||||
describe("cc.internal.event", function()
|
||||
local event = require "cc.internal.event"
|
||||
describe("discard_char", function()
|
||||
|
||||
local function test(events)
|
||||
local unique_event = "flush_" .. math.random(2 ^ 30)
|
||||
|
||||
-- Queue and pull to flush the queue once.
|
||||
os.queueEvent(unique_event)
|
||||
os.pullEvent(unique_event)
|
||||
|
||||
-- Queue our desired events
|
||||
for i = 1, #events do os.queueEvent(table.unpack(events[i])) end
|
||||
|
||||
timeout(0.1, function()
|
||||
event.discard_char()
|
||||
|
||||
-- Then read the remainder of the event queue, and check there's
|
||||
-- no char event.
|
||||
os.queueEvent(unique_event)
|
||||
while true do
|
||||
local event = os.pullEvent()
|
||||
if event == unique_event then break end
|
||||
expect(event):ne("char")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
it("discards char events", function()
|
||||
test { { "char", "a" } }
|
||||
end)
|
||||
|
||||
it("handles an empty event queue", function()
|
||||
test {}
|
||||
end)
|
||||
end)
|
||||
end)
|
Loading…
Reference in New Issue
Block a user