Skip to content

Commit

Permalink
fix: [#3250] Stop cancelled pointer events from bubbling to the top l…
Browse files Browse the repository at this point in the history
…evel

closes: #3250
  • Loading branch information
eonarheim committed Oct 25, 2024
1 parent a08b11e commit b407375
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions src/engine/Input/PointerEventReceiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,31 +208,47 @@ 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);
this.primary.emit('pointerdown', event);
}

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);
Expand Down
59 changes: 59 additions & 0 deletions src/spec/PointerInputSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', <any>document, null, 50, 50);
executeMouseEvent('pointerup', <any>document, null, 50, 50);
executeMouseEvent('pointermove', <any>document, null, 50, 50);
executeMouseEvent('wheel', <any>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({
Expand Down

0 comments on commit b407375

Please sign in to comment.