JDK-8189180 : Background windows revert to system cursor
  • Type: Bug
  • Component: javafx
  • Sub-Component: scenegraph
  • Affected Version: 8,9,10
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2017-10-11
  • Updated: 2017-11-15
  • Resolved: 2017-10-13
Description
FULL PRODUCT VERSION :
C:\Users\russ_>java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows 10

A DESCRIPTION OF THE PROBLEM :
If a cursor is set on a background window, then a new modal window is opened, even if both windows are using the same new, custom cursor, then when hovering over the background window, the cursor reverts to the system cursor. 

I've left an example here: https://stackoverflow.com/questions/46296962/javafx-custom-cursor-reverts-to-system-when-hovering-over-background



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the program in the "executable test case" which I filled in below. Then hover your mouse over the window. Provided the http link which I borrowed is still live, you will see a blue cursor. Then click the open modal button, you will still see a blue cursor when you are over the new window, but when you hover over the window below it, the system cursor is back!

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Run the program in the "Steps to Reproduce" -- You should see the custom cursor fail over the background window. 
ACTUAL -
You DO see the custom cursor fail over the background window. 

ERROR MESSAGES/STACK TRACES THAT OCCUR :
No errors

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.ImageCursor;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class CursorTest extends Application {

    @Override
    public void start(Stage stage) {

        SomeDialog someDialog = new SomeDialog(stage);
        GridPane root = new GridPane();

        HBox buttonHolder= new HBox();
        buttonHolder.setPrefSize(300,300);

        Scene theScene = new Scene(root);

        Canvas canvas = new Canvas();
        canvas.setWidth(300);
        canvas.setHeight(300);
        canvas.getGraphicsContext2D().setFill(Color.RED);
        canvas.getGraphicsContext2D().fillRoundRect(100, 100, 100, 100, 10, 10);

        Image cursorImg = new Image("http://www.pngmart.com/files/3/Cursor-Arrow-PNG-Transparent-Image.png");
        ImageCursor imageCursor = new ImageCursor(cursorImg);
        theScene.setCursor(imageCursor);
        stage.setTitle("Ribbon dialog");
        stage.setScene(theScene);
        VBox vBox = new VBox();
        vBox.getChildren().add(canvas);
        vBox.setSpacing(50);

        Button button = new Button("Show modal");
        button.setPadding(new Insets(30,30,30,30));
        button.setOnMouseClicked(event -> {
            someDialog.showMeAndWait();
        });
        buttonHolder.getChildren().add(button);

        root.getChildren().addAll(vBox, buttonHolder);
        stage.show();
    }

    class SomeDialog {

        Stage newStage;

        public SomeDialog(Stage primaryStage) {
            newStage = new Stage();
            GridPane gridPane = new GridPane();
            Scene theScene = new Scene(gridPane);

            Image cursorImg = new Image("http://www.pngmart.com/files/3/Cursor-Arrow-PNG-Transparent-Image.png");
            ImageCursor imageCursor2 = new ImageCursor(cursorImg);
            theScene.setCursor(imageCursor2);
            theScene.setCursor(imageCursor2);
            theScene.setFill(Color.TRANSPARENT);

            newStage.initOwner(primaryStage);
            newStage.initModality(Modality.APPLICATION_MODAL);
            newStage.setTitle("Player inventory");
            newStage.setScene(theScene);
            newStage.initStyle(StageStyle.TRANSPARENT);

            VBox vBox = new VBox();
            Button someBtn = new Button("Close");
            someBtn.setPadding(new Insets(100,100,100,100));
            someBtn.setOnMouseClicked(event -> newStage.close());
            vBox.getChildren().add(someBtn);
            gridPane.getChildren().add(vBox);
        }

        public void showMeAndWait() {
            newStage.showAndWait();
        }
    }
}

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

CUSTOMER SUBMITTED WORKAROUND :
None.Would love a workaround!


Comments
Closing the issue as "Not an Issue" as the behavior is as expected for Modality.APPLICATION_MODAL.
13-10-2017

This is not a bug. It is an expected behavior of Modality. https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Modality.html#APPLICATION_MODAL The test sets the modality of newStage to APPLICATION_MODAL -> newStage.initModality(Modality.APPLICATION_MODAL); Setting modality to NONE will help the reporter.
12-10-2017

This might be either a windows-toolkit bug or a scenegraph bug.
11-10-2017

Issue is reproducible in JDK 8,9,10 Windows 10 - JDK results --------------------------- 8 GA : Fail 8u144 : Fail 8u152 : Fail 9-ea+181 : Fail 10-ea+23 : Fail
11-10-2017