Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with POINTER_UP_OUTSIDE #6305

Open
sreadixl opened this issue Dec 2, 2022 · 1 comment
Open

Issue with POINTER_UP_OUTSIDE #6305

sreadixl opened this issue Dec 2, 2022 · 1 comment

Comments

@sreadixl
Copy link

sreadixl commented Dec 2, 2022

Version: Phaser Version: 3.55.2
Browser: Windows Chrome 107

I'm running into an interesting problem, and I think I have it narrowed down to the cause, and it's possible that it's expected behavior. I have a game that is running on our website, the game runs inside of an iframe where the contents are on a different domain than the website. We use to have document.domain set, but have recently removed it as it is getting deprecated. I noticed that some of our games weren't working correctly if you were dragging something in the game, dragged your mouse of the game area, and then released. Generally what would happen is the item wouldn't get "dropped" and would continue to follow your mouse.

It seems like the mouseup event is not firing for the game when you release outside of the game. After a bit of diving into Phaser's code, it looks like the mouseup listener for when the mouse is released outside of the game was being down by doing window.top.addEventListener('mouseup') which obviously doesn't work without document domain setting, so it falls back to just using window.addEventListener. The relevant code is found here: https://github.com/photonstorm/phaser/blob/v3.55.2/src/input/mouse/MouseManager.js#L475

I created a simple setup that results in the problem:

const contentWrapper = document.getElementById('contentWrapper');
const canvas = document.createElement('canvas');
canvas.width = 1024;
canvas.height = 768;
contentWrapper.appendChild(canvas);
canvas.addEventListener('mousedown', () => console.log('mouse down on canvas'));
window.addEventListener('mouseup', () => console.info('mouse up on window'));

class Example extends Phaser.Scene {
  create () {
    this.input.on(Phaser.Input.Events.POINTER_UP_OUTSIDE, () => console.info('phaser pointer up outside'));
    this.input.on(Phaser.Input.Events.POINTER_UP, () => console.info('phaser pointer up'));

    this.add.text(this.scale.width / 2,this.scale.height / 2, 'This is a test Phaser game', { align: 'center', color: '#ffffff', fontSize: '32px', fontFamily: 'Arial' }).setOrigin(0.5);
  }
}

/** @type {Phaser.Types.Core.GameConfig} */
const config = {
  type: Phaser.WEBGL,
  width: 1024,
  height: 768,
  parent: 'contentWrapper',
  canvas,
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH
  },
  scene: Example
};

const game = new Phaser.Game(config);

I noticed if I didn't create the Phaser game (comment out the last line of code), the canvas/window listeners work - you get the "mouse up on window" if you click inside of the canvas, and then release outside of the canvas. Once the Phaser game is created, that stops working.

After a bit more digging, I found that adding the following to the config fixes the issue: input:{mouse:{preventDefaultDown:false}}. The relevant code that this is used is here: https://github.com/photonstorm/phaser/blob/v3.55.2/src/input/mouse/MouseManager.js#L391. I am assuming that what is happening is the event gets its "prevent default" called, which prevents it from correctly firing on the window. I'm not 100% sure why turning off the down prevent default fixes it for the up event, but turning off the prevent default for up doesn't fix it. I would assume the reason why the window.top version works is because that has its own mouse up event that is fired, so it wouldn't have prevent default set on it.

Again, this might be expected behavior. I'm not sure what ramifications turning off preventDefaultDown would have, so I'm hesitant to do that. In the meantime I'm going to look at other solutions but maybe someone can shed some light on why this happens the way it does, and whether there might be a solution.

An additional note: POINTER_UP_OUTSIDE works correctly on our website on Windows Firefox, but doesn't work correctly on Windows Edge. Not sure about Mac browsers, and the structure of our website on mobile is different so it "works" on mobile but the page setup is different so I don't think the issue is relevant on there.

Final note: I noticed that Phaser 2.11.0 works. After diving through that code, it doesn't seem like they prevent default on any of the events - there's a way for that to be turned on, but it looks like it is off by default.

@sreadixl
Copy link
Author

sreadixl commented Dec 5, 2022

The solution I ended up going with is

this.input.on(Phaser.Input.Events.GAME_OUT, (time, event) => {
  if (event instanceof MouseEvent) {
    this.input.manager.onMouseUp(event);
  }
});

The one "gotcha" with this is the event listener for ending drag has to be "drag end" instead of "pointer up", because if the pointer isn't over the game object when the pointer goes outside of the game window, the pointer up event doesn't fire on the gameobject, but the drag end event does (which makes sense).

@phaserjs phaserjs deleted a comment Dec 16, 2022
@phaserjs phaserjs deleted a comment from SlimHajRomdhane Mar 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants