Fix skill window close button racing with fly-here handler

- Stamp `closedByButtonAt` in `SkillWindow.close()` so the scene can tell a console ✕ click apart from a world click on the same frame.
- Add a 20ms guard in `GameScene` that suppresses the fly-here action when the close just fired, matching the mining menu and comms panel contract.
This commit is contained in:
Brian Fertig 2026-09-27 10:49:34 -06:00
parent c423bfa8ab
commit fdd0b4900c
2 changed files with 14 additions and 0 deletions

View File

@ -1990,6 +1990,18 @@ export class GameScene extends Phaser.Scene {
if (this.shipWindow && this.shipWindow.isOpen) return;
// The skill tree console (depth 80) — the same full-screen contract.
if (this.skillWindow && this.skillWindow.isOpen) return;
// A click the console's OWN ✕ just handled (the two handlers race on
// event order — close() lands first, so the guard above can miss it):
// it is the console's click, never a fly-here. Same-frame test, the
// mining menu's and the comms panel's contract. The console is full-
// screen, so no footprint check — any click that frame is its own.
if (
this.skillWindow &&
this.skillWindow.closedByButtonAt !== null &&
this.time.now - this.skillWindow.closedByButtonAt < 20
) {
return;
}
// Sub-bar OPEN: a click INSIDE it is its own (the panel or one of
// its buttons — the buttons fire on their own pointerdown). ANY
// click OUTSIDE — world, deck, HUD, compass — folds it back down

View File

@ -127,6 +127,7 @@ export class SkillWindow extends Phaser.GameObjects.Container {
this.onClearSeat = typeof o.onClearSeat === 'function' ? o.onClearSeat : null;
this.onClose = typeof o.onClose === 'function' ? o.onClose : null;
this.spec = windowSpec();
this.closedByButtonAt = null; // stamped when a BUTTON fires (race guard, MiningPopup's contract)
this._hits = []; // every button's rect (see button()); reset on each rebuild
this.openState = 'closed';
this._sig = '';
@ -166,6 +167,7 @@ export class SkillWindow extends Phaser.GameObjects.Container {
/** Closing is COMMITTING: the scene signs the session off here (see GameScene). */
close(o = {}) {
if (!this.isOpen) return;
this.closedByButtonAt = this.scene.time.now; // this click is the console's (the scene's guard reconciles)
this.openState = 'closed';
this.setVisible(false);
this._disarmInput();