Adobe-Runtime-Support icon indicating copy to clipboard operation
Adobe-Runtime-Support copied to clipboard

Mouse stops interaction with application after native drag over TextField

Open itlancer opened this issue 2 years ago • 4 comments

Problem Description

Mouse stops interaction with AIR application after native drag over TextField. After drag over TextField any MouseEvents stops firing (MOUSE_OVER, ...). This issue prevent smooth UX where drag-and-drop functionality used.

It has been tested with multiple AIR versions (even with latest AIR 33.1.1.821) with multiple Windows and macOS devices with different OS versions. Same problem in all cases.

Tracker link: https://tracker.adobe.com/#/view/AIR-3794521

Related issues (not the same): https://github.com/airsdk/Adobe-Runtime-Support/issues/193 https://github.com/airsdk/Adobe-Runtime-Support/issues/194

Steps to Reproduce

  1. Launch code below with Windows or macOS device.
  2. Make a left button mouse press (and hold it) anywhere on stage just to start native drag-and-drop.
  3. Drag over TextField at the right.
  4. Drag over SimpleButton at the left.

Application example with sources attached. nativedrag_mouseover_bug.zip

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.events.MouseEvent;
	import flash.display.BitmapData;
	import flash.display.SimpleButton;
	import flash.text.TextField;
	import flash.desktop.Clipboard;
	import flash.desktop.NativeDragManager;
	
	public class NativeDragMouseOverBug extends Sprite {
		
		public function NativeDragMouseOverBug() {
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			var upState:Sprite = new Sprite();
			upState.graphics.beginFill(0xff0000);
			upState.graphics.drawRect(0, 0, 100, 100);
			upState.graphics.endFill();

			var overState:Sprite = new Sprite();
			overState.graphics.beginFill(0x00ff00);
			overState.graphics.drawRect(0, 0, 100, 100);
			overState.graphics.endFill();

			var button:SimpleButton = new SimpleButton(upState, overState, overState, overState);
			button.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);//This event not fired after drag over TextField
			addChild(button);

			var textField:TextField = new TextField();
			textField.text = "Text field.\nDrag over it";
			textField.border = true;
			textField.x = 200;
			addChild(textField);
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, startNativeDrag);
		}
		
		private function startNativeDrag(e:MouseEvent):void {
			var clipboard:Clipboard = new Clipboard();
			var bd:BitmapData = new BitmapData(100, 100, false, 0xff0000);
			NativeDragManager.doDrag(stage, clipboard, bd);
		}

		private function mouseOver(e:MouseEvent):void {
			trace("over");
		}
	}
}

Actual Result: Mouse events didn't fired anymore until you not finish drag-drop (by release mouse button). SimpleButton not change state when your mouse over it.

Expected Result: Mouse events should works. In traces you will see "over" messages when mouse goes over SimpleButton. SimpleButton change state when your mouse over it.

Known Workarounds

Use NativeDragEvent.NATIVE_DRAG_ENTER, NativeDragEvent.NATIVE_DRAG_DROP and NativeDragEvent.NATIVE_DRAG_EXIT events to change render state by youself. Instead of SimpleButton you need your own button implementation to control button render states. https://github.com/airsdk/Adobe-Runtime-Support/issues/1897#issuecomment-1122141169 *Also you can set up mouseEnabled=false for all TextFields on native drag start just to avoid such behavior until drag-and-drop will be end.

itlancer avatar May 09 '22 15:05 itlancer

Can you try using the NativeDragEvent instead of MouseEvent?

			button.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER,
			                        onDragEnter);

			button.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP,
			                        onDragDrop);

			button.addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT,
			                        onDragExit);

https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/NativeDragEvent.html

EDIT: MouseEvents will not work (properly) while NativeDragManager.isDragging is true

2jfw avatar May 10 '22 09:05 2jfw

@2jfw Thank you for a hint! Added NativeDragEvent usage as workaround in the original post.

Anyway I think such behaviour looks like a bug cause it happens only when you drag something over TextField. With other DisplayObjects all works fine.

MouseEvents will not work (properly) while NativeDragManager.isDragging is true

Its from your experience or it noticed somewhere in AIR reference? NativeDragEvent has MouseEvent as a superclass and seems like it should work without such issues.

itlancer avatar May 10 '22 10:05 itlancer

Its from your experience or it noticed somewhere in AIR reference? NativeDragEvent has MouseEvent as a superclass and seems like it should work without such issues.

This is what is happening in our app - while dragging something all MouseEvents are not triggered (e.g. RollOver/RollOut etc). You need to explicitly use the (Native)DragEvent in order to listen to mouse events while a dragging interaction is ongoing (NativeDragManager.isDragging is true).

2jfw avatar May 10 '22 11:05 2jfw

I would think that this is actually working as intended for the following reason: if you would start dragging something and UI components would "normally" react on MouseEvents like roll over, this could imply for the user that it is possible to interact with the component, which may be misleading and undesired.

2jfw avatar May 10 '22 12:05 2jfw