2727
2828import java .awt .*;
2929import java .util .*;
30+ import java .util .concurrent .Callable ;
3031
3132import sun .java2d .*;
33+ import sun .lwawt .macosx .CThreading ;
3234
3335/**
3436 * This is an implementation of a GraphicsEnvironment object for the default
@@ -112,15 +114,18 @@ public CGraphicsEnvironment() {
112114 * @param displayId CoreGraphics displayId
113115 * @param removed true if displayId was removed, false otherwise.
114116 */
117+ @ SuppressWarnings ("unused" )
115118 void _displayReconfiguration (final int displayId , final boolean removed ) {
116119 synchronized (this ) {
120+ // We don't need to switch to AppKit, we're already there
121+ mainDisplayID = getMainDisplayID ();
117122 if (removed && devices .containsKey (displayId )) {
118123 final CGraphicsDevice gd = devices .remove (displayId );
119- gd .invalidate (getMainDisplayID () );
124+ gd .invalidate (mainDisplayID );
120125 gd .displayChanged ();
121126 }
122127 }
123- initDevices ();
128+ initDevices (mainDisplayID );
124129 }
125130
126131 @ Override
@@ -136,30 +141,63 @@ protected void finalize() throws Throwable {
136141 /**
137142 * (Re)create all CGraphicsDevices, reuses a devices if it is possible.
138143 */
139- private void initDevices () {
144+ private void initDevices (int mainDisplID ) {
140145 synchronized (this ) {
141- final Map <Integer , CGraphicsDevice > old = new HashMap <>(devices );
142- devices .clear ();
146+ mainDisplayID = mainDisplID ;
147+ createDevices ();
148+ }
149+ displayChanged ();
150+ }
143151
144- mainDisplayID = getMainDisplayID ();
152+ private void initDevices () {
153+ synchronized (this ) {
145154
146155 // initialization of the graphics device may change
147156 // list of displays on hybrid systems via an activation
148157 // of discrete video.
149158 // So, we initialize the main display first, and then
150159 // retrieve actual list of displays.
151- if (!old .containsKey (mainDisplayID )) {
152- old .put (mainDisplayID , new CGraphicsDevice (mainDisplayID ));
153- }
154160
155- for (final int id : getDisplayIDs ()) {
156- devices .put (id , old .containsKey (id ) ? old .get (id )
157- : new CGraphicsDevice (id ));
161+ try {
162+ mainDisplayID = CThreading .privilegedExecuteOnAppKit (
163+ CGraphicsEnvironment ::getMainDisplayID );
164+ } catch (RuntimeException e ) {
165+ throw e ;
166+ } catch (Exception e ) {
167+ throw new RuntimeException ("Could not get main display ID: " +
168+ e .getMessage () );
158169 }
170+
171+ createDevices ();
172+
159173 }
160174 displayChanged ();
161175 }
162176
177+ private void createDevices () {
178+ final Map <Integer , CGraphicsDevice > old = new HashMap <>(devices );
179+ devices .clear ();
180+
181+ if (!old .containsKey (mainDisplayID )) {
182+ old .put (mainDisplayID , new CGraphicsDevice (mainDisplayID ));
183+ }
184+ int [] displayIDs ;
185+ try {
186+ displayIDs = CThreading .privilegedExecuteOnAppKit (
187+ CGraphicsEnvironment ::getDisplayIDs );
188+ } catch (RuntimeException e ) {
189+ throw e ;
190+ } catch (Exception e ) {
191+ throw new RuntimeException ("Could not get display IDs: " +
192+ e .getMessage ());
193+ }
194+
195+ for (final int id : displayIDs ) {
196+ devices .put (id , old .containsKey (id ) ? old .get (id )
197+ : new CGraphicsDevice (id ));
198+ }
199+ }
200+
163201 @ Override
164202 public synchronized GraphicsDevice getDefaultScreenDevice () throws HeadlessException {
165203 CGraphicsDevice d = devices .get (mainDisplayID );
0 commit comments