< prev index next >

src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.lwawt.macosx;
  27 
  28 import com.apple.eawt.FullScreenAdapter;
  29 import com.apple.eawt.FullScreenUtilities;
  30 import com.apple.eawt.event.FullScreenEvent;
  31 import java.awt.*;
  32 import java.awt.Dialog.ModalityType;
  33 import java.awt.event.*;
  34 import java.beans.*;












  35 import java.lang.reflect.InvocationTargetException;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;

  38 import java.util.concurrent.atomic.AtomicBoolean;
  39 import java.util.concurrent.atomic.AtomicLong;
  40 import java.util.concurrent.atomic.AtomicReference;
  41 
  42 import javax.swing.*;


  43 
  44 import sun.awt.*;

  45 import sun.awt.AWTAccessor.ComponentAccessor;
  46 import sun.awt.AWTAccessor.WindowAccessor;
  47 import sun.java2d.SurfaceData;
  48 import sun.java2d.opengl.CGLSurfaceData;
  49 import sun.lwawt.*;


  50 import sun.util.logging.PlatformLogger;
  51 
  52 import com.apple.laf.*;
  53 import com.apple.laf.ClientPropertyApplicator.Property;
  54 import com.sun.awt.AWTUtilities;
  55 import sun.lwawt.LWWindowPeer.PeerType;
  56 
  57 public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
  58     private native long nativeCreateNSWindow(long nsViewPtr,long ownerPtr, long styleBits, double x, double y, double w, double h);
  59     private static native void nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data);
  60     private static native void nativeSetNSWindowMenuBar(long nsWindowPtr, long menuBarPtr);
  61     private static native Insets nativeGetNSWindowInsets(long nsWindowPtr);
  62     private static native void nativeSetNSWindowBounds(long nsWindowPtr, double x, double y, double w, double h);
  63     private static native void nativeSetNSWindowLocationByPlatform(long nsWindowPtr);
  64     private static native void nativeSetNSWindowStandardFrame(long nsWindowPtr,
  65             double x, double y, double w, double h);
  66     private static native void nativeSetNSWindowMinMax(long nsWindowPtr, double minW, double minH, double maxW, double maxH);
  67     private static native void nativePushNSWindowToBack(long nsWindowPtr);
  68     private static native void nativePushNSWindowToFront(long nsWindowPtr);
  69     private static native void nativeSetNSWindowTitle(long nsWindowPtr, String title);
  70     private static native void nativeRevalidateNSWindowShadow(long nsWindowPtr);
  71     private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
  72     private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);


 207             c.execute(ptr -> nativeRevalidateNSWindowShadow(ptr));
 208         }},
 209         new Property<CPlatformWindow>(WINDOW_DOCUMENT_FILE) { public void applyProperty(final CPlatformWindow c, final Object value) {
 210             if (value == null || !(value instanceof java.io.File)) {
 211                 c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, null));
 212                 return;
 213             }
 214 
 215             final String filename = ((java.io.File)value).getAbsolutePath();
 216             c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, filename));
 217         }}
 218     }) {
 219         @SuppressWarnings("deprecation")
 220         public CPlatformWindow convertJComponentToTarget(final JRootPane p) {
 221             Component root = SwingUtilities.getRoot(p);
 222             final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
 223             if (root == null || acc.getPeer(root) == null) return null;
 224             return (CPlatformWindow)((LWWindowPeer)acc.getPeer(root)).getPlatformWindow();
 225         }
 226     };














 227 
 228     // Bounds of the native widget but in the Java coordinate system.
 229     // In order to keep it up-to-date we will update them on
 230     // 1) setting native bounds via nativeSetBounds() call
 231     // 2) getting notification from the native level via deliverMoveResizeEvent()
 232     private Rectangle nativeBounds = new Rectangle(0, 0, 0, 0);
 233     private volatile boolean isFullScreenMode;
 234     private boolean isFullScreenAnimationOn;
 235 
 236     private volatile boolean isInFullScreen;
 237     private volatile boolean isIconifyAnimationActive;
 238     private volatile boolean isZoomed;
 239 
 240     private Window target;
 241     private LWWindowPeer peer;
 242     protected CPlatformView contentView;
 243     protected CPlatformWindow owner;
 244     protected boolean visible = false; // visibility status from native perspective
 245     private boolean undecorated; // initialized in getInitialStyleBits()
 246     private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
 247     private CPlatformResponder responder;

 248 
 249     public CPlatformWindow() {
 250         super(0, true);
 251     }
 252 
 253     /*
 254      * Delegate initialization (create native window and all the
 255      * related resources).
 256      */
 257     @Override // PlatformWindow
 258     public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) {
 259         initializeBase(_target, _peer, _owner, new CPlatformView());
 260 
 261         final int styleBits = getInitialStyleBits();
 262 
 263         responder = createPlatformResponder();
 264         contentView = createContentView();
 265         contentView.initialize(peer, responder);
 266 
 267         Rectangle bounds;


1155     private void orderAboveSiblings() {
1156         // Recursively pop up the windows from the very bottom, (i.e. root owner) so that
1157         // the windows are ordered above their nearest owner; ancestors of the window,
1158         // which is going to become 'main window', are placed above their siblings.
1159         CPlatformWindow rootOwner = getRootOwner();
1160         if (rootOwner.isVisible() && !rootOwner.isIconified()) {
1161             rootOwner.execute(CWrapper.NSWindow::orderFront);
1162         }
1163         // Do not order child windows of iconified owner.
1164         if (!rootOwner.isIconified()) {
1165             final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
1166             orderAboveSiblingsImpl(windowAccessor.getOwnedWindows(rootOwner.target));
1167         }
1168     }
1169 
1170     private void orderAboveSiblingsImpl(Window[] windows) {
1171         ArrayList<Window> childWindows = new ArrayList<Window>();
1172 
1173         final ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
1174         final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
1175 
1176         // Go through the list of windows and perform ordering.

1177         for (Window w : windows) {
1178             boolean iconified = false;
1179             final Object p = componentAccessor.getPeer(w);
1180             if (p instanceof LWWindowPeer) {
1181                 CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
1182                 iconified = isIconified();
1183                 if (pw != null && pw.isVisible() && !iconified) {
1184                     // If the window is one of ancestors of 'main window' or is going to become main by itself,
1185                     // the window should be ordered above its siblings; otherwise the window is just ordered
1186                     // above its nearest parent.
1187                     if (pw.isOneOfOwnersOrSelf(this)) {
1188                         pw.execute(CWrapper.NSWindow::orderFront);
1189                     } else {
1190                         pw.owner.execute(ownerPtr -> {



1191                             pw.execute(ptr -> {
1192                                 CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, ownerPtr);
1193                             });
1194                         });

1195                     }
1196                     pw.applyWindowLevel(w);
1197                 }
1198             }
1199             // Retrieve the child windows for each window from the list except iconified ones
1200             // and store them for future use.
1201             // Note: we collect data about child windows even for invisible owners, since they may have
1202             // visible children.
1203             if (!iconified) {
1204                 childWindows.addAll(Arrays.asList(windowAccessor.getOwnedWindows(w)));
1205             }
1206         }
1207         // If some windows, which have just been ordered, have any child windows, let's start new iteration
1208         // and order these child windows.
1209         if (!childWindows.isEmpty()) {
1210             orderAboveSiblingsImpl(childWindows.toArray(new Window[0]));
1211         }
1212     }
1213 
1214     protected void applyWindowLevel(Window target) {
1215         if (target.isAlwaysOnTop() && target.getType() != Window.Type.POPUP) {
1216             execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSFloatingWindowLevel));
1217         } else if (target.getType() == Window.Type.POPUP) {
1218             execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSPopUpMenuWindowLevel));
1219         }
1220     }
1221 
1222     // ----------------------------------------------------------------------
1223     //                          NATIVE CALLBACKS
1224     // ----------------------------------------------------------------------
1225 
1226     private void windowWillMiniaturize() {
1227         isIconifyAnimationActive = true;
1228     }
1229 
1230     private void windowDidBecomeMain() {

1231         if (checkBlockingAndOrder()) return;
1232         // If it's not blocked, make sure it's above its siblings
1233         orderAboveSiblings();
1234     }
1235 
1236     private void windowWillEnterFullScreen() {
1237         isFullScreenAnimationOn = true;
1238     }
1239 
1240     private void windowDidEnterFullScreen() {
1241         isInFullScreen = true;
1242         isFullScreenAnimationOn = false;
1243     }
1244 
1245     private void windowWillExitFullScreen() {
1246         isFullScreenAnimationOn = true;
1247     }
1248 
1249     private void windowDidExitFullScreen() {
1250         isInFullScreen = false;


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.lwawt.macosx;
  27 
  28 import java.awt.Color;
  29 import java.awt.Component;
  30 import java.awt.DefaultKeyboardFocusManager;
  31 import java.awt.Dialog;
  32 import java.awt.Dialog.ModalityType;
  33 import java.awt.Font;
  34 import java.awt.FontMetrics;
  35 import java.awt.Frame;
  36 import java.awt.GraphicsDevice;
  37 import java.awt.Insets;
  38 import java.awt.MenuBar;
  39 import java.awt.Point;
  40 import java.awt.Rectangle;
  41 import java.awt.Toolkit;
  42 import java.awt.Window;
  43 import java.awt.event.FocusEvent;
  44 import java.awt.event.WindowEvent;
  45 import java.beans.PropertyChangeEvent;
  46 import java.beans.PropertyChangeListener;
  47 import java.lang.reflect.InvocationTargetException;
  48 import java.util.ArrayList;
  49 import java.util.Arrays;
  50 import java.util.Comparator;
  51 import java.util.concurrent.atomic.AtomicBoolean;
  52 import java.util.concurrent.atomic.AtomicLong;
  53 import java.util.concurrent.atomic.AtomicReference;
  54 
  55 import javax.swing.JRootPane;
  56 import javax.swing.RootPaneContainer;
  57 import javax.swing.SwingUtilities;
  58 
  59 import com.apple.laf.ClientPropertyApplicator;
  60 import sun.awt.AWTAccessor;
  61 import sun.awt.AWTAccessor.ComponentAccessor;
  62 import sun.awt.AWTAccessor.WindowAccessor;
  63 import sun.java2d.SurfaceData;
  64 import sun.java2d.opengl.CGLSurfaceData;
  65 import sun.lwawt.LWToolkit;
  66 import sun.lwawt.LWWindowPeer;
  67 import sun.lwawt.PlatformWindow;
  68 import sun.util.logging.PlatformLogger;
  69 

  70 import com.apple.laf.ClientPropertyApplicator.Property;
  71 import com.sun.awt.AWTUtilities;
  72 import sun.lwawt.LWWindowPeer.PeerType;
  73 
  74 public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
  75     private native long nativeCreateNSWindow(long nsViewPtr,long ownerPtr, long styleBits, double x, double y, double w, double h);
  76     private static native void nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data);
  77     private static native void nativeSetNSWindowMenuBar(long nsWindowPtr, long menuBarPtr);
  78     private static native Insets nativeGetNSWindowInsets(long nsWindowPtr);
  79     private static native void nativeSetNSWindowBounds(long nsWindowPtr, double x, double y, double w, double h);
  80     private static native void nativeSetNSWindowLocationByPlatform(long nsWindowPtr);
  81     private static native void nativeSetNSWindowStandardFrame(long nsWindowPtr,
  82             double x, double y, double w, double h);
  83     private static native void nativeSetNSWindowMinMax(long nsWindowPtr, double minW, double minH, double maxW, double maxH);
  84     private static native void nativePushNSWindowToBack(long nsWindowPtr);
  85     private static native void nativePushNSWindowToFront(long nsWindowPtr);
  86     private static native void nativeSetNSWindowTitle(long nsWindowPtr, String title);
  87     private static native void nativeRevalidateNSWindowShadow(long nsWindowPtr);
  88     private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
  89     private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);


 224             c.execute(ptr -> nativeRevalidateNSWindowShadow(ptr));
 225         }},
 226         new Property<CPlatformWindow>(WINDOW_DOCUMENT_FILE) { public void applyProperty(final CPlatformWindow c, final Object value) {
 227             if (value == null || !(value instanceof java.io.File)) {
 228                 c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, null));
 229                 return;
 230             }
 231 
 232             final String filename = ((java.io.File)value).getAbsolutePath();
 233             c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, filename));
 234         }}
 235     }) {
 236         @SuppressWarnings("deprecation")
 237         public CPlatformWindow convertJComponentToTarget(final JRootPane p) {
 238             Component root = SwingUtilities.getRoot(p);
 239             final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
 240             if (root == null || acc.getPeer(root) == null) return null;
 241             return (CPlatformWindow)((LWWindowPeer)acc.getPeer(root)).getPlatformWindow();
 242         }
 243     };
 244     private final Comparator<Window> siblingsComparator = (w1, w2) -> {
 245         if (w1 == w2) {
 246             return 0;
 247         }
 248         ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
 249         Object p1 = componentAccessor.getPeer(w1);
 250         Object p2 = componentAccessor.getPeer(w2);
 251         if (p1 instanceof LWWindowPeer && p2 instanceof LWWindowPeer) {
 252             return Long.compare(
 253                     ((CPlatformWindow) (((LWWindowPeer) p1).getPlatformWindow())).lastBecomeMainTime,
 254                     ((CPlatformWindow) (((LWWindowPeer) p2).getPlatformWindow())).lastBecomeMainTime);
 255         }
 256         return 0;
 257     };
 258 
 259     // Bounds of the native widget but in the Java coordinate system.
 260     // In order to keep it up-to-date we will update them on
 261     // 1) setting native bounds via nativeSetBounds() call
 262     // 2) getting notification from the native level via deliverMoveResizeEvent()
 263     private Rectangle nativeBounds = new Rectangle(0, 0, 0, 0);
 264     private volatile boolean isFullScreenMode;
 265     private boolean isFullScreenAnimationOn;
 266 
 267     private volatile boolean isInFullScreen;
 268     private volatile boolean isIconifyAnimationActive;
 269     private volatile boolean isZoomed;
 270 
 271     private Window target;
 272     private LWWindowPeer peer;
 273     protected CPlatformView contentView;
 274     protected CPlatformWindow owner;
 275     protected boolean visible = false; // visibility status from native perspective
 276     private boolean undecorated; // initialized in getInitialStyleBits()
 277     private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
 278     private CPlatformResponder responder;
 279     private long lastBecomeMainTime; // this is necessary to preserve right siblings order
 280 
 281     public CPlatformWindow() {
 282         super(0, true);
 283     }
 284 
 285     /*
 286      * Delegate initialization (create native window and all the
 287      * related resources).
 288      */
 289     @Override // PlatformWindow
 290     public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) {
 291         initializeBase(_target, _peer, _owner, new CPlatformView());
 292 
 293         final int styleBits = getInitialStyleBits();
 294 
 295         responder = createPlatformResponder();
 296         contentView = createContentView();
 297         contentView.initialize(peer, responder);
 298 
 299         Rectangle bounds;


1187     private void orderAboveSiblings() {
1188         // Recursively pop up the windows from the very bottom, (i.e. root owner) so that
1189         // the windows are ordered above their nearest owner; ancestors of the window,
1190         // which is going to become 'main window', are placed above their siblings.
1191         CPlatformWindow rootOwner = getRootOwner();
1192         if (rootOwner.isVisible() && !rootOwner.isIconified()) {
1193             rootOwner.execute(CWrapper.NSWindow::orderFront);
1194         }
1195         // Do not order child windows of iconified owner.
1196         if (!rootOwner.isIconified()) {
1197             final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
1198             orderAboveSiblingsImpl(windowAccessor.getOwnedWindows(rootOwner.target));
1199         }
1200     }
1201 
1202     private void orderAboveSiblingsImpl(Window[] windows) {
1203         ArrayList<Window> childWindows = new ArrayList<Window>();
1204 
1205         final ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
1206         final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
1207         Arrays.sort(windows, siblingsComparator);
1208         // Go through the list of windows and perform ordering.
1209         CPlatformWindow pwUnder = null;
1210         for (Window w : windows) {
1211             boolean iconified = false;
1212             final Object p = componentAccessor.getPeer(w);
1213             if (p instanceof LWWindowPeer) {
1214                 CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
1215                 iconified = isIconified();
1216                 if (pw != null && pw.isVisible() && !iconified) {
1217                     // If the window is one of ancestors of 'main window' or is going to become main by itself,
1218                     // the window should be ordered above its siblings; otherwise the window is just ordered
1219                     // above its nearest parent.
1220                     if (pw.isOneOfOwnersOrSelf(this)) {
1221                         pw.execute(CWrapper.NSWindow::orderFront);
1222                     } else {
1223                         if (pwUnder == null) {
1224                             pwUnder = pw.owner;
1225                         }
1226                         pwUnder.execute(underPtr -> {
1227                             pw.execute(ptr -> {
1228                                 CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, underPtr);
1229                             });
1230                         });
1231                         pwUnder = pw;
1232                     }
1233                     pw.applyWindowLevel(w);
1234                 }
1235             }
1236             // Retrieve the child windows for each window from the list except iconified ones
1237             // and store them for future use.
1238             // Note: we collect data about child windows even for invisible owners, since they may have
1239             // visible children.
1240             if (!iconified) {
1241                 childWindows.addAll(Arrays.asList(windowAccessor.getOwnedWindows(w)));
1242             }
1243         }
1244         // If some windows, which have just been ordered, have any child windows, let's start new iteration
1245         // and order these child windows.
1246         if (!childWindows.isEmpty()) {
1247             orderAboveSiblingsImpl(childWindows.toArray(new Window[0]));
1248         }
1249     }
1250 
1251     protected void applyWindowLevel(Window target) {
1252         if (target.isAlwaysOnTop() && target.getType() != Window.Type.POPUP) {
1253             execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSFloatingWindowLevel));
1254         } else if (target.getType() == Window.Type.POPUP) {
1255             execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSPopUpMenuWindowLevel));
1256         }
1257     }
1258 
1259     // ----------------------------------------------------------------------
1260     //                          NATIVE CALLBACKS
1261     // ----------------------------------------------------------------------
1262 
1263     private void windowWillMiniaturize() {
1264         isIconifyAnimationActive = true;
1265     }
1266 
1267     private void windowDidBecomeMain() {
1268         lastBecomeMainTime = System.currentTimeMillis();
1269         if (checkBlockingAndOrder()) return;
1270         // If it's not blocked, make sure it's above its siblings
1271         orderAboveSiblings();
1272     }
1273 
1274     private void windowWillEnterFullScreen() {
1275         isFullScreenAnimationOn = true;
1276     }
1277 
1278     private void windowDidEnterFullScreen() {
1279         isInFullScreen = true;
1280         isFullScreenAnimationOn = false;
1281     }
1282 
1283     private void windowWillExitFullScreen() {
1284         isFullScreenAnimationOn = true;
1285     }
1286 
1287     private void windowDidExitFullScreen() {
1288         isInFullScreen = false;
< prev index next >