From 231a9b359d57a08112fd0a73530f35632575f36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Vivet?= Date: Tue, 10 Feb 2026 15:38:47 +0100 Subject: [PATCH 1/5] Update howler-sound-manager.ts --- .../howler-sound-manager.ts | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts b/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts index 01747f967f7c..288f9c6be194 100644 --- a/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts +++ b/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts @@ -503,6 +503,15 @@ namespace gdjs { _resourceLoader: gdjs.ResourceLoader; + // Event listener references cleanup + private _onDocumentPause = () => { + this.pauseAllActiveSounds(); + }; + + private _onDocumentResume = () => { + this.resumeAllActiveSounds(); + }; + /** * @param resourceLoader The resources loader of the game. */ @@ -512,23 +521,11 @@ namespace gdjs { gdjs.registerRuntimeScenePostEventsCallback( this._clearCachedSpatialPosition.bind(this) ); - const that = this; - document.addEventListener('deviceready', function () { + + document.addEventListener('deviceready', () => { // pause/resume sounds in Cordova when the app is being paused/resumed - document.addEventListener( - 'pause', - function () { - that.pauseAllActiveSounds(); - }, - false - ); - document.addEventListener( - 'resume', - function () { - that.resumeAllActiveSounds(); - }, - false - ); + document.addEventListener('pause', this._onDocumentPause, false); + document.addEventListener('resume', this._onDocumentResume, false); }); } @@ -1206,6 +1203,8 @@ namespace gdjs { * Unloads all audio from memory, clear Howl cache and stop all audio. */ dispose(): void { + document.removeEventListener('pause', this._onDocumentPause); + document.removeEventListener('resume', this._onDocumentResume); this.unloadAll(); } From 571b2ce9377b0e6b72d65166820754b40421243c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Vivet?= Date: Tue, 10 Feb 2026 15:43:28 +0100 Subject: [PATCH 2/5] Update InGameEditor.tsx --- GDJS/Runtime/InGameEditor/InGameEditor.tsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/GDJS/Runtime/InGameEditor/InGameEditor.tsx b/GDJS/Runtime/InGameEditor/InGameEditor.tsx index ebfecdaaba11..bfeceb8b0c2c 100644 --- a/GDJS/Runtime/InGameEditor/InGameEditor.tsx +++ b/GDJS/Runtime/InGameEditor/InGameEditor.tsx @@ -366,13 +366,17 @@ namespace gdjs { }; let hasWindowFocus = true; + // References for cleanup + const _onWindowFocus = () => { + hasWindowFocus = true; + }; + const _onWindowBlur = () => { + hasWindowFocus = false; + }; + if (typeof window !== 'undefined') { - window.addEventListener('focus', () => { - hasWindowFocus = true; - }); - window.addEventListener('blur', () => { - hasWindowFocus = false; - }); + window.addEventListener('focus', _onWindowFocus); + window.addEventListener('blur', _onWindowBlur); } function isDefined(value: T | null | undefined): value is NonNullable { @@ -962,6 +966,10 @@ namespace gdjs { this._unregisterContextLostListener(); this._unregisterContextLostListener = null; } + if (typeof window !== 'undefined') { + window.removeEventListener('focus', _onWindowFocus); + window.removeEventListener('blur', _onWindowBlur); + } } private _applyInGameEditorSettings() { From 0b28f0ca42a903ad2814c7be07f92ef3c4dc1517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Vivet?= Date: Tue, 10 Feb 2026 16:20:24 +0100 Subject: [PATCH 3/5] Dispose EventListener for the debugger when game closed --- .../window-message-debugger-client.ts | 13 +++++++++---- GDJS/Runtime/runtimegame.ts | 3 +++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/GDJS/Runtime/debugger-client/window-message-debugger-client.ts b/GDJS/Runtime/debugger-client/window-message-debugger-client.ts index 5c35a9004427..c764daac4fce 100644 --- a/GDJS/Runtime/debugger-client/window-message-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/window-message-debugger-client.ts @@ -8,6 +8,10 @@ namespace gdjs { */ export class WindowMessageDebuggerClient extends gdjs.AbstractDebuggerClient { _opener: Window | null = null; + private _onWindowMessage = (event: MessageEvent) => { + const data = event.data; + this.handleCommand(data); + }; constructor(runtimeGame: RuntimeGame) { super(runtimeGame); @@ -24,10 +28,11 @@ namespace gdjs { return; } - window.addEventListener('message', (event) => { - const data = event.data; - this.handleCommand(data); - }); + window.addEventListener('message', this._onWindowMessage); + } + + dispose() { + window.removeEventListener('message', this._onWindowMessage); } protected _sendMessage(message: string) { diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index be92cd47d24e..df1d29ce772f 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -1270,6 +1270,9 @@ namespace gdjs { if (this._inGameEditor) { this._inGameEditor.dispose(); } + if (this._debuggerClient) { + this._debuggerClient.dispose(); + } this._renderer.stopGameLoop(); this._sceneStack.dispose(); this._renderer.dispose(removeCanvas); From 5f9c56122f25b791ae37831e0dcd0ab29d58f43f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Vivet?= Date: Tue, 10 Feb 2026 16:34:49 +0100 Subject: [PATCH 4/5] Close the game > Dispose Debugger => Close WebSockets --- GDJS/Runtime/debugger-client/abstract-debugger-client.ts | 2 ++ GDJS/Runtime/debugger-client/minimal-debugger-client.ts | 2 ++ GDJS/Runtime/debugger-client/websocket-debugger-client.ts | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/GDJS/Runtime/debugger-client/abstract-debugger-client.ts b/GDJS/Runtime/debugger-client/abstract-debugger-client.ts index 3930778ec4cb..adfe4c6e480c 100644 --- a/GDJS/Runtime/debugger-client/abstract-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/abstract-debugger-client.ts @@ -499,6 +499,8 @@ namespace gdjs { } } + abstract dispose(): void; + /** * Should be re-implemented by derived class to send a stringified message object * to the debugger server. diff --git a/GDJS/Runtime/debugger-client/minimal-debugger-client.ts b/GDJS/Runtime/debugger-client/minimal-debugger-client.ts index 2da441a5fbb2..4a5e82c93f2d 100644 --- a/GDJS/Runtime/debugger-client/minimal-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/minimal-debugger-client.ts @@ -8,6 +8,8 @@ namespace gdjs { super(runtimeGame); } + dispose(): void {} + protected _sendMessage(message: string) {} } diff --git a/GDJS/Runtime/debugger-client/websocket-debugger-client.ts b/GDJS/Runtime/debugger-client/websocket-debugger-client.ts index a6462acad739..7af40df5a111 100644 --- a/GDJS/Runtime/debugger-client/websocket-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/websocket-debugger-client.ts @@ -86,6 +86,13 @@ namespace gdjs { } private hasLoggedError: boolean = false; + + dispose(): void { + if (this._ws) { + this._ws.close(); + } + } + protected _sendMessage(message: string) { if (!this._ws) { // The error can be logged only once, since logger.warn will call this function again, From f934844e8d53ee61cb3e8314328b2dcb7dfe2ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Vivet?= Date: Mon, 16 Feb 2026 13:53:01 +0100 Subject: [PATCH 5/5] revert unsure howler changes --- .../howler-sound-manager.ts | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts b/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts index 288f9c6be194..01747f967f7c 100644 --- a/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts +++ b/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts @@ -503,15 +503,6 @@ namespace gdjs { _resourceLoader: gdjs.ResourceLoader; - // Event listener references cleanup - private _onDocumentPause = () => { - this.pauseAllActiveSounds(); - }; - - private _onDocumentResume = () => { - this.resumeAllActiveSounds(); - }; - /** * @param resourceLoader The resources loader of the game. */ @@ -521,11 +512,23 @@ namespace gdjs { gdjs.registerRuntimeScenePostEventsCallback( this._clearCachedSpatialPosition.bind(this) ); - - document.addEventListener('deviceready', () => { + const that = this; + document.addEventListener('deviceready', function () { // pause/resume sounds in Cordova when the app is being paused/resumed - document.addEventListener('pause', this._onDocumentPause, false); - document.addEventListener('resume', this._onDocumentResume, false); + document.addEventListener( + 'pause', + function () { + that.pauseAllActiveSounds(); + }, + false + ); + document.addEventListener( + 'resume', + function () { + that.resumeAllActiveSounds(); + }, + false + ); }); } @@ -1203,8 +1206,6 @@ namespace gdjs { * Unloads all audio from memory, clear Howl cache and stop all audio. */ dispose(): void { - document.removeEventListener('pause', this._onDocumentPause); - document.removeEventListener('resume', this._onDocumentResume); this.unloadAll(); }