changeset 7417:ea458832eefc

RT-37602: [Spec] Cursor.setVisible behavior is unspecified Reviewed-by: dblaukop
author Anthony Petrov <anthony.petrov@oracle.com>
date Fri, 04 Jul 2014 00:23:46 +0400
parents 0ac23d3086e3
children 5343b3c3f733
files modules/graphics/src/main/java/com/sun/glass/ui/Cursor.java modules/graphics/src/main/java/com/sun/glass/ui/mac/MacCursor.java modules/graphics/src/main/native-glass/mac/GlassCursor.m
diffstat 3 files changed, 50 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/glass/ui/Cursor.java	Thu Jul 03 11:09:34 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/Cursor.java	Fri Jul 04 00:23:46 2014 +0400
@@ -75,6 +75,33 @@
 
     /**
      * Shows or hides the cursor.
+     * <p>
+     * If the cursor is currently hidden with a previous call to {@code
+     * setVisible(false)}, setting a new cursor shape (e.g. by means of calling
+     * {@code Window.setCursor()}) does not automatically display the cursor on
+     * the screen until the client code calls {@code setVisible(true)} to show
+     * the cursor again.
+     * <p>
+     * If the mouse cursor is located over a non-Glass window at the time of
+     * calling this method, the call may or may not affect the native cursor's
+     * visibility. This behavior is platform-dependent.
+     * <p>
+     * When the mouse pointer is moved over a non-Glass window, depending on
+     * the native platform behavior, the cursor may or may not become visible
+     * on the screen, even if it was previously hidden by calling {@code
+     * setVisible(false)}. After this occurs, on some platforms the cursor may
+     * even remain visible permanently. For example, Mac OS X makes the cursor
+     * visible unconditionally when the mouse is moved over the Dock or Menu
+     * Bar areas. There's no way to detect that the native cursor became
+     * visible, however, from Glass perspective it is still considered hidden,
+     * and thus, when the mouse cursor is needed again, the app should call
+     * {@code setVisible(true)} in order to continue to operate properly.
+     * <p>
+     * Calling this method multiple times with the same argument may not have
+     * any effect. For example, if the cursor was hidden and the native OS
+     * restored its visibility, calling {@code setVisible(false)} again may not
+     * hide the cursor. If the app needs to ultimately hide the cursor, it
+     * should first show the cursor again, and then proceed with hiding it.
      */
     public static void setVisible(boolean visible) {
         Application.checkEventThread();
--- a/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacCursor.java	Thu Jul 03 11:09:34 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacCursor.java	Fri Jul 04 00:23:46 2014 +0400
@@ -50,7 +50,10 @@
 
     void set() {
         int type = getType();
-        setVisible(type != CURSOR_NONE);
+        isCursorNONE = type == CURSOR_NONE;
+        // Re-apply the last requested cursor visibility, and take into account
+        // the isCursorNONE flag (see the setter below).
+        setVisible(isVisible);
 
         switch (type) {
             case CURSOR_NONE:
@@ -70,8 +73,25 @@
     native private static void _setVisible(boolean visible);
     native private static Size _getBestSize(int width, int height);
 
+    // [NSCursor (un)hide] method calls must be balanced,
+    // so we keep the state in the boolean field to avoid
+    // multiple native calls.
+    private static boolean isNSCursorVisible = true;
+
+    // These two flags help us handle the NONE cursor which
+    // we emulate by hidding the cursor.
+    private static boolean isCursorNONE = false;
+    private static boolean isVisible = true; // as requested by client code
+
     static void setVisible_impl(boolean visible) {
-        _setVisible(visible);
+        isVisible = visible;
+        final boolean effectiveVisible = visible && !isCursorNONE;
+        if (isNSCursorVisible == effectiveVisible) {
+            return;
+        } else {
+            isNSCursorVisible = effectiveVisible;
+            _setVisible(effectiveVisible);
+        }
     }
 
     static Size getBestSize_impl(int width, int height) {
--- a/modules/graphics/src/main/native-glass/mac/GlassCursor.m	Thu Jul 03 11:09:34 2014 -0700
+++ b/modules/graphics/src/main/native-glass/mac/GlassCursor.m	Fri Jul 04 00:23:46 2014 +0400
@@ -245,7 +245,7 @@
 JNIEXPORT jobject JNICALL Java_com_sun_glass_ui_mac_MacCursor__1getBestSize
 (JNIEnv *env, jclass jCursorClass, jint width, jint height)
 {
-    LOG("Java_com_sun_glass_ui_mac_MacCursor__1setVisible");
+    LOG("Java_com_sun_glass_ui_mac_MacCursor__1getBestSize");
     
     jobject jsize = NULL;