JDK-8156094 : ContextMenu shown at wrong position on Windows10 with Extended Screen
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: 8u92,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: other
  • CPU: x86
  • Submitted: 2016-04-27
  • Updated: 2016-08-18
  • Resolved: 2016-05-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u112Fixed 9Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) Client VM (build 25.92-b14, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [version 10.0.10586]

A DESCRIPTION OF THE PROBLEM :
On windows10, on extended screen mode,  contextMenu is displayed at wrong position depending if main Javafx Window is on primary or secondary screen.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Run the attach example on a Windows10 computer with 2 screen.

2) Right click on label

Depending if the main JavaFX windows is on primary or secondary screen, the contextMenu will be displayed next to mouse position or not.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ContextMenu should always be displayed close to mouse position!

Same program works fine on Windows7 and 8.
ACTUAL -
I can send a screenshot if you ask me.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package contextmenubug;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 *
 * @author Daniel
 */
public class ContextMenuBug extends Application {
    
    @Override
    public void start(Stage primaryStage) {
        Label btn = new Label();
        btn.setText("ContextMenuBug fail on windows10 with extended screen");
        
        MenuItem menuItem = new MenuItem("click on me, blablablblblbalbla");
        menuItem.setOnAction((ActionEvent event) -> {
            System.out.println("Hello World!");
        });
        ContextMenu contextMenu = new ContextMenu(menuItem);
//        contextMenu.setAutoFix(false);
        btn.setContextMenu(contextMenu);
        
        StackPane root = new StackPane();
        root.getChildren().add(btn);
        
        Scene scene = new Scene(root);
        primaryStage.sizeToScene();
        
        primaryStage.setTitle("ContextMenuBug!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
    
}

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


Comments
http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/9577881b86c3
10-05-2016

+1 Approved to backport to 8u-dev for 8u112.
10-05-2016

webrev for 9-dev: http://cr.openjdk.java.net/~flar/JDK-8156094/9-dev/webrev.00/ webrev for 8u-dev: http://cr.openjdk.java.net/~flar/JDK-8156094/8u-dev/webrev.00/
07-05-2016

The above comment leads to a fairly targeted and isolated fix for 9, but unfortunately the same information is not available in the 8u source base for a simple fix, in particular the platform locations of the screens are not exported to Java. Fortunately, there is another idiosyncrasy of the way that Windows manages screens for non-per-monitor aware applications (such as Java applications running in JDK8) is that the screens have fairly isolated locations relative each other and the code that lays out the screens leaves them in their isolated locations so the FX and platform origins of the windows are identical. Basically the same patch works on FX8, but it would fail if we ever enable JDK8 for per-monitor DPI awareness.
07-05-2016

It looks like the screen coordinates in events are not adjusted properly, they are simply divided by the current screen's scaling factor, but they need to be scaled relative to the origin of the current screen. In other words: xScreen = xScreen / scale; yScreen = yScreen / scale; needs to be: xScreen = (xScreen - screen.platformOriginX) / scale + screen.fxOriginX; yScreen = (yScreen - screen.platformOriginY) / scale + screen.fxOriginY;
05-05-2016