--- old/src/macosx/classes/sun/lwawt/LWComponentPeer.java 2012-03-31 23:06:04.092245300 +0400 +++ new/src/macosx/classes/sun/lwawt/LWComponentPeer.java 2012-03-31 23:06:03.839230800 +0400 @@ -616,6 +616,17 @@ windowLocation.y + locationInWindow.y); } + /** + * Returns the cursor of the peer, which is cursor of the target by default, + * but peer can override this behavior. + * + * @param p Point relative to the peer. + * @return Cursor of the peer or null if default cursor should be used. + */ + protected Cursor getCursor(final Point p) { + return getTarget().getCursor(); + } + @Override public void setBackground(final Color c) { final Color oldBg = getBackground(); --- old/src/macosx/classes/sun/lwawt/LWCursorManager.java 2012-03-31 23:06:06.242368200 +0400 +++ new/src/macosx/classes/sun/lwawt/LWCursorManager.java 2012-03-31 23:06:05.972352800 +0400 @@ -36,32 +36,34 @@ public abstract class LWCursorManager { - // A flag to indicate if the update is scheduled, so we don't - // process it twice - private AtomicBoolean updatePending = new AtomicBoolean(false); + /** + * A flag to indicate if the update is scheduled, so we don't process it + * twice. + */ + private final AtomicBoolean updatePending = new AtomicBoolean(false); protected LWCursorManager() { } - /* + /** * Sets the cursor to correspond the component currently under mouse. * * This method should not be executed on the toolkit thread as it * calls to user code (e.g. Container.findComponentAt). */ - public void updateCursor() { + public final void updateCursor() { updatePending.set(false); updateCursorImpl(); } - /* + /** * Schedules updating the cursor on the corresponding event dispatch * thread for the given window. * * This method is called on the toolkit thread as a result of a * native update cursor request (e.g. WM_SETCURSOR on Windows). */ - public void updateCursorLater(LWWindowPeer window) { + public final void updateCursorLater(final LWWindowPeer window) { if (updatePending.compareAndSet(false, true)) { Runnable r = new Runnable() { @Override @@ -74,45 +76,58 @@ } private void updateCursorImpl() { - LWWindowPeer windowUnderCursor = LWWindowPeer.getWindowUnderCursor(); - Point cursorPos = getCursorPosition(); - LWComponentPeer componentUnderCursor = null; - // TODO: it's possible to get the component under cursor directly as - // it's stored in LWWindowPee anyway (lastMouseEventPeer) - if (windowUnderCursor != null) { - componentUnderCursor = windowUnderCursor.findPeerAt(cursorPos.x, cursorPos.y); + final Point cursorPos = getCursorPosition(); + final Component c = findComponent(cursorPos); + final Cursor cursor; + final Object peer = LWToolkit.targetToPeer(c); + if (peer instanceof LWComponentPeer) { + final LWComponentPeer lwpeer = (LWComponentPeer) peer; + final Point p = lwpeer.getLocationOnScreen(); + cursor = lwpeer.getCursor(new Point(cursorPos.x - p.x, + cursorPos.y - p.y)); + } else { + cursor = (c != null) ? c.getCursor() : null; } - Cursor cursor = null; - if (componentUnderCursor != null) { - Component c = componentUnderCursor.getTarget(); + // TODO: default cursor for modal blocked windows + setCursor(cursor); + } + + /** + * Returns the first visible, enabled and showing component under cursor. + * + * @param cursorPos Current cursor position. + * @return Component + */ + private static final Component findComponent(final Point cursorPos) { + final LWComponentPeer peer = LWWindowPeer.getPeerUnderCursor(); + Component c = null; + if (peer != null) { + c = peer.getTarget(); if (c instanceof Container) { - Point p = componentUnderCursor.getLocationOnScreen(); - c = ((Container)c).findComponentAt(cursorPos.x - p.x, cursorPos.y - p.y); + final Point p = peer.getLocationOnScreen(); + c = ((Container) c).findComponentAt(cursorPos.x - p.x, + cursorPos.y - p.y); } - // Traverse up to the first visible, enabled and showing component while (c != null) { if (c.isVisible() && c.isEnabled() && (c.getPeer() != null)) { break; } c = c.getParent(); } - if (c != null) { - cursor = c.getCursor(); - } } - // TODO: default cursor for modal blocked windows - setCursor(windowUnderCursor, cursor); + return c; } - /* + /** * Returns the current cursor position. */ // TODO: make it public to reuse for MouseInfo protected abstract Point getCursorPosition(); - /* - * Sets a cursor. The cursor can be null if the mouse is not over a Java window. + /** + * Sets a cursor. The cursor can be null if the mouse is not over a Java + * window. + * @param cursor the new {@code Cursor}. */ - protected abstract void setCursor(LWWindowPeer windowUnderCursor, Cursor cursor); - + protected abstract void setCursor(Cursor cursor); } --- old/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java 2012-03-31 23:06:08.295485700 +0400 +++ new/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java 2012-03-31 23:06:08.014469600 +0400 @@ -27,6 +27,7 @@ package sun.lwawt; import java.awt.Component; +import java.awt.Cursor; import java.awt.Dimension; import java.awt.Point; import java.awt.TextArea; @@ -72,6 +73,15 @@ } @Override + protected Cursor getCursor(final Point p) { + final boolean isContains; + synchronized (getDelegateLock()) { + isContains = getDelegate().getViewport().getBounds().contains(p); + } + return isContains ? super.getCursor(p) : null; + } + + @Override protected Component getDelegateFocusOwner() { return getTextComponent(); } --- old/src/macosx/classes/sun/lwawt/LWWindowPeer.java 2012-03-31 23:06:10.387605300 +0400 +++ new/src/macosx/classes/sun/lwawt/LWWindowPeer.java 2012-03-31 23:06:10.132590800 +0400 @@ -784,9 +784,8 @@ } mouseClickButtons &= ~eventButtonMask; } - - notifyUpdateCursor(); } + notifyUpdateCursor(); } public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers, @@ -1057,6 +1056,10 @@ return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null; } + public static LWComponentPeer getPeerUnderCursor() { + return lastMouseEventPeer; + } + public boolean requestWindowFocus(CausedFocusEvent.Cause cause) { if (focusLog.isLoggable(PlatformLogger.FINE)) { focusLog.fine("requesting native focus to " + this); --- old/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java 2012-03-31 23:06:12.414721300 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java 2012-03-31 23:06:12.172707400 +0400 @@ -25,24 +25,26 @@ package sun.lwawt.macosx; -import java.awt.*; +import sun.lwawt.LWCursorManager; + +import java.awt.Cursor; +import java.awt.Point; import java.awt.geom.Point2D; -import sun.lwawt.*; +final class CCursorManager extends LWCursorManager { -public class CCursorManager extends LWCursorManager { private static native Point2D nativeGetCursorPosition(); private static native void nativeSetBuiltInCursor(final int type, final String name); private static native void nativeSetCustomCursor(final long imgPtr, final double x, final double y); private static final int NAMED_CURSOR = -1; - private final static CCursorManager theInstance = new CCursorManager(); + private static final CCursorManager theInstance = new CCursorManager(); public static CCursorManager getInstance() { return theInstance; } - Cursor currentCursor; + private volatile Cursor currentCursor; private CCursorManager() { } @@ -62,8 +64,11 @@ } @Override - protected void setCursor(final LWWindowPeer windowUnderCursor, final Cursor cursor) { - if (cursor == currentCursor) return; + protected void setCursor(final Cursor cursor) { + if (cursor == currentCursor) { + return; + } + currentCursor = cursor; if (cursor == null) { nativeSetBuiltInCursor(Cursor.DEFAULT_CURSOR, null); @@ -71,10 +76,12 @@ } if (cursor instanceof CCustomCursor) { - final CCustomCursor customCursor = ((CCustomCursor)cursor); + final CCustomCursor customCursor = (CCustomCursor) cursor; final long imagePtr = customCursor.getImageData(); - final Point hotSpot = customCursor.getHotSpot(); - if(imagePtr != 0L) nativeSetCustomCursor(imagePtr, hotSpot.x, hotSpot.y); + if (imagePtr != 0L) { + final Point hotSpot = customCursor.getHotSpot(); + nativeSetCustomCursor(imagePtr, hotSpot.x, hotSpot.y); + } return; } @@ -94,13 +101,6 @@ throw new RuntimeException("Unimplemented"); } - static long getNativeWindow(final LWWindowPeer window) { - if (window == null) return 0; - final CPlatformWindow platformWindow = (CPlatformWindow)window.getPlatformWindow(); - if (platformWindow == null) return 0; - return platformWindow.getNSWindowPtr(); - } - // package private methods to handle cursor change during drag-and-drop private boolean isDragging = false; private Point dragPos = null; @@ -109,9 +109,7 @@ if (isDragging) { throw new RuntimeException("Invalid Drag state in CCursorManager!"); } - isDragging = true; - dragPos = new Point(x, y); }