From 723b6a08c379d45793fbe10180b2ccf522429be1 Mon Sep 17 00:00:00 2001 From: dmarkov Date: Thu, 19 Jan 2017 22:42:34 -0800 Subject: [PATCH] 8035568: [macosx] Cursor management unification Reviewed-by: anthony, serb --- .../classes/sun/lwawt/LWMouseInfoPeer.java | 8 +++- src/macosx/classes/sun/lwawt/LWToolkit.java | 2 + .../classes/sun/lwawt/LWWindowPeer.java | 8 ++-- .../classes/sun/lwawt/PlatformWindow.java | 2 - .../lwawt/macosx/CPlatformEmbeddedFrame.java | 5 --- .../sun/lwawt/macosx/CPlatformLWWindow.java | 5 --- .../sun/lwawt/macosx/CPlatformWindow.java | 6 +-- .../classes/sun/lwawt/macosx/CRobot.java | 33 +++++++++++++++- .../macosx/CViewPlatformEmbeddedFrame.java | 5 --- .../classes/sun/lwawt/macosx/LWCToolkit.java | 5 +++ src/macosx/native/sun/awt/AWTWindow.m | 13 ++++--- src/macosx/native/sun/awt/CCursorManager.m | 12 +++--- src/macosx/native/sun/awt/CRobot.m | 39 +------------------ 13 files changed, 61 insertions(+), 82 deletions(-) diff --git a/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java b/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java index 1920a73d3..20462a785 100644 --- a/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java +++ b/src/macosx/classes/sun/lwawt/LWMouseInfoPeer.java @@ -51,8 +51,12 @@ public class LWMouseInfoPeer implements MouseInfoPeer { return false; } - final Object windowPeer = AWTAccessor.getComponentAccessor().getPeer(w); - return LWWindowPeer.getWindowUnderCursor() == windowPeer; + LWWindowPeer windowPeer = (LWWindowPeer)AWTAccessor.getComponentAccessor().getPeer(w); + if (windowPeer == null) { + return false; + } + + return LWToolkit.getLWToolkit().getPlatformWindowUnderMouse() == windowPeer.getPlatformWindow(); } } diff --git a/src/macosx/classes/sun/lwawt/LWToolkit.java b/src/macosx/classes/sun/lwawt/LWToolkit.java index ff92b16f5..8a7f91d75 100644 --- a/src/macosx/classes/sun/lwawt/LWToolkit.java +++ b/src/macosx/classes/sun/lwawt/LWToolkit.java @@ -385,6 +385,8 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { return new LWMouseInfoPeer(); } + protected abstract PlatformWindow getPlatformWindowUnderMouse(); + @Override public final PrintJob getPrintJob(Frame frame, String doctitle, Properties props) { diff --git a/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/src/macosx/classes/sun/lwawt/LWWindowPeer.java index b1bf878f3..33511fb61 100644 --- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -749,11 +749,10 @@ public class LWWindowPeer lastMouseEventPeer = targetPeer; } } else { - PlatformWindow topmostPlatforWindow = - platformWindow.getTopmostPlatformWindowUnderMouse(); + PlatformWindow topmostPlatformWindow = LWToolkit.getLWToolkit().getPlatformWindowUnderMouse(); LWWindowPeer topmostWindowPeer = - topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : null; + topmostPlatformWindow != null ? topmostPlatformWindow.getPeer() : null; // topmostWindowPeer == null condition is added for the backward // compatibility with applets. It can be removed when the @@ -764,8 +763,7 @@ public class LWWindowPeer screenX, screenY, modifiers, clickCount, popupTrigger, targetPeer); } else { - LWComponentPeer topmostTargetPeer = - topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null; + LWComponentPeer topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y); topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, screenX, screenY, modifiers, clickCount, popupTrigger, topmostTargetPeer); diff --git a/src/macosx/classes/sun/lwawt/PlatformWindow.java b/src/macosx/classes/sun/lwawt/PlatformWindow.java index 3142aa0c4..ba7512b5a 100644 --- a/src/macosx/classes/sun/lwawt/PlatformWindow.java +++ b/src/macosx/classes/sun/lwawt/PlatformWindow.java @@ -107,8 +107,6 @@ public interface PlatformWindow { public void setAlwaysOnTop(boolean value); - public PlatformWindow getTopmostPlatformWindowUnderMouse(); - public void updateFocusableWindowState(); public boolean rejectFocusRequest(CausedFocusEvent.Cause cause); diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java index 0e8b0b0d2..ee5d7884b 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java @@ -129,11 +129,6 @@ public class CPlatformEmbeddedFrame implements PlatformWindow { @Override public void setAlwaysOnTop(boolean value) {} - // This method should be properly implemented for applets. - // It returns null just as a stub. - @Override - public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; } - @Override public void updateFocusableWindowState() {} diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java index 21a24ef7a..e949e5bc6 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java @@ -156,11 +156,6 @@ public class CPlatformLWWindow extends CPlatformWindow { public void setAlwaysOnTop(boolean isAlwaysOnTop) { } - @Override - public PlatformWindow getTopmostPlatformWindowUnderMouse(){ - return null; - } - @Override public void setOpacity(float opacity) { } diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index abcf70c6e..0ce34f88f 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -65,9 +65,9 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled); private static native void nativeSynthesizeMouseEnteredExitedEvents(); private static native void nativeDispose(long nsWindowPtr); - private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse(); private static native void nativeEnterFullScreenMode(long nsWindowPtr); private static native void nativeExitFullScreenMode(long nsWindowPtr); + static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse(); // Loger to report issues happened during execution but that do not affect functionality private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow"); @@ -769,10 +769,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop); } - public PlatformWindow getTopmostPlatformWindowUnderMouse(){ - return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse(); - } - @Override public void setOpacity(float opacity) { execute(ptr -> CWrapper.NSWindow.setAlphaValue(ptr, opacity)); diff --git a/src/macosx/classes/sun/lwawt/macosx/CRobot.java b/src/macosx/classes/sun/lwawt/macosx/CRobot.java index 0ff5f6795..1c6875c64 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CRobot.java +++ b/src/macosx/classes/sun/lwawt/macosx/CRobot.java @@ -78,7 +78,7 @@ class CRobot implements RobotPeer { @Override public void mousePress(int buttons) { mouseButtonsState |= buttons; - + checkMousePos(); mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY, buttons, true, false); } @@ -92,11 +92,40 @@ class CRobot implements RobotPeer { @Override public void mouseRelease(int buttons) { mouseButtonsState &= ~buttons; - + checkMousePos(); mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY, buttons, false, false); } + /** + * Set unknown mouse location, if needed. + */ + private void checkMousePos() { + if (mouseLastX == MOUSE_LOCATION_UNKNOWN || + mouseLastY == MOUSE_LOCATION_UNKNOWN) { + + Rectangle deviceBounds = fDevice.getDefaultConfiguration().getBounds(); + Point mousePos = CCursorManager.getInstance().getCursorPosition(); + + if (mousePos.x < deviceBounds.x) { + mousePos.x = deviceBounds.x; + } + else if (mousePos.x > deviceBounds.x + deviceBounds.width) { + mousePos.x = deviceBounds.x + deviceBounds.width; + } + + if (mousePos.y < deviceBounds.y) { + mousePos.y = deviceBounds.y; + } + else if (mousePos.y > deviceBounds.y + deviceBounds.height) { + mousePos.y = deviceBounds.y + deviceBounds.height; + } + + mouseLastX = mousePos.x; + mouseLastY = mousePos.y; + } + } + @Override public native void mouseWheel(int wheelAmt); diff --git a/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java b/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java index b1a807a64..82795d2b6 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java +++ b/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java @@ -143,11 +143,6 @@ public class CViewPlatformEmbeddedFrame implements PlatformWindow { public void setAlwaysOnTop(boolean value) { } - @Override - public PlatformWindow getTopmostPlatformWindowUnderMouse() { - return null; - } - @Override public void updateFocusableWindowState() { } diff --git a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 2bf594ece..9b17d8bca 100644 --- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -917,4 +917,9 @@ public final class LWCToolkit extends LWToolkit { !path.endsWith("/") && !path.endsWith("."); } + + @Override + protected PlatformWindow getPlatformWindowUnderMouse() { + return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse(); + } } diff --git a/src/macosx/native/sun/awt/AWTWindow.m b/src/macosx/native/sun/awt/AWTWindow.m index b84f0ecb4..328d05186 100644 --- a/src/macosx/native/sun/awt/AWTWindow.m +++ b/src/macosx/native/sun/awt/AWTWindow.m @@ -1255,15 +1255,16 @@ JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse (JNIEnv *env, jclass clazz) { - jobject topmostWindowUnderMouse = nil; + __block jobject topmostWindowUnderMouse = nil; JNF_COCOA_ENTER(env); - AWT_ASSERT_APPKIT_THREAD; - AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse]; - if (awtWindow != nil) { - topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject]; - } + [ThreadUtilities performOnMainThreadWaiting:YES block:^{ + AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse]; + if (awtWindow != nil) { + topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject]; + } + }]; JNF_COCOA_EXIT(env); diff --git a/src/macosx/native/sun/awt/CCursorManager.m b/src/macosx/native/sun/awt/CCursorManager.m index e3b9e8039..9581b932a 100644 --- a/src/macosx/native/sun/awt/CCursorManager.m +++ b/src/macosx/native/sun/awt/CCursorManager.m @@ -118,13 +118,11 @@ Java_sun_lwawt_macosx_CCursorManager_nativeGetCursorPosition JNF_COCOA_ENTER(env); - __block NSPoint pt = NSZeroPoint; - - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]); - }]; - - jpt = NSToJavaPoint(env, pt); + CGEventRef event = CGEventCreate(NULL); + CGPoint globalPos = CGEventGetLocation(event); + CFRelease(event); + + jpt = NSToJavaPoint(env, globalPos); JNF_COCOA_EXIT(env); diff --git a/src/macosx/native/sun/awt/CRobot.m b/src/macosx/native/sun/awt/CRobot.m index 8d4f2a052..817a3837c 100644 --- a/src/macosx/native/sun/awt/CRobot.m +++ b/src/macosx/native/sun/awt/CRobot.m @@ -146,47 +146,10 @@ Java_sun_lwawt_macosx_CRobot_mouseEvent // This is the native method called when Robot mouse events occur. // The CRobot tracks the mouse position, and which button was - // pressed. If the mouse position is unknown it is obtained from - // CGEvents. The peer also tracks the mouse button desired state, + // pressed. The peer also tracks the mouse button desired state, // the appropriate key modifier state, and whether the mouse action // is simply a mouse move with no mouse button state changes. - CGError err = kCGErrorSuccess; - - CGRect globalDeviceBounds = CGDisplayBounds(displayID); - - // Set unknown mouse location, if needed. - if ((mouseLastX == sun_lwawt_macosx_CRobot_MOUSE_LOCATION_UNKNOWN) || - (mouseLastY == sun_lwawt_macosx_CRobot_MOUSE_LOCATION_UNKNOWN)) - { - CGEventRef event = CGEventCreate(NULL); - if (event == NULL) { - return; - } - - CGPoint globalPos = CGEventGetLocation(event); - CFRelease(event); - - // Normalize the coords within this display device, as - // per Robot rules. - if (globalPos.x < CGRectGetMinX(globalDeviceBounds)) { - globalPos.x = CGRectGetMinX(globalDeviceBounds); - } - else if (globalPos.x > CGRectGetMaxX(globalDeviceBounds)) { - globalPos.x = CGRectGetMaxX(globalDeviceBounds); - } - - if (globalPos.y < CGRectGetMinY(globalDeviceBounds)) { - globalPos.y = CGRectGetMinY(globalDeviceBounds); - } - else if (globalPos.y > CGRectGetMaxY(globalDeviceBounds)) { - globalPos.y = CGRectGetMaxY(globalDeviceBounds); - } - - mouseLastX = (jint)globalPos.x; - mouseLastY = (jint)globalPos.y; - } - // volatile, otherwise it warns that it might be clobbered by 'longjmp' volatile CGPoint point; -- GitLab