< prev index next >

src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java

Print this page




  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
  23  * questions.
  24  */
  25 package sun.awt.X11;
  26 
  27 import java.awt.*;
  28 
  29 import java.awt.event.ComponentEvent;
  30 import java.awt.event.FocusEvent;
  31 import java.awt.event.WindowEvent;

  32 
  33 import java.awt.peer.ComponentPeer;
  34 import java.awt.peer.WindowPeer;
  35 
  36 import java.io.UnsupportedEncodingException;
  37 
  38 import java.security.AccessController;
  39 import java.security.PrivilegedAction;
  40 
  41 import java.util.ArrayList;
  42 import java.util.HashSet;
  43 import java.util.Iterator;
  44 import java.util.Set;
  45 import java.util.Vector;
  46 
  47 import java.util.concurrent.atomic.AtomicBoolean;
  48 
  49 import sun.awt.AWTAccessor.ComponentAccessor;
  50 import sun.util.logging.PlatformLogger;
  51 


 733         SunToolkit.executeOnEventHandlerThread(target, dc);
 734     }
 735 
 736     /**
 737      * From the DisplayChangedListener interface; called from
 738      * X11GraphicsDevice when the display mode has been changed.
 739      */
 740     public void displayChanged() {
 741         executeDisplayChangedOnEDT(getGraphicsConfiguration());
 742     }
 743 
 744     /**
 745      * From the DisplayChangedListener interface; top-levels do not need
 746      * to react to this event.
 747      */
 748     public void paletteChanged() {
 749     }
 750 
 751     private Point queryXLocation()
 752     {
 753         return XlibUtil.translateCoordinates(
 754             getContentWindow(),
 755             XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()),
 756             new Point(0, 0));
 757     }
 758 
 759     protected Point getNewLocation(XConfigureEvent xe, int leftInset, int topInset) {
 760         // Bounds of the window
 761         Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds(target);
 762 
 763         int runningWM = XWM.getWMID();
 764         Point newLocation = targetBounds.getLocation();
 765         if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
 766             // Location, Client size + insets
 767             newLocation = new Point(xe.get_x() - leftInset, xe.get_y() - topInset);

 768         } else {
 769             // ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
 770             // a window is resized but the client can not tell if the window was
 771             // moved or not. The client should consider the position as unkown
 772             // and use TranslateCoordinates to find the actual position.
 773             //
 774             // TODO this should be the default for every case.
 775             switch (runningWM) {
 776                 case XWM.CDE_WM:
 777                 case XWM.MOTIF_WM:
 778                 case XWM.METACITY_WM:
 779                 case XWM.MUTTER_WM:
 780                 case XWM.SAWFISH_WM:
 781                 {
 782                     Point xlocation = queryXLocation();
 783                     if (log.isLoggable(PlatformLogger.Level.FINE)) {
 784                         log.fine("New X location: {0}", xlocation);
 785                     }
 786                     if (xlocation != null) {
 787                         newLocation = xlocation;


 790                 }
 791                 default:
 792                     break;
 793             }
 794         }
 795         return newLocation;
 796     }
 797 
 798     /*
 799      * Overridden to check if we need to update our GraphicsDevice/Config
 800      * Added for 4934052.
 801      */
 802     @Override
 803     public void handleConfigureNotifyEvent(XEvent xev) {
 804         XConfigureEvent xe = xev.get_xconfigure();
 805         /*
 806          * Correct window location which could be wrong in some cases.
 807          * See getNewLocation() for the details.
 808          */
 809         Point newLocation = getNewLocation(xe, 0, 0);
 810         xe.set_x(newLocation.x);
 811         xe.set_y(newLocation.y);
 812         checkIfOnNewScreen(new Rectangle(xe.get_x(),
 813                                          xe.get_y(),
 814                                          xe.get_width(),
 815                                          xe.get_height()));
 816 
 817         // Don't call super until we've handled a screen change.  Otherwise
 818         // there could be a race condition in which a ComponentListener could
 819         // see the old screen.
 820         super.handleConfigureNotifyEvent(xev);
 821         repositionSecurityWarning();
 822     }
 823 
 824     final void requestXFocus(long time) {
 825         requestXFocus(time, true);
 826     }
 827 
 828     final void requestXFocus() {
 829         requestXFocus(0, false);
 830     }
 831 
 832     /**
 833      * Requests focus to this top-level. Descendants should override to provide
 834      * implementations based on a class of top-level.
 835      */


2098     }
2099 
2100     public void setGrab(boolean grab) {
2101         this.grab = grab;
2102         if (grab) {
2103             pressTarget = this;
2104             grabInput();
2105         } else {
2106             ungrabInput();
2107         }
2108     }
2109 
2110     public boolean isGrabbed() {
2111         return grab && XAwtState.getGrabWindow() == this;
2112     }
2113 
2114     public void handleXCrossingEvent(XEvent xev) {
2115         XCrossingEvent xce = xev.get_xcrossing();
2116         if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2117             grabLog.fine("{0}, when grabbed {1}, contains {2}",
2118                          xce, isGrabbed(), containsGlobal(xce.get_x_root(), xce.get_y_root()));


2119         }
2120         if (isGrabbed()) {
2121             // When window is grabbed, all events are dispatched to
2122             // it.  Retarget them to the corresponding windows (notice
2123             // that XBaseWindow.dispatchEvent does the opposite
2124             // translation)
2125             // Note that we need to retarget XCrossingEvents to content window
2126             // since it generates MOUSE_ENTERED/MOUSE_EXITED for frame and dialog.
2127             // (fix for 6390326)
2128             XBaseWindow target = XToolkit.windowToXWindow(xce.get_window());
2129             if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2130                 grabLog.finer("  -  Grab event target {0}", target);
2131             }
2132             if (target != null && target != this) {
2133                 target.dispatchEvent(xev);
2134                 return;
2135             }
2136         }
2137         super.handleXCrossingEvent(xev);
2138     }
2139 
2140     public void handleMotionNotify(XEvent xev) {
2141         XMotionEvent xme = xev.get_xmotion();
2142         if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2143             grabLog.finer("{0}, when grabbed {1}, contains {2}",
2144                           xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root()));


