// MouseDown in non-client area @Override public void notifyNCMouseDown() { // Ungrab except for a click on a Dialog with the grabbing owner if (grabbingWindow != null && !grabbingWindow.isOneOfOwnersOf(this)) { grabbingWindow.ungrab(); } }
/* * Called by the delegate to dispatch the event to Java. Event * coordinates are relative to non-client window are, i.e. the top-left * point of the client area is (insets.top, insets.left). */ @Override public void notifyMouseEvent( PlatformWindow eventPlatformWindow, int id, long when, int button, int x, int y, int screenX, int screenY, int modifiers, int clickCount, boolean popupTrigger, byte[] bdata) { // 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); Component target = lastMouseEventPeer.getTarget(); postMouseExitedEvent( target, when, modifiers, lp, 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); Component target = targetPeer.getTarget(); postMouseEnteredEvent( target, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button); } lastCommonMouseEventPeer = targetPeer; lastMouseEventPeer = targetPeer; } } else { LWWindowPeer topmostWindowPeer = eventPlatformWindow != null ? eventPlatformWindow.getPeer() : null; // topmostWindowPeer == null condition is added for the backward // compatibility with applets. It can be removed when the // getTopmostPlatformWindowUnderMouse() method will be properly // implemented in CPlatformEmbeddedFrame class if (topmostWindowPeer == this || topmostWindowPeer == null) { generateMouseEnterExitEventsForComponents( when, button, x, y, screenX, screenY, modifiers, clickCount, popupTrigger, targetPeer); } else { LWComponentPeer<?, ?> topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y); 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; // For pressed/dragged/released events OS X treats other // mouse buttons as if they were BUTTON2, so we do the same int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1; // MOUSE_ENTERED/EXITED are generated for the components strictly under // mouse even when dragging. That's why we first update lastMouseEventPeer // based on initial targetPeer value and only then recalculate targetPeer // for MOUSE_DRAGGED/RELEASED events if (id == MouseEvent.MOUSE_PRESSED) { // Ungrab only if this window is not an owned window of the grabbing one. if (!isGrabbing() && grabbingWindow != null && !grabbingWindow.isOneOfOwnersOf(this)) { grabbingWindow.ungrab(); } if (otherButtonsPressed == 0) { mouseClickButtons = eventButtonMask; } else { mouseClickButtons |= eventButtonMask; } // The window should be focused on mouse click. If it gets activated by the native platform, // this request will be no op. It will take effect when: // 1. A simple not focused window is clicked. // 2. An active but not focused owner frame/dialog is clicked. // The mouse event then will trigger a focus request "in window" to the component, so the // window // should gain focus before. requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT); mouseDownTarget[targetIdx] = targetPeer; } else if (id == MouseEvent.MOUSE_DRAGGED) { // Cocoa dragged event has the information about which mouse // button is being dragged. Use it to determine the peer that // should receive the dragged event. targetPeer = mouseDownTarget[targetIdx]; mouseClickButtons &= ~modifiers; } else if (id == MouseEvent.MOUSE_RELEASED) { // TODO: currently, mouse released event goes to the same component // that received corresponding mouse pressed event. For most cases, // it's OK, however, we need to make sure that our behavior is consistent // with 1.6 for cases where component in question have been // hidden/removed in between of mouse pressed/released events. targetPeer = mouseDownTarget[targetIdx]; if ((modifiers & eventButtonMask) == 0) { mouseDownTarget[targetIdx] = null; } // 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); postEvent(event); } if (id == MouseEvent.MOUSE_RELEASED) { if ((mouseClickButtons & eventButtonMask) != 0 && targetPeer.isEnabled()) { postEvent( new MouseEvent( targetPeer.getTarget(), MouseEvent.MOUSE_CLICKED, when, modifiers, lp.x, lp.y, screenX, screenY, clickCount, popupTrigger, button)); } mouseClickButtons &= ~eventButtonMask; } } notifyUpdateCursor(); }