src/macosx/classes/sun/lwawt/LWWindowPeer.java
Print this page
*** 86,99 ****
// private VolatileImage backBuffer;
private volatile BufferedImage backBuffer;
private volatile int windowState = Frame.NORMAL;
! // A peer where the last mouse event came to. Used to generate
! // MOUSE_ENTERED/EXITED notifications and by cursor manager to
// find the component under cursor
! private static volatile LWComponentPeer lastMouseEventPeer = null;
// Peers where all dragged/released events should come to,
// depending on what mouse button is being dragged according to Cocoa
private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
--- 86,105 ----
// private VolatileImage backBuffer;
private volatile BufferedImage backBuffer;
private volatile int windowState = Frame.NORMAL;
! // check that the mouse is over the window
! private volatile boolean isMouseOver = false;
!
! // A peer where the last mouse event came to. Used by cursor manager to
// find the component under cursor
! private static volatile LWComponentPeer lastCommonMouseEventPeer = null;
!
! // A peer where the last mouse event came to. Used to generate
! // MOUSE_ENTERED/EXITED notifications
! private volatile LWComponentPeer lastMouseEventPeer;
// Peers where all dragged/released events should come to,
// depending on what mouse button is being dragged according to Cocoa
private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
*** 674,743 ****
{
// TODO: fill "bdata" member of AWTEvent
Rectangle r = getBounds();
// findPeerAt() expects parent coordinates
LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
- LWWindowPeer lastWindowPeer =
- (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
- LWWindowPeer curWindowPeer =
- (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;
if (id == MouseEvent.MOUSE_EXITED) {
! // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
! // to a peer from another window. So we must first check if this peer is
! // the same as lastWindowPeer
! if (lastWindowPeer == this) {
! if (isEnabled()) {
Point lp = lastMouseEventPeer.windowToLocal(x, y,
! lastWindowPeer);
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
MouseEvent.MOUSE_EXITED, when,
modifiers, lp.x, lp.y, screenX,
screenY, clickCount, popupTrigger,
button));
}
- lastMouseEventPeer = null;
- }
- } else {
- if (targetPeer != lastMouseEventPeer) {
! if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) {
! // lastMouseEventPeer may be null if mouse was out of Java windows
! if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
! // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
! // later), in which case lastWindowPeer is another window
! if (lastWindowPeer != this) {
! Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
! // Additionally translate from this to lastWindowPeer coordinates
! Rectangle lr = lastWindowPeer.getBounds();
! oldp.x += r.x - lr.x;
! oldp.y += r.y - lr.y;
! postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
! MouseEvent.MOUSE_EXITED,
! when, modifiers,
! oldp.x, oldp.y, screenX, screenY,
! clickCount, popupTrigger, button));
! } else {
! Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
! postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
! MouseEvent.MOUSE_EXITED,
! when, modifiers,
! oldp.x, oldp.y, screenX, screenY,
! clickCount, popupTrigger, button));
}
}
! if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
! Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
postEvent(new MouseEvent(targetPeer.getTarget(),
! MouseEvent.MOUSE_ENTERED,
! when, modifiers,
! newp.x, newp.y, screenX, screenY,
! clickCount, popupTrigger, button));
! }
}
lastMouseEventPeer = targetPeer;
}
// TODO: fill "bdata" member of AWTEvent
int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
int otherButtonsPressed = modifiers & ~eventButtonMask;
--- 680,749 ----
{
// TODO: fill "bdata" member of AWTEvent
Rectangle r = getBounds();
// findPeerAt() expects parent coordinates
LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
if (id == MouseEvent.MOUSE_EXITED) {
! isMouseOver = false;
! if (lastMouseEventPeer != null) {
! if (lastMouseEventPeer.isEnabled()) {
Point lp = lastMouseEventPeer.windowToLocal(x, y,
! this);
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
MouseEvent.MOUSE_EXITED, when,
modifiers, lp.x, lp.y, screenX,
screenY, clickCount, popupTrigger,
button));
}
! // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
! // to a peer from another window. So we must first check if this peer is
! // the same as lastWindowPeer
! if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
! lastCommonMouseEventPeer = null;
}
+ lastMouseEventPeer = null;
}
! } else if(id == MouseEvent.MOUSE_ENTERED) {
! isMouseOver = true;
! if (targetPeer != null) {
! if (targetPeer.isEnabled()) {
! Point lp = targetPeer.windowToLocal(x, y, this);
postEvent(new MouseEvent(targetPeer.getTarget(),
! MouseEvent.MOUSE_ENTERED, when,
! modifiers, lp.x, lp.y, screenX,
! screenY, clickCount, popupTrigger,
! button));
}
+ lastCommonMouseEventPeer = targetPeer;
lastMouseEventPeer = targetPeer;
}
+ } else {
+ PlatformWindow topmostPlatforWindow =
+ platformWindow.getTopmostPlatformWindowUnderMouse();
+
+ // The getTopmostPlatformWindowUnderMouse method can return null
+ // either because there is no any window under mouse or
+ // because this method is not implemented (see CPlatformEmbeddedFrame).
+ // In both case this window is the target window for the component
+ // mouse enter/exit events generation
+ LWWindowPeer topmostWindowPeer =
+ topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : this;
+
+ if (topmostWindowPeer == this) {
+ generateMouseEnterExitEventsForComponents(when, button, x, y,
+ screenX, screenY, modifiers, clickCount, popupTrigger,
+ targetPeer);
+ } else {
+ LWComponentPeer topmostTargetPeer =
+ topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
+ topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
+ screenX, screenY, modifiers, clickCount, popupTrigger,
+ topmostTargetPeer);
+ }
+
// TODO: fill "bdata" member of AWTEvent
int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
int otherButtonsPressed = modifiers & ~eventButtonMask;
*** 783,805 ****
}
// mouseClickButtons is updated below, after MOUSE_CLICK is sent
}
- // check if we receive mouseEvent from outside the window's bounds
- // it can be either mouseDragged or mouseReleased
- if (curWindowPeer == null) {
- //TODO This can happen if this window is invisible. this is correct behavior in this case?
- curWindowPeer = this;
- }
if (targetPeer == null) {
//TODO This can happen if this window is invisible. this is correct behavior in this case?
targetPeer = this;
}
! Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
if (targetPeer.isEnabled()) {
MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
when, modifiers, lp.x, lp.y,
screenX, screenY, clickCount,
popupTrigger, button);
--- 789,805 ----
}
// mouseClickButtons is updated below, after MOUSE_CLICK is sent
}
if (targetPeer == null) {
//TODO This can happen if this window is invisible. this is correct behavior in this case?
targetPeer = this;
}
! Point lp = targetPeer.windowToLocal(x, y, this);
if (targetPeer.isEnabled()) {
MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
when, modifiers, lp.x, lp.y,
screenX, screenY, clickCount,
popupTrigger, button);
*** 819,828 ****
--- 819,860 ----
}
}
notifyUpdateCursor();
}
+ private void generateMouseEnterExitEventsForComponents(long when,
+ int button, int x, int y, int screenX, int screenY,
+ int modifiers, int clickCount, boolean popupTrigger,
+ LWComponentPeer targetPeer) {
+
+ if (!isMouseOver || targetPeer == lastMouseEventPeer) {
+ return;
+ }
+
+ // Generate Mouse Exit for components
+ if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
+ Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
+ postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
+ MouseEvent.MOUSE_EXITED,
+ when, modifiers,
+ oldp.x, oldp.y, screenX, screenY,
+ clickCount, popupTrigger, button));
+ }
+ lastCommonMouseEventPeer = targetPeer;
+ lastMouseEventPeer = targetPeer;
+
+ // Generate Mouse Enter for components
+ if (targetPeer != null && targetPeer.isEnabled()) {
+ Point newp = targetPeer.windowToLocal(x, y, this);
+ postEvent(new MouseEvent(targetPeer.getTarget(),
+ MouseEvent.MOUSE_ENTERED,
+ when, modifiers,
+ newp.x, newp.y, screenX, screenY,
+ clickCount, popupTrigger, button));
+ }
+ }
+
public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
int scrollType, int scrollAmount,
int wheelRotation, double preciseWheelRotation,
byte[] bdata)
{
*** 1063,1077 ****
return changed;
}
public static LWWindowPeer getWindowUnderCursor() {
! return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
}
public static LWComponentPeer<?, ?> getPeerUnderCursor() {
! return lastMouseEventPeer;
}
/*
* Requests platform to set native focus on a frame/dialog.
* In case of a simple window, triggers appropriate java focus change.
--- 1095,1109 ----
return changed;
}
public static LWWindowPeer getWindowUnderCursor() {
! return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null;
}
public static LWComponentPeer<?, ?> getPeerUnderCursor() {
! return lastCommonMouseEventPeer;
}
/*
* Requests platform to set native focus on a frame/dialog.
* In case of a simple window, triggers appropriate java focus change.