diff --git a/code/th_04_theme.js b/code/th_04_theme.js index 91b82c4..b151165 100644 --- a/code/th_04_theme.js +++ b/code/th_04_theme.js @@ -2,8 +2,41 @@ // =======================【工具:屏幕/旋转】====================== FloatBallAppWM.prototype.getScreenSizePx = function() { var m = new android.util.DisplayMetrics(); - try { this.state.wm.getDefaultDisplay().getRealMetrics(m); } catch (e) { this.state.wm.getDefaultDisplay().getMetrics(m); } - return { w: m.widthPixels, h: m.heightPixels }; + var w = 0; + var h = 0; + + try { + this.state.wm.getDefaultDisplay().getRealMetrics(m); + w = Number(m.widthPixels || 0); + h = Number(m.heightPixels || 0); + } catch (e0) { + try { + this.state.wm.getDefaultDisplay().getMetrics(m); + w = Number(m.widthPixels || 0); + h = Number(m.heightPixels || 0); + } catch (e1) {} + } + + try { + var rot = this.getRotation ? this.getRotation() : -1; + var isLandscape = (rot === android.view.Surface.ROTATION_90 || rot === android.view.Surface.ROTATION_270); + var isPortrait = (rot === android.view.Surface.ROTATION_0 || rot === android.view.Surface.ROTATION_180); + if (isLandscape && w > 0 && h > 0 && w < h) { + var t = w; w = h; h = t; + } else if (isPortrait && w > 0 && h > 0 && w > h) { + var t2 = w; w = h; h = t2; + } + } catch (eRot) {} + + if (w <= 0 || h <= 0) { + try { + var dm = context.getResources().getDisplayMetrics(); + if (w <= 0) w = Number(dm.widthPixels || 0); + if (h <= 0) h = Number(dm.heightPixels || 0); + } catch (eRes) {} + } + + return { w: Math.max(1, Math.floor(w)), h: Math.max(1, Math.floor(h)) }; }; FloatBallAppWM.prototype.getRotation = function() { try { return this.state.wm.getDefaultDisplay().getRotation(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return -1; }; diff --git a/code/th_09_animation.js b/code/th_09_animation.js index eb887e8..640da7e 100644 --- a/code/th_09_animation.js +++ b/code/th_09_animation.js @@ -650,6 +650,13 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) { // 如果需要保护,调用方自己判断 if (this.state.dragging) return; + try { + var freshScreen = this.getScreenSizePx(); + if (freshScreen && freshScreen.w > 0 && freshScreen.h > 0) { + this.state.screen = freshScreen; + } + } catch (eScreen) {} + var di = this.getDockInfo(); var ballSize = di.ballSize; var visible = di.visiblePx; @@ -882,12 +889,10 @@ FloatBallAppWM.prototype.safeUiCall = function(tag, fn) { ; -FloatBallAppWM.prototype.onScreenChangedReflow = function() { +FloatBallAppWM.prototype.onScreenChangedReflow = function(reason) { if (this.state.closing) return; if (!this.state.addedBall) return; - var di = this.getDockInfo(); - var oldW = this.state.screen.w; var oldH = this.state.screen.h; @@ -896,11 +901,23 @@ FloatBallAppWM.prototype.onScreenChangedReflow = function() { var newH = newScreen.h; if (newW <= 0 || newH <= 0) return; + var rotNow = -1; + try { rotNow = this.getRotation ? this.getRotation() : -1; } catch (eRotNow) { rotNow = -1; } + try { + var rotLandscape = (rotNow === android.view.Surface.ROTATION_90 || rotNow === android.view.Surface.ROTATION_270); + var rotPortrait = (rotNow === android.view.Surface.ROTATION_0 || rotNow === android.view.Surface.ROTATION_180); + if ((rotLandscape && newW < newH) || (rotPortrait && newW > newH)) { + safeLog(this.L, 'w', "screen reflow skip unstable size reason=" + String(reason || "") + " new=" + newW + "x" + newH + " rot=" + String(rotNow)); + return; + } + } catch (eStable) {} if (oldW <= 0) oldW = newW; if (oldH <= 0) oldH = newH; this.state.screen = { w: newW, h: newH }; + var di = this.getDockInfo(); + var ballSize = di.ballSize; var visible = di.visiblePx; var hidden = di.hiddenPx; @@ -943,7 +960,41 @@ FloatBallAppWM.prototype.onScreenChangedReflow = function() { try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU) { safeLog(null, 'e', "catch " + String(eU)); } this.savePos(this.state.ballLp.x, this.state.ballLp.y); - safeLog(this.L, 'i', "screen reflow w=" + String(newW) + " h=" + String(newH) + " x=" + String(this.state.ballLp.x) + " y=" + String(this.state.ballLp.y)); + safeLog(this.L, 'i', + "screen reflow reason=" + String(reason || "") + + " old=" + oldW + "x" + oldH + + " new=" + newW + "x" + newH + + " rot=" + String(rotNow) + + " docked=" + String(this.state.docked) + + " side=" + String(this.state.dockSide || "") + + " x=" + String(this.state.ballLp.x) + + " y=" + String(this.state.ballLp.y) + ); +}; + +FloatBallAppWM.prototype.scheduleScreenReflow = function(reason) { + try { + var self = this; + if (!this.state.h) { + this.onScreenChangedReflow(reason); + return; + } + + this.onScreenChangedReflow(reason); + + this.state.h.postDelayed(new JavaAdapter(java.lang.Runnable, { + run: function() { + try { + if (self.state.closing) return; + self.onScreenChangedReflow(String(reason || "") + ":delayed"); + } catch (e) { + safeLog(self.L, "w", "delayed screen reflow fail reason=" + String(reason || "") + " err=" + String(e)); + } + } + }), 260); + } catch (e0) { + try { this.onScreenChangedReflow(reason); } catch(e1) {} + } }; FloatBallAppWM.prototype.setupDisplayMonitor = function() { @@ -983,7 +1034,7 @@ FloatBallAppWM.prototype.setupDisplayMonitor = function() { if (changed) { self.cancelDockTimer(); - self.onScreenChangedReflow(); + self.scheduleScreenReflow("display_changed"); self.touchActivity(); } } catch (e1) { diff --git a/code/th_16_entry.js b/code/th_16_entry.js index 1db9177..931550b 100644 --- a/code/th_16_entry.js +++ b/code/th_16_entry.js @@ -229,7 +229,7 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) { if (act === android.content.Intent.ACTION_CONFIGURATION_CHANGED) { self.cancelDockTimer(); - self.onScreenChangedReflow(); + self.scheduleScreenReflow("configuration_changed"); self.touchActivity(); } diff --git a/manifest.json b/manifest.json index 54d7a84..719f387 100644 --- a/manifest.json +++ b/manifest.json @@ -14,8 +14,8 @@ "size": 5598 }, "th_04_theme.js": { - "sha256": "cb020f0fd3842df526429b7816ad0cec7abbe1b7c45dc587198c9b2bbdb4b0d6", - "size": 40884 + "sha256": "b839d36cfdf9ed66cb207673119ec4f4567f4afca93a9ca8ca0a52fd01e1ded6", + "size": 41840 }, "th_05_persistence.js": { "sha256": "7d913b2caddf04c41ca13023c06763c03a7e372bb31080af37e7a3b2aa81d5f8", @@ -34,8 +34,8 @@ "size": 7938 }, "th_09_animation.js": { - "sha256": "b89876717fb62b4fd4249ce906b2741b90d25f7943c56b5afff3173ae9e41867", - "size": 38495 + "sha256": "2a991cbf4bf38bfb3d1dda876c0c86778e5dbbe75d6eb268a068e3f200ce0c13", + "size": 40229 }, "th_10_shell.js": { "sha256": "0ed793079c2f6ba7d29f4c0d411705cb72419f45f572cbe37ed32ac16527a8bc", @@ -62,11 +62,11 @@ "size": 99378 }, "th_16_entry.js": { - "sha256": "e7c99c3dfbd6aedab05551426955081ae6cae034754f2f557cefa01dc75dc001", - "size": 12777 + "sha256": "6c59d9891cd010647f84c3db93f1cf95c7bbfb758470ea21044bf72eb8ff73d1", + "size": 12799 } }, "keyId": "toolhub-targets-2026-rsa3072", "schema": 2, - "version": 20260518193704 + "version": 20260518210607 } diff --git a/manifest.sig b/manifest.sig index 1a1cbb7..308d292 100644 --- a/manifest.sig +++ b/manifest.sig @@ -1 +1 @@ -RiocpL++kNT2BnMm7JXBi0t4M2cek0qF1WIsf3WiUXER3N2sUlCH1jx87D5fWKnSm4LUqka7AvBYGvsce0B8HxEs7jXV28OqEjaf0UoACyELffN61hU2O4muSmXjAmqaDeT8yInsK4fpMSfhiS3sAWtiMk03e9S7qmx+3xECaUefIrKCAomdSMflXF+Y/i9oc+Uf8p4l1uOZvZpyDmF03HSsk+slLNasd79NvzLSA4QYh6YFhKFGRRW73w0FGbao5+VquFPwmq5CeCKePVWE4sSWIFhOdhaCXqhyuwjTP/A6zoX0Rv3qWg8drYqnhcJADYDVWBC/SIts8hIqRRKeN5RiGV62kPEh6nMeF9F1L8xrayaP2NqadZbw/6MT72YW1s0uXz1KsXJHMLl8vY78gZF1YA7+9cgpRDfp4pY15r4zvXi95gUlGoTkVljagbQaoSDyAgRDfPl2lFkzP5GoCebCMQWmt/IrPqM4qXc6oBw5BHBjjWxHnJmjiZN3Q0+H +WBXJChinrrMlwabV7hAH9X1GqZb4PRhs8OampWGTU8W5rxDWpB8Tjj7CF73M2PuoB5+tmwERxl26E6YwdCaJgEKhjUm8kOBsL6CnCAdx7nRujXYjaFN6nYqilekeZqOj2R8YyASfUfgXTzMGjFoWwGlBXbbFQq9fWf2TFECGR5mv6v9p3gp3RHVlZG/D0rBiGwu663OHsGtdD4hlfxk3LfcjFwHaWIxIfSZW1GWMgS5GiXqnCUB/x1cvLguUFlRMcQxM1fjPjrhkpx9Z0AJH5Qc6XhmFHGovzQDUROCtmHSpbjBCxAiqRxwVFBsmz8/xmZYQWo0B4m65M1usXp45rNRMKu/OJCx/UlSD07ICqGhJz2ISZJBrps2bBlnrrtLUhdMBbK1khHn6rlZ4C++zc25o7KigdVqMqQ3KWyQRgQu5cPT25fmkSfWEjv0MUaL1gXaHhNyBIFUx6ixKRbO3vUJnvYSbWI3+2FI0/nq1RhhG7GuDobNJ8zmDGgBJNNIn