jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
changeset 13647 de61414bbcf2
parent 13550 648dd6fa0dee
child 13648 90effcfc064f
equal deleted inserted replaced
13552:5270c932737d 13647:de61414bbcf2
    86 //    private VolatileImage backBuffer;
    86 //    private VolatileImage backBuffer;
    87     private volatile BufferedImage backBuffer;
    87     private volatile BufferedImage backBuffer;
    88 
    88 
    89     private volatile int windowState = Frame.NORMAL;
    89     private volatile int windowState = Frame.NORMAL;
    90 
    90 
       
    91     // check that the mouse is over the window
       
    92     private volatile boolean isMouseOver = false;
       
    93 
       
    94     // A peer where the last mouse event came to. Used by cursor manager to
       
    95     // find the component under cursor
       
    96     private static volatile LWComponentPeer lastCommonMouseEventPeer = null;
       
    97 
    91     // A peer where the last mouse event came to. Used to generate
    98     // A peer where the last mouse event came to. Used to generate
    92     // MOUSE_ENTERED/EXITED notifications and by cursor manager to
    99     // MOUSE_ENTERED/EXITED notifications
    93     // find the component under cursor
   100     private volatile LWComponentPeer lastMouseEventPeer;
    94     private static volatile LWComponentPeer lastMouseEventPeer = null;
       
    95 
   101 
    96     // Peers where all dragged/released events should come to,
   102     // Peers where all dragged/released events should come to,
    97     // depending on what mouse button is being dragged according to Cocoa
   103     // depending on what mouse button is being dragged according to Cocoa
    98     private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
   104     private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
    99 
   105 
   705     {
   711     {
   706         // TODO: fill "bdata" member of AWTEvent
   712         // TODO: fill "bdata" member of AWTEvent
   707         Rectangle r = getBounds();
   713         Rectangle r = getBounds();
   708         // findPeerAt() expects parent coordinates
   714         // findPeerAt() expects parent coordinates
   709         LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
   715         LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
   710         LWWindowPeer lastWindowPeer =
       
   711             (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
       
   712         LWWindowPeer curWindowPeer =
       
   713             (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;
       
   714 
   716 
   715         if (id == MouseEvent.MOUSE_EXITED) {
   717         if (id == MouseEvent.MOUSE_EXITED) {
   716             // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
   718             isMouseOver = false;
   717             // to a peer from another window. So we must first check if this peer is
   719             if (lastMouseEventPeer != null) {
   718             // the same as lastWindowPeer
   720                 if (lastMouseEventPeer.isEnabled()) {
   719             if (lastWindowPeer == this) {
       
   720                 if (isEnabled()) {
       
   721                     Point lp = lastMouseEventPeer.windowToLocal(x, y,
   721                     Point lp = lastMouseEventPeer.windowToLocal(x, y,
   722                                                                 lastWindowPeer);
   722                             this);
   723                     postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
   723                     postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
   724                                              MouseEvent.MOUSE_EXITED, when,
   724                             MouseEvent.MOUSE_EXITED, when,
   725                                              modifiers, lp.x, lp.y, screenX,
   725                             modifiers, lp.x, lp.y, screenX,
   726                                              screenY, clickCount, popupTrigger,
   726                             screenY, clickCount, popupTrigger,
   727                                              button));
   727                             button));
       
   728                 }
       
   729 
       
   730                 // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
       
   731                 // to a peer from another window. So we must first check if this peer is
       
   732                 // the same as lastWindowPeer
       
   733                 if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
       
   734                     lastCommonMouseEventPeer = null;
   728                 }
   735                 }
   729                 lastMouseEventPeer = null;
   736                 lastMouseEventPeer = null;
   730             }
   737             }
       
   738         } else if(id == MouseEvent.MOUSE_ENTERED) {
       
   739             isMouseOver = true;
       
   740             if (targetPeer != null) {
       
   741                 if (targetPeer.isEnabled()) {
       
   742                     Point lp = targetPeer.windowToLocal(x, y, this);
       
   743                         postEvent(new MouseEvent(targetPeer.getTarget(),
       
   744                             MouseEvent.MOUSE_ENTERED, when,
       
   745                             modifiers, lp.x, lp.y, screenX,
       
   746                             screenY, clickCount, popupTrigger,
       
   747                             button));
       
   748                 }
       
   749                 lastCommonMouseEventPeer = targetPeer;
       
   750                 lastMouseEventPeer = targetPeer;
       
   751             }
   731         } else {
   752         } else {
   732             if (targetPeer != lastMouseEventPeer) {
   753             PlatformWindow topmostPlatforWindow =
   733 
   754                     platformWindow.getTopmostPlatformWindowUnderMouse();
   734                 if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) {
   755 
   735                     // lastMouseEventPeer may be null if mouse was out of Java windows
   756             LWWindowPeer topmostWindowPeer =
   736                     if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
   757                     topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : null;
   737                         // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
   758 
   738                         // later), in which case lastWindowPeer is another window
   759             // topmostWindowPeer == null condition is added for the backward
   739                         if (lastWindowPeer != this) {
   760             // compatibility with applets. It can be removed when the
   740                             Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
   761             // getTopmostPlatformWindowUnderMouse() method will be properly
   741                             // Additionally translate from this to lastWindowPeer coordinates
   762             // implemented in CPlatformEmbeddedFrame class
   742                             Rectangle lr = lastWindowPeer.getBounds();
   763             if (topmostWindowPeer == this || topmostWindowPeer == null) {
   743                             oldp.x += r.x - lr.x;
   764                 generateMouseEnterExitEventsForComponents(when, button, x, y,
   744                             oldp.y += r.y - lr.y;
   765                         screenX, screenY, modifiers, clickCount, popupTrigger,
   745                             postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
   766                         targetPeer);
   746                                                      MouseEvent.MOUSE_EXITED,
   767             } else {
   747                                                      when, modifiers,
   768                 LWComponentPeer topmostTargetPeer =
   748                                                      oldp.x, oldp.y, screenX, screenY,
   769                         topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
   749                                                      clickCount, popupTrigger, button));
   770                 topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
   750                         } else {
   771                         screenX, screenY, modifiers, clickCount, popupTrigger,
   751                             Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
   772                         topmostTargetPeer);
   752                             postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
   773             }
   753                                                      MouseEvent.MOUSE_EXITED,
   774 
   754                                                      when, modifiers,
       
   755                                                      oldp.x, oldp.y, screenX, screenY,
       
   756                                                      clickCount, popupTrigger, button));
       
   757                         }
       
   758                     }
       
   759                     if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
       
   760                         Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
       
   761                         postEvent(new MouseEvent(targetPeer.getTarget(),
       
   762                                                  MouseEvent.MOUSE_ENTERED,
       
   763                                                  when, modifiers,
       
   764                                                  newp.x, newp.y, screenX, screenY,
       
   765                                                  clickCount, popupTrigger, button));
       
   766                     }
       
   767                 }
       
   768                 lastMouseEventPeer = targetPeer;
       
   769             }
       
   770             // TODO: fill "bdata" member of AWTEvent
   775             // TODO: fill "bdata" member of AWTEvent
   771 
   776 
   772             int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
   777             int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
   773             int otherButtonsPressed = modifiers & ~eventButtonMask;
   778             int otherButtonsPressed = modifiers & ~eventButtonMask;
   774 
   779 
   814                 }
   819                 }
   815 
   820 
   816                 // mouseClickButtons is updated below, after MOUSE_CLICK is sent
   821                 // mouseClickButtons is updated below, after MOUSE_CLICK is sent
   817             }
   822             }
   818 
   823 
   819             // check if we receive mouseEvent from outside the window's bounds
       
   820             // it can be either mouseDragged or mouseReleased
       
   821             if (curWindowPeer == null) {
       
   822                 //TODO This can happen if this window is invisible. this is correct behavior in this case?
       
   823                 curWindowPeer = this;
       
   824             }
       
   825             if (targetPeer == null) {
   824             if (targetPeer == null) {
   826                 //TODO This can happen if this window is invisible. this is correct behavior in this case?
   825                 //TODO This can happen if this window is invisible. this is correct behavior in this case?
   827                 targetPeer = this;
   826                 targetPeer = this;
   828             }
   827             }
   829 
   828 
   830 
   829 
   831             Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
   830             Point lp = targetPeer.windowToLocal(x, y, this);
   832             if (targetPeer.isEnabled()) {
   831             if (targetPeer.isEnabled()) {
   833                 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
   832                 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
   834                                                   when, modifiers, lp.x, lp.y,
   833                                                   when, modifiers, lp.x, lp.y,
   835                                                   screenX, screenY, clickCount,
   834                                                   screenX, screenY, clickCount,
   836                                                   popupTrigger, button);
   835                                                   popupTrigger, button);
   848                 }
   847                 }
   849                 mouseClickButtons &= ~eventButtonMask;
   848                 mouseClickButtons &= ~eventButtonMask;
   850             }
   849             }
   851         }
   850         }
   852         notifyUpdateCursor();
   851         notifyUpdateCursor();
       
   852     }
       
   853 
       
   854     private void generateMouseEnterExitEventsForComponents(long when,
       
   855             int button, int x, int y, int screenX, int screenY,
       
   856             int modifiers, int clickCount, boolean popupTrigger,
       
   857             LWComponentPeer targetPeer) {
       
   858 
       
   859         if (!isMouseOver || targetPeer == lastMouseEventPeer) {
       
   860             return;
       
   861         }
       
   862 
       
   863         // Generate Mouse Exit for components
       
   864         if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
       
   865             Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
       
   866             postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
       
   867                     MouseEvent.MOUSE_EXITED,
       
   868                     when, modifiers,
       
   869                     oldp.x, oldp.y, screenX, screenY,
       
   870                     clickCount, popupTrigger, button));
       
   871         }
       
   872         lastCommonMouseEventPeer = targetPeer;
       
   873         lastMouseEventPeer = targetPeer;
       
   874 
       
   875         // Generate Mouse Enter for components
       
   876         if (targetPeer != null && targetPeer.isEnabled()) {
       
   877             Point newp = targetPeer.windowToLocal(x, y, this);
       
   878             postEvent(new MouseEvent(targetPeer.getTarget(),
       
   879                     MouseEvent.MOUSE_ENTERED,
       
   880                     when, modifiers,
       
   881                     newp.x, newp.y, screenX, screenY,
       
   882                     clickCount, popupTrigger, button));
       
   883         }
   853     }
   884     }
   854 
   885 
   855     public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
   886     public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
   856                                         int scrollType, int scrollAmount,
   887                                         int scrollType, int scrollAmount,
   857                                         int wheelRotation, double preciseWheelRotation,
   888                                         int wheelRotation, double preciseWheelRotation,
  1094 
  1125 
  1095         return changed;
  1126         return changed;
  1096     }
  1127     }
  1097 
  1128 
  1098     public static LWWindowPeer getWindowUnderCursor() {
  1129     public static LWWindowPeer getWindowUnderCursor() {
  1099         return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
  1130         return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null;
  1100     }
  1131     }
  1101 
  1132 
  1102     public static LWComponentPeer<?, ?> getPeerUnderCursor() {
  1133     public static LWComponentPeer<?, ?> getPeerUnderCursor() {
  1103         return lastMouseEventPeer;
  1134         return lastCommonMouseEventPeer;
  1104     }
  1135     }
  1105 
  1136 
  1106     /*
  1137     /*
  1107      * Requests platform to set native focus on a frame/dialog.
  1138      * Requests platform to set native focus on a frame/dialog.
  1108      * In case of a simple window, triggers appropriate java focus change.
  1139      * In case of a simple window, triggers appropriate java focus change.