diff --git a/CHANGELOG.md b/CHANGELOG.md index 84c0f1659..d19d4bdac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -128,6 +128,7 @@ are doing mtv adjustments during precollision. ### Fixed +- Fixed issue where `cancel()`'d events still bubbled to the top level input handlers - Fixed issue where unexpected html HTML content from an image would silently hang the loader - Fixed issue where Collision events ahd inconsistent targets, sometimes they were Colliders and sometimes they were Entities - Fixed issue where `ex.Engine.screenshot()` images may not yet be loaded in time for use in `ex.Transition`s diff --git a/src/engine/Input/PointerEventReceiver.ts b/src/engine/Input/PointerEventReceiver.ts index c0e329f0f..9827e33f3 100644 --- a/src/engine/Input/PointerEventReceiver.ts +++ b/src/engine/Input/PointerEventReceiver.ts @@ -208,6 +208,9 @@ export class PointerEventReceiver { this.lastFramePointerCoords = new Map(this.currentFramePointerCoords); for (const event of this.currentFrameDown) { + if (!event.active) { + continue; + } this.emit('down', event); const pointer = this.at(event.pointerId); pointer.emit('down', event); @@ -215,24 +218,37 @@ export class PointerEventReceiver { } for (const event of this.currentFrameUp) { + if (!event.active) { + continue; + } this.emit('up', event); const pointer = this.at(event.pointerId); pointer.emit('up', event); } for (const event of this.currentFrameMove) { + if (!event.active) { + continue; + } this.emit('move', event); const pointer = this.at(event.pointerId); pointer.emit('move', event); } for (const event of this.currentFrameCancel) { + if (!event.active) { + continue; + } this.emit('cancel', event); const pointer = this.at(event.pointerId); pointer.emit('cancel', event); } for (const event of this.currentFrameWheel) { + if (!event.active) { + continue; + } + this.emit('pointerwheel', event); this.emit('wheel', event); this.primary.emit('pointerwheel', event); this.primary.emit('wheel', event); diff --git a/src/spec/PointerInputSpec.ts b/src/spec/PointerInputSpec.ts index 187e655f2..bdd415a6e 100644 --- a/src/spec/PointerInputSpec.ts +++ b/src/spec/PointerInputSpec.ts @@ -170,6 +170,65 @@ describe('A pointer', () => { expect(actualOrder).toEqual(['actor4', 'actor3', 'actor2', 'actor1']); }); + it('should not dispatch canceled events to the top level', () => { + const actor1 = new ex.Actor({ x: 50, y: 50, width: 100, height: 100 }); + + const spyActorDown = jasmine.createSpy('actorDown'); + actor1.on('pointerdown', (e) => { + spyActorDown(); + e.cancel(); + }); + const spyActorUp = jasmine.createSpy('actorUp'); + actor1.on('pointerup', (e) => { + spyActorUp(); + e.cancel(); + }); + const spyActorMove = jasmine.createSpy('actorMove'); + actor1.on('pointermove', (e) => { + spyActorMove(); + e.cancel(); + }); + const spyActorWheel = jasmine.createSpy('actorWheel'); + actor1.on('pointerwheel', (e) => { + spyActorWheel(); + e.cancel(); + }); + engine.add(actor1); + + const spyTopLevelPointerDown = jasmine.createSpy('pointerdown'); + engine.input.pointers.primary.on('down', spyTopLevelPointerDown); + engine.input.pointers.on('down', spyTopLevelPointerDown); + const spyTopLevelPointerUp = jasmine.createSpy('pointerup'); + engine.input.pointers.primary.on('up', spyTopLevelPointerUp); + engine.input.pointers.on('up', spyTopLevelPointerUp); + const spyTopLevelPointerMove = jasmine.createSpy('pointermove'); + engine.input.pointers.primary.on('move', spyTopLevelPointerMove); + engine.input.pointers.on('move', spyTopLevelPointerMove); + const spyTopLevelPointerWheel = jasmine.createSpy('pointerwheel'); + engine.input.pointers.primary.on('wheel', spyTopLevelPointerWheel); + engine.input.pointers.on('wheel', spyTopLevelPointerWheel); + + executeMouseEvent('pointerdown', document, null, 50, 50); + executeMouseEvent('pointerup', document, null, 50, 50); + executeMouseEvent('pointermove', document, null, 50, 50); + executeMouseEvent('wheel', document, null, 50, 50); + + // process pointer events + engine.currentScene.update(engine, 0); + + expect(spyActorDown).toHaveBeenCalledTimes(1); + expect(spyTopLevelPointerDown).not.toHaveBeenCalled(); + + expect(spyActorUp).toHaveBeenCalledTimes(1); + expect(spyTopLevelPointerUp).not.toHaveBeenCalled(); + + expect(spyActorMove).toHaveBeenCalledTimes(1); + expect(spyTopLevelPointerMove).not.toHaveBeenCalled(); + + expect(spyActorWheel).toHaveBeenCalledTimes(1); + expect(spyTopLevelPointerWheel).not.toHaveBeenCalled(); + }); + it('should dispatch point events on screen elements', () => { const pointerDownSpy = jasmine.createSpy('pointerdown'); const screenElement = new ex.ScreenElement({