diff --git a/code/th_14_panels.js b/code/th_14_panels.js index b4ac4ac..0e3b973 100644 --- a/code/th_14_panels.js +++ b/code/th_14_panels.js @@ -4620,7 +4620,36 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) { if (panelHeight > sh - self.dp(48)) panelHeight = sh - self.dp(48); if (panelHeight < self.dp(420)) panelHeight = Math.min(sh - self.dp(24), self.dp(420)); - var root = new android.widget.FrameLayout(context); + var popupClosed = false; + var popupBackDispatcher = null; + var popupBackCallback = null; + var root = new JavaAdapter(android.widget.FrameLayout, { + onWindowFocusChanged: function(hasFocus) { + try { + android.widget.FrameLayout.prototype.onWindowFocusChanged.call(this, hasFocus); + } catch(eSuperFocus) {} + try { + if (popupClosed) return; + // 用户底部上滑回主页 / 进入后台时,overlay 往往会失去焦点;弹窗应自动关闭。 + if (!hasFocus) this.post(new java.lang.Runnable({ run: function() { closePopup(); } })); + } catch(eFocusClose) {} + }, + onWindowVisibilityChanged: function(visibility) { + try { + android.widget.FrameLayout.prototype.onWindowVisibilityChanged.call(this, visibility); + } catch(eSuperVis) {} + try { + if (popupClosed) return; + if (visibility !== android.view.View.VISIBLE) this.post(new java.lang.Runnable({ run: function() { closePopup(); } })); + } catch(eVisClose) {} + }, + onDetachedFromWindow: function() { + try { popupClosed = true; } catch(eMarkDetached) {} + try { + android.widget.FrameLayout.prototype.onDetachedFromWindow.call(this); + } catch(eSuperDetach) {} + } + }, context); root.setBackgroundColor(self.withAlpha(isDark ? 0xFF000000 : 0xFFFFFFFF, isDark ? 0.58 : 0.42)); root.setClickable(true); try { root.setFocusable(true); root.setFocusableInTouchMode(true); } catch(eRootFocus) {} @@ -4811,8 +4840,35 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) { | android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN; try { wm.addView(root, lp); } catch(eAdd) { safeLog(self.L, 'e', "popup addView fail: " + String(eAdd)); return null; } + try { + root.requestFocus(); + root.post(new java.lang.Runnable({ run: function() { + try { + if (popupClosed) return; + var dispatcher = null; + try { dispatcher = root.findOnBackInvokedDispatcher(); } catch(eFindBack) { dispatcher = null; } + if (!dispatcher) return; + var cbCls = java.lang.Class.forName("android.window.OnBackInvokedCallback"); + var cb = new JavaAdapter(cbCls, { onBackInvoked: function() { closePopup(); } }); + var priority = 0; + try { priority = android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT; } catch(ePri) { priority = 0; } + dispatcher.registerOnBackInvokedCallback(priority, cb); + popupBackDispatcher = dispatcher; + popupBackCallback = cb; + } catch(eRegPopupBack) { + try { safeLog(self.L, 'w', 'popup back callback register fail: ' + String(eRegPopupBack)); } catch(eLogReg) {} + } + }})); + } catch(eReqFocus) {} function closePopup() { + if (popupClosed) return; + popupClosed = true; + try { + if (popupBackDispatcher && popupBackCallback) popupBackDispatcher.unregisterOnBackInvokedCallback(popupBackCallback); + } catch(eUnregPopupBack) {} + popupBackDispatcher = null; + popupBackCallback = null; try { wm.removeView(root); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (typeof onDismiss === "function") { try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); } diff --git a/manifest.json b/manifest.json index cc72fff..97a4f34 100644 --- a/manifest.json +++ b/manifest.json @@ -62,8 +62,8 @@ "size": 23906 }, "th_14_panels.js": { - "sha256": "9ecfbb5f367802cb3b9f3cbcfbb473e75656207cd03ad61cd25bb43d080c8c41", - "size": 272423 + "sha256": "c014e103cccc083c47e1bd6646e9bf56621f3696b1db2f9a81fa6e37fd5991fd", + "size": 274859 }, "th_14_schema_editor.js": { "sha256": "5669d0b5a16f770bed24eedee24203df57f7cbc7910c840931e533adac1ef146", @@ -80,5 +80,5 @@ }, "keyId": "toolhub-targets-2026-rsa3072", "schema": 2, - "version": 20260522220817 + "version": 20260522221302 } diff --git a/manifest.sig b/manifest.sig index 58afad0..9ea9d0d 100644 --- a/manifest.sig +++ b/manifest.sig @@ -1 +1 @@ -YhHLAiZPsJLqf7OEX6ttGyJW25rDDxh+lv066wwRbJMIVsvbpX5m0NKmXTwTJhHYrwc2G3Fsile9hvTe6UXXEQU8FurBxA55g3U9WQadSsXVBi2I3E41IiES5IiFxpp1BHDXr4X3mOv1tvNmAfiPdVZ9NU/YD8+gGHdcGUK/OT5DWpfFduTOAdkC9garVWdfHPCxHlxwCS7TYoeKxkGdi8gQdR/pWHfRp6F9pZ103HyuRyTWCZVeU+1Nh/VGOb5a+HGPGQmHOcEb/Gqh4+w9AuGH++VhpH50fMJJdh5CZVObuTlfsEnili+F0QmHhMeKhzpnPnP2gj15ahAm0ThK6rOgDxdyeJ1DzptbkhjYAckoTMLcDEKulJ24fiugkPIvL1vx/OR6mqM8/JJKIA/4aFe+Km1SRLNj7c9m6VOYGQypA6PD2qwDdreMm2AZzyhcIEQdUIbH0k8lFUPFrVVRBAYgJf7R/SkTeLvHgeczPGsjX1nadPavl+4RsrLpLeVi +jrjLCzwfZFg36cyiTezt+pUr5KLOjP8TdEQvnw4Kh2hAWxwhIM3spgt7sIhspiD9bGeeR7NlRpNiNslxpW7PtT/cVdQS7fq11ZtrEK59ZgWLMcFIioZwsAYO1kdFkgzfMshW9Gb8RCOJkk1TofUNf7LCe/S69S5qb2LA14S0/yihHbFwQg6uIf9yLqPS6HHyUCDWta9csivRng9PHrOtGpPZ7hqJMdIQlzvZzH28ahqb13CIdrcgJcLK3jR67LjmePuzB4Z+CUKmDJ4bkhwnl8IsDGxOnuc4q8iCbe+p6aRrU2yaeeT3z2/9EkdQ+iwWjcp1krsqURtY1Zw8yFiUWSDKTo6ejUWbvgY0Y/0YUlcNcIeIuJEx1PuRcvDMQ5YrkvsG9WWruXvMXP8zWxqkHa2WYeqSuqpDwl1JaPiDeT5b0PJz59NxyMlBqe0yJJ6N1Ae+9fVXzWN4PiB6zFjNW5P61g8t5c67mt4l1891gsN3UOReoj/6NBesatjmJJoo