Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8186559

[macos] the screen location is wrong when using AWT/SWT bridge with dual monitors

XMLWordPrintable

    • b31
    • x86
    • os_x

      FULL PRODUCT VERSION :
      Java(TM) SE Runtime Environment (build 9+181)
      Java(TM) SE Runtime Environment (build 1.8.0_141-b15)

      ADDITIONAL OS VERSION INFORMATION :
      Mac OS X, 10.12.6 build: 16G29
      Mac OS X, 10.11

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Dual or more monitors with different screen size (resolution).

      A DESCRIPTION OF THE PROBLEM :
      On macOS the screen location is wrong for AWT/Swing components that are displayed inside a SWT container via a EmbeddedFrame, when the window is displayed on the second screen.
      Depending on which is the main screen the y coordinate is to low or to high.
      The location on the screen with the grater height is always to low (smaller screen is the main screen) and on the screen with the lower height is always to high (larger screen is the main screen). The y position differs always by (mainScreenHeight - secondScreenHeight)
      Seems to be a problem with native implementation of "GeomUtilities.ConvertNSScreenRect(JNIEnv *env, NSRect rect)" on macOS.


      REGRESSION. Last worked in version 8u121

      ADDITIONAL REGRESSION INFORMATION:
      Java(TM) SE Runtime Environment (build 1.8.0_121-b13)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a AWT Component, place it inside a EmbeddedFrame of an SWT container and check getLocationOnScreen() of the AWT component, when the window is on the main screen and on the second screen.
      See attached example that can be run within Eclipse. From command line use -XstartOnFirstThread.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Screen location should be correct.
      ACTUAL -
      If
      1. Smaller screen is the main screen and window is on the larger screen:
      Y-position of the screen location is to low.
      2. Larger screen is the main screen and window is on the smaller screen:
      Y-position of the screen location is to high.


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      No message

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.BorderLayout;
      import java.awt.Frame;
      import java.awt.event.ActionEvent;

      import javax.swing.AbstractAction;
      import javax.swing.JButton;
      import javax.swing.JLabel;

      import org.eclipse.swt.SWT;
      import org.eclipse.swt.awt.SWT_AWT;
      import org.eclipse.swt.layout.FillLayout;
      import org.eclipse.swt.widgets.Composite;
      import org.eclipse.swt.widgets.Display;
      import org.eclipse.swt.widgets.Shell;

      /*
      Synopsis:
          On macOS (Mac OS X) the screen location is wrong when using AWT/SWT bridge with dual monitors
          
      Full OS version:
          Mac OS X, 10.12.6 build: 16G29
          
      Additional Configuration Information:
          Dual or more monitors with different screen size (resolution).
          
      Development Kit or Runtime version:
          Java(TM) SE Runtime Environment (build 9+181)
          Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
          
      Description:
          On macOS the screen location is wrong for AWT/Swing components that are displayed inside
          a SWT container via a EmbeddedFrame, when the window is displayed on the second screen.
          
          Depending on which is the main screen the y coordinate is to low or to high.
          
          The location on the screen with the grater height is always to low (smaller screen is the main screen)
          and on the screen with the lower height is always to high (larger screen is the main screen).
          The y position differs always by (mainScreenHeight - secondScreenHeight)
          
          Seems to be a problem with native implementation of "GeomUtilities.ConvertNSScreenRect(JNIEnv *env, NSRect rect)" on macOS.
          
      Steps to Reproduce:
          Create a AWT Component, place it inside a EmbeddedFrame of an SWT container and check getLocationOnScreen() of the
          AWT component, when the window is on the main screen and on the second screen.
          See attached example that can be run within Eclipse. From command line use -XstartOnFirstThread.
              
      Expected Results:
          Screen location should be correct.
          
      Actual Result:
          1. Smaller screen is the main screen and window is on the larger screen:
              Y-position of the screen location is to low.
          2. Larger screen is the main screen and window is on the smaller screen:
              Y-position of the screen location is to high.
          
      Frequency: Allways
      Error Message: No message
      Workarround: none
      Severity: Every JPopup and JMenu is displayed on the wrong position.

      */
      public class Screenlocation
      {
          static JLabel awtLabel;
          static JButton awtButton;
          
          public static void main(String[] args)
          {
              final Display display = new Display();
              final Shell shell = new Shell(display);
              shell.setLayout(new FillLayout());
              Composite composite = new Composite(shell, SWT.EMBEDDED);
              
              // create AWT frame inside window
              Frame awtFrame = SWT_AWT.new_Frame(composite);
              awtLabel = new JLabel("Press button <Screenlocation> to display its screen location.");
              awtButton = new JButton(new AbstractAction("Screenlocation")
              {
                  @Override
                  public void actionPerformed(ActionEvent e)
                  {
                      // display screen location
                      awtLabel.setText("Screenlocation: " + awtButton.getLocationOnScreen());
                  }
              });
              awtFrame.add(awtButton, BorderLayout.NORTH);
              awtFrame.add(awtLabel, BorderLayout.CENTER);
              
              shell.open();
              while(!shell.isDisposed())
              {
                  if(!display.readAndDispatch())
                      display.sleep();
              }
              display.dispose();
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround

            serb Sergey Bylokhov
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: