diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 6eb3a0863..7d7e994d1 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -418,8 +418,12 @@ function UIManager:broadcastEvent(event) while (i <= #self._window_stack) do local prev_widget = self._window_stack[i].widget self._window_stack[i].widget:handleEvent(event) - if (self._window_stack[i].widget == prev_widget) then - i = i + 1 + local top_widget = self._window_stack[i] + if top_widget == nil then + -- top widget closed itself + break + elseif (top_window.widget == prev_widget) then + i = i + 1 end end end diff --git a/spec/unit/uimanager_spec.lua b/spec/unit/uimanager_spec.lua index c502b5ef6..a8dd67832 100644 --- a/spec/unit/uimanager_spec.lua +++ b/spec/unit/uimanager_spec.lua @@ -303,4 +303,46 @@ describe("UIManager spec", function() assert.is.same(call_signals[2], 1) assert.is.same(call_signals[3], 1) end) + + it("should handle stack change when broadcasting events", function() + UIManager._window_stack = { + { + widget = { + handleEvent = function() + UIManager._window_stack[1] = nil + end + } + }, + } + UIManager:broadcastEvent("foo") + assert.is.same(#UIManager._window_stack, 0) + + UIManager._window_stack = { + { + widget = { + handleEvent = function() + UIManager._window_stack[1] = nil + UIManager._window_stack[2] = nil + UIManager._window_stack[3] = nil + end + } + }, + { + widget = { + handleEvent = function() + assert.falsy(true); + end + } + }, + { + widget = { + handleEvent = function() + assert.falsy(true); + end + } + }, + } + UIManager:broadcastEvent("foo") + assert.is.same(#UIManager._window_stack, 0) + end) end)