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 }
|