src/macosx/classes/sun/lwawt/LWWindowPeer.java

Print this page


   1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 667             }
 668         }
 669     }
 670 
 671     @Override
 672     public void notifyUpdateCursor() {
 673         getLWToolkit().getCursorManager().updateCursorLater(this);
 674     }
 675 
 676     @Override
 677     public void notifyActivation(boolean activation, LWWindowPeer opposite) {
 678         Window oppositeWindow = (opposite == null)? null : opposite.getTarget();
 679         changeFocusedWindow(activation, oppositeWindow);
 680     }
 681 
 682     // MouseDown in non-client area
 683     @Override
 684     public void notifyNCMouseDown() {
 685         // Ungrab except for a click on a Dialog with the grabbing owner
 686         if (grabbingWindow != null &&
 687             grabbingWindow != getOwnerFrameDialog(this))
 688         {
 689             grabbingWindow.ungrab();
 690         }
 691     }
 692 
 693     // ---- EVENTS ---- //
 694 
 695     /*
 696      * Called by the delegate to dispatch the event to Java. Event
 697      * coordinates are relative to non-client window are, i.e. the top-left
 698      * point of the client area is (insets.top, insets.left).
 699      */
 700     @Override
 701     public void notifyMouseEvent(int id, long when, int button,
 702                                  int x, int y, int screenX, int screenY,
 703                                  int modifiers, int clickCount, boolean popupTrigger,
 704                                  byte[] bdata)
 705     {
 706         // TODO: fill "bdata" member of AWTEvent
 707         Rectangle r = getBounds();


 762                         topmostTargetPeer);
 763             }
 764 
 765             // TODO: fill "bdata" member of AWTEvent
 766 
 767             int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
 768             int otherButtonsPressed = modifiers & ~eventButtonMask;
 769 
 770             // For pressed/dragged/released events OS X treats other
 771             // mouse buttons as if they were BUTTON2, so we do the same
 772             int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;
 773 
 774             // MOUSE_ENTERED/EXITED are generated for the components strictly under
 775             // mouse even when dragging. That's why we first update lastMouseEventPeer
 776             // based on initial targetPeer value and only then recalculate targetPeer
 777             // for MOUSE_DRAGGED/RELEASED events
 778             if (id == MouseEvent.MOUSE_PRESSED) {
 779 
 780                 // Ungrab only if this window is not an owned window of the grabbing one.
 781                 if (!isGrabbing() && grabbingWindow != null &&
 782                     grabbingWindow != getOwnerFrameDialog(this))
 783                 {
 784                     grabbingWindow.ungrab();
 785                 }
 786                 if (otherButtonsPressed == 0) {
 787                     mouseClickButtons = eventButtonMask;
 788                 } else {
 789                     mouseClickButtons |= eventButtonMask;
 790                 }
 791 
 792                 // The window should be focused on mouse click. If it gets activated by the native platform,
 793                 // this request will be no op. It will take effect when:
 794                 // 1. A simple not focused window is clicked.
 795                 // 2. An active but not focused owner frame/dialog is clicked.
 796                 // The mouse event then will trigger a focus request "in window" to the component, so the window
 797                 // should gain focus before.
 798                 requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
 799 
 800                 mouseDownTarget[targetIdx] = targetPeer;
 801             } else if (id == MouseEvent.MOUSE_DRAGGED) {
 802                 // Cocoa dragged event has the information about which mouse


1215         if (isSimpleWindow()) {
1216             LWWindowPeer ownerPeer = getOwnerFrameDialog(this);
1217             if (ownerPeer == null) {
1218                 return false;
1219             }
1220             return focusable && ownerPeer.getTarget().isFocusableWindow();
1221         }
1222         return focusable;
1223     }
1224 
1225     public boolean isSimpleWindow() {
1226         Window window = getTarget();
1227         return !(window instanceof Dialog || window instanceof Frame);
1228     }
1229 
1230     @Override
1231     public void emulateActivation(boolean activate) {
1232         changeFocusedWindow(activate, null);
1233     }
1234 











