From d758d2b232e6501c9a53c375a69d2c6f7916903c Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Oct 2024 16:41:56 +0200 Subject: [PATCH] pgui: Fix crash when PGEntry removes itself w/ background focus Fixes #1650 --- panda/src/pgui/pgItem.cxx | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/panda/src/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index 1ad3441a63..e955613362 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/panda/src/pgui/pgItem.cxx @@ -784,9 +784,14 @@ move(const MouseWatcherParameter ¶m) { */ void PGItem:: background_press(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + // We have to be careful, because objects may remove themselves from the set + // while we're iterating over it. + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->press(param, true); + PT(PGItem) item_ref(item); + item_ref->press(param, true); } } } @@ -796,9 +801,12 @@ background_press(const MouseWatcherParameter ¶m) { */ void PGItem:: background_release(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->release(param, true); + PT(PGItem) item_ref(item); + item_ref->release(param, true); } } } @@ -808,9 +816,12 @@ background_release(const MouseWatcherParameter ¶m) { */ void PGItem:: background_keystroke(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->keystroke(param, true); + PT(PGItem) item_ref(item); + item_ref->keystroke(param, true); } } } @@ -820,9 +831,12 @@ background_keystroke(const MouseWatcherParameter ¶m) { */ void PGItem:: background_candidate(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->candidate(param, true); + PT(PGItem) item_ref(item); + item_ref->candidate(param, true); } } }