JDK-8227004 : Using an image with Dragboard.setDragView() on GTK3 breaks drag and drop
  • Type: Bug
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: openjfx12,openjfx13
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2019-06-28
  • Updated: 2020-04-06
  • Resolved: 2020-04-06
Related Reports
Blocks :  
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
Linux Mint 19
Java 12.0.1
OpenJFX 13-ea+9

A DESCRIPTION OF THE PROBLEM :
After switching to OpenJFX 13-ea+9 drag and drop was working fine until I tried to set a drag image with Dragboard.setDragView(). The results were similar to the problems found with OpenJFX 12 and fixed in OpenJFX 13. See https://bugs.openjdk.java.net/browse/JDK-8211302.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
When implementing drag and drop functionality set a drag view with Dragboard.setDragView(). Drag events stop being published consistently to drag targets.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Events published to the drag target consistently.
ACTUAL -
Events inconsistently published to drag targets.

---------- BEGIN SOURCE ----------
package com.xeomar.xenon;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class DndDemo extends Application {

	@Override
	public void start( Stage stage ) {
		Group root = new Group();
		Scene scene = new Scene( root, 400, 200 );

		final Label source = new Label( "DRAG ME" );
		source.setCursor( Cursor.HAND );
		source.relocate( 50, 100 );
		source.setScaleX( 2.0 );
		source.setScaleY( 2.0 );
		source.setBackground( new Background( new BackgroundFill( Color.YELLOW, CornerRadii.EMPTY, Insets.EMPTY ) ) );

		final Label target = new Label( "DROP HERE" );
		target.relocate( 250, 100 );
		target.setScaleX( 2.0 );
		target.setScaleY( 2.0 );
		target.setBackground( new Background( new BackgroundFill( Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY ) ) );

		source.setOnDragDetected( ( event ) -> {
			System.out.println( "onDragDetected" );

			Dragboard db = source.startDragAndDrop( TransferMode.MOVE );
			ClipboardContent content = new ClipboardContent();
			content.putString( "DRAGGED CONTENT" );
			db.setContent( content );

			// FIXME Using setDragView() breaks DnD on OpenJFK 13
			Image image = source.snapshot( null, null );
			db.setDragView( image, 0.5 * image.getWidth(), 0.5 * image.getHeight() );

			event.consume();
		} );

		source.setOnDragDone( ( event ) -> {
			System.out.println( "onDragDone" );

			if( event.getTransferMode() == TransferMode.MOVE ) source.setText( "" );

			event.consume();
		} );

		target.setOnDragOver( ( event ) -> {
			System.out.println( "onDragOver" );

			if( event.getGestureSource() != target && event.getDragboard().hasString() ) {
				event.acceptTransferModes( TransferMode.MOVE );
			}

			event.consume();
		} );

		target.setOnDragEntered( ( event ) -> {
			System.out.println( "onDragEntered" );

			if( event.getGestureSource() != target && event.getDragboard().hasString() ) {
				target.setTextFill( Color.WHITE );
			}

			event.consume();
		} );

		target.setOnDragExited( ( event ) -> {
			target.setTextFill( Color.BLACK );

			event.consume();
		} );

		target.setOnDragDropped( ( event ) -> {
			System.out.println( "onDragDropped" );

			Dragboard db = event.getDragboard();
			boolean hasString = db.hasString();
			if( hasString ) target.setText( db.getString() );

			event.setDropCompleted( hasString );

			event.consume();
		} );

		root.getChildren().add( source );
		root.getChildren().add( target );
		stage.setScene( scene );
		stage.show();
	}

	public static void main( String[] args ) {
		Application.launch( args );
	}

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No known workaround if a drag view is desired.

FREQUENCY : always



Comments
Closing as a duplicate of JDK-8225571.
06-04-2020

I think this can be closed.
05-04-2020

In that case, we should probably not spend any more time on this one, but rather wait until JDK-8225571 is done.
11-07-2019

I was aware of this and did try to fix it. The dragview actually works, but not if it's under the cursor tip. Only managed to get it working on the gtk port (https://github.com/javafxports/openjdk-jfx/pull/490). This is one of the reasons I have decided to use gtk. I have looked at gtk source do find out how they do it and try to replicate, but did not find any difference or explicit code doing this.
11-07-2019

[~tsayao] Would you be able to take a look at this?
10-07-2019