From a700d9e648dc83c76b33d9cc94561dd05ad106f1 Mon Sep 17 00:00:00 2001 From: jelveh Date: Thu, 16 Jul 2026 19:44:42 -0700 Subject: [PATCH] fix: stop leaking a document keydown handler per uninstall-modal dismissal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit showUninstallModal bound `keydown.uninstall-modal` on document but only detached it on the Escape and Confirm paths. Dismissing via Cancel or a backdrop click called `close()`, which just removed the overlay and left the handler attached (closing over a now-detached overlay). Each open→cancel cycle stacked another document-level listener for the page lifetime. Move the `.off('keydown.uninstall-modal')` into `close()` so every dismissal path cleans up, and drop the now-redundant explicit detaches. --- src/gui/src/UI/Dashboard/TabApps.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/gui/src/UI/Dashboard/TabApps.js b/src/gui/src/UI/Dashboard/TabApps.js index d739182d9..e951ecf3a 100644 --- a/src/gui/src/UI/Dashboard/TabApps.js +++ b/src/gui/src/UI/Dashboard/TabApps.js @@ -129,17 +129,17 @@ function showUninstallModal ({ appName, appTitle, appUid, self, $el_window }) { $el_window.append($overlay); - const close = () => $overlay.remove(); + const close = () => { + $overlay.remove(); + $(document).off('keydown.uninstall-modal'); + }; $overlay.on('click', '.myapps-modal-cancel', close); $overlay.on('click', function (e) { if ( e.target === $overlay[0] ) close(); }); $(document).on('keydown.uninstall-modal', function (e) { - if ( e.key === 'Escape' ) { - close(); - $(document).off('keydown.uninstall-modal'); - } + if ( e.key === 'Escape' ) close(); }); $overlay.on('click', '.myapps-modal-confirm', async function () { @@ -154,7 +154,6 @@ function showUninstallModal ({ appName, appTitle, appUid, self, $el_window }) { console.error('Failed to uninstall app:', err); } close(); - $(document).off('keydown.uninstall-modal'); }); }