Strange intermittent SimpleButton bug that moves button

In the last month or so, I noticed a strange intermittent behavior with disabled SimpleButtons (enable flag = false) that when a mouse down on a button followed by a drag off the button before a mouse up results in the button moved to upper left corner of browser window. This only happened with buttons that are disabled and have no listeners for any mouse event. This behavior is very intermittent and I cannot predict when it will occur. I assume that some OpenFl update introduced this problem. Below are images from a very simple example I made to illustrate the problem.

In this image, there are three simple buttons. Button 1 is enable, buttons 2 & 3 are disabled. My code that enables/disables button, changes the alpha to reflect enabled/disabled.

In this image, I have done the mouse down, drag off and mouse up on the middle button which resulted in the repositioning of that button. Note that the alpha has been changed to 1 but it doesn’t respond to any mouse clicks. And I have no code that changes the position of the button. Also note that the button is not inside the background.

This image shows that the buttons have been enabled but the moved button does not act like it has been enabled, doesn’t show down state when clicked.

In this image, the the cursor has been dragged over the original location of the button, the button is mysteriously moved back to the original location and is now clickable.

The background and the buttons are stored in an swf file. Below is all the code that I used to make this example. There’s nothing there that repositions any button.

package;

import flash.display.InteractiveObject;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

class Test extends Sprite
{
private var bkgnd:Background;

public function new ()
{
super();

  bkgnd = new Background();
  addChild(bkgnd);

  enableSimpleButton(bkgnd.test_btn_1, true);
  enableSimpleButton(bkgnd.test_btn_2, false);
  enableSimpleButton(bkgnd.test_btn_3, false);

}

private function processMouseClick(event:MouseEvent)
{
    var button:SimpleButton = try cast(event.target, SimpleButton) catch(e:Dynamic) null;

  switch (button.name) {
  	case "test_btn_1":
  		enableSimpleButton(bkgnd.test_btn_2, true);
  		enableSimpleButton(bkgnd.test_btn_3, true);
  	case "test_btn_2":
  		enableSimpleButton(bkgnd.test_btn_2, false);
  		enableSimpleButton(bkgnd.test_btn_3, false);
  }
}

private function enableSimpleButton(button:SimpleButton, enable:Bool, dimAlpha=0.6, func:MouseEvent->Void = null)
{
  button.enabled = enable;
  button.useHandCursor = enable;
    enableMouseClick(button, enable, dimAlpha, func);
}

private function enableMouseClick(object:InteractiveObject, enable:Bool, dimAlpha=0.6, func:MouseEvent->Void = null)
{
if (func == null)
func = processMouseClick;
object.alpha = (enable) ? 1 : dimAlpha;
object.mouseEnabled = enable;
if (enable)
object.addEventListener(MouseEvent.CLICK, func);
else object.removeEventListener(MouseEvent.CLICK, func);
}

}

This has become a real problem for me since I often enable/disable SimpleButtons in almost all of my HTML5 projects.

I was able to determine this problem only occurs after clicking on a button whose enabled parameter has been set to false followed by a mouseOver, mouseOut, etc. I couldn’t determine which. I also found that the x and y coordinates stored within the class instance does not change after the button has been moved.

Also discovered that if I change the scale of the button, when it mysteriously moves, which is always to the top left corner of the browser window, regardless of where the stage is, it is full size and does not act as a button, i.e. you can click on it but nothing happens.

And if a graphic is placed over the button and visible is true, the button underneath does not seem to receive any mouse event and the problem doesn’t occur. Making such a shield for every SimpleButton in every project would be a solution but a real chore to implement.

What version of OpenFL? Thanks

8.9.5 which I believe is the current version since when I do a “lime upgrade openfl” it says “openfl is up to date.”

Did this work for you before? When did this behavior start for you?

I started noticing it about Sept. 2019. As far as I can tell, I started using SimpleButtons in Feb. 2019. I just tested a project with a last build in June 2019 and I was unable to reproduce the problem.

I don’t know what version of OpenFl I used then. Is the version number stored in any of the files created by the build to html5?

I want to say this worked up through OpenFL 8.9.1 (which was released around May 2019)

I created an 8.9.6 branch that reverts renderer changes that might have affected this issue:

Please explain how do I use that?

It could be something like this:

git clone -branch 8.9.6 https://github.com/openfl/openfl

# or

git clone https://github.com/openfl/openfl
cd openfl
git checkout 8.9.6

# then

haxelib dev openfl path/to/openfl

That will use this dev version temporarily so you can test how it behaves against your project. Then haxelib dev openfl will disable the dev directory and switch back to the haxelib version you already have installed if you want to switch back.

I see a few commits that might affect SimpleButton behavior on that branch if it still is not working. You could try reverting either or both of these commits:

cd path/to/openfl
git revert f63edb0c0df7e0dc26064b43b0cc245f173fc51e
cd path/to/openfl
git revert a8bc23c3c4a7b008a086953334d0508c40424691

If it doesn’t make a difference you can go back to the original 8.9.6 branch version like this:

git reset --hard origin/8.9.6

I tried both git reverts and got “fatal: bad object” followed by which code I used. I tried doing them when in the openfl folder and since that folder has two folders 8,9,5 and 8,9,6 so I did a cd 8,9,6 but still got that error message. There’s 2 openfl folders inside 8,9,6 and tried both of those and got the same result. So I’m not sure which openfl folder I supposed to use.

I saw the Fixes for roll out behavior (resolve #2236) post which I assume shows changes to Stage.hx. In the 8.9.6 folder there are 3 of them, one in each of these folders:

openfl⁩ ▸ ⁨8,9,6⁩ ▸ ⁨lib⁩ ▸ ⁨openfl⁩ ▸ ⁨display⁩
openfl⁩ ▸ ⁨8,9,6⁩ ▸ ⁨src⁩ ▸ ⁨openfl⁩ ▸ ⁨display⁩
openfl⁩ ▸ ⁨8,9,6⁩ ▸ ⁨externs⁩ ▸ ⁨flash⁩ ▸ ⁨flash⁩ ▸ ⁨display⁩

Which one(s) is supposed to get the changes specified in resolve #2236?
Is there an easy way to download whatever Stage.hx files include those changes?

Is your 8,9,6 folder installed from GIT or installed from Haxelib? If it’s from Haxelib it won’t have any GIT history and won’t be able to revert.

The changes you’re looking for would apply to files under “src” only. The “lib” and “externs” folders are extern classes for NPM and Flash respectively

I installed from Haxelib. Made the changes specified in Fixes for roll out behavior (resolve #2236) and that did not fix the problem. Saved the original file so I can go back to it.

Now what?

The problem, I believe, is in the reuse of one of the states. I mean, when the same DisplayObject is used for different states.