1235     /*
1236      * Changes focused window on java level.
1237      */
1238     protected void changeFocusedWindow(boolean becomesFocused, Window opposite) {
1239         if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1240             focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
1241         }
1242         if (skipNextFocusChange) {
1243             focusLog.fine("skipping focus change");
1244             skipNextFocusChange = false;
1245             return;
1246         }
1247         if (!isFocusableWindow() && becomesFocused) {
1248             focusLog.fine("the window is not focusable");
1249             return;
1250         }
1251         if (becomesFocused) {
1252             synchronized (getPeerTreeLock()) {
1253                 if (blocker != null) {
1254                     if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
1255                         focusLog.finest("the window is blocked by " + blocker);
1256                     }
1257                     return;
1258                 }
1259             }
1260         }
1261 
1262         // Note, the method is not called:
1263         // - when the opposite (gaining focus) window is an owned/owner window.
1264         // - for a simple window in any case.
1265         if (!becomesFocused &&
1266             (isGrabbing() || getOwnerFrameDialog(grabbingWindow) == this))
1267         {
1268             if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1269                 focusLog.fine("ungrabbing on " + grabbingWindow);
1270             }
1271             // ungrab a simple window if its owner looses activation.
1272             grabbingWindow.ungrab();
1273         }
1274 
1275         KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
1276         kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
1277 
1278         int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
1279         WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, opposite, System.currentTimeMillis());
1280 
1281         // TODO: wrap in SequencedEvent
1282         postEvent(windowEvent);
1283     }
1284 





