JDK-8072069 : Toolkit.getScreenInsets() doesn't update if insets change
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 8u20
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-02-02
  • Updated: 2015-09-29
  • Resolved: 2015-02-17
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
8u60Fixed 9 b54Fixed
Description
toolkit.getScreenInsets() is used by clients in conjunction with screen
bounds to position components on screen so they do not overlap the dock or
task bar.
However, if the dock location changes when the component is up, the insets
retrieved by this call do not reflect the new reality.

Test case:
Run the following code. Press the button that appears on screen and note the
insets.
With the app still running, change the dock position in the OS
Press the button again. The insets do not reflect the location of the dock.

Restart app, the insets are now updated.

import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;

public class DockUpdate {

    public static void main(String[] args) {

        JButton button = new JButton();
        button.addActionListener((evt) ->
                
System.out.println(Toolkit.getDefaultToolkit().getScreenInsets(
                        button.getGraphicsConfiguration())));
        
        JFrame frame = new JFrame();
        frame.add(button);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(50, 50);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
} 
Comments
It was finally turned out that NSApplicationDidChangeScreenParametersNotification if fired only when the Dock changes its location but is missing when the Dock size changes. Thus the only option is to query insets natively each time the getScreenInsets() is invoked.
17-02-2015

Review: http://cr.openjdk.java.net/~anashaty/8072069/9/webrev.00/
13-02-2015

There is a Cocoa notification NSApplicationDidChangeScreenParametersNotification which should be called on dock position changes (it is not strictly mentioned in the apple doc https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/index.html#//apple_ref/c/data/NSApplicationDidChangeScreenParametersNotification but people says it is called) We need to be sure that adding a new callback will not conflict with the existing Quarz callback CGDisplayReconfigurationCallBack.
02-02-2015

As a workaround you may add the following call prior to requesting insets: ((SunGraphicsEnvironment)GraphicsEnvironment.getLocalGraphicsEnvironment()).displayChanged();
02-02-2015

Seems like the insets are cached and reconfigured when the CGDisplayReconfigurationCallBack is fired. It seems that this event is not fired when the dock position is changed.
02-02-2015