changeset 4648:a05473e09c47

RT-15314 Allow trusted apps to disable the fullscreen overlay warning
author ddhill
date Fri, 09 Aug 2013 18:08:11 -0400
parents b0a1b8b91e3b
children 984368f375ed
files modules/graphics/src/main/java/com/sun/javafx/tk/DummyToolkit.java modules/graphics/src/main/java/com/sun/javafx/tk/TKSceneListener.java modules/graphics/src/main/java/com/sun/javafx/tk/TKStage.java modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedScene.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/OverlayWarning.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/WindowStage.java modules/graphics/src/main/java/javafx/scene/Scene.java modules/graphics/src/main/java/javafx/scene/input/KeyCombination.java modules/graphics/src/main/java/javafx/stage/PopupWindow.java modules/graphics/src/main/java/javafx/stage/Stage.java modules/graphics/src/stub/java/com/sun/javafx/pgstub/StubToolkit.java
diffstat 14 files changed, 215 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/DummyToolkit.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/DummyToolkit.java	Fri Aug 09 18:08:11 2013 -0400
@@ -43,7 +43,9 @@
 import javafx.scene.shape.StrokeType;
 import javafx.stage.FileChooser.ExtensionFilter;
 import javafx.stage.Modality;
+import javafx.stage.Stage;
 import javafx.stage.StageStyle;
+import javafx.stage.Window;
 import java.io.File;
 import java.io.InputStream;
 import java.security.AccessControlContext;
@@ -90,12 +92,12 @@
     }
 
     @Override
-    public TKStage createTKStage(StageStyle stageStyle, boolean primary, Modality modality, TKStage owner, boolean rtl, AccessControlContext acc) {
+    public TKStage createTKStage(Window peerWindow, StageStyle stageStyle, boolean primary, Modality modality, TKStage owner, boolean rtl, AccessControlContext acc) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
     @Override
-    public TKStage createTKPopupStage(TKStage owner, AccessControlContext acc) {
+    public TKStage createTKPopupStage(Window peerWindow, TKStage owner, AccessControlContext acc) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/TKSceneListener.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/TKSceneListener.java	Fri Aug 09 18:08:11 2013 -0400
@@ -62,8 +62,7 @@
     /**
      * Pass a key event to the scene to handle
      */
-    public void keyEvent(EventType<KeyEvent> type, int key, char[] chars,
-                         boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown);
+    public void keyEvent(KeyEvent keyEvent);
 
     /**
      * Pass an input method event to the scene to handle
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/TKStage.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/TKStage.java	Fri Aug 09 18:08:11 2013 -0400
@@ -29,6 +29,9 @@
 import com.sun.javafx.accessible.providers.AccessibleStageProvider;
 
 import java.security.AccessControlContext;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination.ModifierValue;
 
 /**
  * TKStage - Peer interface for a Stage
@@ -258,4 +261,13 @@
                                              int newProperty );
     public void accessibleFirePropertyChange(Object nativeAcc, int propertyId, boolean oldProperty,
                                              boolean newProperty );    
+
+
+    public static final KeyCodeCombination defaultFullScreenExitKeycombo =
+            new KeyCodeCombination(KeyCode.ESCAPE,
+            ModifierValue.UP,
+            ModifierValue.UP,
+            ModifierValue.UP,
+            ModifierValue.UP,
+            ModifierValue.UP);
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java	Fri Aug 09 18:08:11 2013 -0400
@@ -51,6 +51,7 @@
 import javafx.scene.shape.StrokeType;
 import javafx.stage.FileChooser.ExtensionFilter;
 import javafx.stage.Modality;
+import javafx.stage.Stage;
 import javafx.stage.StageStyle;
 import javafx.stage.Window;
 import java.io.File;
@@ -272,10 +273,10 @@
 
     public abstract boolean isNestedLoopRunning();
 
-    public abstract TKStage createTKStage(StageStyle stageStyle, boolean primary,
+    public abstract TKStage createTKStage(Window peerWindow, StageStyle stageStyle, boolean primary,
             Modality modality, TKStage owner, boolean rtl, AccessControlContext acc);
 
-    public abstract TKStage createTKPopupStage(TKStage owner, AccessControlContext acc);
+    public abstract TKStage createTKPopupStage(Window peerWindow, TKStage owner, AccessControlContext acc);
     public abstract TKStage createTKEmbeddedStage(HostInterface host, AccessControlContext acc);
 
     /**
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedScene.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedScene.java	Fri Aug 09 18:08:11 2013 -0400
@@ -27,6 +27,7 @@
 
 import javafx.application.Platform;
 import javafx.event.EventType;
+import javafx.scene.input.KeyCode;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.input.ScrollEvent;
 import java.nio.IntBuffer;
@@ -38,6 +39,7 @@
 import com.sun.javafx.embed.EmbeddedSceneDropTargetInterface;
 import com.sun.javafx.embed.EmbeddedSceneInterface;
 import com.sun.javafx.embed.HostInterface;
+import com.sun.javafx.scene.input.KeyCodeMap;
 import com.sun.javafx.scene.traversal.Direction;
 import com.sun.javafx.sg.prism.NGNode;
 import com.sun.javafx.tk.TKClipboard;
@@ -252,8 +254,15 @@
                             boolean controlDown = (modifiers & AbstractEvents.MODIFIER_CONTROL) != 0;
                             boolean altDown = (modifiers & AbstractEvents.MODIFIER_ALT) != 0;
                             boolean metaDown = (modifiers & AbstractEvents.MODIFIER_META) != 0;
-                            sceneListener.keyEvent(AbstractEvents.keyIDToFXEventType(type),
-                                    key, ch, shiftDown, controlDown, altDown, metaDown);
+
+                            String str = new String(ch);
+                            String text = str; // TODO: this must be a text like "HOME", "F1", or "A"
+                            javafx.scene.input.KeyEvent keyEvent = new javafx.scene.input.KeyEvent(
+                                    AbstractEvents.keyIDToFXEventType(type),
+                                    str, text,
+                                    KeyCodeMap.valueOf(key),
+                                    shiftDown, controlDown, altDown, metaDown);
+                            sceneListener.keyEvent(keyEvent);
                         }
                         return null;
                     }
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java	Fri Aug 09 18:08:11 2013 -0400
@@ -37,6 +37,7 @@
 import com.sun.glass.ui.Window;
 import com.sun.javafx.PlatformUtil;
 import com.sun.javafx.collections.TrackableObservableList;
+import com.sun.javafx.scene.input.KeyCodeMap;
 
 import javafx.collections.ListChangeListener;
 import javafx.collections.ObservableList;
@@ -134,11 +135,27 @@
                 if (stage != null) {
                     stage.setInEventHandler(true);
                 }
+
+                boolean shiftDown = (modifiers & KeyEvent.MODIFIER_SHIFT) != 0;
+                boolean controlDown = (modifiers & KeyEvent.MODIFIER_CONTROL) != 0;
+                boolean altDown = (modifiers & KeyEvent.MODIFIER_ALT) != 0;
+                boolean metaDown = (modifiers & KeyEvent.MODIFIER_WINDOWS) != 0;
+
+                String str = new String(chars);
+                String text = str; // TODO: this must be a text like "HOME", "F1", or "A"
+
+                javafx.scene.input.KeyEvent keyEvent = new javafx.scene.input.KeyEvent(
+                        keyEventType(type),
+                        str, text, 
+                        KeyCodeMap.valueOf(key) ,
+                        shiftDown, controlDown, altDown, metaDown);
+
                 switch (type) {
                     case com.sun.glass.events.KeyEvent.PRESS:
-                        if (key == com.sun.glass.events.KeyEvent.VK_ESCAPE &&
-                                view.isInFullscreen() && stage != null) {
-                            stage.exitFullScreen();
+                        if (view.isInFullscreen() && stage != null) {
+                            if (stage.getSavedFullScreenExitKey().match(keyEvent)) {
+                                stage.exitFullScreen();
+                            }
                         }
                         /* NOBREAK */
                     case com.sun.glass.events.KeyEvent.RELEASE:
@@ -149,14 +166,7 @@
                             }
                         }
                         if (scene.sceneListener != null) {
-                            EventType<javafx.scene.input.KeyEvent> eventType = keyEventType(type);
-                            boolean shiftDown = (modifiers & KeyEvent.MODIFIER_SHIFT) != 0;
-                            boolean controlDown = (modifiers & KeyEvent.MODIFIER_CONTROL) != 0;
-                            boolean altDown = (modifiers & KeyEvent.MODIFIER_ALT) != 0;
-                            boolean metaDown = (modifiers & KeyEvent.MODIFIER_WINDOWS) != 0;
-
-                            scene.sceneListener.keyEvent(eventType, key, chars,
-                                    shiftDown, controlDown, altDown, metaDown);
+                            scene.sceneListener.keyEvent(keyEvent);
                         }
                         break;
                     default:
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/OverlayWarning.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/OverlayWarning.java	Fri Aug 09 18:08:11 2013 -0400
@@ -127,7 +127,13 @@
         });
    }
     
-    protected void warn() {
+    protected void warn(String msg) {
+        text.setText(msg == null
+                ? localize("OverlayWarningESC")
+                : msg);
+        // needed to force the text to update...
+        text.impl_updatePeer();
+        
         warningTransition = true;
         painter.setRenderOverlay(true);
         overlayTransition.play();
@@ -149,21 +155,19 @@
         return warningTransition;
     }
     
-    private Text text;
+    private Text text = new Text();
     private Rectangle background;
     private Group root;
     
     private Group createOverlayGroup() {
         final Scene scene = new Scene(new Group());
         final Font font = new Font(Font.getDefault().getFamily(), FONTSIZE);
-        final Text text = new Text();
         final Rectangle2D screenBounds = javafx.stage.Screen.getPrimary().getBounds();
         
         scene.setFill(null);
         
         String TEXT_CSS =
             "-fx-effect: dropshadow(two-pass-box, rgba(0,0,0,0.75), 3, 0.0, 0, 2);";
-        text.setText(localize("OverlayWarningESC"));
         text.setStroke(Color.WHITE);
         text.setFill(Color.WHITE);
         text.setFont(font);
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java	Fri Aug 09 18:08:11 2013 -0400
@@ -127,6 +127,7 @@
 import com.sun.scenario.effect.impl.prism.PrImage;
 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGER;
 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGING_ENABLED;
+import javafx.stage.Window;
 
 public final class QuantumToolkit extends Toolkit {
 
@@ -513,10 +514,10 @@
         }
     }
 
-    @Override public TKStage createTKStage(StageStyle stageStyle,
+    @Override public TKStage createTKStage(Window peerWindow, StageStyle stageStyle,
             boolean primary, Modality modality, TKStage owner, boolean rtl, AccessControlContext acc) {
         assertToolkitRunning();
-        WindowStage stage = new WindowStage(stageStyle, modality, owner);
+        WindowStage stage = new WindowStage(peerWindow, stageStyle, modality, owner);
         stage.setSecurityContext(acc);
         if (primary) {
             stage.setIsPrimary();
@@ -566,10 +567,11 @@
         eventLoop.leave(rval);
     }
 
-    @Override public TKStage createTKPopupStage(TKStage owner,
+    @Override public TKStage createTKPopupStage(Window peerWindow,
+                                                TKStage owner,
                                                 AccessControlContext acc) {
         assertToolkitRunning();
-        WindowStage stage = new WindowStage(StageStyle.TRANSPARENT, null, owner);
+        WindowStage stage = new WindowStage(peerWindow, StageStyle.TRANSPARENT, null, owner);
         stage.setSecurityContext(acc);
         stage.setIsPopup();
         stage.init(systemMenu);
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/WindowStage.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/WindowStage.java	Fri Aug 09 18:08:11 2013 -0400
@@ -38,7 +38,9 @@
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 
+import javafx.scene.input.KeyCombination;
 import javafx.stage.Modality;
+import javafx.stage.Stage;
 import javafx.stage.StageStyle;
 
 import com.sun.glass.events.WindowEvent;
@@ -60,6 +62,8 @@
 
     protected Window platformWindow;
 
+    protected javafx.stage.Stage fxStage;
+
     private StageStyle style;
     private GlassStage owner = null;
     private Modality modality = Modality.NONE;
@@ -94,11 +98,17 @@
         return appletWindow;
     }
 
-    public WindowStage(final StageStyle stageStyle, Modality modality, TKStage owner) {
+    public WindowStage(javafx.stage.Window peerWindow, final StageStyle stageStyle, Modality modality, TKStage owner) {
         this.style = stageStyle;
         this.owner = (GlassStage)owner;
         this.modality = modality;
 
+        if (peerWindow instanceof javafx.stage.Stage) {
+            fxStage = (Stage)peerWindow;
+        } else {
+            fxStage = null;
+        }
+
         transparent = stageStyle == StageStyle.TRANSPARENT;
         if (owner == null) {
             if (this.modality == Modality.WINDOW_MODAL) {
@@ -507,6 +517,12 @@
 
     private boolean fullScreenFromUserEvent = false;
 
+    private KeyCombination savedFullScreenExitKey = null;
+
+    public final KeyCombination getSavedFullScreenExitKey() {
+        return savedFullScreenExitKey;
+    }
+
     private void applyFullScreen() {
         if (platformWindow == null) {
             // applyFullScreen() can be called from setVisible(false), while the
@@ -520,15 +536,49 @@
                 // indicating that the fullscreen request came from an input
                 // event handler.
                 // If not notify the stageListener to reset fullscreen to false.
-                if (!isTrustedFullScreen() && !fullScreenFromUserEvent) {
+                final boolean isTrusted = isTrustedFullScreen();
+                if (!isTrusted && !fullScreenFromUserEvent) {
                     exitFullScreen();
                 } else {
                     v.enterFullscreen(false, false, false);
                     if (warning != null && warning.inWarningTransition()) {
                         warning.setView(getViewScene());
-                    } else if (warning == null) {
-                        warning = new OverlayWarning(getViewScene());
-                        warning.warn();
+                    } else {                        
+                        boolean showWarning = true;
+
+                        KeyCombination key = null;
+                        String exitMessage = null;
+
+                        if (isTrusted && (fxStage != null)) {
+                            // copy the user set definitions for later use.
+                            key = fxStage.getFullScreenExitKeyCombination();
+
+                            exitMessage = fxStage.getFullScreenExitHint();
+                        }
+                        
+                        savedFullScreenExitKey =
+                                key == null
+                                ? defaultFullScreenExitKeycombo
+                                : key;
+
+                        // if the hint is "" dont show
+                        if (exitMessage != null &&
+                                (exitMessage.equals(""))) {
+                            showWarning = false;
+                        }
+
+                        // if the key is NO_MATCH dont show
+                        if (savedFullScreenExitKey.equals(KeyCombination.NO_MATCH)) {
+                            showWarning = false;
+                        }
+                        
+                        if (showWarning && warning == null) {
+                            warning = new OverlayWarning(getViewScene());
+                        }
+
+                        if (showWarning && warning != null) {
+                            warning.warn(exitMessage);
+                        }
                     }
                 }
             } else {
--- a/modules/graphics/src/main/java/javafx/scene/Scene.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Scene.java	Fri Aug 09 18:08:11 2013 -0400
@@ -2395,14 +2395,10 @@
             impl_processMouseEvent(mouseEvent);
         }
 
+
         @Override
-        public void keyEvent(EventType<KeyEvent> type, int key, char[] cs,
-                             boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown)
+        public void keyEvent(KeyEvent keyEvent)
         {
-            String chars = new String(cs);
-            String text = chars; // TODO: this must be a text like "HOME", "F1", or "A"
-            KeyEvent keyEvent = new KeyEvent(type, chars, text, KeyCodeMap.valueOf(key),
-                    shiftDown, controlDown, altDown, metaDown);
             impl_processKeyEvent(keyEvent);
         }
 
--- a/modules/graphics/src/main/java/javafx/scene/input/KeyCombination.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/input/KeyCombination.java	Fri Aug 09 18:08:11 2013 -0400
@@ -101,6 +101,17 @@
         META_DOWN, META_ANY,
         SHORTCUT_DOWN, SHORTCUT_ANY
     };
+
+    /**
+     * A KeyCombination that will match with no events.
+     */
+    public static final KeyCombination NO_MATCH = new KeyCombination() {
+        @Override
+        public boolean match(KeyEvent e) {
+            return false;
+        }
+    };
+
     /** The state of the {@code shift} key in this key combination. */
     private final ModifierValue shift;
 
--- a/modules/graphics/src/main/java/javafx/stage/PopupWindow.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/stage/PopupWindow.java	Fri Aug 09 18:08:11 2013 -0400
@@ -432,7 +432,7 @@
         Toolkit toolkit = Toolkit.getToolkit();
         if (visible && (impl_peer == null)) {
             // Setup the peer
-            impl_peer = toolkit.createTKPopupStage(getOwnerWindow().impl_getPeer(), acc);
+            impl_peer = toolkit.createTKPopupStage(this, getOwnerWindow().impl_getPeer(), acc);
             peerListener = new PopupWindowPeerListener(PopupWindow.this);
         }
     }
--- a/modules/graphics/src/main/java/javafx/stage/Stage.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/stage/Stage.java	Fri Aug 09 18:08:11 2013 -0400
@@ -39,6 +39,7 @@
 import javafx.geometry.NodeOrientation;
 import javafx.scene.Scene;
 import javafx.scene.image.Image;
+import javafx.scene.input.KeyCombination;
 
 import com.sun.javafx.beans.annotations.Default;
 import com.sun.javafx.collections.TrackableObservableList;
@@ -51,9 +52,11 @@
 import com.sun.javafx.tk.Toolkit;
 import javafx.beans.property.DoubleProperty;
 import javafx.beans.property.DoublePropertyBase;
+import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.Property;
 import javafx.beans.property.ReadOnlyBooleanProperty;
 import javafx.beans.property.ReadOnlyBooleanWrapper;
+import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ObservableValue;
 
 /**
@@ -575,10 +578,10 @@
      * For desktop profile the user can unconditionally exit full-screen mode
      * at any time by pressing {@code ESC}.
      * <p>
-     * There are differences in behavior between signed and unsigned
-     * applications. Signed applications are allowed to enter full-screen
-     * exclusive mode unrestricted while unsigned applications will
-     * have the following restrictions:
+     * There are differences in behavior between applications if a security 
+     * manager is present. Applications with permissions are allowed to enter 
+     * full-screen exclusive mode unrestricted. Applications without the proper 
+     * permissions will have the following restrictions:
      * </p>
      * <ul>
      *  <li>Applications can only enter FSEM in response
@@ -1040,7 +1043,7 @@
             Scene scene = getScene();
             boolean rtl = scene != null && scene.getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT;
 
-            impl_peer = toolkit.createTKStage(getStyle(), isPrimary(), getModality(), tkStage, rtl, acc);
+            impl_peer = toolkit.createTKStage(this, getStyle(), isPrimary(), getModality(), tkStage, rtl, acc);
             impl_peer.setMinimumSize((int) Math.ceil(getMinWidth()),
                     (int) Math.ceil(getMinHeight()));
             impl_peer.setMaximumSize((int) Math.floor(getMaxWidth()),
@@ -1123,4 +1126,72 @@
     Window getWindowOwner() {
         return getOwner();
     }
+
+    
+    private final ObjectProperty<KeyCombination> fullScreenExitCombination =
+            new SimpleObjectProperty<KeyCombination>(this, "fullScreenExitCombination", null);
+
+    /**
+     * Specifies what KeyCombination will allow the user to exit full screen
+     * mode. A value of KeyCombination.NO_MATCH will not match any KeyEvent and
+     * will make it so the user is not able to escape from Full Screen mode. In 
+     * addition, using NO_MATCH will disable the Full Screen Exit Hint.
+     * A value of null means that the default platform specific key combination
+     * should be used. 
+     * <p>
+     * An internal copy of this value is made when entering FullScreen mode and will be 
+     * used to trigger the exit from the mode. If an application does not have
+     * the proper permissions, this setting will be ignored.
+     * </p>
+     * The default string displayed is controlled using the {@code fullScreenExitKeyProperty}
+     * and should be changed to match the {@code KeyCombination} used.
+     * @param keyCombination the key combination to exit on
+     * @since JavaFX 8.0 
+     */
+    public final void setFullScreenExitKeyCombination(KeyCombination keyCombination) {
+        fullScreenExitCombination.set(keyCombination);
+    }
+
+    /**
+     * Get the current sequence used to exit Full Screen mode.
+     * @return the current setting (null for system default)
+     * @since JavaFX 8.0 
+     */
+    public final KeyCombination getFullScreenExitKeyCombination() {
+        return fullScreenExitCombination.get();
+    }
+
+    /**
+     * Get the property for the Full Screen exit key combination.
+     * @return the property.
+     * @since JavaFX 8.0 
+     */
+    public final ObjectProperty<KeyCombination> fullScreenExitKeyProperty() {
+        return fullScreenExitCombination;
+    }
+
+    private final ObjectProperty<String> fullScreenExitHint = 
+            new SimpleObjectProperty<String>(this, "fullScreenExitHint", null);
+                
+    /**
+     * Specifies the text to show when a user enters full screen mode, usually
+     * used to indicate the way a user should go about exiting out of full
+     * screen mode. A value of null will result in the default per-locale
+     * message being displayed. If set to the empty string, then no message will
+     * be displayed. If an application does not have the proper permissions, 
+     * this setting will be ignored.
+     * @param value the string to be displayed.
+     * @since JavaFX 8.0 
+     */
+    public final void setFullScreenExitHint(String value) {
+        fullScreenExitHint.set(value);
+    }
+
+    public final String getFullScreenExitHint() {
+        return fullScreenExitHint.get();
+    }
+
+    public final ObjectProperty<String> fullScreenExitHintProperty() {
+        return fullScreenExitHint;
+    }
 }
--- a/modules/graphics/src/stub/java/com/sun/javafx/pgstub/StubToolkit.java	Fri Aug 09 14:27:08 2013 -0700
+++ b/modules/graphics/src/stub/java/com/sun/javafx/pgstub/StubToolkit.java	Fri Aug 09 18:08:11 2013 -0400
@@ -59,6 +59,7 @@
 import javafx.stage.FileChooser.ExtensionFilter;
 import javafx.stage.Modality;
 import javafx.stage.StageStyle;
+import javafx.stage.Window;
 import javafx.util.Pair;
 
 import java.io.File;
@@ -117,14 +118,15 @@
         return true;
     }
 
-    public TKStage createTKStage(StageStyle stageStyle, boolean primary,
+    @Override
+    public TKStage createTKStage(Window peerWindow, StageStyle stageStyle, boolean primary,
             Modality modality, TKStage owner, boolean rtl, AccessControlContext acc) {
 
         return new StubStage();
     }
 
     @Override
-    public TKStage createTKPopupStage(TKStage owner, AccessControlContext acc) {
+    public TKStage createTKPopupStage(Window peerWindow, TKStage owner, AccessControlContext acc) {
         return new StubPopupStage();
     }