1285     static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) {
1286         Window owner = (peer != null ? peer.getTarget().getOwner() : null);
1287         while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
1288             owner = owner.getOwner();
1289         }
1290         return owner == null ? null :
1291                (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner);
1292     }
1293 
1294     /**
1295      * Returns the foremost modal blocker of this window, or null.
1296      */
1297     public LWWindowPeer getBlocker() {
1298         synchronized (getPeerTreeLock()) {
1299             LWWindowPeer blocker = this.blocker;
1300             if (blocker == null) {
1301                 return null;
1302             }
1303             while (blocker.blocker != null) {
1304                 blocker = blocker.blocker;


   1 /*
   2  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 667             }
 668         }
 669     }
 670 
 671     @Override
 672     public void notifyUpdateCursor() {
 673         getLWToolkit().getCursorManager().updateCursorLater(this);
 674     }
 675 
 676     @Override
 677     public void notifyActivation(boolean activation, LWWindowPeer opposite) {
 678         Window oppositeWindow = (opposite == null)? null : opposite.getTarget();
 679         changeFocusedWindow(activation, oppositeWindow);
 680     }
 681 
 682     // MouseDown in non-client area
 683     @Override
 684     public void notifyNCMouseDown() {
 685         // Ungrab except for a click on a Dialog with the grabbing owner
 686         if (grabbingWindow != null &&
 687             !grabbingWindow.isOneOfOwnersOf(this))
 688         {
 689             grabbingWindow.ungrab();
 690         }
 691     }
 692 
 693     // ---- EVENTS ---- //
 694 
 695     /*
 696      * Called by the delegate to dispatch the event to Java. Event
 697      * coordinates are relative to non-client window are, i.e. the top-left
 698      * point of the client area is (insets.top, insets.left).
 699      */
 700     @Override
 701     public void notifyMouseEvent(int id, long when, int button,
 702                                  int x, int y, int screenX, int screenY,
 703                                  int modifiers, int clickCount, boolean popupTrigger,
 704                                  byte[] bdata)
 705     {
 706         // TODO: fill "bdata" member of AWTEvent
 707         Rectangle r = getBounds();


 762                         topmostTargetPeer);
 763             }
 764 
 765             // TODO: fill "bdata" member of AWTEvent
 766 
 767             int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
 768             int otherButtonsPressed = modifiers & ~eventButtonMask;
 769 
 770             // For pressed/dragged/released events OS X treats other
 771             // mouse buttons as if they were BUTTON2, so we do the same
 772             int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;
 773 
 774             // MOUSE_ENTERED/EXITED are generated for the components strictly under
 775             // mouse even when dragging. That's why we first update lastMouseEventPeer
 776             // based on initial targetPeer value and only then recalculate targetPeer
 777             // for MOUSE_DRAGGED/RELEASED events
 778             if (id == MouseEvent.MOUSE_PRESSED) {
 779 
 780                 // Ungrab only if this window is not an owned window of the grabbing one.
 781                 if (!isGrabbing() && grabbingWindow != null &&
 782                     !grabbingWindow.isOneOfOwnersOf(this))
 783                 {
 784                     grabbingWindow.ungrab();
 785                 }
 786                 if (otherButtonsPressed == 0) {
 787                     mouseClickButtons = eventButtonMask;
 788                 } else {
 789                     mouseClickButtons |= eventButtonMask;
 790                 }
 791 
 792                 // The window should be focused on mouse click. If it gets activated by the native platform,
 793                 // this request will be no op. It will take effect when:
 794                 // 1. A simple not focused window is clicked.
 795                 // 2. An active but not focused owner frame/dialog is clicked.
 796                 // The mouse event then will trigger a focus request "in window" to the component, so the window
 797                 // should gain focus before.
 798                 requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
 799 
 800                 mouseDownTarget[targetIdx] = targetPeer;
 801             } else if (id == MouseEvent.MOUSE_DRAGGED) {
 802                 // Cocoa dragged event has the information about which mouse


1215         if (isSimpleWindow()) {
1216             LWWindowPeer ownerPeer = getOwnerFrameDialog(this);
1217             if (ownerPeer == null) {
1218                 return false;
1219             }
1220             return focusable && ownerPeer.getTarget().isFocusableWindow();
1221         }
1222         return focusable;
1223     }
1224 
1225     public boolean isSimpleWindow() {
1226         Window window = getTarget();
1227         return !(window instanceof Dialog || window instanceof Frame);
1228     }
1229 
1230     @Override
1231     public void emulateActivation(boolean activate) {
1232         changeFocusedWindow(activate, null);
1233     }
1234 
1235     private boolean isOneOfOwnersOf(LWWindowPeer peer) {
1236         Window owner = (peer != null ? peer.getTarget().getOwner() : null);
1237         while (owner != null) {
1238             if ((LWWindowPeer)owner.getPeer() == this) {
1239                 return true;
1240             }
1241             owner = owner.getOwner();
1242         }
1243         return false;
1244     }
1245 
1246     /*
1247      * Changes focused window on java level.
1248      */
1249     protected void changeFocusedWindow(boolean becomesFocused, Window opposite) {
1250         if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1251             focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
1252         }
1253         if (skipNextFocusChange) {
1254             focusLog.fine("skipping focus change");
1255             skipNextFocusChange = false;
1256             return;
1257         }
1258         if (!isFocusableWindow() && becomesFocused) {
1259             focusLog.fine("the window is not focusable");
1260             return;
1261         }
1262         if (becomesFocused) {
1263             synchronized (getPeerTreeLock()) {
1264                 if (blocker != null) {
1265                     if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
1266                         focusLog.finest("the window is blocked by " + blocker);
1267                     }
1268                     return;
1269                 }
1270             }
1271         }
1272 
1273         // Note, the method is not called:
1274         // - when the opposite (gaining focus) window is an owned/owner window.
1275         // - for a simple window in any case.
1276         if (!becomesFocused &&
1277             (isGrabbing() || this.isOneOfOwnersOf(grabbingWindow)))
1278         {
1279             if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1280                 focusLog.fine("ungrabbing on " + grabbingWindow);
1281             }
1282             // ungrab a simple window if its owner looses activation.
1283             grabbingWindow.ungrab();
1284         }
1285 
1286         KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
1287         kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
1288 
1289         int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
1290         WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, opposite, System.currentTimeMillis());
1291 
1292         // TODO: wrap in SequencedEvent
1293         postEvent(windowEvent);
1294     }
1295 
1296     /*
1297      * Retrieves the owner of the peer.
1298      * Note: this method returns the owner which can be activated, (i.e. the instance
1299      * of Frame or Dialog may be returned).
1300      */
1301     static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) {
1302         Window owner = (peer != null ? peer.getTarget().getOwner() : null);
1303         while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
1304             owner = owner.getOwner();
1305         }
1306         return owner == null ? null :
1307                (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner);
1308     }
1309 
1310     /**
1311      * Returns the foremost modal blocker of this window, or null.
1312      */
1313     public LWWindowPeer getBlocker() {
1314         synchronized (getPeerTreeLock()) {
1315             LWWindowPeer blocker = this.blocker;
1316             if (blocker == null) {
1317                 return null;
1318             }
1319             while (blocker.blocker != null) {
1320                 blocker = blocker.blocker;