diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp
index 495d7b7cb..5f83cf420 100644
--- a/es-app/src/FileData.cpp
+++ b/es-app/src/FileData.cpp
@@ -1394,9 +1394,22 @@ void FileData::launchGame()
 #endif
     }
 
-    Scripting::fireEvent("game-end", romPath, getSourceFileData()->metadata.get("name"),
-                         getSourceFileData()->getSystem()->getName(),
-                         getSourceFileData()->getSystem()->getFullName());
+    // If running in the background then don't trigger the game-end event, which will instead be
+    // triggered in ViewController when manually waking up the application.
+    if (!runInBackground) {
+        Scripting::fireEvent("game-end", romPath, getSourceFileData()->metadata.get("name"),
+                             getSourceFileData()->getSystem()->getName(),
+                             getSourceFileData()->getSystem()->getFullName());
+    }
+    else {
+        std::vector<std::string>& gameEndParams {
+            ViewController::getInstance()->getGameEndEventParams()};
+        gameEndParams.emplace_back("game-end");
+        gameEndParams.emplace_back(romPath);
+        gameEndParams.emplace_back(getSourceFileData()->metadata.get("name"));
+        gameEndParams.emplace_back(getSourceFileData()->getSystem()->getName());
+        gameEndParams.emplace_back(getSourceFileData()->getSystem()->getFullName());
+    }
 
     // Unless we're running in the background while the game is launched, re-enable the text
     // scrolling that was disabled in ViewController.
diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp
index 675f5850a..35728612a 100644
--- a/es-app/src/views/ViewController.cpp
+++ b/es-app/src/views/ViewController.cpp
@@ -15,6 +15,7 @@
 #include "FileFilterIndex.h"
 #include "InputManager.h"
 #include "Log.h"
+#include "Scripting.h"
 #include "Settings.h"
 #include "Sound.h"
 #include "SystemData.h"
@@ -828,6 +829,13 @@ bool ViewController::input(InputConfig* config, Input input)
         // queued when leaving the game.
         if (config->isMappedTo("a", input) && input.value != 0)
             return true;
+        // Trigger the game-end event.
+        if (mGameEndEventParams.size() == 5) {
+            Scripting::fireEvent(mGameEndEventParams[0], mGameEndEventParams[1],
+                                 mGameEndEventParams[2], mGameEndEventParams[3],
+                                 mGameEndEventParams[4]);
+            mGameEndEventParams.clear();
+        }
     }
 
     // Open the main menu.
diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h
index 3071805d3..e883e694c 100644
--- a/es-app/src/views/ViewController.h
+++ b/es-app/src/views/ViewController.h
@@ -79,6 +79,7 @@ public:
         mLockInput = true;
     };
     bool getGameLaunchTriggered() { return (mGameToLaunch != nullptr); }
+    std::vector<std::string>& getGameEndEventParams() { return mGameEndEventParams; }
 
     bool input(InputConfig* config, Input input) override;
     void update(int deltaTime) override;
@@ -170,6 +171,7 @@ private:
     std::map<SystemData*, std::shared_ptr<GamelistView>> mGamelistViews;
     std::shared_ptr<SystemView> mSystemListView;
 
+    std::vector<std::string> mGameEndEventParams;
     FileData* mGameToLaunch;
     State mState;