2145         }
2146         if (isGrabbed()) {
2147             boolean dragging = false;
2148             final int buttonsNumber = XToolkit.getNumberOfButtonsForMask();
2149 
2150             for (int i = 0; i < buttonsNumber; i++){
2151                 // here is the bug in WM: extra buttons doesn't have state!=0 as they should.
2152                 if ((i != 4) && (i != 5)){
2153                     dragging = dragging || ((xme.get_state() & XlibUtil.getButtonMask(i + 1)) != 0);
2154                 }
2155             }
2156             // When window is grabbed, all events are dispatched to
2157             // it.  Retarget them to the corresponding windows (notice
2158             // that XBaseWindow.dispatchEvent does the opposite
2159             // translation)
2160             XBaseWindow target = XToolkit.windowToXWindow(xme.get_window());
2161             if (dragging && pressTarget != target) {
2162                 // for some reasons if we grab input MotionNotify for drag is reported with target
2163                 // to underlying window, not to window on which we have initiated drag
2164                 // so we need to retarget them.  Here I use simplified logic which retarget all
2165                 // such events to source of mouse press (or the grabber).  It helps with fix for 6390326.
2166                 // So, I do not want to implement complicated logic for better retargeting.
2167                 target = pressTarget.isVisible() ? pressTarget : this;
2168                 xme.set_window(target.getWindow());
2169                 Point localCoord = target.toLocal(xme.get_x_root(), xme.get_y_root());
2170                 xme.set_x(localCoord.x);
2171                 xme.set_y(localCoord.y);

2172             }
2173             if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2174                 grabLog.finer("  -  Grab event target {0}", target);
2175             }
2176             if (target != null) {
2177                 if (target != getContentXWindow() && target != this) {
2178                     target.dispatchEvent(xev);
2179                     return;
2180                 }
2181             }
2182 
2183             // note that we need to pass dragging events to the grabber (6390326)
2184             // see comment above for more inforamtion.
2185             if (!containsGlobal(xme.get_x_root(), xme.get_y_root()) && !dragging) {


2186                 // Outside of Java
2187                 return;
2188             }
2189         }
2190         super.handleMotionNotify(xev);
2191     }
2192 
2193     // we use it to retarget mouse drag and mouse release during grab.
2194     private XBaseWindow pressTarget = this;
2195 
2196     public void handleButtonPressRelease(XEvent xev) {
2197         XButtonEvent xbe = xev.get_xbutton();
2198 
2199         /*
2200          * Ignore the buttons above 20 due to the bit limit for
2201          * InputEvent.BUTTON_DOWN_MASK.
2202          * One more bit is reserved for FIRST_HIGH_BIT.
2203          */
2204         if (xbe.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
2205             return;
2206         }
2207         if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2208             grabLog.fine("{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})",
2209                          xbe, isGrabbed(), containsGlobal(xbe.get_x_root(), xbe.get_y_root()), getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight());




2210         }
2211         if (isGrabbed()) {
2212             // When window is grabbed, all events are dispatched to
2213             // it.  Retarget them to the corresponding windows (notice
2214             // that XBaseWindow.dispatchEvent does the opposite
2215             // translation)
2216             XBaseWindow target = XToolkit.windowToXWindow(xbe.get_window());
2217             try {
2218                 if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2219                     grabLog.finer("  -  Grab event target {0} (press target {1})", target, pressTarget);
2220                 }
2221                 if (xbe.get_type() == XConstants.ButtonPress
2222                     && xbe.get_button() == XConstants.buttons[0])
2223                 {
2224                     // need to keep it to retarget mouse release
2225                     pressTarget = target;
2226                 } else if (xbe.get_type() == XConstants.ButtonRelease
2227                            && xbe.get_button() == XConstants.buttons[0]
2228                            && pressTarget != target)
2229                 {
2230                     // during grab we do receive mouse release on different component (not on the source
2231                     // of mouse press).  So we need to retarget it.
2232                     // see 6390326 for more information.
2233                     target = pressTarget.isVisible() ? pressTarget : this;
2234                     xbe.set_window(target.getWindow());
2235                     Point localCoord = target.toLocal(xbe.get_x_root(), xbe.get_y_root());
2236                     xbe.set_x(localCoord.x);
2237                     xbe.set_y(localCoord.y);

2238                     pressTarget = this;
2239                 }
2240                 if (target != null && target != getContentXWindow() && target != this) {
2241                     target.dispatchEvent(xev);
2242                     return;
2243                 }
2244             } finally {
2245                 if (target != null) {
2246                     // Target is either us or our content window -
2247                     // check that event is inside.  'Us' in case of
2248                     // shell will mean that this will also filter out press on title
2249                     if ((target == this || target == getContentXWindow()) && !containsGlobal(xbe.get_x_root(), xbe.get_y_root())) {



2250                         // Outside this toplevel hierarchy
2251                         // According to the specification of UngrabEvent, post it
2252                         // when press occurs outside of the window and not on its owned windows
2253                         if (xbe.get_type() == XConstants.ButtonPress) {
2254                             if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2255                                 grabLog.fine("Generating UngrabEvent on {0} because not inside of shell", this);
2256                             }
2257                             postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2258                             return;
2259                         }
2260                     }
2261                     // First, get the toplevel
2262                     XWindowPeer toplevel = target.getToplevelXWindow();
2263                     if (toplevel != null) {
2264                         Window w = (Window)toplevel.target;
2265                         while (w != null && toplevel != this && !(toplevel instanceof XDialogPeer)) {
2266                             w = (Window) AWTAccessor.getComponentAccessor().getParent(w);
2267                             if (w != null) {
2268                                 toplevel = AWTAccessor.getComponentAccessor().getPeer(w);
2269                             }




  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
  23  * questions.
  24  */
  25 package sun.awt.X11;
  26 
  27 import java.awt.*;
  28 
  29 import java.awt.event.ComponentEvent;
  30 import java.awt.event.FocusEvent;
  31 import java.awt.event.WindowEvent;
  32 import java.awt.geom.AffineTransform;
  33 
  34 import java.awt.peer.ComponentPeer;
  35 import java.awt.peer.WindowPeer;
  36 
  37 import java.io.UnsupportedEncodingException;
  38 
  39 import java.security.AccessController;
  40 import java.security.PrivilegedAction;
  41 
  42 import java.util.ArrayList;
  43 import java.util.HashSet;
  44 import java.util.Iterator;
  45 import java.util.Set;
  46 import java.util.Vector;
  47 
  48 import java.util.concurrent.atomic.AtomicBoolean;
  49 
  50 import sun.awt.AWTAccessor.ComponentAccessor;
  51 import sun.util.logging.PlatformLogger;
  52 


 734         SunToolkit.executeOnEventHandlerThread(target, dc);
 735     }
 736 
 737     /**
 738      * From the DisplayChangedListener interface; called from
 739      * X11GraphicsDevice when the display mode has been changed.
 740      */
 741     public void displayChanged() {
 742         executeDisplayChangedOnEDT(getGraphicsConfiguration());
 743     }
 744 
 745     /**
 746      * From the DisplayChangedListener interface; top-levels do not need
 747      * to react to this event.
 748      */
 749     public void paletteChanged() {
 750     }
 751 
 752     private Point queryXLocation()
 753     {
 754         return XlibUtil.translateCoordinates(getContentWindow(), XlibWrapper
 755                                              .RootWindow(XToolkit.getDisplay(),
 756                                              getScreenNumber()),
 757                                              new Point(0, 0), getScale());
 758     }
 759 
 760     protected Point getNewLocation(XConfigureEvent xe, int leftInset, int topInset) {
 761         // Bounds of the window
 762         Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds(target);
 763 
 764         int runningWM = XWM.getWMID();
 765         Point newLocation = targetBounds.getLocation();
 766         if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
 767             // Location, Client size + insets
 768             newLocation = new Point(scaleDown(xe.get_x()) - leftInset,
 769                                     scaleDown(xe.get_y()) - topInset);
 770         } else {
 771             // ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
 772             // a window is resized but the client can not tell if the window was
 773             // moved or not. The client should consider the position as unkown
 774             // and use TranslateCoordinates to find the actual position.
 775             //
 776             // TODO this should be the default for every case.
 777             switch (runningWM) {
 778                 case XWM.CDE_WM:
 779                 case XWM.MOTIF_WM:
 780                 case XWM.METACITY_WM:
 781                 case XWM.MUTTER_WM:
 782                 case XWM.SAWFISH_WM:
 783                 {
 784                     Point xlocation = queryXLocation();
 785                     if (log.isLoggable(PlatformLogger.Level.FINE)) {
 786                         log.fine("New X location: {0}", xlocation);
 787                     }
 788                     if (xlocation != null) {
 789                         newLocation = xlocation;


 792                 }
 793                 default:
 794                     break;
 795             }
 796         }
 797         return newLocation;
 798     }
 799 
 800     /*
 801      * Overridden to check if we need to update our GraphicsDevice/Config
 802      * Added for 4934052.
 803      */
 804     @Override
 805     public void handleConfigureNotifyEvent(XEvent xev) {
 806         XConfigureEvent xe = xev.get_xconfigure();
 807         /*
 808          * Correct window location which could be wrong in some cases.
 809          * See getNewLocation() for the details.
 810          */
 811         Point newLocation = getNewLocation(xe, 0, 0);
 812         xe.set_x(scaleUp(newLocation.x));
 813         xe.set_y(scaleUp(newLocation.y));
 814         checkIfOnNewScreen(new Rectangle(newLocation.x,
 815                                          newLocation.y,
 816                                          scaleDown(xe.get_width()),
 817                                          scaleDown(xe.get_height())));
 818 
 819         // Don't call super until we've handled a screen change.  Otherwise
 820         // there could be a race condition in which a ComponentListener could
 821         // see the old screen.
 822         super.handleConfigureNotifyEvent(xev);
 823         repositionSecurityWarning();
 824     }
 825 
 826     final void requestXFocus(long time) {
 827         requestXFocus(time, true);
 828     }
 829 
 830     final void requestXFocus() {
 831         requestXFocus(0, false);
 832     }
 833 
 834     /**
 835      * Requests focus to this top-level. Descendants should override to provide
 836      * implementations based on a class of top-level.
 837      */


2100     }
2101 
2102     public void setGrab(boolean grab) {
2103         this.grab = grab;
2104         if (grab) {
2105             pressTarget = this;
2106             grabInput();
2107         } else {
2108             ungrabInput();
2109         }
2110     }
2111 
2112     public boolean isGrabbed() {
2113         return grab && XAwtState.getGrabWindow() == this;
2114     }
2115 
2116     public void handleXCrossingEvent(XEvent xev) {
2117         XCrossingEvent xce = xev.get_xcrossing();
2118         if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2119             grabLog.fine("{0}, when grabbed {1}, contains {2}",
2120                          xce, isGrabbed(),
2121                          containsGlobal(scaleDown(xce.get_x_root()),
2122                                         scaleDown(xce.get_y_root())));
2123         }
2124         if (isGrabbed()) {
2125             // When window is grabbed, all events are dispatched to
2126             // it.  Retarget them to the corresponding windows (notice
2127             // that XBaseWindow.dispatchEvent does the opposite
2128             // translation)
2129             // Note that we need to retarget XCrossingEvents to content window
2130             // since it generates MOUSE_ENTERED/MOUSE_EXITED for frame and dialog.
2131             // (fix for 6390326)
2132             XBaseWindow target = XToolkit.windowToXWindow(xce.get_window());
2133             if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2134                 grabLog.finer("  -  Grab event target {0}", target);
2135             }
2136             if (target != null && target != this) {
2137                 target.dispatchEvent(xev);
2138                 return;
2139             }
2140         }
2141         super.handleXCrossingEvent(xev);
2142     }
2143 
2144     public void handleMotionNotify(XEvent xev) {
2145         XMotionEvent xme = xev.get_xmotion();
2146         if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2147             grabLog.finer("{0}, when grabbed {1}, contains {2}",
2148                           xme, isGrabbed(),
2149                           containsGlobal(scaleDown(xme.get_x_root()),
2150                                          scaleDown(xme.get_y_root())));
2151         }
2152         if (isGrabbed()) {
2153             boolean dragging = false;
2154             final int buttonsNumber = XToolkit.getNumberOfButtonsForMask();
2155 
2156             for (int i = 0; i < buttonsNumber; i++){
2157                 // here is the bug in WM: extra buttons doesn't have state!=0 as they should.
2158                 if ((i != 4) && (i != 5)){
2159                     dragging = dragging || ((xme.get_state() & XlibUtil.getButtonMask(i + 1)) != 0);
2160                 }
2161             }
2162             // When window is grabbed, all events are dispatched to
2163             // it.  Retarget them to the corresponding windows (notice
2164             // that XBaseWindow.dispatchEvent does the opposite
2165             // translation)
2166             XBaseWindow target = XToolkit.windowToXWindow(xme.get_window());
2167             if (dragging && pressTarget != target) {
2168                 // for some reasons if we grab input MotionNotify for drag is reported with target
2169                 // to underlying window, not to window on which we have initiated drag
2170                 // so we need to retarget them.  Here I use simplified logic which retarget all
2171                 // such events to source of mouse press (or the grabber).  It helps with fix for 6390326.
2172                 // So, I do not want to implement complicated logic for better retargeting.
2173                 target = pressTarget.isVisible() ? pressTarget : this;
2174                 xme.set_window(target.getWindow());
2175                 Point localCoord = target.toLocal(scaleDown(xme.get_x_root()),
2176                                                   scaleDown(xme.get_y_root()));
2177                 xme.set_x(scaleUp(localCoord.x));
2178                 xme.set_y(scaleUp(localCoord.y));
2179             }
2180             if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2181                 grabLog.finer("  -  Grab event target {0}", target);
2182             }
2183             if (target != null) {
2184                 if (target != getContentXWindow() && target != this) {
2185                     target.dispatchEvent(xev);
2186                     return;
2187                 }
2188             }
2189 
2190             // note that we need to pass dragging events to the grabber (6390326)
2191             // see comment above for more inforamtion.
2192             if (!containsGlobal(scaleDown(xme.get_x_root()),
2193                                 scaleDown(xme.get_y_root()))
2194                     && !dragging) {
2195                 // Outside of Java
2196                 return;
2197             }
2198         }
2199         super.handleMotionNotify(xev);
2200     }
2201 
2202     // we use it to retarget mouse drag and mouse release during grab.
2203     private XBaseWindow pressTarget = this;
2204 
2205     public void handleButtonPressRelease(XEvent xev) {
2206         XButtonEvent xbe = xev.get_xbutton();

2207         /*
2208          * Ignore the buttons above 20 due to the bit limit for
2209          * InputEvent.BUTTON_DOWN_MASK.
2210          * One more bit is reserved for FIRST_HIGH_BIT.
2211          */
2212         if (xbe.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
2213             return;
2214         }
2215         if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2216             grabLog.fine("{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})",
2217                          xbe, isGrabbed(),
2218                          containsGlobal(scaleDown(xbe.get_x_root()),
2219                                         scaleDown(xbe.get_y_root())),
2220                          getAbsoluteX(), getAbsoluteY(),
2221                          getWidth(), getHeight());
2222         }
2223         if (isGrabbed()) {
2224             // When window is grabbed, all events are dispatched to
2225             // it.  Retarget them to the corresponding windows (notice
2226             // that XBaseWindow.dispatchEvent does the opposite
2227             // translation)
2228             XBaseWindow target = XToolkit.windowToXWindow(xbe.get_window());
2229             try {
2230                 if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2231                     grabLog.finer("  -  Grab event target {0} (press target {1})", target, pressTarget);
2232                 }
2233                 if (xbe.get_type() == XConstants.ButtonPress
2234                     && xbe.get_button() == XConstants.buttons[0])
2235                 {
2236                     // need to keep it to retarget mouse release
2237                     pressTarget = target;
2238                 } else if (xbe.get_type() == XConstants.ButtonRelease
2239                            && xbe.get_button() == XConstants.buttons[0]
2240                            && pressTarget != target)
2241                 {
2242                     // during grab we do receive mouse release on different component (not on the source
2243                     // of mouse press).  So we need to retarget it.
2244                     // see 6390326 for more information.
2245                     target = pressTarget.isVisible() ? pressTarget : this;
2246                     xbe.set_window(target.getWindow());
2247                     Point localCoord = target.toLocal(scaleDown(xbe.get_x_root()),
2248                                                       scaleDown(xbe.get_y_root()));
2249                     xbe.set_x(scaleUp(localCoord.x));
2250                     xbe.set_y(scaleUp(localCoord.y));
2251                     pressTarget = this;
2252                 }
2253                 if (target != null && target != getContentXWindow() && target != this) {
2254                     target.dispatchEvent(xev);
2255                     return;
2256                 }
2257             } finally {
2258                 if (target != null) {
2259                     // Target is either us or our content window -
2260                     // check that event is inside.  'Us' in case of
2261                     // shell will mean that this will also filter out press on title
2262                     if ((target == this || target == getContentXWindow())
2263                             && !containsGlobal(scaleDown(xbe.get_x_root()),
2264                                                scaleDown(xbe.get_y_root())))
2265                     {
2266                         // Outside this toplevel hierarchy
2267                         // According to the specification of UngrabEvent, post it
2268                         // when press occurs outside of the window and not on its owned windows
2269                         if (xbe.get_type() == XConstants.ButtonPress) {
2270                             if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2271                                 grabLog.fine("Generating UngrabEvent on {0} because not inside of shell", this);
2272                             }
2273                             postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2274                             return;
2275                         }
2276                     }
2277                     // First, get the toplevel
2278                     XWindowPeer toplevel = target.getToplevelXWindow();
2279                     if (toplevel != null) {
2280                         Window w = (Window)toplevel.target;
2281                         while (w != null && toplevel != this && !(toplevel instanceof XDialogPeer)) {
2282                             w = (Window) AWTAccessor.getComponentAccessor().getParent(w);
2283                             if (w != null) {
2284                                 toplevel = AWTAccessor.getComponentAccessor().getPeer(w);
2285                             }


< prev index next >