Index: ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/page_emptyPage.xml
===================================================================
--- ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/page_emptyPage.xml
+++ ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/page_emptyPage.xml
@@ -0,0 +1,4 @@
+
+
+ common/styles.xml
+
Index: ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/page_pushWithPopOnInit.xml
===================================================================
--- ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/page_pushWithPopOnInit.xml
+++ ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/page_pushWithPopOnInit.xml
@@ -0,0 +1,5 @@
+
+
+ common/styles.xml
+ regainFocus/pushWithPopOnInit.xml
+
Index: ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/pushWithPopOnInit.js
===================================================================
--- ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/pushWithPopOnInit.js
+++ ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/pushWithPopOnInit.js
@@ -0,0 +1 @@
+Engine.PushGuiPage("regainFocus/page_emptyPage.xml", {}, () => Engine.PopGuiPage());
Index: ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/pushWithPopOnInit.xml
===================================================================
--- ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/pushWithPopOnInit.xml
+++ ps/trunk/binaries/data/mods/_test.gui/gui/regainFocus/pushWithPopOnInit.xml
@@ -0,0 +1,4 @@
+
+
+
+
Index: ps/trunk/source/gui/GUIManager.h
===================================================================
--- ps/trunk/source/gui/GUIManager.h
+++ ps/trunk/source/gui/GUIManager.h
@@ -24,6 +24,7 @@
#include "ps/TemplateLoader.h"
#include "scriptinterface/StructuredClone.h"
+#include
#include
#include
@@ -167,7 +168,12 @@
std::shared_ptr m_ScriptContext;
std::shared_ptr m_ScriptInterface;
- using PageStackType = std::vector;
+ /**
+ * The page stack must not move pointers on push/pop, or pushing a page in a page's init method
+ * may crash (as the pusher page will suddenly have moved, and the stack will be confused).
+ * Therefore use std::deque over std::vector.
+ */
+ using PageStackType = std::deque;
PageStackType m_PageStack;
CTemplateLoader m_TemplateLoader;
Index: ps/trunk/source/gui/tests/test_GuiManager.h
===================================================================
--- ps/trunk/source/gui/tests/test_GuiManager.h
+++ ps/trunk/source/gui/tests/test_GuiManager.h
@@ -197,4 +197,29 @@
UnloadHotkeys();
}
+
+ void test_PageRegainedFocusEvent()
+ {
+ // Load up a test page.
+ const ScriptInterface& scriptInterface = *(g_GUI->GetScriptInterface());
+ ScriptRequest rq(scriptInterface);
+ JS::RootedValue val(rq.cx);
+ Script::CreateObject(rq, &val);
+
+ Script::StructuredClone data = Script::WriteStructuredClone(rq, JS::NullHandleValue);
+ g_GUI->PushPage(L"regainFocus/page_emptyPage.xml", data, JS::UndefinedHandleValue);
+
+ const ScriptInterface& pageScriptInterface = *(g_GUI->GetActiveGUI()->GetScriptInterface());
+ ScriptRequest prq(pageScriptInterface);
+ JS::RootedValue global(prq.cx, prq.globalValue());
+
+ g_GUI->PushPage(L"regainFocus/page_emptyPage.xml", data, JS::UndefinedHandleValue);
+ g_GUI->PopPage(data);
+
+ // This page instantly pushes an empty page with a callback that pops another page again.
+ g_GUI->PushPage(L"regainFocus/page_pushWithPopOnInit.xml", data, JS::UndefinedHandleValue);
+
+ // Pop the empty page and trigger the callback (effectively pops twice).
+ g_GUI->PopPage(data);
+ }
};